• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3  * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33 
34 #include <linux/slab.h>
35 #include <linux/export.h>
36 #include <linux/errno.h>
37 #include <net/devlink.h>
38 
39 #include "mlx4.h"
40 
41 static DEFINE_MUTEX(intf_mutex);
42 static DEFINE_IDA(mlx4_adev_ida);
43 
is_eth_supported(struct mlx4_dev * dev)44 static bool is_eth_supported(struct mlx4_dev *dev)
45 {
46 	for (int port = 1; port <= dev->caps.num_ports; port++)
47 		if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
48 			return true;
49 
50 	return false;
51 }
52 
is_ib_supported(struct mlx4_dev * dev)53 static bool is_ib_supported(struct mlx4_dev *dev)
54 {
55 	for (int port = 1; port <= dev->caps.num_ports; port++)
56 		if (dev->caps.port_type[port] == MLX4_PORT_TYPE_IB)
57 			return true;
58 
59 	if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE)
60 		return true;
61 
62 	return false;
63 }
64 
65 static const struct mlx4_adev_device {
66 	const char *suffix;
67 	bool (*is_supported)(struct mlx4_dev *dev);
68 } mlx4_adev_devices[] = {
69 	{ "eth", is_eth_supported },
70 	{ "ib", is_ib_supported },
71 };
72 
mlx4_adev_init(struct mlx4_dev * dev)73 int mlx4_adev_init(struct mlx4_dev *dev)
74 {
75 	struct mlx4_priv *priv = mlx4_priv(dev);
76 
77 	priv->adev_idx = ida_alloc(&mlx4_adev_ida, GFP_KERNEL);
78 	if (priv->adev_idx < 0)
79 		return priv->adev_idx;
80 
81 	priv->adev = kcalloc(ARRAY_SIZE(mlx4_adev_devices),
82 			     sizeof(struct mlx4_adev *), GFP_KERNEL);
83 	if (!priv->adev) {
84 		ida_free(&mlx4_adev_ida, priv->adev_idx);
85 		return -ENOMEM;
86 	}
87 
88 	return 0;
89 }
90 
mlx4_adev_cleanup(struct mlx4_dev * dev)91 void mlx4_adev_cleanup(struct mlx4_dev *dev)
92 {
93 	struct mlx4_priv *priv = mlx4_priv(dev);
94 
95 	kfree(priv->adev);
96 	ida_free(&mlx4_adev_ida, priv->adev_idx);
97 }
98 
adev_release(struct device * dev)99 static void adev_release(struct device *dev)
100 {
101 	struct mlx4_adev *mlx4_adev =
102 		container_of(dev, struct mlx4_adev, adev.dev);
103 	struct mlx4_priv *priv = mlx4_priv(mlx4_adev->mdev);
104 	int idx = mlx4_adev->idx;
105 
106 	kfree(mlx4_adev);
107 	priv->adev[idx] = NULL;
108 }
109 
add_adev(struct mlx4_dev * dev,int idx)110 static struct mlx4_adev *add_adev(struct mlx4_dev *dev, int idx)
111 {
112 	struct mlx4_priv *priv = mlx4_priv(dev);
113 	const char *suffix = mlx4_adev_devices[idx].suffix;
114 	struct auxiliary_device *adev;
115 	struct mlx4_adev *madev;
116 	int ret;
117 
118 	madev = kzalloc(sizeof(*madev), GFP_KERNEL);
119 	if (!madev)
120 		return ERR_PTR(-ENOMEM);
121 
122 	adev = &madev->adev;
123 	adev->id = priv->adev_idx;
124 	adev->name = suffix;
125 	adev->dev.parent = &dev->persist->pdev->dev;
126 	adev->dev.release = adev_release;
127 	madev->mdev = dev;
128 	madev->idx = idx;
129 
130 	ret = auxiliary_device_init(adev);
131 	if (ret) {
132 		kfree(madev);
133 		return ERR_PTR(ret);
134 	}
135 
136 	ret = auxiliary_device_add(adev);
137 	if (ret) {
138 		auxiliary_device_uninit(adev);
139 		return ERR_PTR(ret);
140 	}
141 	return madev;
142 }
143 
del_adev(struct auxiliary_device * adev)144 static void del_adev(struct auxiliary_device *adev)
145 {
146 	auxiliary_device_delete(adev);
147 	auxiliary_device_uninit(adev);
148 }
149 
mlx4_register_auxiliary_driver(struct mlx4_adrv * madrv)150 int mlx4_register_auxiliary_driver(struct mlx4_adrv *madrv)
151 {
152 	return auxiliary_driver_register(&madrv->adrv);
153 }
154 EXPORT_SYMBOL_GPL(mlx4_register_auxiliary_driver);
155 
mlx4_unregister_auxiliary_driver(struct mlx4_adrv * madrv)156 void mlx4_unregister_auxiliary_driver(struct mlx4_adrv *madrv)
157 {
158 	auxiliary_driver_unregister(&madrv->adrv);
159 }
160 EXPORT_SYMBOL_GPL(mlx4_unregister_auxiliary_driver);
161 
mlx4_do_bond(struct mlx4_dev * dev,bool enable)162 int mlx4_do_bond(struct mlx4_dev *dev, bool enable)
163 {
164 	struct mlx4_priv *priv = mlx4_priv(dev);
165 	int i, ret;
166 
167 	if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PORT_REMAP))
168 		return -EOPNOTSUPP;
169 
170 	ret = mlx4_disable_rx_port_check(dev, enable);
171 	if (ret) {
172 		mlx4_err(dev, "Fail to %s rx port check\n",
173 			 enable ? "enable" : "disable");
174 		return ret;
175 	}
176 	if (enable) {
177 		dev->flags |= MLX4_FLAG_BONDED;
178 	} else {
179 		ret = mlx4_virt2phy_port_map(dev, 1, 2);
180 		if (ret) {
181 			mlx4_err(dev, "Fail to reset port map\n");
182 			return ret;
183 		}
184 		dev->flags &= ~MLX4_FLAG_BONDED;
185 	}
186 
187 	mutex_lock(&intf_mutex);
188 
189 	for (i = 0; i < ARRAY_SIZE(mlx4_adev_devices); i++) {
190 		struct mlx4_adev *madev = priv->adev[i];
191 		struct mlx4_adrv *madrv;
192 		enum mlx4_protocol protocol;
193 
194 		if (!madev)
195 			continue;
196 
197 		device_lock(&madev->adev.dev);
198 		if (!madev->adev.dev.driver) {
199 			device_unlock(&madev->adev.dev);
200 			continue;
201 		}
202 
203 		madrv = container_of(madev->adev.dev.driver, struct mlx4_adrv,
204 				     adrv.driver);
205 		if (!(madrv->flags & MLX4_INTFF_BONDING)) {
206 			device_unlock(&madev->adev.dev);
207 			continue;
208 		}
209 
210 		if (mlx4_is_mfunc(dev)) {
211 			mlx4_dbg(dev,
212 				 "SRIOV, disabled HA mode for intf proto %d\n",
213 				 madrv->protocol);
214 			device_unlock(&madev->adev.dev);
215 			continue;
216 		}
217 
218 		protocol = madrv->protocol;
219 		device_unlock(&madev->adev.dev);
220 
221 		del_adev(&madev->adev);
222 		priv->adev[i] = add_adev(dev, i);
223 		if (IS_ERR(priv->adev[i])) {
224 			mlx4_warn(dev, "Device[%d] (%s) failed to load\n", i,
225 				  mlx4_adev_devices[i].suffix);
226 			priv->adev[i] = NULL;
227 			continue;
228 		}
229 
230 		mlx4_dbg(dev,
231 			 "Interface for protocol %d restarted with bonded mode %s\n",
232 			 protocol, enable ? "enabled" : "disabled");
233 	}
234 
235 	mutex_unlock(&intf_mutex);
236 
237 	return 0;
238 }
239 
mlx4_dispatch_event(struct mlx4_dev * dev,enum mlx4_dev_event type,void * param)240 void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type,
241 			 void *param)
242 {
243 	struct mlx4_priv *priv = mlx4_priv(dev);
244 
245 	atomic_notifier_call_chain(&priv->event_nh, type, param);
246 }
247 
mlx4_register_event_notifier(struct mlx4_dev * dev,struct notifier_block * nb)248 int mlx4_register_event_notifier(struct mlx4_dev *dev,
249 				 struct notifier_block *nb)
250 {
251 	struct mlx4_priv *priv = mlx4_priv(dev);
252 
253 	return atomic_notifier_chain_register(&priv->event_nh, nb);
254 }
255 EXPORT_SYMBOL(mlx4_register_event_notifier);
256 
mlx4_unregister_event_notifier(struct mlx4_dev * dev,struct notifier_block * nb)257 int mlx4_unregister_event_notifier(struct mlx4_dev *dev,
258 				   struct notifier_block *nb)
259 {
260 	struct mlx4_priv *priv = mlx4_priv(dev);
261 
262 	return atomic_notifier_chain_unregister(&priv->event_nh, nb);
263 }
264 EXPORT_SYMBOL(mlx4_unregister_event_notifier);
265 
add_drivers(struct mlx4_dev * dev)266 static int add_drivers(struct mlx4_dev *dev)
267 {
268 	struct mlx4_priv *priv = mlx4_priv(dev);
269 	int i, ret = 0;
270 
271 	for (i = 0; i < ARRAY_SIZE(mlx4_adev_devices); i++) {
272 		bool is_supported = false;
273 
274 		if (priv->adev[i])
275 			continue;
276 
277 		if (mlx4_adev_devices[i].is_supported)
278 			is_supported = mlx4_adev_devices[i].is_supported(dev);
279 
280 		if (!is_supported)
281 			continue;
282 
283 		priv->adev[i] = add_adev(dev, i);
284 		if (IS_ERR(priv->adev[i])) {
285 			mlx4_warn(dev, "Device[%d] (%s) failed to load\n", i,
286 				  mlx4_adev_devices[i].suffix);
287 			/* We continue to rescan drivers and leave to the caller
288 			 * to make decision if to release everything or
289 			 * continue. */
290 			ret = PTR_ERR(priv->adev[i]);
291 			priv->adev[i] = NULL;
292 		}
293 	}
294 	return ret;
295 }
296 
delete_drivers(struct mlx4_dev * dev)297 static void delete_drivers(struct mlx4_dev *dev)
298 {
299 	struct mlx4_priv *priv = mlx4_priv(dev);
300 	bool delete_all;
301 	int i;
302 
303 	delete_all = !(dev->persist->interface_state & MLX4_INTERFACE_STATE_UP);
304 
305 	for (i = ARRAY_SIZE(mlx4_adev_devices) - 1; i >= 0; i--) {
306 		bool is_supported = false;
307 
308 		if (!priv->adev[i])
309 			continue;
310 
311 		if (mlx4_adev_devices[i].is_supported && !delete_all)
312 			is_supported = mlx4_adev_devices[i].is_supported(dev);
313 
314 		if (is_supported)
315 			continue;
316 
317 		del_adev(&priv->adev[i]->adev);
318 		priv->adev[i] = NULL;
319 	}
320 }
321 
322 /* This function is used after mlx4_dev is reconfigured.
323  */
rescan_drivers_locked(struct mlx4_dev * dev)324 static int rescan_drivers_locked(struct mlx4_dev *dev)
325 {
326 	lockdep_assert_held(&intf_mutex);
327 
328 	delete_drivers(dev);
329 	if (!(dev->persist->interface_state & MLX4_INTERFACE_STATE_UP))
330 		return 0;
331 
332 	return add_drivers(dev);
333 }
334 
mlx4_register_device(struct mlx4_dev * dev)335 int mlx4_register_device(struct mlx4_dev *dev)
336 {
337 	int ret;
338 
339 	mutex_lock(&intf_mutex);
340 
341 	dev->persist->interface_state |= MLX4_INTERFACE_STATE_UP;
342 
343 	ret = rescan_drivers_locked(dev);
344 
345 	mutex_unlock(&intf_mutex);
346 
347 	if (ret) {
348 		mlx4_unregister_device(dev);
349 		return ret;
350 	}
351 
352 	mlx4_start_catas_poll(dev);
353 
354 	return ret;
355 }
356 
mlx4_unregister_device(struct mlx4_dev * dev)357 void mlx4_unregister_device(struct mlx4_dev *dev)
358 {
359 	if (!(dev->persist->interface_state & MLX4_INTERFACE_STATE_UP))
360 		return;
361 
362 	mlx4_stop_catas_poll(dev);
363 	if (dev->persist->interface_state & MLX4_INTERFACE_STATE_DELETION &&
364 	    mlx4_is_slave(dev)) {
365 		/* In mlx4_remove_one on a VF */
366 		u32 slave_read =
367 			swab32(readl(&mlx4_priv(dev)->mfunc.comm->slave_read));
368 
369 		if (mlx4_comm_internal_err(slave_read)) {
370 			mlx4_dbg(dev, "%s: comm channel is down, entering error state.\n",
371 				 __func__);
372 			mlx4_enter_error_state(dev->persist);
373 		}
374 	}
375 	mutex_lock(&intf_mutex);
376 
377 	dev->persist->interface_state &= ~MLX4_INTERFACE_STATE_UP;
378 
379 	rescan_drivers_locked(dev);
380 
381 	mutex_unlock(&intf_mutex);
382 }
383 
mlx4_get_devlink_port(struct mlx4_dev * dev,int port)384 struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port)
385 {
386 	struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
387 
388 	return &info->devlink_port;
389 }
390 EXPORT_SYMBOL_GPL(mlx4_get_devlink_port);
391