GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / net / ethernet / netronome / nfp / flower / lag_conf.c
1 /*
2  * Copyright (C) 2018 Netronome Systems, Inc.
3  *
4  * This software is dual licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree or the BSD 2-Clause License provided below.  You have the
7  * option to license this software under the complete terms of either license.
8  *
9  * The BSD 2-Clause License:
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  *      1. Redistributions of source code must retain the above
16  *         copyright notice, this list of conditions and the following
17  *         disclaimer.
18  *
19  *      2. 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 "main.h"
35
36 /* LAG group config flags. */
37 #define NFP_FL_LAG_LAST                 BIT(1)
38 #define NFP_FL_LAG_FIRST                BIT(2)
39 #define NFP_FL_LAG_DATA                 BIT(3)
40 #define NFP_FL_LAG_XON                  BIT(4)
41 #define NFP_FL_LAG_SYNC                 BIT(5)
42 #define NFP_FL_LAG_SWITCH               BIT(6)
43 #define NFP_FL_LAG_RESET                BIT(7)
44
45 /* LAG port state flags. */
46 #define NFP_PORT_LAG_LINK_UP            BIT(0)
47 #define NFP_PORT_LAG_TX_ENABLED         BIT(1)
48 #define NFP_PORT_LAG_CHANGED            BIT(2)
49
50 enum nfp_fl_lag_batch {
51         NFP_FL_LAG_BATCH_FIRST,
52         NFP_FL_LAG_BATCH_MEMBER,
53         NFP_FL_LAG_BATCH_FINISHED
54 };
55
56 /**
57  * struct nfp_flower_cmsg_lag_config - control message payload for LAG config
58  * @ctrl_flags: Configuration flags
59  * @reserved:   Reserved for future use
60  * @ttl:        Time to live of packet - host always sets to 0xff
61  * @pkt_number: Config message packet number - increment for each message
62  * @batch_ver:  Batch version of messages - increment for each batch of messages
63  * @group_id:   Group ID applicable
64  * @group_inst: Group instance number - increment when group is reused
65  * @members:    Array of 32-bit words listing all active group members
66  */
67 struct nfp_flower_cmsg_lag_config {
68         u8 ctrl_flags;
69         u8 reserved[2];
70         u8 ttl;
71         __be32 pkt_number;
72         __be32 batch_ver;
73         __be32 group_id;
74         __be32 group_inst;
75         __be32 members[];
76 };
77
78 /**
79  * struct nfp_fl_lag_group - list entry for each LAG group
80  * @group_id:           Assigned group ID for host/kernel sync
81  * @group_inst:         Group instance in case of ID reuse
82  * @list:               List entry
83  * @master_ndev:        Group master Netdev
84  * @dirty:              Marked if the group needs synced to HW
85  * @offloaded:          Marked if the group is currently offloaded to NIC
86  * @to_remove:          Marked if the group should be removed from NIC
87  * @to_destroy:         Marked if the group should be removed from driver
88  * @slave_cnt:          Number of slaves in group
89  */
90 struct nfp_fl_lag_group {
91         unsigned int group_id;
92         u8 group_inst;
93         struct list_head list;
94         struct net_device *master_ndev;
95         bool dirty;
96         bool offloaded;
97         bool to_remove;
98         bool to_destroy;
99         unsigned int slave_cnt;
100 };
101
102 #define NFP_FL_LAG_PKT_NUMBER_MASK      GENMASK(30, 0)
103 #define NFP_FL_LAG_VERSION_MASK         GENMASK(22, 0)
104 #define NFP_FL_LAG_HOST_TTL             0xff
105
106 /* Use this ID with zero members to ack a batch config */
107 #define NFP_FL_LAG_SYNC_ID              0
108 #define NFP_FL_LAG_GROUP_MIN            1 /* ID 0 reserved */
109 #define NFP_FL_LAG_GROUP_MAX            32 /* IDs 1 to 31 are valid */
110
111 /* wait for more config */
112 #define NFP_FL_LAG_DELAY                (msecs_to_jiffies(2))
113
114 #define NFP_FL_LAG_RETRANS_LIMIT        100 /* max retrans cmsgs to store */
115
116 static unsigned int nfp_fl_get_next_pkt_number(struct nfp_fl_lag *lag)
117 {
118         lag->pkt_num++;
119         lag->pkt_num &= NFP_FL_LAG_PKT_NUMBER_MASK;
120
121         return lag->pkt_num;
122 }
123
124 static void nfp_fl_increment_version(struct nfp_fl_lag *lag)
125 {
126         /* LSB is not considered by firmware so add 2 for each increment. */
127         lag->batch_ver += 2;
128         lag->batch_ver &= NFP_FL_LAG_VERSION_MASK;
129
130         /* Zero is reserved by firmware. */
131         if (!lag->batch_ver)
132                 lag->batch_ver += 2;
133 }
134
135 static struct nfp_fl_lag_group *
136 nfp_fl_lag_group_create(struct nfp_fl_lag *lag, struct net_device *master)
137 {
138         struct nfp_fl_lag_group *group;
139         struct nfp_flower_priv *priv;
140         int id;
141
142         priv = container_of(lag, struct nfp_flower_priv, nfp_lag);
143
144         id = ida_simple_get(&lag->ida_handle, NFP_FL_LAG_GROUP_MIN,
145                             NFP_FL_LAG_GROUP_MAX, GFP_KERNEL);
146         if (id < 0) {
147                 nfp_flower_cmsg_warn(priv->app,
148                                      "No more bonding groups available\n");
149                 return ERR_PTR(id);
150         }
151
152         group = kmalloc(sizeof(*group), GFP_KERNEL);
153         if (!group) {
154                 ida_simple_remove(&lag->ida_handle, id);
155                 return ERR_PTR(-ENOMEM);
156         }
157
158         group->group_id = id;
159         group->master_ndev = master;
160         group->dirty = true;
161         group->offloaded = false;
162         group->to_remove = false;
163         group->to_destroy = false;
164         group->slave_cnt = 0;
165         group->group_inst = ++lag->global_inst;
166         list_add_tail(&group->list, &lag->group_list);
167
168         return group;
169 }
170
171 static struct nfp_fl_lag_group *
172 nfp_fl_lag_find_group_for_master_with_lag(struct nfp_fl_lag *lag,
173                                           struct net_device *master)
174 {
175         struct nfp_fl_lag_group *entry;
176
177         if (!master)
178                 return NULL;
179
180         list_for_each_entry(entry, &lag->group_list, list)
181                 if (entry->master_ndev == master)
182                         return entry;
183
184         return NULL;
185 }
186
187 int nfp_flower_lag_populate_pre_action(struct nfp_app *app,
188                                        struct net_device *master,
189                                        struct nfp_fl_pre_lag *pre_act)
190 {
191         struct nfp_flower_priv *priv = app->priv;
192         struct nfp_fl_lag_group *group = NULL;
193         __be32 temp_vers;
194
195         mutex_lock(&priv->nfp_lag.lock);
196         group = nfp_fl_lag_find_group_for_master_with_lag(&priv->nfp_lag,
197                                                           master);
198         if (!group) {
199                 mutex_unlock(&priv->nfp_lag.lock);
200                 return -ENOENT;
201         }
202
203         pre_act->group_id = cpu_to_be16(group->group_id);
204         temp_vers = cpu_to_be32(priv->nfp_lag.batch_ver <<
205                                 NFP_FL_PRE_LAG_VER_OFF);
206         memcpy(pre_act->lag_version, &temp_vers, 3);
207         pre_act->instance = group->group_inst;
208         mutex_unlock(&priv->nfp_lag.lock);
209
210         return 0;
211 }
212
213 int nfp_flower_lag_get_output_id(struct nfp_app *app, struct net_device *master)
214 {
215         struct nfp_flower_priv *priv = app->priv;
216         struct nfp_fl_lag_group *group = NULL;
217         int group_id = -ENOENT;
218
219         mutex_lock(&priv->nfp_lag.lock);
220         group = nfp_fl_lag_find_group_for_master_with_lag(&priv->nfp_lag,
221                                                           master);
222         if (group)
223                 group_id = group->group_id;
224         mutex_unlock(&priv->nfp_lag.lock);
225
226         return group_id;
227 }
228
229 static int
230 nfp_fl_lag_config_group(struct nfp_fl_lag *lag, struct nfp_fl_lag_group *group,
231                         struct net_device **active_members,
232                         unsigned int member_cnt, enum nfp_fl_lag_batch *batch)
233 {
234         struct nfp_flower_cmsg_lag_config *cmsg_payload;
235         struct nfp_flower_priv *priv;
236         unsigned long int flags;
237         unsigned int size, i;
238         struct sk_buff *skb;
239
240         priv = container_of(lag, struct nfp_flower_priv, nfp_lag);
241         size = sizeof(*cmsg_payload) + sizeof(__be32) * member_cnt;
242         skb = nfp_flower_cmsg_alloc(priv->app, size,
243                                     NFP_FLOWER_CMSG_TYPE_LAG_CONFIG,
244                                     GFP_KERNEL);
245         if (!skb)
246                 return -ENOMEM;
247
248         cmsg_payload = nfp_flower_cmsg_get_data(skb);
249         flags = 0;
250
251         /* Increment batch version for each new batch of config messages. */
252         if (*batch == NFP_FL_LAG_BATCH_FIRST) {
253                 flags |= NFP_FL_LAG_FIRST;
254                 nfp_fl_increment_version(lag);
255                 *batch = NFP_FL_LAG_BATCH_MEMBER;
256         }
257
258         /* If it is a reset msg then it is also the end of the batch. */
259         if (lag->rst_cfg) {
260                 flags |= NFP_FL_LAG_RESET;
261                 *batch = NFP_FL_LAG_BATCH_FINISHED;
262         }
263
264         /* To signal the end of a batch, both the switch and last flags are set
265          * and the the reserved SYNC group ID is used.
266          */
267         if (*batch == NFP_FL_LAG_BATCH_FINISHED) {
268                 flags |= NFP_FL_LAG_SWITCH | NFP_FL_LAG_LAST;
269                 lag->rst_cfg = false;
270                 cmsg_payload->group_id = cpu_to_be32(NFP_FL_LAG_SYNC_ID);
271                 cmsg_payload->group_inst = 0;
272         } else {
273                 cmsg_payload->group_id = cpu_to_be32(group->group_id);
274                 cmsg_payload->group_inst = cpu_to_be32(group->group_inst);
275         }
276
277         cmsg_payload->reserved[0] = 0;
278         cmsg_payload->reserved[1] = 0;
279         cmsg_payload->ttl = NFP_FL_LAG_HOST_TTL;
280         cmsg_payload->ctrl_flags = flags;
281         cmsg_payload->batch_ver = cpu_to_be32(lag->batch_ver);
282         cmsg_payload->pkt_number = cpu_to_be32(nfp_fl_get_next_pkt_number(lag));
283
284         for (i = 0; i < member_cnt; i++)
285                 cmsg_payload->members[i] =
286                         cpu_to_be32(nfp_repr_get_port_id(active_members[i]));
287
288         nfp_ctrl_tx(priv->app->ctrl, skb);
289         return 0;
290 }
291
292 static void nfp_fl_lag_do_work(struct work_struct *work)
293 {
294         enum nfp_fl_lag_batch batch = NFP_FL_LAG_BATCH_FIRST;
295         struct nfp_fl_lag_group *entry, *storage;
296         struct delayed_work *delayed_work;
297         struct nfp_flower_priv *priv;
298         struct nfp_fl_lag *lag;
299         int err;
300
301         delayed_work = to_delayed_work(work);
302         lag = container_of(delayed_work, struct nfp_fl_lag, work);
303         priv = container_of(lag, struct nfp_flower_priv, nfp_lag);
304
305         mutex_lock(&lag->lock);
306         list_for_each_entry_safe(entry, storage, &lag->group_list, list) {
307                 struct net_device *iter_netdev, **acti_netdevs;
308                 struct nfp_flower_repr_priv *repr_priv;
309                 int active_count = 0, slaves = 0;
310                 struct nfp_repr *repr;
311                 unsigned long *flags;
312
313                 if (entry->to_remove) {
314                         /* Active count of 0 deletes group on hw. */
315                         err = nfp_fl_lag_config_group(lag, entry, NULL, 0,
316                                                       &batch);
317                         if (!err) {
318                                 entry->to_remove = false;
319                                 entry->offloaded = false;
320                         } else {
321                                 nfp_flower_cmsg_warn(priv->app,
322                                                      "group delete failed\n");
323                                 schedule_delayed_work(&lag->work,
324                                                       NFP_FL_LAG_DELAY);
325                                 continue;
326                         }
327
328                         if (entry->to_destroy) {
329                                 ida_simple_remove(&lag->ida_handle,
330                                                   entry->group_id);
331                                 list_del(&entry->list);
332                                 kfree(entry);
333                         }
334                         continue;
335                 }
336
337                 acti_netdevs = kmalloc_array(entry->slave_cnt,
338                                              sizeof(*acti_netdevs), GFP_KERNEL);
339
340                 /* Include sanity check in the loop. It may be that a bond has
341                  * changed between processing the last notification and the
342                  * work queue triggering. If the number of slaves has changed
343                  * or it now contains netdevs that cannot be offloaded, ignore
344                  * the group until pending notifications are processed.
345                  */
346                 rcu_read_lock();
347                 for_each_netdev_in_bond_rcu(entry->master_ndev, iter_netdev) {
348                         if (!nfp_netdev_is_nfp_repr(iter_netdev)) {
349                                 slaves = 0;
350                                 break;
351                         }
352
353                         repr = netdev_priv(iter_netdev);
354
355                         if (repr->app != priv->app) {
356                                 slaves = 0;
357                                 break;
358                         }
359
360                         slaves++;
361                         if (slaves > entry->slave_cnt)
362                                 break;
363
364                         /* Check the ports for state changes. */
365                         repr_priv = repr->app_priv;
366                         flags = &repr_priv->lag_port_flags;
367
368                         if (*flags & NFP_PORT_LAG_CHANGED) {
369                                 *flags &= ~NFP_PORT_LAG_CHANGED;
370                                 entry->dirty = true;
371                         }
372
373                         if ((*flags & NFP_PORT_LAG_TX_ENABLED) &&
374                             (*flags & NFP_PORT_LAG_LINK_UP))
375                                 acti_netdevs[active_count++] = iter_netdev;
376                 }
377                 rcu_read_unlock();
378
379                 if (slaves != entry->slave_cnt || !entry->dirty) {
380                         kfree(acti_netdevs);
381                         continue;
382                 }
383
384                 err = nfp_fl_lag_config_group(lag, entry, acti_netdevs,
385                                               active_count, &batch);
386                 if (!err) {
387                         entry->offloaded = true;
388                         entry->dirty = false;
389                 } else {
390                         nfp_flower_cmsg_warn(priv->app,
391                                              "group offload failed\n");
392                         schedule_delayed_work(&lag->work, NFP_FL_LAG_DELAY);
393                 }
394
395                 kfree(acti_netdevs);
396         }
397
398         /* End the config batch if at least one packet has been batched. */
399         if (batch == NFP_FL_LAG_BATCH_MEMBER) {
400                 batch = NFP_FL_LAG_BATCH_FINISHED;
401                 err = nfp_fl_lag_config_group(lag, NULL, NULL, 0, &batch);
402                 if (err)
403                         nfp_flower_cmsg_warn(priv->app,
404                                              "group batch end cmsg failed\n");
405         }
406
407         mutex_unlock(&lag->lock);
408 }
409
410 static int
411 nfp_fl_lag_put_unprocessed(struct nfp_fl_lag *lag, struct sk_buff *skb)
412 {
413         struct nfp_flower_cmsg_lag_config *cmsg_payload;
414
415         cmsg_payload = nfp_flower_cmsg_get_data(skb);
416         if (be32_to_cpu(cmsg_payload->group_id) >= NFP_FL_LAG_GROUP_MAX)
417                 return -EINVAL;
418
419         /* Drop cmsg retrans if storage limit is exceeded to prevent
420          * overloading. If the fw notices that expected messages have not been
421          * received in a given time block, it will request a full resync.
422          */
423         if (skb_queue_len(&lag->retrans_skbs) >= NFP_FL_LAG_RETRANS_LIMIT)
424                 return -ENOSPC;
425
426         __skb_queue_tail(&lag->retrans_skbs, skb);
427
428         return 0;
429 }
430
431 static void nfp_fl_send_unprocessed(struct nfp_fl_lag *lag)
432 {
433         struct nfp_flower_priv *priv;
434         struct sk_buff *skb;
435
436         priv = container_of(lag, struct nfp_flower_priv, nfp_lag);
437
438         while ((skb = __skb_dequeue(&lag->retrans_skbs)))
439                 nfp_ctrl_tx(priv->app->ctrl, skb);
440 }
441
442 bool nfp_flower_lag_unprocessed_msg(struct nfp_app *app, struct sk_buff *skb)
443 {
444         struct nfp_flower_cmsg_lag_config *cmsg_payload;
445         struct nfp_flower_priv *priv = app->priv;
446         struct nfp_fl_lag_group *group_entry;
447         unsigned long int flags;
448         bool store_skb = false;
449         int err;
450
451         cmsg_payload = nfp_flower_cmsg_get_data(skb);
452         flags = cmsg_payload->ctrl_flags;
453
454         /* Note the intentional fall through below. If DATA and XON are both
455          * set, the message will stored and sent again with the rest of the
456          * unprocessed messages list.
457          */
458
459         /* Store */
460         if (flags & NFP_FL_LAG_DATA)
461                 if (!nfp_fl_lag_put_unprocessed(&priv->nfp_lag, skb))
462                         store_skb = true;
463
464         /* Send stored */
465         if (flags & NFP_FL_LAG_XON)
466                 nfp_fl_send_unprocessed(&priv->nfp_lag);
467
468         /* Resend all */
469         if (flags & NFP_FL_LAG_SYNC) {
470                 /* To resend all config:
471                  * 1) Clear all unprocessed messages
472                  * 2) Mark all groups dirty
473                  * 3) Reset NFP group config
474                  * 4) Schedule a LAG config update
475                  */
476
477                 __skb_queue_purge(&priv->nfp_lag.retrans_skbs);
478
479                 mutex_lock(&priv->nfp_lag.lock);
480                 list_for_each_entry(group_entry, &priv->nfp_lag.group_list,
481                                     list)
482                         group_entry->dirty = true;
483
484                 err = nfp_flower_lag_reset(&priv->nfp_lag);
485                 if (err)
486                         nfp_flower_cmsg_warn(priv->app,
487                                              "mem err in group reset msg\n");
488                 mutex_unlock(&priv->nfp_lag.lock);
489
490                 schedule_delayed_work(&priv->nfp_lag.work, 0);
491         }
492
493         return store_skb;
494 }
495
496 static void
497 nfp_fl_lag_schedule_group_remove(struct nfp_fl_lag *lag,
498                                  struct nfp_fl_lag_group *group)
499 {
500         group->to_remove = true;
501
502         schedule_delayed_work(&lag->work, NFP_FL_LAG_DELAY);
503 }
504
505 static int
506 nfp_fl_lag_schedule_group_delete(struct nfp_fl_lag *lag,
507                                  struct net_device *master)
508 {
509         struct nfp_fl_lag_group *group;
510
511         mutex_lock(&lag->lock);
512         group = nfp_fl_lag_find_group_for_master_with_lag(lag, master);
513         if (!group) {
514                 mutex_unlock(&lag->lock);
515                 return -ENOENT;
516         }
517
518         group->to_remove = true;
519         group->to_destroy = true;
520         mutex_unlock(&lag->lock);
521
522         schedule_delayed_work(&lag->work, NFP_FL_LAG_DELAY);
523         return 0;
524 }
525
526 static int
527 nfp_fl_lag_changeupper_event(struct nfp_fl_lag *lag,
528                              struct netdev_notifier_changeupper_info *info)
529 {
530         struct net_device *upper = info->upper_dev, *iter_netdev;
531         struct netdev_lag_upper_info *lag_upper_info;
532         struct nfp_fl_lag_group *group;
533         struct nfp_flower_priv *priv;
534         unsigned int slave_count = 0;
535         bool can_offload = true;
536         struct nfp_repr *repr;
537
538         if (!netif_is_lag_master(upper))
539                 return 0;
540
541         priv = container_of(lag, struct nfp_flower_priv, nfp_lag);
542
543         rcu_read_lock();
544         for_each_netdev_in_bond_rcu(upper, iter_netdev) {
545                 if (!nfp_netdev_is_nfp_repr(iter_netdev)) {
546                         can_offload = false;
547                         break;
548                 }
549                 repr = netdev_priv(iter_netdev);
550
551                 /* Ensure all ports are created by the same app/on same card. */
552                 if (repr->app != priv->app) {
553                         can_offload = false;
554                         break;
555                 }
556
557                 slave_count++;
558         }
559         rcu_read_unlock();
560
561         lag_upper_info = info->upper_info;
562
563         /* Firmware supports active/backup and L3/L4 hash bonds. */
564         if (lag_upper_info &&
565             lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_ACTIVEBACKUP &&
566             (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH ||
567              (lag_upper_info->hash_type != NETDEV_LAG_HASH_L34 &&
568               lag_upper_info->hash_type != NETDEV_LAG_HASH_E34 &&
569               lag_upper_info->hash_type != NETDEV_LAG_HASH_UNKNOWN))) {
570                 can_offload = false;
571                 nfp_flower_cmsg_warn(priv->app,
572                                      "Unable to offload tx_type %u hash %u\n",
573                                      lag_upper_info->tx_type,
574                                      lag_upper_info->hash_type);
575         }
576
577         mutex_lock(&lag->lock);
578         group = nfp_fl_lag_find_group_for_master_with_lag(lag, upper);
579
580         if (slave_count == 0 || !can_offload) {
581                 /* Cannot offload the group - remove if previously offloaded. */
582                 if (group && group->offloaded)
583                         nfp_fl_lag_schedule_group_remove(lag, group);
584
585                 mutex_unlock(&lag->lock);
586                 return 0;
587         }
588
589         if (!group) {
590                 group = nfp_fl_lag_group_create(lag, upper);
591                 if (IS_ERR(group)) {
592                         mutex_unlock(&lag->lock);
593                         return PTR_ERR(group);
594                 }
595         }
596
597         group->dirty = true;
598         group->slave_cnt = slave_count;
599
600         /* Group may have been on queue for removal but is now offfloable. */
601         group->to_remove = false;
602         mutex_unlock(&lag->lock);
603
604         schedule_delayed_work(&lag->work, NFP_FL_LAG_DELAY);
605         return 0;
606 }
607
608 static int
609 nfp_fl_lag_changels_event(struct nfp_fl_lag *lag, struct net_device *netdev,
610                           struct netdev_notifier_changelowerstate_info *info)
611 {
612         struct netdev_lag_lower_state_info *lag_lower_info;
613         struct nfp_flower_repr_priv *repr_priv;
614         struct nfp_flower_priv *priv;
615         struct nfp_repr *repr;
616         unsigned long *flags;
617
618         if (!netif_is_lag_port(netdev) || !nfp_netdev_is_nfp_repr(netdev))
619                 return 0;
620
621         lag_lower_info = info->lower_state_info;
622         if (!lag_lower_info)
623                 return 0;
624
625         priv = container_of(lag, struct nfp_flower_priv, nfp_lag);
626         repr = netdev_priv(netdev);
627
628         /* Verify that the repr is associated with this app. */
629         if (repr->app != priv->app)
630                 return 0;
631
632         repr_priv = repr->app_priv;
633         flags = &repr_priv->lag_port_flags;
634
635         mutex_lock(&lag->lock);
636         if (lag_lower_info->link_up)
637                 *flags |= NFP_PORT_LAG_LINK_UP;
638         else
639                 *flags &= ~NFP_PORT_LAG_LINK_UP;
640
641         if (lag_lower_info->tx_enabled)
642                 *flags |= NFP_PORT_LAG_TX_ENABLED;
643         else
644                 *flags &= ~NFP_PORT_LAG_TX_ENABLED;
645
646         *flags |= NFP_PORT_LAG_CHANGED;
647         mutex_unlock(&lag->lock);
648
649         schedule_delayed_work(&lag->work, NFP_FL_LAG_DELAY);
650         return 0;
651 }
652
653 static int
654 nfp_fl_lag_netdev_event(struct notifier_block *nb, unsigned long event,
655                         void *ptr)
656 {
657         struct net_device *netdev;
658         struct nfp_fl_lag *lag;
659         int err;
660
661         netdev = netdev_notifier_info_to_dev(ptr);
662         lag = container_of(nb, struct nfp_fl_lag, lag_nb);
663
664         switch (event) {
665         case NETDEV_CHANGEUPPER:
666                 err = nfp_fl_lag_changeupper_event(lag, ptr);
667                 if (err)
668                         return NOTIFY_BAD;
669                 return NOTIFY_OK;
670         case NETDEV_CHANGELOWERSTATE:
671                 err = nfp_fl_lag_changels_event(lag, netdev, ptr);
672                 if (err)
673                         return NOTIFY_BAD;
674                 return NOTIFY_OK;
675         case NETDEV_UNREGISTER:
676                 if (netif_is_bond_master(netdev)) {
677                         err = nfp_fl_lag_schedule_group_delete(lag, netdev);
678                         if (err)
679                                 return NOTIFY_BAD;
680                         return NOTIFY_OK;
681                 }
682         }
683
684         return NOTIFY_DONE;
685 }
686
687 int nfp_flower_lag_reset(struct nfp_fl_lag *lag)
688 {
689         enum nfp_fl_lag_batch batch = NFP_FL_LAG_BATCH_FIRST;
690
691         lag->rst_cfg = true;
692         return nfp_fl_lag_config_group(lag, NULL, NULL, 0, &batch);
693 }
694
695 void nfp_flower_lag_init(struct nfp_fl_lag *lag)
696 {
697         INIT_DELAYED_WORK(&lag->work, nfp_fl_lag_do_work);
698         INIT_LIST_HEAD(&lag->group_list);
699         mutex_init(&lag->lock);
700         ida_init(&lag->ida_handle);
701
702         __skb_queue_head_init(&lag->retrans_skbs);
703
704         /* 0 is a reserved batch version so increment to first valid value. */
705         nfp_fl_increment_version(lag);
706
707         lag->lag_nb.notifier_call = nfp_fl_lag_netdev_event;
708 }
709
710 void nfp_flower_lag_cleanup(struct nfp_fl_lag *lag)
711 {
712         struct nfp_fl_lag_group *entry, *storage;
713
714         cancel_delayed_work_sync(&lag->work);
715
716         __skb_queue_purge(&lag->retrans_skbs);
717
718         /* Remove all groups. */
719         mutex_lock(&lag->lock);
720         list_for_each_entry_safe(entry, storage, &lag->group_list, list) {
721                 list_del(&entry->list);
722                 kfree(entry);
723         }
724         mutex_unlock(&lag->lock);
725         mutex_destroy(&lag->lock);
726         ida_destroy(&lag->ida_handle);
727 }