1
2
3
4
5
6#include "ice.h"
7#include "ice_lag.h"
8
9
10
11
12
13rx_handler_result_t ice_lag_nop_handler(struct sk_buff __always_unused **pskb)
14{
15 return RX_HANDLER_PASS;
16}
17
18
19
20
21
22static 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
40
41
42static 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
60
61
62static 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
96
97
98
99
100
101static void ice_lag_info_event(struct ice_lag *lag, void *ptr)
102{
103 struct netdev_notifier_bonding_info *info;
104 struct netdev_bonding_info *bonding_info;
105 struct net_device *event_netdev;
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 if (bonding_info->slave.state)
127 ice_lag_set_backup(lag);
128 else
129 ice_lag_set_primary(lag);
130
131lag_out:
132 ice_display_lag_info(lag);
133}
134
135
136
137
138
139
140static void
141ice_lag_link(struct ice_lag *lag, struct netdev_notifier_changeupper_info *info)
142{
143 struct net_device *netdev_tmp, *upper = info->upper_dev;
144 struct ice_pf *pf = lag->pf;
145 int peers = 0;
146
147 if (lag->bonded)
148 dev_warn(ice_pf_to_dev(pf), "%s Already part of a bond\n",
149 netdev_name(lag->netdev));
150
151 rcu_read_lock();
152 for_each_netdev_in_bond_rcu(upper, netdev_tmp)
153 peers++;
154 rcu_read_unlock();
155
156 if (lag->upper_netdev != upper) {
157 dev_hold(upper);
158 lag->upper_netdev = upper;
159 }
160
161 ice_clear_sriov_cap(pf);
162 ice_clear_rdma_cap(pf);
163
164 lag->bonded = true;
165 lag->role = ICE_LAG_UNSET;
166
167
168 lag->master = !!(peers == 1);
169}
170
171
172
173
174
175
176static void
177ice_lag_unlink(struct ice_lag *lag,
178 struct netdev_notifier_changeupper_info *info)
179{
180 struct net_device *netdev_tmp, *upper = info->upper_dev;
181 struct ice_pf *pf = lag->pf;
182 bool found = false;
183
184 if (!lag->bonded) {
185 netdev_dbg(lag->netdev, "bonding unlink event on non-LAG netdev\n");
186 return;
187 }
188
189
190 rcu_read_lock();
191 for_each_netdev_in_bond_rcu(upper, netdev_tmp) {
192 if (netdev_tmp == lag->netdev) {
193 found = true;
194 break;
195 }
196 }
197 rcu_read_unlock();
198
199 if (found)
200 return;
201
202 if (lag->upper_netdev) {
203 dev_put(lag->upper_netdev);
204 lag->upper_netdev = NULL;
205 }
206
207 if (lag->peer_netdev) {
208 dev_put(lag->peer_netdev);
209 lag->peer_netdev = NULL;
210 }
211
212 ice_set_sriov_cap(pf);
213 ice_set_rdma_cap(pf);
214 lag->bonded = false;
215 lag->role = ICE_LAG_NONE;
216}
217
218
219
220
221
222
223
224
225static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)
226{
227 struct netdev_notifier_changeupper_info *info;
228 struct net_device *netdev;
229
230 info = ptr;
231 netdev = netdev_notifier_info_to_dev(ptr);
232
233
234 if (netdev != lag->netdev)
235 return;
236
237 if (!info->upper_dev) {
238 netdev_dbg(netdev, "changeupper rcvd, but no upper defined\n");
239 return;
240 }
241
242 netdev_dbg(netdev, "bonding %s\n", info->linking ? "LINK" : "UNLINK");
243
244 if (!netif_is_lag_master(info->upper_dev)) {
245 netdev_dbg(netdev, "changeupper rcvd, but not master. bail\n");
246 return;
247 }
248
249 if (info->linking)
250 ice_lag_link(lag, info);
251 else
252 ice_lag_unlink(lag, info);
253
254 ice_display_lag_info(lag);
255}
256
257
258
259
260
261
262
263
264static void ice_lag_changelower_event(struct ice_lag *lag, void *ptr)
265{
266 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
267
268 if (netdev != lag->netdev)
269 return;
270
271 netdev_dbg(netdev, "bonding info\n");
272
273 if (!netif_is_lag_port(netdev))
274 netdev_dbg(netdev, "CHANGELOWER rcvd, but netdev not in LAG. Bail\n");
275}
276
277
278
279
280
281
282
283static int
284ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,
285 void *ptr)
286{
287 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
288 struct ice_lag *lag;
289
290 lag = container_of(notif_blk, struct ice_lag, notif_block);
291
292 if (!lag->netdev)
293 return NOTIFY_DONE;
294
295
296 if (!net_eq(dev_net(netdev), &init_net))
297 return NOTIFY_DONE;
298
299 switch (event) {
300 case NETDEV_CHANGEUPPER:
301 ice_lag_changeupper_event(lag, ptr);
302 break;
303 case NETDEV_CHANGELOWERSTATE:
304 ice_lag_changelower_event(lag, ptr);
305 break;
306 case NETDEV_BONDING_INFO:
307 ice_lag_info_event(lag, ptr);
308 break;
309 case NETDEV_UNREGISTER:
310 ice_lag_unlink(lag, ptr);
311 break;
312 default:
313 break;
314 }
315
316 return NOTIFY_DONE;
317}
318
319
320
321
322
323static int ice_register_lag_handler(struct ice_lag *lag)
324{
325 struct device *dev = ice_pf_to_dev(lag->pf);
326 struct notifier_block *notif_blk;
327
328 notif_blk = &lag->notif_block;
329
330 if (!notif_blk->notifier_call) {
331 notif_blk->notifier_call = ice_lag_event_handler;
332 if (register_netdevice_notifier(notif_blk)) {
333 notif_blk->notifier_call = NULL;
334 dev_err(dev, "FAIL register LAG event handler!\n");
335 return -EINVAL;
336 }
337 dev_dbg(dev, "LAG event handler registered\n");
338 }
339 return 0;
340}
341
342
343
344
345
346static void ice_unregister_lag_handler(struct ice_lag *lag)
347{
348 struct device *dev = ice_pf_to_dev(lag->pf);
349 struct notifier_block *notif_blk;
350
351 notif_blk = &lag->notif_block;
352 if (notif_blk->notifier_call) {
353 unregister_netdevice_notifier(notif_blk);
354 dev_dbg(dev, "LAG event handler unregistered\n");
355 }
356}
357
358
359
360
361
362
363
364
365int ice_init_lag(struct ice_pf *pf)
366{
367 struct device *dev = ice_pf_to_dev(pf);
368 struct ice_lag *lag;
369 struct ice_vsi *vsi;
370 int err;
371
372 pf->lag = kzalloc(sizeof(*lag), GFP_KERNEL);
373 if (!pf->lag)
374 return -ENOMEM;
375 lag = pf->lag;
376
377 vsi = ice_get_main_vsi(pf);
378 if (!vsi) {
379 dev_err(dev, "couldn't get main vsi, link aggregation init fail\n");
380 err = -EIO;
381 goto lag_error;
382 }
383
384 lag->pf = pf;
385 lag->netdev = vsi->netdev;
386 lag->role = ICE_LAG_NONE;
387 lag->bonded = false;
388 lag->peer_netdev = NULL;
389 lag->upper_netdev = NULL;
390 lag->notif_block.notifier_call = NULL;
391
392 err = ice_register_lag_handler(lag);
393 if (err) {
394 dev_warn(dev, "INIT LAG: Failed to register event handler\n");
395 goto lag_error;
396 }
397
398 ice_display_lag_info(lag);
399
400 dev_dbg(dev, "INIT LAG complete\n");
401 return 0;
402
403lag_error:
404 kfree(lag);
405 pf->lag = NULL;
406 return err;
407}
408
409
410
411
412
413
414
415
416void ice_deinit_lag(struct ice_pf *pf)
417{
418 struct ice_lag *lag;
419
420 lag = pf->lag;
421
422 if (!lag)
423 return;
424
425 if (lag->pf)
426 ice_unregister_lag_handler(lag);
427
428 if (lag->upper_netdev)
429 dev_put(lag->upper_netdev);
430
431 if (lag->peer_netdev)
432 dev_put(lag->peer_netdev);
433
434 kfree(lag);
435
436 pf->lag = NULL;
437}
438