GNU Linux-libre 4.9.337-gnu1
[releases.git] / drivers / net / ethernet / mellanox / mlx5 / core / 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 <linux/mlx5/driver.h>
35 #include <linux/mlx5/vport.h>
36 #include "mlx5_core.h"
37
38 enum {
39         MLX5_LAG_FLAG_BONDED = 1 << 0,
40 };
41
42 struct lag_func {
43         struct mlx5_core_dev *dev;
44         struct net_device    *netdev;
45 };
46
47 /* Used for collection of netdev event info. */
48 struct lag_tracker {
49         enum   netdev_lag_tx_type           tx_type;
50         struct netdev_lag_lower_state_info  netdev_state[MLX5_MAX_PORTS];
51         bool is_bonded;
52 };
53
54 /* LAG data of a ConnectX card.
55  * It serves both its phys functions.
56  */
57 struct mlx5_lag {
58         u8                        flags;
59         u8                        v2p_map[MLX5_MAX_PORTS];
60         struct lag_func           pf[MLX5_MAX_PORTS];
61         struct lag_tracker        tracker;
62         struct delayed_work       bond_work;
63         struct notifier_block     nb;
64 };
65
66 /* General purpose, use for short periods of time.
67  * Beware of lock dependencies (preferably, no locks should be acquired
68  * under it).
69  */
70 static DEFINE_MUTEX(lag_mutex);
71
72 static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, u8 remap_port1,
73                                u8 remap_port2)
74 {
75         u32   in[MLX5_ST_SZ_DW(create_lag_in)]   = {0};
76         u32   out[MLX5_ST_SZ_DW(create_lag_out)] = {0};
77         void *lag_ctx = MLX5_ADDR_OF(create_lag_in, in, ctx);
78
79         MLX5_SET(create_lag_in, in, opcode, MLX5_CMD_OP_CREATE_LAG);
80
81         MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, remap_port1);
82         MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, remap_port2);
83
84         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
85 }
86
87 static int mlx5_cmd_modify_lag(struct mlx5_core_dev *dev, u8 remap_port1,
88                                u8 remap_port2)
89 {
90         u32   in[MLX5_ST_SZ_DW(modify_lag_in)]   = {0};
91         u32   out[MLX5_ST_SZ_DW(modify_lag_out)] = {0};
92         void *lag_ctx = MLX5_ADDR_OF(modify_lag_in, in, ctx);
93
94         MLX5_SET(modify_lag_in, in, opcode, MLX5_CMD_OP_MODIFY_LAG);
95         MLX5_SET(modify_lag_in, in, field_select, 0x1);
96
97         MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, remap_port1);
98         MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, remap_port2);
99
100         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
101 }
102
103 static int mlx5_cmd_destroy_lag(struct mlx5_core_dev *dev)
104 {
105         u32  in[MLX5_ST_SZ_DW(destroy_lag_in)]  = {0};
106         u32 out[MLX5_ST_SZ_DW(destroy_lag_out)] = {0};
107
108         MLX5_SET(destroy_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_LAG);
109
110         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
111 }
112
113 int mlx5_cmd_create_vport_lag(struct mlx5_core_dev *dev)
114 {
115         u32  in[MLX5_ST_SZ_DW(create_vport_lag_in)]  = {0};
116         u32 out[MLX5_ST_SZ_DW(create_vport_lag_out)] = {0};
117
118         MLX5_SET(create_vport_lag_in, in, opcode, MLX5_CMD_OP_CREATE_VPORT_LAG);
119
120         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
121 }
122 EXPORT_SYMBOL(mlx5_cmd_create_vport_lag);
123
124 int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev)
125 {
126         u32  in[MLX5_ST_SZ_DW(destroy_vport_lag_in)]  = {0};
127         u32 out[MLX5_ST_SZ_DW(destroy_vport_lag_out)] = {0};
128
129         MLX5_SET(destroy_vport_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_VPORT_LAG);
130
131         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
132 }
133 EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag);
134
135 static struct mlx5_lag *mlx5_lag_dev_get(struct mlx5_core_dev *dev)
136 {
137         return dev->priv.lag;
138 }
139
140 static int mlx5_lag_dev_get_netdev_idx(struct mlx5_lag *ldev,
141                                        struct net_device *ndev)
142 {
143         int i;
144
145         for (i = 0; i < MLX5_MAX_PORTS; i++)
146                 if (ldev->pf[i].netdev == ndev)
147                         return i;
148
149         return -1;
150 }
151
152 static bool mlx5_lag_is_bonded(struct mlx5_lag *ldev)
153 {
154         return !!(ldev->flags & MLX5_LAG_FLAG_BONDED);
155 }
156
157 static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker,
158                                            u8 *port1, u8 *port2)
159 {
160         *port1 = 1;
161         *port2 = 2;
162         if (!tracker->netdev_state[0].tx_enabled ||
163             !tracker->netdev_state[0].link_up) {
164                 *port1 = 2;
165                 return;
166         }
167
168         if (!tracker->netdev_state[1].tx_enabled ||
169             !tracker->netdev_state[1].link_up)
170                 *port2 = 1;
171 }
172
173 static void mlx5_activate_lag(struct mlx5_lag *ldev,
174                               struct lag_tracker *tracker)
175 {
176         struct mlx5_core_dev *dev0 = ldev->pf[0].dev;
177         int err;
178
179         ldev->flags |= MLX5_LAG_FLAG_BONDED;
180
181         mlx5_infer_tx_affinity_mapping(tracker, &ldev->v2p_map[0],
182                                        &ldev->v2p_map[1]);
183
184         err = mlx5_cmd_create_lag(dev0, ldev->v2p_map[0], ldev->v2p_map[1]);
185         if (err)
186                 mlx5_core_err(dev0,
187                               "Failed to create LAG (%d)\n",
188                               err);
189 }
190
191 static void mlx5_deactivate_lag(struct mlx5_lag *ldev)
192 {
193         struct mlx5_core_dev *dev0 = ldev->pf[0].dev;
194         int err;
195
196         ldev->flags &= ~MLX5_LAG_FLAG_BONDED;
197
198         err = mlx5_cmd_destroy_lag(dev0);
199         if (err)
200                 mlx5_core_err(dev0,
201                               "Failed to destroy LAG (%d)\n",
202                               err);
203 }
204
205 static void mlx5_do_bond(struct mlx5_lag *ldev)
206 {
207         struct mlx5_core_dev *dev0 = ldev->pf[0].dev;
208         struct mlx5_core_dev *dev1 = ldev->pf[1].dev;
209         struct lag_tracker tracker;
210         u8 v2p_port1, v2p_port2;
211         int i, err;
212
213         if (!dev0 || !dev1)
214                 return;
215
216         mutex_lock(&lag_mutex);
217         tracker = ldev->tracker;
218         mutex_unlock(&lag_mutex);
219
220         if (tracker.is_bonded && !mlx5_lag_is_bonded(ldev)) {
221                 if (mlx5_sriov_is_enabled(dev0) ||
222                     mlx5_sriov_is_enabled(dev1)) {
223                         mlx5_core_warn(dev0, "LAG is not supported with SRIOV");
224                         return;
225                 }
226
227                 for (i = 0; i < MLX5_MAX_PORTS; i++)
228                         mlx5_remove_dev_by_protocol(ldev->pf[i].dev,
229                                                     MLX5_INTERFACE_PROTOCOL_IB);
230
231                 mlx5_activate_lag(ldev, &tracker);
232
233                 mlx5_add_dev_by_protocol(dev0, MLX5_INTERFACE_PROTOCOL_IB);
234                 mlx5_nic_vport_enable_roce(dev1);
235         } else if (tracker.is_bonded && mlx5_lag_is_bonded(ldev)) {
236                 mlx5_infer_tx_affinity_mapping(&tracker, &v2p_port1,
237                                                &v2p_port2);
238
239                 if ((v2p_port1 != ldev->v2p_map[0]) ||
240                     (v2p_port2 != ldev->v2p_map[1])) {
241                         ldev->v2p_map[0] = v2p_port1;
242                         ldev->v2p_map[1] = v2p_port2;
243
244                         err = mlx5_cmd_modify_lag(dev0, v2p_port1, v2p_port2);
245                         if (err)
246                                 mlx5_core_err(dev0,
247                                               "Failed to modify LAG (%d)\n",
248                                               err);
249                 }
250         } else if (!tracker.is_bonded && mlx5_lag_is_bonded(ldev)) {
251                 mlx5_remove_dev_by_protocol(dev0, MLX5_INTERFACE_PROTOCOL_IB);
252                 mlx5_nic_vport_disable_roce(dev1);
253
254                 mlx5_deactivate_lag(ldev);
255
256                 for (i = 0; i < MLX5_MAX_PORTS; i++)
257                         if (ldev->pf[i].dev)
258                                 mlx5_add_dev_by_protocol(ldev->pf[i].dev,
259                                                          MLX5_INTERFACE_PROTOCOL_IB);
260         }
261 }
262
263 static void mlx5_queue_bond_work(struct mlx5_lag *ldev, unsigned long delay)
264 {
265         schedule_delayed_work(&ldev->bond_work, delay);
266 }
267
268 static void mlx5_do_bond_work(struct work_struct *work)
269 {
270         struct delayed_work *delayed_work = to_delayed_work(work);
271         struct mlx5_lag *ldev = container_of(delayed_work, struct mlx5_lag,
272                                              bond_work);
273         int status;
274
275         status = mlx5_dev_list_trylock();
276         if (!status) {
277                 /* 1 sec delay. */
278                 mlx5_queue_bond_work(ldev, HZ);
279                 return;
280         }
281
282         mlx5_do_bond(ldev);
283         mlx5_dev_list_unlock();
284 }
285
286 static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
287                                          struct lag_tracker *tracker,
288                                          struct net_device *ndev,
289                                          struct netdev_notifier_changeupper_info *info)
290 {
291         struct net_device *upper = info->upper_dev, *ndev_tmp;
292         struct netdev_lag_upper_info *lag_upper_info = NULL;
293         bool is_bonded;
294         int bond_status = 0;
295         int num_slaves = 0;
296         int idx;
297
298         if (!netif_is_lag_master(upper))
299                 return 0;
300
301         if (info->linking)
302                 lag_upper_info = info->upper_info;
303
304         /* The event may still be of interest if the slave does not belong to
305          * us, but is enslaved to a master which has one or more of our netdevs
306          * as slaves (e.g., if a new slave is added to a master that bonds two
307          * of our netdevs, we should unbond).
308          */
309         rcu_read_lock();
310         for_each_netdev_in_bond_rcu(upper, ndev_tmp) {
311                 idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
312                 if (idx > -1)
313                         bond_status |= (1 << idx);
314
315                 num_slaves++;
316         }
317         rcu_read_unlock();
318
319         /* None of this lagdev's netdevs are slaves of this master. */
320         if (!(bond_status & 0x3))
321                 return 0;
322
323         if (lag_upper_info)
324                 tracker->tx_type = lag_upper_info->tx_type;
325
326         /* Determine bonding status:
327          * A device is considered bonded if both its physical ports are slaves
328          * of the same lag master, and only them.
329          * Lag mode must be activebackup or hash.
330          */
331         is_bonded = (num_slaves == MLX5_MAX_PORTS) &&
332                     (bond_status == 0x3) &&
333                     ((tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) ||
334                      (tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH));
335
336         if (tracker->is_bonded != is_bonded) {
337                 tracker->is_bonded = is_bonded;
338                 return 1;
339         }
340
341         return 0;
342 }
343
344 static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
345                                               struct lag_tracker *tracker,
346                                               struct net_device *ndev,
347                                               struct netdev_notifier_changelowerstate_info *info)
348 {
349         struct netdev_lag_lower_state_info *lag_lower_info;
350         int idx;
351
352         if (!netif_is_lag_port(ndev))
353                 return 0;
354
355         idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev);
356         if (idx == -1)
357                 return 0;
358
359         /* This information is used to determine virtual to physical
360          * port mapping.
361          */
362         lag_lower_info = info->lower_state_info;
363         if (!lag_lower_info)
364                 return 0;
365
366         tracker->netdev_state[idx] = *lag_lower_info;
367
368         return 1;
369 }
370
371 static int mlx5_lag_netdev_event(struct notifier_block *this,
372                                  unsigned long event, void *ptr)
373 {
374         struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
375         struct lag_tracker tracker;
376         struct mlx5_lag *ldev;
377         int changed = 0;
378
379         if (!net_eq(dev_net(ndev), &init_net))
380                 return NOTIFY_DONE;
381
382         if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
383                 return NOTIFY_DONE;
384
385         ldev    = container_of(this, struct mlx5_lag, nb);
386         tracker = ldev->tracker;
387
388         switch (event) {
389         case NETDEV_CHANGEUPPER:
390                 changed = mlx5_handle_changeupper_event(ldev, &tracker, ndev,
391                                                         ptr);
392                 break;
393         case NETDEV_CHANGELOWERSTATE:
394                 changed = mlx5_handle_changelowerstate_event(ldev, &tracker,
395                                                              ndev, ptr);
396                 break;
397         }
398
399         mutex_lock(&lag_mutex);
400         ldev->tracker = tracker;
401         mutex_unlock(&lag_mutex);
402
403         if (changed)
404                 mlx5_queue_bond_work(ldev, 0);
405
406         return NOTIFY_DONE;
407 }
408
409 static struct mlx5_lag *mlx5_lag_dev_alloc(void)
410 {
411         struct mlx5_lag *ldev;
412
413         ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
414         if (!ldev)
415                 return NULL;
416
417         INIT_DELAYED_WORK(&ldev->bond_work, mlx5_do_bond_work);
418
419         return ldev;
420 }
421
422 static void mlx5_lag_dev_free(struct mlx5_lag *ldev)
423 {
424         kfree(ldev);
425 }
426
427 static void mlx5_lag_dev_add_pf(struct mlx5_lag *ldev,
428                                 struct mlx5_core_dev *dev,
429                                 struct net_device *netdev)
430 {
431         unsigned int fn = PCI_FUNC(dev->pdev->devfn);
432
433         if (fn >= MLX5_MAX_PORTS)
434                 return;
435
436         mutex_lock(&lag_mutex);
437         ldev->pf[fn].dev    = dev;
438         ldev->pf[fn].netdev = netdev;
439         ldev->tracker.netdev_state[fn].link_up = 0;
440         ldev->tracker.netdev_state[fn].tx_enabled = 0;
441
442         dev->priv.lag = ldev;
443         mutex_unlock(&lag_mutex);
444 }
445
446 static void mlx5_lag_dev_remove_pf(struct mlx5_lag *ldev,
447                                    struct mlx5_core_dev *dev)
448 {
449         int i;
450
451         for (i = 0; i < MLX5_MAX_PORTS; i++)
452                 if (ldev->pf[i].dev == dev)
453                         break;
454
455         if (i == MLX5_MAX_PORTS)
456                 return;
457
458         mutex_lock(&lag_mutex);
459         memset(&ldev->pf[i], 0, sizeof(*ldev->pf));
460
461         dev->priv.lag = NULL;
462         mutex_unlock(&lag_mutex);
463 }
464
465
466 /* Must be called with intf_mutex held */
467 void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev)
468 {
469         struct mlx5_lag *ldev = NULL;
470         struct mlx5_core_dev *tmp_dev;
471
472         if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
473             !MLX5_CAP_GEN(dev, lag_master) ||
474             (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_MAX_PORTS))
475                 return;
476
477         tmp_dev = mlx5_get_next_phys_dev(dev);
478         if (tmp_dev)
479                 ldev = tmp_dev->priv.lag;
480
481         if (!ldev) {
482                 ldev = mlx5_lag_dev_alloc();
483                 if (!ldev) {
484                         mlx5_core_err(dev, "Failed to alloc lag dev\n");
485                         return;
486                 }
487         }
488
489         mlx5_lag_dev_add_pf(ldev, dev, netdev);
490
491         if (!ldev->nb.notifier_call) {
492                 ldev->nb.notifier_call = mlx5_lag_netdev_event;
493                 if (register_netdevice_notifier(&ldev->nb)) {
494                         ldev->nb.notifier_call = NULL;
495                         mlx5_core_err(dev, "Failed to register LAG netdev notifier\n");
496                 }
497         }
498 }
499
500 /* Must be called with intf_mutex held */
501 void mlx5_lag_remove(struct mlx5_core_dev *dev)
502 {
503         struct mlx5_lag *ldev;
504         int i;
505
506         ldev = mlx5_lag_dev_get(dev);
507         if (!ldev)
508                 return;
509
510         if (mlx5_lag_is_bonded(ldev))
511                 mlx5_deactivate_lag(ldev);
512
513         mlx5_lag_dev_remove_pf(ldev, dev);
514
515         for (i = 0; i < MLX5_MAX_PORTS; i++)
516                 if (ldev->pf[i].dev)
517                         break;
518
519         if (i == MLX5_MAX_PORTS) {
520                 if (ldev->nb.notifier_call)
521                         unregister_netdevice_notifier(&ldev->nb);
522                 cancel_delayed_work_sync(&ldev->bond_work);
523                 mlx5_lag_dev_free(ldev);
524         }
525 }
526
527 bool mlx5_lag_is_active(struct mlx5_core_dev *dev)
528 {
529         struct mlx5_lag *ldev;
530         bool res;
531
532         mutex_lock(&lag_mutex);
533         ldev = mlx5_lag_dev_get(dev);
534         res  = ldev && mlx5_lag_is_bonded(ldev);
535         mutex_unlock(&lag_mutex);
536
537         return res;
538 }
539 EXPORT_SYMBOL(mlx5_lag_is_active);
540
541 struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev)
542 {
543         struct net_device *ndev = NULL;
544         struct mlx5_lag *ldev;
545
546         mutex_lock(&lag_mutex);
547         ldev = mlx5_lag_dev_get(dev);
548
549         if (!(ldev && mlx5_lag_is_bonded(ldev)))
550                 goto unlock;
551
552         if (ldev->tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
553                 ndev = ldev->tracker.netdev_state[0].tx_enabled ?
554                        ldev->pf[0].netdev : ldev->pf[1].netdev;
555         } else {
556                 ndev = ldev->pf[0].netdev;
557         }
558         if (ndev)
559                 dev_hold(ndev);
560
561 unlock:
562         mutex_unlock(&lag_mutex);
563
564         return ndev;
565 }
566 EXPORT_SYMBOL(mlx5_lag_get_roce_netdev);
567
568 bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv)
569 {
570         struct mlx5_core_dev *dev = container_of(priv, struct mlx5_core_dev,
571                                                  priv);
572         struct mlx5_lag *ldev;
573
574         if (intf->protocol != MLX5_INTERFACE_PROTOCOL_IB)
575                 return true;
576
577         ldev = mlx5_lag_dev_get(dev);
578         if (!ldev || !mlx5_lag_is_bonded(ldev) || ldev->pf[0].dev == dev)
579                 return true;
580
581         /* If bonded, we do not add an IB device for PF1. */
582         return false;
583 }
584