]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blob - drivers/net/ethernet/intel/ice/ice_lag.c
blk-mq-debugfs: Show active requests per queue for shared tags
[mirror_ubuntu-kernels.git] / drivers / net / ethernet / intel / ice / ice_lag.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2018-2021, Intel Corporation. */
3
4 /* Link Aggregation code */
5
6 #include "ice.h"
7 #include "ice_lag.h"
8
9 /**
10 * ice_lag_nop_handler - no-op Rx handler to disable LAG
11 * @pskb: pointer to skb pointer
12 */
13 rx_handler_result_t ice_lag_nop_handler(struct sk_buff __always_unused **pskb)
14 {
15 return RX_HANDLER_PASS;
16 }
17
18 /**
19 * ice_lag_set_primary - set PF LAG state as Primary
20 * @lag: LAG info struct
21 */
22 static void ice_lag_set_primary(struct ice_lag *lag)
23 {
24 struct ice_pf *pf = lag->pf;
25
26 if (!pf)
27 return;
28
29 if (lag->role != ICE_LAG_UNSET && lag->role != ICE_LAG_BACKUP) {
30 dev_warn(ice_pf_to_dev(pf), "%s: Attempt to be Primary, but incompatible state.\n",
31 netdev_name(lag->netdev));
32 return;
33 }
34
35 lag->role = ICE_LAG_PRIMARY;
36 }
37
38 /**
39 * ice_lag_set_backup - set PF LAG state to Backup
40 * @lag: LAG info struct
41 */
42 static void ice_lag_set_backup(struct ice_lag *lag)
43 {
44 struct ice_pf *pf = lag->pf;
45
46 if (!pf)
47 return;
48
49 if (lag->role != ICE_LAG_UNSET && lag->role != ICE_LAG_PRIMARY) {
50 dev_dbg(ice_pf_to_dev(pf), "%s: Attempt to be Backup, but incompatible state\n",
51 netdev_name(lag->netdev));
52 return;
53 }
54
55 lag->role = ICE_LAG_BACKUP;
56 }
57
58 /**
59 * ice_display_lag_info - print LAG info
60 * @lag: LAG info struct
61 */
62 static void ice_display_lag_info(struct ice_lag *lag)
63 {
64 const char *name, *peer, *upper, *role, *bonded, *master;
65 struct device *dev = &lag->pf->pdev->dev;
66
67 name = lag->netdev ? netdev_name(lag->netdev) : "unset";
68 peer = lag->peer_netdev ? netdev_name(lag->peer_netdev) : "unset";
69 upper = lag->upper_netdev ? netdev_name(lag->upper_netdev) : "unset";
70 master = lag->master ? "TRUE" : "FALSE";
71 bonded = lag->bonded ? "BONDED" : "UNBONDED";
72
73 switch (lag->role) {
74 case ICE_LAG_NONE:
75 role = "NONE";
76 break;
77 case ICE_LAG_PRIMARY:
78 role = "PRIMARY";
79 break;
80 case ICE_LAG_BACKUP:
81 role = "BACKUP";
82 break;
83 case ICE_LAG_UNSET:
84 role = "UNSET";
85 break;
86 default:
87 role = "ERROR";
88 }
89
90 dev_dbg(dev, "%s %s, peer:%s, upper:%s, role:%s, master:%s\n", name,
91 bonded, peer, upper, role, master);
92 }
93
94 /**
95 * ice_lag_info_event - handle NETDEV_BONDING_INFO event
96 * @lag: LAG info struct
97 * @ptr: opaque data pointer
98 *
99 * ptr is to be cast to (netdev_notifier_bonding_info *)
100 */
101 static void ice_lag_info_event(struct ice_lag *lag, void *ptr)
102 {
103 struct net_device *event_netdev, *netdev_tmp;
104 struct netdev_notifier_bonding_info *info;
105 struct netdev_bonding_info *bonding_info;
106 const char *lag_netdev_name;
107
108 event_netdev = netdev_notifier_info_to_dev(ptr);
109 info = ptr;
110 lag_netdev_name = netdev_name(lag->netdev);
111 bonding_info = &info->bonding_info;
112
113 if (event_netdev != lag->netdev || !lag->bonded || !lag->upper_netdev)
114 return;
115
116 if (bonding_info->master.bond_mode != BOND_MODE_ACTIVEBACKUP) {
117 netdev_dbg(lag->netdev, "Bonding event recv, but mode not active/backup\n");
118 goto lag_out;
119 }
120
121 if (strcmp(bonding_info->slave.slave_name, lag_netdev_name)) {
122 netdev_dbg(lag->netdev, "Bonding event recv, but slave info not for us\n");
123 goto lag_out;
124 }
125
126 rcu_read_lock();
127 for_each_netdev_in_bond_rcu(lag->upper_netdev, netdev_tmp) {
128 if (!netif_is_ice(netdev_tmp))
129 continue;
130
131 if (netdev_tmp && netdev_tmp != lag->netdev &&
132 lag->peer_netdev != netdev_tmp) {
133 dev_hold(netdev_tmp);
134 lag->peer_netdev = netdev_tmp;
135 }
136 }
137 rcu_read_unlock();
138
139 if (bonding_info->slave.state)
140 ice_lag_set_backup(lag);
141 else
142 ice_lag_set_primary(lag);
143
144 lag_out:
145 ice_display_lag_info(lag);
146 }
147
148 /**
149 * ice_lag_link - handle LAG link event
150 * @lag: LAG info struct
151 * @info: info from the netdev notifier
152 */
153 static void
154 ice_lag_link(struct ice_lag *lag, struct netdev_notifier_changeupper_info *info)
155 {
156 struct net_device *netdev_tmp, *upper = info->upper_dev;
157 struct ice_pf *pf = lag->pf;
158 int peers = 0;
159
160 if (lag->bonded)
161 dev_warn(ice_pf_to_dev(pf), "%s Already part of a bond\n",
162 netdev_name(lag->netdev));
163
164 rcu_read_lock();
165 for_each_netdev_in_bond_rcu(upper, netdev_tmp)
166 peers++;
167 rcu_read_unlock();
168
169 if (lag->upper_netdev != upper) {
170 dev_hold(upper);
171 lag->upper_netdev = upper;
172 }
173
174 ice_clear_sriov_cap(pf);
175 ice_clear_rdma_cap(pf);
176
177 lag->bonded = true;
178 lag->role = ICE_LAG_UNSET;
179
180 /* if this is the first element in an LAG mark as master */
181 lag->master = !!(peers == 1);
182 }
183
184 /**
185 * ice_lag_unlink - handle unlink event
186 * @lag: LAG info struct
187 * @info: info from netdev notification
188 */
189 static void
190 ice_lag_unlink(struct ice_lag *lag,
191 struct netdev_notifier_changeupper_info *info)
192 {
193 struct net_device *netdev_tmp, *upper = info->upper_dev;
194 struct ice_pf *pf = lag->pf;
195 bool found = false;
196
197 if (!lag->bonded) {
198 netdev_dbg(lag->netdev, "bonding unlink event on non-LAG netdev\n");
199 return;
200 }
201
202 /* determine if we are in the new LAG config or not */
203 rcu_read_lock();
204 for_each_netdev_in_bond_rcu(upper, netdev_tmp) {
205 if (netdev_tmp == lag->netdev) {
206 found = true;
207 break;
208 }
209 }
210 rcu_read_unlock();
211
212 if (found)
213 return;
214
215 if (lag->upper_netdev) {
216 dev_put(lag->upper_netdev);
217 lag->upper_netdev = NULL;
218 }
219
220 if (lag->peer_netdev) {
221 dev_put(lag->peer_netdev);
222 lag->peer_netdev = NULL;
223 }
224
225 ice_set_sriov_cap(pf);
226 ice_set_rdma_cap(pf);
227 lag->bonded = false;
228 lag->role = ICE_LAG_NONE;
229 }
230
231 /**
232 * ice_lag_changeupper_event - handle LAG changeupper event
233 * @lag: LAG info struct
234 * @ptr: opaque pointer data
235 *
236 * ptr is to be cast into netdev_notifier_changeupper_info
237 */
238 static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)
239 {
240 struct netdev_notifier_changeupper_info *info;
241 struct net_device *netdev;
242
243 info = ptr;
244 netdev = netdev_notifier_info_to_dev(ptr);
245
246 /* not for this netdev */
247 if (netdev != lag->netdev)
248 return;
249
250 if (!info->upper_dev) {
251 netdev_dbg(netdev, "changeupper rcvd, but no upper defined\n");
252 return;
253 }
254
255 netdev_dbg(netdev, "bonding %s\n", info->linking ? "LINK" : "UNLINK");
256
257 if (!netif_is_lag_master(info->upper_dev)) {
258 netdev_dbg(netdev, "changeupper rcvd, but not master. bail\n");
259 return;
260 }
261
262 if (info->linking)
263 ice_lag_link(lag, info);
264 else
265 ice_lag_unlink(lag, info);
266
267 ice_display_lag_info(lag);
268 }
269
270 /**
271 * ice_lag_changelower_event - handle LAG changelower event
272 * @lag: LAG info struct
273 * @ptr: opaque data pointer
274 *
275 * ptr to be cast to netdev_notifier_changelowerstate_info
276 */
277 static void ice_lag_changelower_event(struct ice_lag *lag, void *ptr)
278 {
279 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
280
281 if (netdev != lag->netdev)
282 return;
283
284 netdev_dbg(netdev, "bonding info\n");
285
286 if (!netif_is_lag_port(netdev))
287 netdev_dbg(netdev, "CHANGELOWER rcvd, but netdev not in LAG. Bail\n");
288 }
289
290 /**
291 * ice_lag_event_handler - handle LAG events from netdev
292 * @notif_blk: notifier block registered by this netdev
293 * @event: event type
294 * @ptr: opaque data containing notifier event
295 */
296 static int
297 ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,
298 void *ptr)
299 {
300 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
301 struct ice_lag *lag;
302
303 lag = container_of(notif_blk, struct ice_lag, notif_block);
304
305 if (!lag->netdev)
306 return NOTIFY_DONE;
307
308 /* Check that the netdev is in the working namespace */
309 if (!net_eq(dev_net(netdev), &init_net))
310 return NOTIFY_DONE;
311
312 switch (event) {
313 case NETDEV_CHANGEUPPER:
314 ice_lag_changeupper_event(lag, ptr);
315 break;
316 case NETDEV_CHANGELOWERSTATE:
317 ice_lag_changelower_event(lag, ptr);
318 break;
319 case NETDEV_BONDING_INFO:
320 ice_lag_info_event(lag, ptr);
321 break;
322 default:
323 break;
324 }
325
326 return NOTIFY_DONE;
327 }
328
329 /**
330 * ice_register_lag_handler - register LAG handler on netdev
331 * @lag: LAG struct
332 */
333 static int ice_register_lag_handler(struct ice_lag *lag)
334 {
335 struct device *dev = ice_pf_to_dev(lag->pf);
336 struct notifier_block *notif_blk;
337
338 notif_blk = &lag->notif_block;
339
340 if (!notif_blk->notifier_call) {
341 notif_blk->notifier_call = ice_lag_event_handler;
342 if (register_netdevice_notifier(notif_blk)) {
343 notif_blk->notifier_call = NULL;
344 dev_err(dev, "FAIL register LAG event handler!\n");
345 return -EINVAL;
346 }
347 dev_dbg(dev, "LAG event handler registered\n");
348 }
349 return 0;
350 }
351
352 /**
353 * ice_unregister_lag_handler - unregister LAG handler on netdev
354 * @lag: LAG struct
355 */
356 static void ice_unregister_lag_handler(struct ice_lag *lag)
357 {
358 struct device *dev = ice_pf_to_dev(lag->pf);
359 struct notifier_block *notif_blk;
360
361 notif_blk = &lag->notif_block;
362 if (notif_blk->notifier_call) {
363 unregister_netdevice_notifier(notif_blk);
364 dev_dbg(dev, "LAG event handler unregistered\n");
365 }
366 }
367
368 /**
369 * ice_init_lag - initialize support for LAG
370 * @pf: PF struct
371 *
372 * Alloc memory for LAG structs and initialize the elements.
373 * Memory will be freed in ice_deinit_lag
374 */
375 int ice_init_lag(struct ice_pf *pf)
376 {
377 struct device *dev = ice_pf_to_dev(pf);
378 struct ice_lag *lag;
379 struct ice_vsi *vsi;
380 int err;
381
382 pf->lag = kzalloc(sizeof(*lag), GFP_KERNEL);
383 if (!pf->lag)
384 return -ENOMEM;
385 lag = pf->lag;
386
387 vsi = ice_get_main_vsi(pf);
388 if (!vsi) {
389 dev_err(dev, "couldn't get main vsi, link aggregation init fail\n");
390 err = -EIO;
391 goto lag_error;
392 }
393
394 lag->pf = pf;
395 lag->netdev = vsi->netdev;
396 lag->role = ICE_LAG_NONE;
397 lag->bonded = false;
398 lag->peer_netdev = NULL;
399 lag->upper_netdev = NULL;
400 lag->notif_block.notifier_call = NULL;
401
402 err = ice_register_lag_handler(lag);
403 if (err) {
404 dev_warn(dev, "INIT LAG: Failed to register event handler\n");
405 goto lag_error;
406 }
407
408 ice_display_lag_info(lag);
409
410 dev_dbg(dev, "INIT LAG complete\n");
411 return 0;
412
413 lag_error:
414 kfree(lag);
415 pf->lag = NULL;
416 return err;
417 }
418
419 /**
420 * ice_deinit_lag - Clean up LAG
421 * @pf: PF struct
422 *
423 * Clean up kernel LAG info and free memory
424 * This function is meant to only be called on driver remove/shutdown
425 */
426 void ice_deinit_lag(struct ice_pf *pf)
427 {
428 struct ice_lag *lag;
429
430 lag = pf->lag;
431
432 if (!lag)
433 return;
434
435 if (lag->pf)
436 ice_unregister_lag_handler(lag);
437
438 if (lag->upper_netdev)
439 dev_put(lag->upper_netdev);
440
441 if (lag->peer_netdev)
442 dev_put(lag->peer_netdev);
443
444 kfree(lag);
445
446 pf->lag = NULL;
447 }