c55e36e0571d18a95c2c70d64c3793d80312b7fb
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / mellanox / mlx5 / core / lag / lag.c
1 /*
2  * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <linux/netdevice.h>
34 #include <net/bonding.h>
35 #include <linux/mlx5/driver.h>
36 #include <linux/mlx5/eswitch.h>
37 #include <linux/mlx5/vport.h>
38 #include "lib/devcom.h"
39 #include "mlx5_core.h"
40 #include "eswitch.h"
41 #include "esw/acl/ofld.h"
42 #include "lag.h"
43 #include "mp.h"
44 #include "mpesw.h"
45
46 enum {
47         MLX5_LAG_EGRESS_PORT_1 = 1,
48         MLX5_LAG_EGRESS_PORT_2,
49 };
50
51 /* General purpose, use for short periods of time.
52  * Beware of lock dependencies (preferably, no locks should be acquired
53  * under it).
54  */
55 static DEFINE_SPINLOCK(lag_lock);
56
57 static int get_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
58 {
59         if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags))
60                 return MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_FT;
61
62         if (mode == MLX5_LAG_MODE_MPESW)
63                 return MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_MPESW;
64
65         return MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY;
66 }
67
68 static u8 lag_active_port_bits(struct mlx5_lag *ldev)
69 {
70         u8 enabled_ports[MLX5_MAX_PORTS] = {};
71         u8 active_port = 0;
72         int num_enabled;
73         int idx;
74
75         mlx5_infer_tx_enabled(&ldev->tracker, ldev->ports, enabled_ports,
76                               &num_enabled);
77         for (idx = 0; idx < num_enabled; idx++)
78                 active_port |= BIT_MASK(enabled_ports[idx]);
79
80         return active_port;
81 }
82
83 static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, u8 *ports, int mode,
84                                unsigned long flags)
85 {
86         bool fdb_sel_mode = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
87                                      &flags);
88         int port_sel_mode = get_port_sel_mode(mode, flags);
89         u32 in[MLX5_ST_SZ_DW(create_lag_in)] = {};
90         void *lag_ctx;
91
92         lag_ctx = MLX5_ADDR_OF(create_lag_in, in, ctx);
93         MLX5_SET(create_lag_in, in, opcode, MLX5_CMD_OP_CREATE_LAG);
94         MLX5_SET(lagc, lag_ctx, fdb_selection_mode, fdb_sel_mode);
95
96         switch (port_sel_mode) {
97         case MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY:
98                 MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, ports[0]);
99                 MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, ports[1]);
100                 break;
101         case MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_FT:
102                 if (!MLX5_CAP_PORT_SELECTION(dev, port_select_flow_table_bypass))
103                         break;
104
105                 MLX5_SET(lagc, lag_ctx, active_port,
106                          lag_active_port_bits(mlx5_lag_dev(dev)));
107                 break;
108         default:
109                 break;
110         }
111         MLX5_SET(lagc, lag_ctx, port_select_mode, port_sel_mode);
112
113         return mlx5_cmd_exec_in(dev, create_lag, in);
114 }
115
116 static int mlx5_cmd_modify_lag(struct mlx5_core_dev *dev, u8 num_ports,
117                                u8 *ports)
118 {
119         u32 in[MLX5_ST_SZ_DW(modify_lag_in)] = {};
120         void *lag_ctx = MLX5_ADDR_OF(modify_lag_in, in, ctx);
121
122         MLX5_SET(modify_lag_in, in, opcode, MLX5_CMD_OP_MODIFY_LAG);
123         MLX5_SET(modify_lag_in, in, field_select, 0x1);
124
125         MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, ports[0]);
126         MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, ports[1]);
127
128         return mlx5_cmd_exec_in(dev, modify_lag, in);
129 }
130
131 int mlx5_cmd_create_vport_lag(struct mlx5_core_dev *dev)
132 {
133         u32 in[MLX5_ST_SZ_DW(create_vport_lag_in)] = {};
134
135         MLX5_SET(create_vport_lag_in, in, opcode, MLX5_CMD_OP_CREATE_VPORT_LAG);
136
137         return mlx5_cmd_exec_in(dev, create_vport_lag, in);
138 }
139 EXPORT_SYMBOL(mlx5_cmd_create_vport_lag);
140
141 int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev)
142 {
143         u32 in[MLX5_ST_SZ_DW(destroy_vport_lag_in)] = {};
144
145         MLX5_SET(destroy_vport_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_VPORT_LAG);
146
147         return mlx5_cmd_exec_in(dev, destroy_vport_lag, in);
148 }
149 EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag);
150
151 static void mlx5_infer_tx_disabled(struct lag_tracker *tracker, u8 num_ports,
152                                    u8 *ports, int *num_disabled)
153 {
154         int i;
155
156         *num_disabled = 0;
157         for (i = 0; i < num_ports; i++) {
158                 if (!tracker->netdev_state[i].tx_enabled ||
159                     !tracker->netdev_state[i].link_up)
160                         ports[(*num_disabled)++] = i;
161         }
162 }
163
164 void mlx5_infer_tx_enabled(struct lag_tracker *tracker, u8 num_ports,
165                            u8 *ports, int *num_enabled)
166 {
167         int i;
168
169         *num_enabled = 0;
170         for (i = 0; i < num_ports; i++) {
171                 if (tracker->netdev_state[i].tx_enabled &&
172                     tracker->netdev_state[i].link_up)
173                         ports[(*num_enabled)++] = i;
174         }
175
176         if (*num_enabled == 0)
177                 mlx5_infer_tx_disabled(tracker, num_ports, ports, num_enabled);
178 }
179
180 static void mlx5_lag_print_mapping(struct mlx5_core_dev *dev,
181                                    struct mlx5_lag *ldev,
182                                    struct lag_tracker *tracker,
183                                    unsigned long flags)
184 {
185         char buf[MLX5_MAX_PORTS * 10 + 1] = {};
186         u8 enabled_ports[MLX5_MAX_PORTS] = {};
187         int written = 0;
188         int num_enabled;
189         int idx;
190         int err;
191         int i;
192         int j;
193
194         if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags)) {
195                 mlx5_infer_tx_enabled(tracker, ldev->ports, enabled_ports,
196                                       &num_enabled);
197                 for (i = 0; i < num_enabled; i++) {
198                         err = scnprintf(buf + written, 4, "%d, ", enabled_ports[i] + 1);
199                         if (err != 3)
200                                 return;
201                         written += err;
202                 }
203                 buf[written - 2] = 0;
204                 mlx5_core_info(dev, "lag map active ports: %s\n", buf);
205         } else {
206                 for (i = 0; i < ldev->ports; i++) {
207                         for (j  = 0; j < ldev->buckets; j++) {
208                                 idx = i * ldev->buckets + j;
209                                 err = scnprintf(buf + written, 10,
210                                                 " port %d:%d", i + 1, ldev->v2p_map[idx]);
211                                 if (err != 9)
212                                         return;
213                                 written += err;
214                         }
215                 }
216                 mlx5_core_info(dev, "lag map:%s\n", buf);
217         }
218 }
219
220 static int mlx5_lag_netdev_event(struct notifier_block *this,
221                                  unsigned long event, void *ptr);
222 static void mlx5_do_bond_work(struct work_struct *work);
223
224 static void mlx5_ldev_free(struct kref *ref)
225 {
226         struct mlx5_lag *ldev = container_of(ref, struct mlx5_lag, ref);
227
228         if (ldev->nb.notifier_call)
229                 unregister_netdevice_notifier_net(&init_net, &ldev->nb);
230         mlx5_lag_mp_cleanup(ldev);
231         cancel_delayed_work_sync(&ldev->bond_work);
232         destroy_workqueue(ldev->wq);
233         mutex_destroy(&ldev->lock);
234         kfree(ldev);
235 }
236
237 static void mlx5_ldev_put(struct mlx5_lag *ldev)
238 {
239         kref_put(&ldev->ref, mlx5_ldev_free);
240 }
241
242 static void mlx5_ldev_get(struct mlx5_lag *ldev)
243 {
244         kref_get(&ldev->ref);
245 }
246
247 static struct mlx5_lag *mlx5_lag_dev_alloc(struct mlx5_core_dev *dev)
248 {
249         struct mlx5_lag *ldev;
250         int err;
251
252         ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
253         if (!ldev)
254                 return NULL;
255
256         ldev->wq = create_singlethread_workqueue("mlx5_lag");
257         if (!ldev->wq) {
258                 kfree(ldev);
259                 return NULL;
260         }
261
262         kref_init(&ldev->ref);
263         mutex_init(&ldev->lock);
264         INIT_DELAYED_WORK(&ldev->bond_work, mlx5_do_bond_work);
265
266         ldev->nb.notifier_call = mlx5_lag_netdev_event;
267         if (register_netdevice_notifier_net(&init_net, &ldev->nb)) {
268                 ldev->nb.notifier_call = NULL;
269                 mlx5_core_err(dev, "Failed to register LAG netdev notifier\n");
270         }
271         ldev->mode = MLX5_LAG_MODE_NONE;
272
273         err = mlx5_lag_mp_init(ldev);
274         if (err)
275                 mlx5_core_err(dev, "Failed to init multipath lag err=%d\n",
276                               err);
277
278         ldev->ports = MLX5_CAP_GEN(dev, num_lag_ports);
279         ldev->buckets = 1;
280
281         return ldev;
282 }
283
284 int mlx5_lag_dev_get_netdev_idx(struct mlx5_lag *ldev,
285                                 struct net_device *ndev)
286 {
287         int i;
288
289         for (i = 0; i < ldev->ports; i++)
290                 if (ldev->pf[i].netdev == ndev)
291                         return i;
292
293         return -ENOENT;
294 }
295
296 static bool __mlx5_lag_is_roce(struct mlx5_lag *ldev)
297 {
298         return ldev->mode == MLX5_LAG_MODE_ROCE;
299 }
300
301 static bool __mlx5_lag_is_sriov(struct mlx5_lag *ldev)
302 {
303         return ldev->mode == MLX5_LAG_MODE_SRIOV;
304 }
305
306 /* Create a mapping between steering slots and active ports.
307  * As we have ldev->buckets slots per port first assume the native
308  * mapping should be used.
309  * If there are ports that are disabled fill the relevant slots
310  * with mapping that points to active ports.
311  */
312 static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker,
313                                            u8 num_ports,
314                                            u8 buckets,
315                                            u8 *ports)
316 {
317         int disabled[MLX5_MAX_PORTS] = {};
318         int enabled[MLX5_MAX_PORTS] = {};
319         int disabled_ports_num = 0;
320         int enabled_ports_num = 0;
321         int idx;
322         u32 rand;
323         int i;
324         int j;
325
326         for (i = 0; i < num_ports; i++) {
327                 if (tracker->netdev_state[i].tx_enabled &&
328                     tracker->netdev_state[i].link_up)
329                         enabled[enabled_ports_num++] = i;
330                 else
331                         disabled[disabled_ports_num++] = i;
332         }
333
334         /* Use native mapping by default where each port's buckets
335          * point the native port: 1 1 1 .. 1 2 2 2 ... 2 3 3 3 ... 3 etc
336          */
337         for (i = 0; i < num_ports; i++)
338                 for (j = 0; j < buckets; j++) {
339                         idx = i * buckets + j;
340                         ports[idx] = MLX5_LAG_EGRESS_PORT_1 + i;
341                 }
342
343         /* If all ports are disabled/enabled keep native mapping */
344         if (enabled_ports_num == num_ports ||
345             disabled_ports_num == num_ports)
346                 return;
347
348         /* Go over the disabled ports and for each assign a random active port */
349         for (i = 0; i < disabled_ports_num; i++) {
350                 for (j = 0; j < buckets; j++) {
351                         get_random_bytes(&rand, 4);
352                         ports[disabled[i] * buckets + j] = enabled[rand % enabled_ports_num] + 1;
353                 }
354         }
355 }
356
357 static bool mlx5_lag_has_drop_rule(struct mlx5_lag *ldev)
358 {
359         int i;
360
361         for (i = 0; i < ldev->ports; i++)
362                 if (ldev->pf[i].has_drop)
363                         return true;
364         return false;
365 }
366
367 static void mlx5_lag_drop_rule_cleanup(struct mlx5_lag *ldev)
368 {
369         int i;
370
371         for (i = 0; i < ldev->ports; i++) {
372                 if (!ldev->pf[i].has_drop)
373                         continue;
374
375                 mlx5_esw_acl_ingress_vport_drop_rule_destroy(ldev->pf[i].dev->priv.eswitch,
376                                                              MLX5_VPORT_UPLINK);
377                 ldev->pf[i].has_drop = false;
378         }
379 }
380
381 static void mlx5_lag_drop_rule_setup(struct mlx5_lag *ldev,
382                                      struct lag_tracker *tracker)
383 {
384         u8 disabled_ports[MLX5_MAX_PORTS] = {};
385         struct mlx5_core_dev *dev;
386         int disabled_index;
387         int num_disabled;
388         int err;
389         int i;
390
391         /* First delete the current drop rule so there won't be any dropped
392          * packets
393          */
394         mlx5_lag_drop_rule_cleanup(ldev);
395
396         if (!ldev->tracker.has_inactive)
397                 return;
398
399         mlx5_infer_tx_disabled(tracker, ldev->ports, disabled_ports, &num_disabled);
400
401         for (i = 0; i < num_disabled; i++) {
402                 disabled_index = disabled_ports[i];
403                 dev = ldev->pf[disabled_index].dev;
404                 err = mlx5_esw_acl_ingress_vport_drop_rule_create(dev->priv.eswitch,
405                                                                   MLX5_VPORT_UPLINK);
406                 if (!err)
407                         ldev->pf[disabled_index].has_drop = true;
408                 else
409                         mlx5_core_err(dev,
410                                       "Failed to create lag drop rule, error: %d", err);
411         }
412 }
413
414 static int mlx5_cmd_modify_active_port(struct mlx5_core_dev *dev, u8 ports)
415 {
416         u32 in[MLX5_ST_SZ_DW(modify_lag_in)] = {};
417         void *lag_ctx;
418
419         lag_ctx = MLX5_ADDR_OF(modify_lag_in, in, ctx);
420
421         MLX5_SET(modify_lag_in, in, opcode, MLX5_CMD_OP_MODIFY_LAG);
422         MLX5_SET(modify_lag_in, in, field_select, 0x2);
423
424         MLX5_SET(lagc, lag_ctx, active_port, ports);
425
426         return mlx5_cmd_exec_in(dev, modify_lag, in);
427 }
428
429 static int _mlx5_modify_lag(struct mlx5_lag *ldev, u8 *ports)
430 {
431         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
432         u8 active_ports;
433         int ret;
434
435         if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &ldev->mode_flags)) {
436                 ret = mlx5_lag_port_sel_modify(ldev, ports);
437                 if (ret ||
438                     !MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table_bypass))
439                         return ret;
440
441                 active_ports = lag_active_port_bits(ldev);
442
443                 return mlx5_cmd_modify_active_port(dev0, active_ports);
444         }
445         return mlx5_cmd_modify_lag(dev0, ldev->ports, ports);
446 }
447
448 void mlx5_modify_lag(struct mlx5_lag *ldev,
449                      struct lag_tracker *tracker)
450 {
451         u8 ports[MLX5_MAX_PORTS * MLX5_LAG_MAX_HASH_BUCKETS] = {};
452         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
453         int idx;
454         int err;
455         int i;
456         int j;
457
458         mlx5_infer_tx_affinity_mapping(tracker, ldev->ports, ldev->buckets, ports);
459
460         for (i = 0; i < ldev->ports; i++) {
461                 for (j = 0; j < ldev->buckets; j++) {
462                         idx = i * ldev->buckets + j;
463                         if (ports[idx] == ldev->v2p_map[idx])
464                                 continue;
465                         err = _mlx5_modify_lag(ldev, ports);
466                         if (err) {
467                                 mlx5_core_err(dev0,
468                                               "Failed to modify LAG (%d)\n",
469                                               err);
470                                 return;
471                         }
472                         memcpy(ldev->v2p_map, ports, sizeof(ports));
473
474                         mlx5_lag_print_mapping(dev0, ldev, tracker,
475                                                ldev->mode_flags);
476                         break;
477                 }
478         }
479
480         if (tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP &&
481             !(ldev->mode == MLX5_LAG_MODE_ROCE))
482                 mlx5_lag_drop_rule_setup(ldev, tracker);
483 }
484
485 static int mlx5_lag_set_port_sel_mode_roce(struct mlx5_lag *ldev,
486                                            unsigned long *flags)
487 {
488         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
489
490         if (!MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table)) {
491                 if (ldev->ports > 2)
492                         return -EINVAL;
493                 return 0;
494         }
495
496         if (ldev->ports > 2)
497                 ldev->buckets = MLX5_LAG_MAX_HASH_BUCKETS;
498
499         set_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, flags);
500
501         return 0;
502 }
503
504 static void mlx5_lag_set_port_sel_mode_offloads(struct mlx5_lag *ldev,
505                                                 struct lag_tracker *tracker,
506                                                 enum mlx5_lag_mode mode,
507                                                 unsigned long *flags)
508 {
509         struct lag_func *dev0 = &ldev->pf[MLX5_LAG_P1];
510
511         if (mode == MLX5_LAG_MODE_MPESW)
512                 return;
513
514         if (MLX5_CAP_PORT_SELECTION(dev0->dev, port_select_flow_table) &&
515             tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH)
516                 set_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, flags);
517 }
518
519 static int mlx5_lag_set_flags(struct mlx5_lag *ldev, enum mlx5_lag_mode mode,
520                               struct lag_tracker *tracker, bool shared_fdb,
521                               unsigned long *flags)
522 {
523         bool roce_lag = mode == MLX5_LAG_MODE_ROCE;
524
525         *flags = 0;
526         if (shared_fdb) {
527                 set_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, flags);
528                 set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
529         }
530
531         if (mode == MLX5_LAG_MODE_MPESW)
532                 set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
533
534         if (roce_lag)
535                 return mlx5_lag_set_port_sel_mode_roce(ldev, flags);
536
537         mlx5_lag_set_port_sel_mode_offloads(ldev, tracker, mode, flags);
538         return 0;
539 }
540
541 char *mlx5_get_str_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
542 {
543         int port_sel_mode = get_port_sel_mode(mode, flags);
544
545         switch (port_sel_mode) {
546         case MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY: return "queue_affinity";
547         case MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_FT: return "hash";
548         case MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_MPESW: return "mpesw";
549         default: return "invalid";
550         }
551 }
552
553 static int mlx5_lag_create_single_fdb(struct mlx5_lag *ldev)
554 {
555         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
556         struct mlx5_eswitch *master_esw = dev0->priv.eswitch;
557         int err;
558         int i;
559
560         for (i = MLX5_LAG_P1 + 1; i < ldev->ports; i++) {
561                 struct mlx5_eswitch *slave_esw = ldev->pf[i].dev->priv.eswitch;
562
563                 err = mlx5_eswitch_offloads_single_fdb_add_one(master_esw,
564                                                                slave_esw, ldev->ports);
565                 if (err)
566                         goto err;
567         }
568         return 0;
569 err:
570         for (; i > MLX5_LAG_P1; i--)
571                 mlx5_eswitch_offloads_single_fdb_del_one(master_esw,
572                                                          ldev->pf[i].dev->priv.eswitch);
573         return err;
574 }
575
576 static int mlx5_create_lag(struct mlx5_lag *ldev,
577                            struct lag_tracker *tracker,
578                            enum mlx5_lag_mode mode,
579                            unsigned long flags)
580 {
581         bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags);
582         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
583         u32 in[MLX5_ST_SZ_DW(destroy_lag_in)] = {};
584         int err;
585
586         if (tracker)
587                 mlx5_lag_print_mapping(dev0, ldev, tracker, flags);
588         mlx5_core_info(dev0, "shared_fdb:%d mode:%s\n",
589                        shared_fdb, mlx5_get_str_port_sel_mode(mode, flags));
590
591         err = mlx5_cmd_create_lag(dev0, ldev->v2p_map, mode, flags);
592         if (err) {
593                 mlx5_core_err(dev0,
594                               "Failed to create LAG (%d)\n",
595                               err);
596                 return err;
597         }
598
599         if (shared_fdb) {
600                 err = mlx5_lag_create_single_fdb(ldev);
601                 if (err)
602                         mlx5_core_err(dev0, "Can't enable single FDB mode\n");
603                 else
604                         mlx5_core_info(dev0, "Operation mode is single FDB\n");
605         }
606
607         if (err) {
608                 MLX5_SET(destroy_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_LAG);
609                 if (mlx5_cmd_exec_in(dev0, destroy_lag, in))
610                         mlx5_core_err(dev0,
611                                       "Failed to deactivate RoCE LAG; driver restart required\n");
612         }
613
614         return err;
615 }
616
617 int mlx5_activate_lag(struct mlx5_lag *ldev,
618                       struct lag_tracker *tracker,
619                       enum mlx5_lag_mode mode,
620                       bool shared_fdb)
621 {
622         bool roce_lag = mode == MLX5_LAG_MODE_ROCE;
623         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
624         unsigned long flags = 0;
625         int err;
626
627         err = mlx5_lag_set_flags(ldev, mode, tracker, shared_fdb, &flags);
628         if (err)
629                 return err;
630
631         if (mode != MLX5_LAG_MODE_MPESW) {
632                 mlx5_infer_tx_affinity_mapping(tracker, ldev->ports, ldev->buckets, ldev->v2p_map);
633                 if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags)) {
634                         err = mlx5_lag_port_sel_create(ldev, tracker->hash_type,
635                                                        ldev->v2p_map);
636                         if (err) {
637                                 mlx5_core_err(dev0,
638                                               "Failed to create LAG port selection(%d)\n",
639                                               err);
640                                 return err;
641                         }
642                 }
643         }
644
645         err = mlx5_create_lag(ldev, tracker, mode, flags);
646         if (err) {
647                 if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags))
648                         mlx5_lag_port_sel_destroy(ldev);
649                 if (roce_lag)
650                         mlx5_core_err(dev0,
651                                       "Failed to activate RoCE LAG\n");
652                 else
653                         mlx5_core_err(dev0,
654                                       "Failed to activate VF LAG\n"
655                                       "Make sure all VFs are unbound prior to VF LAG activation or deactivation\n");
656                 return err;
657         }
658
659         if (tracker && tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP &&
660             !roce_lag)
661                 mlx5_lag_drop_rule_setup(ldev, tracker);
662
663         ldev->mode = mode;
664         ldev->mode_flags = flags;
665         return 0;
666 }
667
668 int mlx5_deactivate_lag(struct mlx5_lag *ldev)
669 {
670         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
671         struct mlx5_eswitch *master_esw = dev0->priv.eswitch;
672         u32 in[MLX5_ST_SZ_DW(destroy_lag_in)] = {};
673         bool roce_lag = __mlx5_lag_is_roce(ldev);
674         unsigned long flags = ldev->mode_flags;
675         int err;
676         int i;
677
678         ldev->mode = MLX5_LAG_MODE_NONE;
679         ldev->mode_flags = 0;
680         mlx5_lag_mp_reset(ldev);
681
682         if (test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags)) {
683                 for (i = MLX5_LAG_P1 + 1; i < ldev->ports; i++)
684                         mlx5_eswitch_offloads_single_fdb_del_one(master_esw,
685                                                                  ldev->pf[i].dev->priv.eswitch);
686                 clear_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags);
687         }
688
689         MLX5_SET(destroy_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_LAG);
690         err = mlx5_cmd_exec_in(dev0, destroy_lag, in);
691         if (err) {
692                 if (roce_lag) {
693                         mlx5_core_err(dev0,
694                                       "Failed to deactivate RoCE LAG; driver restart required\n");
695                 } else {
696                         mlx5_core_err(dev0,
697                                       "Failed to deactivate VF LAG; driver restart required\n"
698                                       "Make sure all VFs are unbound prior to VF LAG activation or deactivation\n");
699                 }
700                 return err;
701         }
702
703         if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags))
704                 mlx5_lag_port_sel_destroy(ldev);
705         if (mlx5_lag_has_drop_rule(ldev))
706                 mlx5_lag_drop_rule_cleanup(ldev);
707
708         return 0;
709 }
710
711 #define MLX5_LAG_OFFLOADS_SUPPORTED_PORTS 2
712 bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
713 {
714 #ifdef CONFIG_MLX5_ESWITCH
715         struct mlx5_core_dev *dev;
716         u8 mode;
717 #endif
718         int i;
719
720         for (i = 0; i < ldev->ports; i++)
721                 if (!ldev->pf[i].dev)
722                         return false;
723
724 #ifdef CONFIG_MLX5_ESWITCH
725         for (i = 0; i < ldev->ports; i++) {
726                 dev = ldev->pf[i].dev;
727                 if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
728                         return false;
729         }
730
731         dev = ldev->pf[MLX5_LAG_P1].dev;
732         mode = mlx5_eswitch_mode(dev);
733         for (i = 0; i < ldev->ports; i++)
734                 if (mlx5_eswitch_mode(ldev->pf[i].dev) != mode)
735                         return false;
736
737         if (mode == MLX5_ESWITCH_OFFLOADS && ldev->ports != MLX5_LAG_OFFLOADS_SUPPORTED_PORTS)
738                 return false;
739 #else
740         for (i = 0; i < ldev->ports; i++)
741                 if (mlx5_sriov_is_enabled(ldev->pf[i].dev))
742                         return false;
743 #endif
744         return true;
745 }
746
747 void mlx5_lag_add_devices(struct mlx5_lag *ldev)
748 {
749         int i;
750
751         for (i = 0; i < ldev->ports; i++) {
752                 if (!ldev->pf[i].dev)
753                         continue;
754
755                 if (ldev->pf[i].dev->priv.flags &
756                     MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)
757                         continue;
758
759                 ldev->pf[i].dev->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
760                 mlx5_rescan_drivers_locked(ldev->pf[i].dev);
761         }
762 }
763
764 void mlx5_lag_remove_devices(struct mlx5_lag *ldev)
765 {
766         int i;
767
768         for (i = 0; i < ldev->ports; i++) {
769                 if (!ldev->pf[i].dev)
770                         continue;
771
772                 if (ldev->pf[i].dev->priv.flags &
773                     MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)
774                         continue;
775
776                 ldev->pf[i].dev->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
777                 mlx5_rescan_drivers_locked(ldev->pf[i].dev);
778         }
779 }
780
781 void mlx5_disable_lag(struct mlx5_lag *ldev)
782 {
783         bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
784         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
785         struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev;
786         bool roce_lag;
787         int err;
788         int i;
789
790         roce_lag = __mlx5_lag_is_roce(ldev);
791
792         if (shared_fdb) {
793                 mlx5_lag_remove_devices(ldev);
794         } else if (roce_lag) {
795                 if (!(dev0->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)) {
796                         dev0->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
797                         mlx5_rescan_drivers_locked(dev0);
798                 }
799                 for (i = 1; i < ldev->ports; i++)
800                         mlx5_nic_vport_disable_roce(ldev->pf[i].dev);
801         }
802
803         err = mlx5_deactivate_lag(ldev);
804         if (err)
805                 return;
806
807         if (shared_fdb || roce_lag)
808                 mlx5_lag_add_devices(ldev);
809
810         if (shared_fdb) {
811                 if (!(dev0->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
812                         mlx5_eswitch_reload_reps(dev0->priv.eswitch);
813                 if (!(dev1->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
814                         mlx5_eswitch_reload_reps(dev1->priv.eswitch);
815         }
816 }
817
818 bool mlx5_shared_fdb_supported(struct mlx5_lag *ldev)
819 {
820         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
821         struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev;
822
823         if (is_mdev_switchdev_mode(dev0) &&
824             is_mdev_switchdev_mode(dev1) &&
825             mlx5_eswitch_vport_match_metadata_enabled(dev0->priv.eswitch) &&
826             mlx5_eswitch_vport_match_metadata_enabled(dev1->priv.eswitch) &&
827             mlx5_devcom_comp_is_ready(dev0->priv.devcom,
828                                       MLX5_DEVCOM_ESW_OFFLOADS) &&
829             MLX5_CAP_GEN(dev1, lag_native_fdb_selection) &&
830             MLX5_CAP_ESW(dev1, root_ft_on_other_esw) &&
831             MLX5_CAP_ESW(dev0, esw_shared_ingress_acl))
832                 return true;
833
834         return false;
835 }
836
837 static bool mlx5_lag_is_roce_lag(struct mlx5_lag *ldev)
838 {
839         bool roce_lag = true;
840         int i;
841
842         for (i = 0; i < ldev->ports; i++)
843                 roce_lag = roce_lag && !mlx5_sriov_is_enabled(ldev->pf[i].dev);
844
845 #ifdef CONFIG_MLX5_ESWITCH
846         for (i = 0; i < ldev->ports; i++)
847                 roce_lag = roce_lag && is_mdev_legacy_mode(ldev->pf[i].dev);
848 #endif
849
850         return roce_lag;
851 }
852
853 static bool mlx5_lag_should_modify_lag(struct mlx5_lag *ldev, bool do_bond)
854 {
855         return do_bond && __mlx5_lag_is_active(ldev) &&
856                ldev->mode != MLX5_LAG_MODE_MPESW;
857 }
858
859 static bool mlx5_lag_should_disable_lag(struct mlx5_lag *ldev, bool do_bond)
860 {
861         return !do_bond && __mlx5_lag_is_active(ldev) &&
862                ldev->mode != MLX5_LAG_MODE_MPESW;
863 }
864
865 static void mlx5_do_bond(struct mlx5_lag *ldev)
866 {
867         struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev;
868         struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev;
869         struct lag_tracker tracker = { };
870         bool do_bond, roce_lag;
871         int err;
872         int i;
873
874         if (!mlx5_lag_is_ready(ldev)) {
875                 do_bond = false;
876         } else {
877                 /* VF LAG is in multipath mode, ignore bond change requests */
878                 if (mlx5_lag_is_multipath(dev0))
879                         return;
880
881                 tracker = ldev->tracker;
882
883                 do_bond = tracker.is_bonded && mlx5_lag_check_prereq(ldev);
884         }
885
886         if (do_bond && !__mlx5_lag_is_active(ldev)) {
887                 bool shared_fdb = mlx5_shared_fdb_supported(ldev);
888
889                 roce_lag = mlx5_lag_is_roce_lag(ldev);
890
891                 if (shared_fdb || roce_lag)
892                         mlx5_lag_remove_devices(ldev);
893
894                 err = mlx5_activate_lag(ldev, &tracker,
895                                         roce_lag ? MLX5_LAG_MODE_ROCE :
896                                                    MLX5_LAG_MODE_SRIOV,
897                                         shared_fdb);
898                 if (err) {
899                         if (shared_fdb || roce_lag)
900                                 mlx5_lag_add_devices(ldev);
901
902                         return;
903                 } else if (roce_lag) {
904                         dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
905                         mlx5_rescan_drivers_locked(dev0);
906                         for (i = 1; i < ldev->ports; i++)
907                                 mlx5_nic_vport_enable_roce(ldev->pf[i].dev);
908                 } else if (shared_fdb) {
909                         dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
910                         mlx5_rescan_drivers_locked(dev0);
911
912                         err = mlx5_eswitch_reload_reps(dev0->priv.eswitch);
913                         if (!err)
914                                 err = mlx5_eswitch_reload_reps(dev1->priv.eswitch);
915
916                         if (err) {
917                                 dev0->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
918                                 mlx5_rescan_drivers_locked(dev0);
919                                 mlx5_deactivate_lag(ldev);
920                                 mlx5_lag_add_devices(ldev);
921                                 mlx5_eswitch_reload_reps(dev0->priv.eswitch);
922                                 mlx5_eswitch_reload_reps(dev1->priv.eswitch);
923                                 mlx5_core_err(dev0, "Failed to enable lag\n");
924                                 return;
925                         }
926                 }
927         } else if (mlx5_lag_should_modify_lag(ldev, do_bond)) {
928                 mlx5_modify_lag(ldev, &tracker);
929         } else if (mlx5_lag_should_disable_lag(ldev, do_bond)) {
930                 mlx5_disable_lag(ldev);
931         }
932 }
933
934 static void mlx5_queue_bond_work(struct mlx5_lag *ldev, unsigned long delay)
935 {
936         queue_delayed_work(ldev->wq, &ldev->bond_work, delay);
937 }
938
939 static void mlx5_do_bond_work(struct work_struct *work)
940 {
941         struct delayed_work *delayed_work = to_delayed_work(work);
942         struct mlx5_lag *ldev = container_of(delayed_work, struct mlx5_lag,
943                                              bond_work);
944         int status;
945
946         status = mlx5_dev_list_trylock();
947         if (!status) {
948                 mlx5_queue_bond_work(ldev, HZ);
949                 return;
950         }
951
952         mutex_lock(&ldev->lock);
953         if (ldev->mode_changes_in_progress) {
954                 mutex_unlock(&ldev->lock);
955                 mlx5_dev_list_unlock();
956                 mlx5_queue_bond_work(ldev, HZ);
957                 return;
958         }
959
960         mlx5_do_bond(ldev);
961         mutex_unlock(&ldev->lock);
962         mlx5_dev_list_unlock();
963 }
964
965 static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
966                                          struct lag_tracker *tracker,
967                                          struct netdev_notifier_changeupper_info *info)
968 {
969         struct net_device *upper = info->upper_dev, *ndev_tmp;
970         struct netdev_lag_upper_info *lag_upper_info = NULL;
971         bool is_bonded, is_in_lag, mode_supported;
972         bool has_inactive = 0;
973         struct slave *slave;
974         u8 bond_status = 0;
975         int num_slaves = 0;
976         int changed = 0;
977         int idx;
978
979         if (!netif_is_lag_master(upper))
980                 return 0;
981
982         if (info->linking)
983                 lag_upper_info = info->upper_info;
984
985         /* The event may still be of interest if the slave does not belong to
986          * us, but is enslaved to a master which has one or more of our netdevs
987          * as slaves (e.g., if a new slave is added to a master that bonds two
988          * of our netdevs, we should unbond).
989          */
990         rcu_read_lock();
991         for_each_netdev_in_bond_rcu(upper, ndev_tmp) {
992                 idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
993                 if (idx >= 0) {
994                         slave = bond_slave_get_rcu(ndev_tmp);
995                         if (slave)
996                                 has_inactive |= bond_is_slave_inactive(slave);
997                         bond_status |= (1 << idx);
998                 }
999
1000                 num_slaves++;
1001         }
1002         rcu_read_unlock();
1003
1004         /* None of this lagdev's netdevs are slaves of this master. */
1005         if (!(bond_status & GENMASK(ldev->ports - 1, 0)))
1006                 return 0;
1007
1008         if (lag_upper_info) {
1009                 tracker->tx_type = lag_upper_info->tx_type;
1010                 tracker->hash_type = lag_upper_info->hash_type;
1011         }
1012
1013         tracker->has_inactive = has_inactive;
1014         /* Determine bonding status:
1015          * A device is considered bonded if both its physical ports are slaves
1016          * of the same lag master, and only them.
1017          */
1018         is_in_lag = num_slaves == ldev->ports &&
1019                 bond_status == GENMASK(ldev->ports - 1, 0);
1020
1021         /* Lag mode must be activebackup or hash. */
1022         mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP ||
1023                          tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH;
1024
1025         is_bonded = is_in_lag && mode_supported;
1026         if (tracker->is_bonded != is_bonded) {
1027                 tracker->is_bonded = is_bonded;
1028                 changed = 1;
1029         }
1030
1031         if (!is_in_lag)
1032                 return changed;
1033
1034         if (!mlx5_lag_is_ready(ldev))
1035                 NL_SET_ERR_MSG_MOD(info->info.extack,
1036                                    "Can't activate LAG offload, PF is configured with more than 64 VFs");
1037         else if (!mode_supported)
1038                 NL_SET_ERR_MSG_MOD(info->info.extack,
1039                                    "Can't activate LAG offload, TX type isn't supported");
1040
1041         return changed;
1042 }
1043
1044 static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
1045                                               struct lag_tracker *tracker,
1046                                               struct net_device *ndev,
1047                                               struct netdev_notifier_changelowerstate_info *info)
1048 {
1049         struct netdev_lag_lower_state_info *lag_lower_info;
1050         int idx;
1051
1052         if (!netif_is_lag_port(ndev))
1053                 return 0;
1054
1055         idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev);
1056         if (idx < 0)
1057                 return 0;
1058
1059         /* This information is used to determine virtual to physical
1060          * port mapping.
1061          */
1062         lag_lower_info = info->lower_state_info;
1063         if (!lag_lower_info)
1064                 return 0;
1065
1066         tracker->netdev_state[idx] = *lag_lower_info;
1067
1068         return 1;
1069 }
1070
1071 static int mlx5_handle_changeinfodata_event(struct mlx5_lag *ldev,
1072                                             struct lag_tracker *tracker,
1073                                             struct net_device *ndev)
1074 {
1075         struct net_device *ndev_tmp;
1076         struct slave *slave;
1077         bool has_inactive = 0;
1078         int idx;
1079
1080         if (!netif_is_lag_master(ndev))
1081                 return 0;
1082
1083         rcu_read_lock();
1084         for_each_netdev_in_bond_rcu(ndev, ndev_tmp) {
1085                 idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
1086                 if (idx < 0)
1087                         continue;
1088
1089                 slave = bond_slave_get_rcu(ndev_tmp);
1090                 if (slave)
1091                         has_inactive |= bond_is_slave_inactive(slave);
1092         }
1093         rcu_read_unlock();
1094
1095         if (tracker->has_inactive == has_inactive)
1096                 return 0;
1097
1098         tracker->has_inactive = has_inactive;
1099
1100         return 1;
1101 }
1102
1103 /* this handler is always registered to netdev events */
1104 static int mlx5_lag_netdev_event(struct notifier_block *this,
1105                                  unsigned long event, void *ptr)
1106 {
1107         struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
1108         struct lag_tracker tracker;
1109         struct mlx5_lag *ldev;
1110         int changed = 0;
1111
1112         if (event != NETDEV_CHANGEUPPER &&
1113             event != NETDEV_CHANGELOWERSTATE &&
1114             event != NETDEV_CHANGEINFODATA)
1115                 return NOTIFY_DONE;
1116
1117         ldev    = container_of(this, struct mlx5_lag, nb);
1118
1119         tracker = ldev->tracker;
1120
1121         switch (event) {
1122         case NETDEV_CHANGEUPPER:
1123                 changed = mlx5_handle_changeupper_event(ldev, &tracker, ptr);
1124                 break;
1125         case NETDEV_CHANGELOWERSTATE:
1126                 changed = mlx5_handle_changelowerstate_event(ldev, &tracker,
1127                                                              ndev, ptr);
1128                 break;
1129         case NETDEV_CHANGEINFODATA:
1130                 changed = mlx5_handle_changeinfodata_event(ldev, &tracker, ndev);
1131                 break;
1132         }
1133
1134         ldev->tracker = tracker;
1135
1136         if (changed)
1137                 mlx5_queue_bond_work(ldev, 0);
1138
1139         return NOTIFY_DONE;
1140 }
1141
1142 static void mlx5_ldev_add_netdev(struct mlx5_lag *ldev,
1143                                  struct mlx5_core_dev *dev,
1144                                  struct net_device *netdev)
1145 {
1146         unsigned int fn = mlx5_get_dev_index(dev);
1147         unsigned long flags;
1148
1149         if (fn >= ldev->ports)
1150                 return;
1151
1152         spin_lock_irqsave(&lag_lock, flags);
1153         ldev->pf[fn].netdev = netdev;
1154         ldev->tracker.netdev_state[fn].link_up = 0;
1155         ldev->tracker.netdev_state[fn].tx_enabled = 0;
1156         spin_unlock_irqrestore(&lag_lock, flags);
1157 }
1158
1159 static void mlx5_ldev_remove_netdev(struct mlx5_lag *ldev,
1160                                     struct net_device *netdev)
1161 {
1162         unsigned long flags;
1163         int i;
1164
1165         spin_lock_irqsave(&lag_lock, flags);
1166         for (i = 0; i < ldev->ports; i++) {
1167                 if (ldev->pf[i].netdev == netdev) {
1168                         ldev->pf[i].netdev = NULL;
1169                         break;
1170                 }
1171         }
1172         spin_unlock_irqrestore(&lag_lock, flags);
1173 }
1174
1175 static void mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
1176                                struct mlx5_core_dev *dev)
1177 {
1178         unsigned int fn = mlx5_get_dev_index(dev);
1179
1180         if (fn >= ldev->ports)
1181                 return;
1182
1183         ldev->pf[fn].dev = dev;
1184         dev->priv.lag = ldev;
1185 }
1186
1187 static void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev,
1188                                   struct mlx5_core_dev *dev)
1189 {
1190         int i;
1191
1192         for (i = 0; i < ldev->ports; i++)
1193                 if (ldev->pf[i].dev == dev)
1194                         break;
1195
1196         if (i == ldev->ports)
1197                 return;
1198
1199         ldev->pf[i].dev = NULL;
1200         dev->priv.lag = NULL;
1201 }
1202
1203 /* Must be called with intf_mutex held */
1204 static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
1205 {
1206         struct mlx5_lag *ldev = NULL;
1207         struct mlx5_core_dev *tmp_dev;
1208
1209         tmp_dev = mlx5_get_next_phys_dev_lag(dev);
1210         if (tmp_dev)
1211                 ldev = mlx5_lag_dev(tmp_dev);
1212
1213         if (!ldev) {
1214                 ldev = mlx5_lag_dev_alloc(dev);
1215                 if (!ldev) {
1216                         mlx5_core_err(dev, "Failed to alloc lag dev\n");
1217                         return 0;
1218                 }
1219                 mlx5_ldev_add_mdev(ldev, dev);
1220                 return 0;
1221         }
1222
1223         mutex_lock(&ldev->lock);
1224         if (ldev->mode_changes_in_progress) {
1225                 mutex_unlock(&ldev->lock);
1226                 return -EAGAIN;
1227         }
1228         mlx5_ldev_get(ldev);
1229         mlx5_ldev_add_mdev(ldev, dev);
1230         mutex_unlock(&ldev->lock);
1231
1232         return 0;
1233 }
1234
1235 void mlx5_lag_remove_mdev(struct mlx5_core_dev *dev)
1236 {
1237         struct mlx5_lag *ldev;
1238
1239         ldev = mlx5_lag_dev(dev);
1240         if (!ldev)
1241                 return;
1242
1243         /* mdev is being removed, might as well remove debugfs
1244          * as early as possible.
1245          */
1246         mlx5_ldev_remove_debugfs(dev->priv.dbg.lag_debugfs);
1247 recheck:
1248         mutex_lock(&ldev->lock);
1249         if (ldev->mode_changes_in_progress) {
1250                 mutex_unlock(&ldev->lock);
1251                 msleep(100);
1252                 goto recheck;
1253         }
1254         mlx5_ldev_remove_mdev(ldev, dev);
1255         mutex_unlock(&ldev->lock);
1256         mlx5_ldev_put(ldev);
1257 }
1258
1259 void mlx5_lag_add_mdev(struct mlx5_core_dev *dev)
1260 {
1261         int err;
1262
1263         if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
1264             !MLX5_CAP_GEN(dev, lag_master) ||
1265             (MLX5_CAP_GEN(dev, num_lag_ports) > MLX5_MAX_PORTS ||
1266              MLX5_CAP_GEN(dev, num_lag_ports) <= 1))
1267                 return;
1268
1269 recheck:
1270         mlx5_dev_list_lock();
1271         err = __mlx5_lag_dev_add_mdev(dev);
1272         mlx5_dev_list_unlock();
1273
1274         if (err) {
1275                 msleep(100);
1276                 goto recheck;
1277         }
1278         mlx5_ldev_add_debugfs(dev);
1279 }
1280
1281 void mlx5_lag_remove_netdev(struct mlx5_core_dev *dev,
1282                             struct net_device *netdev)
1283 {
1284         struct mlx5_lag *ldev;
1285         bool lag_is_active;
1286
1287         ldev = mlx5_lag_dev(dev);
1288         if (!ldev)
1289                 return;
1290
1291         mutex_lock(&ldev->lock);
1292         mlx5_ldev_remove_netdev(ldev, netdev);
1293         clear_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags);
1294
1295         lag_is_active = __mlx5_lag_is_active(ldev);
1296         mutex_unlock(&ldev->lock);
1297
1298         if (lag_is_active)
1299                 mlx5_queue_bond_work(ldev, 0);
1300 }
1301
1302 void mlx5_lag_add_netdev(struct mlx5_core_dev *dev,
1303                          struct net_device *netdev)
1304 {
1305         struct mlx5_lag *ldev;
1306         int i;
1307
1308         ldev = mlx5_lag_dev(dev);
1309         if (!ldev)
1310                 return;
1311
1312         mutex_lock(&ldev->lock);
1313         mlx5_ldev_add_netdev(ldev, dev, netdev);
1314
1315         for (i = 0; i < ldev->ports; i++)
1316                 if (!ldev->pf[i].netdev)
1317                         break;
1318
1319         if (i >= ldev->ports)
1320                 set_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags);
1321         mutex_unlock(&ldev->lock);
1322         mlx5_queue_bond_work(ldev, 0);
1323 }
1324
1325 bool mlx5_lag_is_roce(struct mlx5_core_dev *dev)
1326 {
1327         struct mlx5_lag *ldev;
1328         unsigned long flags;
1329         bool res;
1330
1331         spin_lock_irqsave(&lag_lock, flags);
1332         ldev = mlx5_lag_dev(dev);
1333         res  = ldev && __mlx5_lag_is_roce(ldev);
1334         spin_unlock_irqrestore(&lag_lock, flags);
1335
1336         return res;
1337 }
1338 EXPORT_SYMBOL(mlx5_lag_is_roce);
1339
1340 bool mlx5_lag_is_active(struct mlx5_core_dev *dev)
1341 {
1342         struct mlx5_lag *ldev;
1343         unsigned long flags;
1344         bool res;
1345
1346         spin_lock_irqsave(&lag_lock, flags);
1347         ldev = mlx5_lag_dev(dev);
1348         res  = ldev && __mlx5_lag_is_active(ldev);
1349         spin_unlock_irqrestore(&lag_lock, flags);
1350
1351         return res;
1352 }
1353 EXPORT_SYMBOL(mlx5_lag_is_active);
1354
1355 bool mlx5_lag_mode_is_hash(struct mlx5_core_dev *dev)
1356 {
1357         struct mlx5_lag *ldev;
1358         unsigned long flags;
1359         bool res = 0;
1360
1361         spin_lock_irqsave(&lag_lock, flags);
1362         ldev = mlx5_lag_dev(dev);
1363         if (ldev)
1364                 res = test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &ldev->mode_flags);
1365         spin_unlock_irqrestore(&lag_lock, flags);
1366
1367         return res;
1368 }
1369 EXPORT_SYMBOL(mlx5_lag_mode_is_hash);
1370
1371 bool mlx5_lag_is_master(struct mlx5_core_dev *dev)
1372 {
1373         struct mlx5_lag *ldev;
1374         unsigned long flags;
1375         bool res;
1376
1377         spin_lock_irqsave(&lag_lock, flags);
1378         ldev = mlx5_lag_dev(dev);
1379         res = ldev && __mlx5_lag_is_active(ldev) &&
1380                 dev == ldev->pf[MLX5_LAG_P1].dev;
1381         spin_unlock_irqrestore(&lag_lock, flags);
1382
1383         return res;
1384 }
1385 EXPORT_SYMBOL(mlx5_lag_is_master);
1386
1387 bool mlx5_lag_is_sriov(struct mlx5_core_dev *dev)
1388 {
1389         struct mlx5_lag *ldev;
1390         unsigned long flags;
1391         bool res;
1392
1393         spin_lock_irqsave(&lag_lock, flags);
1394         ldev = mlx5_lag_dev(dev);
1395         res  = ldev && __mlx5_lag_is_sriov(ldev);
1396         spin_unlock_irqrestore(&lag_lock, flags);
1397
1398         return res;
1399 }
1400 EXPORT_SYMBOL(mlx5_lag_is_sriov);
1401
1402 bool mlx5_lag_is_shared_fdb(struct mlx5_core_dev *dev)
1403 {
1404         struct mlx5_lag *ldev;
1405         unsigned long flags;
1406         bool res;
1407
1408         spin_lock_irqsave(&lag_lock, flags);
1409         ldev = mlx5_lag_dev(dev);
1410         res = ldev && test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
1411         spin_unlock_irqrestore(&lag_lock, flags);
1412
1413         return res;
1414 }
1415 EXPORT_SYMBOL(mlx5_lag_is_shared_fdb);
1416
1417 void mlx5_lag_disable_change(struct mlx5_core_dev *dev)
1418 {
1419         struct mlx5_lag *ldev;
1420
1421         ldev = mlx5_lag_dev(dev);
1422         if (!ldev)
1423                 return;
1424
1425         mlx5_dev_list_lock();
1426         mutex_lock(&ldev->lock);
1427
1428         ldev->mode_changes_in_progress++;
1429         if (__mlx5_lag_is_active(ldev))
1430                 mlx5_disable_lag(ldev);
1431
1432         mutex_unlock(&ldev->lock);
1433         mlx5_dev_list_unlock();
1434 }
1435
1436 void mlx5_lag_enable_change(struct mlx5_core_dev *dev)
1437 {
1438         struct mlx5_lag *ldev;
1439
1440         ldev = mlx5_lag_dev(dev);
1441         if (!ldev)
1442                 return;
1443
1444         mutex_lock(&ldev->lock);
1445         ldev->mode_changes_in_progress--;
1446         mutex_unlock(&ldev->lock);
1447         mlx5_queue_bond_work(ldev, 0);
1448 }
1449
1450 struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev)
1451 {
1452         struct net_device *ndev = NULL;
1453         struct mlx5_lag *ldev;
1454         unsigned long flags;
1455         int i;
1456
1457         spin_lock_irqsave(&lag_lock, flags);
1458         ldev = mlx5_lag_dev(dev);
1459
1460         if (!(ldev && __mlx5_lag_is_roce(ldev)))
1461                 goto unlock;
1462
1463         if (ldev->tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
1464                 for (i = 0; i < ldev->ports; i++)
1465                         if (ldev->tracker.netdev_state[i].tx_enabled)
1466                                 ndev = ldev->pf[i].netdev;
1467                 if (!ndev)
1468                         ndev = ldev->pf[ldev->ports - 1].netdev;
1469         } else {
1470                 ndev = ldev->pf[MLX5_LAG_P1].netdev;
1471         }
1472         if (ndev)
1473                 dev_hold(ndev);
1474
1475 unlock:
1476         spin_unlock_irqrestore(&lag_lock, flags);
1477
1478         return ndev;
1479 }
1480 EXPORT_SYMBOL(mlx5_lag_get_roce_netdev);
1481
1482 u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev,
1483                            struct net_device *slave)
1484 {
1485         struct mlx5_lag *ldev;
1486         unsigned long flags;
1487         u8 port = 0;
1488         int i;
1489
1490         spin_lock_irqsave(&lag_lock, flags);
1491         ldev = mlx5_lag_dev(dev);
1492         if (!(ldev && __mlx5_lag_is_roce(ldev)))
1493                 goto unlock;
1494
1495         for (i = 0; i < ldev->ports; i++) {
1496                 if (ldev->pf[MLX5_LAG_P1].netdev == slave) {
1497                         port = i;
1498                         break;
1499                 }
1500         }
1501
1502         port = ldev->v2p_map[port * ldev->buckets];
1503
1504 unlock:
1505         spin_unlock_irqrestore(&lag_lock, flags);
1506         return port;
1507 }
1508 EXPORT_SYMBOL(mlx5_lag_get_slave_port);
1509
1510 u8 mlx5_lag_get_num_ports(struct mlx5_core_dev *dev)
1511 {
1512         struct mlx5_lag *ldev;
1513
1514         ldev = mlx5_lag_dev(dev);
1515         if (!ldev)
1516                 return 0;
1517
1518         return ldev->ports;
1519 }
1520 EXPORT_SYMBOL(mlx5_lag_get_num_ports);
1521
1522 struct mlx5_core_dev *mlx5_lag_get_next_peer_mdev(struct mlx5_core_dev *dev, int *i)
1523 {
1524         struct mlx5_core_dev *peer_dev = NULL;
1525         struct mlx5_lag *ldev;
1526         unsigned long flags;
1527         int idx;
1528
1529         spin_lock_irqsave(&lag_lock, flags);
1530         ldev = mlx5_lag_dev(dev);
1531         if (!ldev)
1532                 goto unlock;
1533
1534         if (*i == ldev->ports)
1535                 goto unlock;
1536         for (idx = *i; idx < ldev->ports; idx++)
1537                 if (ldev->pf[idx].dev != dev)
1538                         break;
1539
1540         if (idx == ldev->ports) {
1541                 *i = idx;
1542                 goto unlock;
1543         }
1544         *i = idx + 1;
1545
1546         peer_dev = ldev->pf[idx].dev;
1547
1548 unlock:
1549         spin_unlock_irqrestore(&lag_lock, flags);
1550         return peer_dev;
1551 }
1552 EXPORT_SYMBOL(mlx5_lag_get_next_peer_mdev);
1553
1554 int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
1555                                  u64 *values,
1556                                  int num_counters,
1557                                  size_t *offsets)
1558 {
1559         int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out);
1560         struct mlx5_core_dev **mdev;
1561         struct mlx5_lag *ldev;
1562         unsigned long flags;
1563         int num_ports;
1564         int ret, i, j;
1565         void *out;
1566
1567         out = kvzalloc(outlen, GFP_KERNEL);
1568         if (!out)
1569                 return -ENOMEM;
1570
1571         mdev = kvzalloc(sizeof(mdev[0]) * MLX5_MAX_PORTS, GFP_KERNEL);
1572         if (!mdev) {
1573                 ret = -ENOMEM;
1574                 goto free_out;
1575         }
1576
1577         memset(values, 0, sizeof(*values) * num_counters);
1578
1579         spin_lock_irqsave(&lag_lock, flags);
1580         ldev = mlx5_lag_dev(dev);
1581         if (ldev && __mlx5_lag_is_active(ldev)) {
1582                 num_ports = ldev->ports;
1583                 for (i = 0; i < ldev->ports; i++)
1584                         mdev[i] = ldev->pf[i].dev;
1585         } else {
1586                 num_ports = 1;
1587                 mdev[MLX5_LAG_P1] = dev;
1588         }
1589         spin_unlock_irqrestore(&lag_lock, flags);
1590
1591         for (i = 0; i < num_ports; ++i) {
1592                 u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {};
1593
1594                 MLX5_SET(query_cong_statistics_in, in, opcode,
1595                          MLX5_CMD_OP_QUERY_CONG_STATISTICS);
1596                 ret = mlx5_cmd_exec_inout(mdev[i], query_cong_statistics, in,
1597                                           out);
1598                 if (ret)
1599                         goto free_mdev;
1600
1601                 for (j = 0; j < num_counters; ++j)
1602                         values[j] += be64_to_cpup((__be64 *)(out + offsets[j]));
1603         }
1604
1605 free_mdev:
1606         kvfree(mdev);
1607 free_out:
1608         kvfree(out);
1609         return ret;
1610 }
1611 EXPORT_SYMBOL(mlx5_lag_query_cong_counters);