OSDN Git Service

mlx5: add pause frame stats
[tomoyo/tomoyo-test1.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_rep.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 <generated/utsrelease.h>
34 #include <linux/mlx5/fs.h>
35 #include <net/switchdev.h>
36 #include <net/pkt_cls.h>
37 #include <net/act_api.h>
38 #include <net/devlink.h>
39 #include <net/ipv6_stubs.h>
40
41 #include "eswitch.h"
42 #include "esw/chains.h"
43 #include "en.h"
44 #include "en_rep.h"
45 #include "en/txrx.h"
46 #include "en_tc.h"
47 #include "en/rep/tc.h"
48 #include "en/rep/neigh.h"
49 #include "fs_core.h"
50 #include "lib/mlx5.h"
51 #define CREATE_TRACE_POINTS
52 #include "diag/en_rep_tracepoint.h"
53
54 #define MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE \
55         max(0x7, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
56 #define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1
57
58 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
59
60 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
61                                   struct ethtool_drvinfo *drvinfo)
62 {
63         struct mlx5e_priv *priv = netdev_priv(dev);
64         struct mlx5_core_dev *mdev = priv->mdev;
65
66         strlcpy(drvinfo->driver, mlx5e_rep_driver_name,
67                 sizeof(drvinfo->driver));
68         strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
69         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
70                  "%d.%d.%04d (%.16s)",
71                  fw_rev_maj(mdev), fw_rev_min(mdev),
72                  fw_rev_sub(mdev), mdev->board_id);
73 }
74
75 static void mlx5e_uplink_rep_get_drvinfo(struct net_device *dev,
76                                          struct ethtool_drvinfo *drvinfo)
77 {
78         struct mlx5e_priv *priv = netdev_priv(dev);
79
80         mlx5e_rep_get_drvinfo(dev, drvinfo);
81         strlcpy(drvinfo->bus_info, pci_name(priv->mdev->pdev),
82                 sizeof(drvinfo->bus_info));
83 }
84
85 static const struct counter_desc sw_rep_stats_desc[] = {
86         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
87         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
88         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
89         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
90 };
91
92 struct vport_stats {
93         u64 vport_rx_packets;
94         u64 vport_tx_packets;
95         u64 vport_rx_bytes;
96         u64 vport_tx_bytes;
97 };
98
99 static const struct counter_desc vport_rep_stats_desc[] = {
100         { MLX5E_DECLARE_STAT(struct vport_stats, vport_rx_packets) },
101         { MLX5E_DECLARE_STAT(struct vport_stats, vport_rx_bytes) },
102         { MLX5E_DECLARE_STAT(struct vport_stats, vport_tx_packets) },
103         { MLX5E_DECLARE_STAT(struct vport_stats, vport_tx_bytes) },
104 };
105
106 #define NUM_VPORT_REP_SW_COUNTERS ARRAY_SIZE(sw_rep_stats_desc)
107 #define NUM_VPORT_REP_HW_COUNTERS ARRAY_SIZE(vport_rep_stats_desc)
108
109 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(sw_rep)
110 {
111         return NUM_VPORT_REP_SW_COUNTERS;
112 }
113
114 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(sw_rep)
115 {
116         int i;
117
118         for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
119                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
120                        sw_rep_stats_desc[i].format);
121         return idx;
122 }
123
124 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(sw_rep)
125 {
126         int i;
127
128         for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
129                 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
130                                                    sw_rep_stats_desc, i);
131         return idx;
132 }
133
134 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw_rep)
135 {
136         struct mlx5e_sw_stats *s = &priv->stats.sw;
137         struct rtnl_link_stats64 stats64 = {};
138
139         memset(s, 0, sizeof(*s));
140         mlx5e_fold_sw_stats64(priv, &stats64);
141
142         s->rx_packets = stats64.rx_packets;
143         s->rx_bytes   = stats64.rx_bytes;
144         s->tx_packets = stats64.tx_packets;
145         s->tx_bytes   = stats64.tx_bytes;
146         s->tx_queue_dropped = stats64.tx_dropped;
147 }
148
149 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(vport_rep)
150 {
151         return NUM_VPORT_REP_HW_COUNTERS;
152 }
153
154 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(vport_rep)
155 {
156         int i;
157
158         for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
159                 strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_rep_stats_desc[i].format);
160         return idx;
161 }
162
163 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(vport_rep)
164 {
165         int i;
166
167         for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
168                 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
169                                                    vport_rep_stats_desc, i);
170         return idx;
171 }
172
173 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(vport_rep)
174 {
175         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
176         struct mlx5e_rep_priv *rpriv = priv->ppriv;
177         struct mlx5_eswitch_rep *rep = rpriv->rep;
178         struct rtnl_link_stats64 *vport_stats;
179         struct ifla_vf_stats vf_stats;
180         int err;
181
182         err = mlx5_eswitch_get_vport_stats(esw, rep->vport, &vf_stats);
183         if (err) {
184                 netdev_warn(priv->netdev, "vport %d error %d reading stats\n",
185                             rep->vport, err);
186                 return;
187         }
188
189         vport_stats = &priv->stats.vf_vport;
190         /* flip tx/rx as we are reporting the counters for the switch vport */
191         vport_stats->rx_packets = vf_stats.tx_packets;
192         vport_stats->rx_bytes   = vf_stats.tx_bytes;
193         vport_stats->tx_packets = vf_stats.rx_packets;
194         vport_stats->tx_bytes   = vf_stats.rx_bytes;
195 }
196
197 static void mlx5e_rep_get_strings(struct net_device *dev,
198                                   u32 stringset, uint8_t *data)
199 {
200         struct mlx5e_priv *priv = netdev_priv(dev);
201
202         switch (stringset) {
203         case ETH_SS_STATS:
204                 mlx5e_stats_fill_strings(priv, data);
205                 break;
206         }
207 }
208
209 static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
210                                         struct ethtool_stats *stats, u64 *data)
211 {
212         struct mlx5e_priv *priv = netdev_priv(dev);
213
214         mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
215 }
216
217 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
218 {
219         struct mlx5e_priv *priv = netdev_priv(dev);
220
221         switch (sset) {
222         case ETH_SS_STATS:
223                 return mlx5e_stats_total_num(priv);
224         default:
225                 return -EOPNOTSUPP;
226         }
227 }
228
229 static void mlx5e_rep_get_ringparam(struct net_device *dev,
230                                 struct ethtool_ringparam *param)
231 {
232         struct mlx5e_priv *priv = netdev_priv(dev);
233
234         mlx5e_ethtool_get_ringparam(priv, param);
235 }
236
237 static int mlx5e_rep_set_ringparam(struct net_device *dev,
238                                struct ethtool_ringparam *param)
239 {
240         struct mlx5e_priv *priv = netdev_priv(dev);
241
242         return mlx5e_ethtool_set_ringparam(priv, param);
243 }
244
245 static void mlx5e_rep_get_channels(struct net_device *dev,
246                                    struct ethtool_channels *ch)
247 {
248         struct mlx5e_priv *priv = netdev_priv(dev);
249
250         mlx5e_ethtool_get_channels(priv, ch);
251 }
252
253 static int mlx5e_rep_set_channels(struct net_device *dev,
254                                   struct ethtool_channels *ch)
255 {
256         struct mlx5e_priv *priv = netdev_priv(dev);
257
258         return mlx5e_ethtool_set_channels(priv, ch);
259 }
260
261 static int mlx5e_rep_get_coalesce(struct net_device *netdev,
262                                   struct ethtool_coalesce *coal)
263 {
264         struct mlx5e_priv *priv = netdev_priv(netdev);
265
266         return mlx5e_ethtool_get_coalesce(priv, coal);
267 }
268
269 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
270                                   struct ethtool_coalesce *coal)
271 {
272         struct mlx5e_priv *priv = netdev_priv(netdev);
273
274         return mlx5e_ethtool_set_coalesce(priv, coal);
275 }
276
277 static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
278 {
279         struct mlx5e_priv *priv = netdev_priv(netdev);
280
281         return mlx5e_ethtool_get_rxfh_key_size(priv);
282 }
283
284 static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
285 {
286         struct mlx5e_priv *priv = netdev_priv(netdev);
287
288         return mlx5e_ethtool_get_rxfh_indir_size(priv);
289 }
290
291 static void mlx5e_uplink_rep_get_pause_stats(struct net_device *netdev,
292                                              struct ethtool_pause_stats *stats)
293 {
294         struct mlx5e_priv *priv = netdev_priv(netdev);
295
296         mlx5e_stats_pause_get(priv, stats);
297 }
298
299 static void mlx5e_uplink_rep_get_pauseparam(struct net_device *netdev,
300                                             struct ethtool_pauseparam *pauseparam)
301 {
302         struct mlx5e_priv *priv = netdev_priv(netdev);
303
304         mlx5e_ethtool_get_pauseparam(priv, pauseparam);
305 }
306
307 static int mlx5e_uplink_rep_set_pauseparam(struct net_device *netdev,
308                                            struct ethtool_pauseparam *pauseparam)
309 {
310         struct mlx5e_priv *priv = netdev_priv(netdev);
311
312         return mlx5e_ethtool_set_pauseparam(priv, pauseparam);
313 }
314
315 static int mlx5e_uplink_rep_get_link_ksettings(struct net_device *netdev,
316                                                struct ethtool_link_ksettings *link_ksettings)
317 {
318         struct mlx5e_priv *priv = netdev_priv(netdev);
319
320         return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
321 }
322
323 static int mlx5e_uplink_rep_set_link_ksettings(struct net_device *netdev,
324                                                const struct ethtool_link_ksettings *link_ksettings)
325 {
326         struct mlx5e_priv *priv = netdev_priv(netdev);
327
328         return mlx5e_ethtool_set_link_ksettings(priv, link_ksettings);
329 }
330
331 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
332         .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
333                                      ETHTOOL_COALESCE_MAX_FRAMES |
334                                      ETHTOOL_COALESCE_USE_ADAPTIVE,
335         .get_drvinfo       = mlx5e_rep_get_drvinfo,
336         .get_link          = ethtool_op_get_link,
337         .get_strings       = mlx5e_rep_get_strings,
338         .get_sset_count    = mlx5e_rep_get_sset_count,
339         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
340         .get_ringparam     = mlx5e_rep_get_ringparam,
341         .set_ringparam     = mlx5e_rep_set_ringparam,
342         .get_channels      = mlx5e_rep_get_channels,
343         .set_channels      = mlx5e_rep_set_channels,
344         .get_coalesce      = mlx5e_rep_get_coalesce,
345         .set_coalesce      = mlx5e_rep_set_coalesce,
346         .get_rxfh_key_size   = mlx5e_rep_get_rxfh_key_size,
347         .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
348 };
349
350 static const struct ethtool_ops mlx5e_uplink_rep_ethtool_ops = {
351         .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
352                                      ETHTOOL_COALESCE_MAX_FRAMES |
353                                      ETHTOOL_COALESCE_USE_ADAPTIVE,
354         .get_drvinfo       = mlx5e_uplink_rep_get_drvinfo,
355         .get_link          = ethtool_op_get_link,
356         .get_strings       = mlx5e_rep_get_strings,
357         .get_sset_count    = mlx5e_rep_get_sset_count,
358         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
359         .get_ringparam     = mlx5e_rep_get_ringparam,
360         .set_ringparam     = mlx5e_rep_set_ringparam,
361         .get_channels      = mlx5e_rep_get_channels,
362         .set_channels      = mlx5e_rep_set_channels,
363         .get_coalesce      = mlx5e_rep_get_coalesce,
364         .set_coalesce      = mlx5e_rep_set_coalesce,
365         .get_link_ksettings = mlx5e_uplink_rep_get_link_ksettings,
366         .set_link_ksettings = mlx5e_uplink_rep_set_link_ksettings,
367         .get_rxfh_key_size   = mlx5e_rep_get_rxfh_key_size,
368         .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
369         .get_rxfh          = mlx5e_get_rxfh,
370         .set_rxfh          = mlx5e_set_rxfh,
371         .get_rxnfc         = mlx5e_get_rxnfc,
372         .set_rxnfc         = mlx5e_set_rxnfc,
373         .get_pause_stats   = mlx5e_uplink_rep_get_pause_stats,
374         .get_pauseparam    = mlx5e_uplink_rep_get_pauseparam,
375         .set_pauseparam    = mlx5e_uplink_rep_set_pauseparam,
376 };
377
378 static void mlx5e_rep_get_port_parent_id(struct net_device *dev,
379                                          struct netdev_phys_item_id *ppid)
380 {
381         struct mlx5e_priv *priv;
382         u64 parent_id;
383
384         priv = netdev_priv(dev);
385
386         parent_id = mlx5_query_nic_system_image_guid(priv->mdev);
387         ppid->id_len = sizeof(parent_id);
388         memcpy(ppid->id, &parent_id, sizeof(parent_id));
389 }
390
391 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
392                                  struct mlx5_eswitch_rep *rep)
393 {
394         struct mlx5e_rep_sq *rep_sq, *tmp;
395         struct mlx5e_rep_priv *rpriv;
396
397         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
398                 return;
399
400         rpriv = mlx5e_rep_to_rep_priv(rep);
401         list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) {
402                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
403                 list_del(&rep_sq->list);
404                 kfree(rep_sq);
405         }
406 }
407
408 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
409                                  struct mlx5_eswitch_rep *rep,
410                                  u32 *sqns_array, int sqns_num)
411 {
412         struct mlx5_flow_handle *flow_rule;
413         struct mlx5e_rep_priv *rpriv;
414         struct mlx5e_rep_sq *rep_sq;
415         int err;
416         int i;
417
418         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
419                 return 0;
420
421         rpriv = mlx5e_rep_to_rep_priv(rep);
422         for (i = 0; i < sqns_num; i++) {
423                 rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL);
424                 if (!rep_sq) {
425                         err = -ENOMEM;
426                         goto out_err;
427                 }
428
429                 /* Add re-inject rule to the PF/representor sqs */
430                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw,
431                                                                 rep->vport,
432                                                                 sqns_array[i]);
433                 if (IS_ERR(flow_rule)) {
434                         err = PTR_ERR(flow_rule);
435                         kfree(rep_sq);
436                         goto out_err;
437                 }
438                 rep_sq->send_to_vport_rule = flow_rule;
439                 list_add(&rep_sq->list, &rpriv->vport_sqs_list);
440         }
441         return 0;
442
443 out_err:
444         mlx5e_sqs2vport_stop(esw, rep);
445         return err;
446 }
447
448 int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
449 {
450         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
451         struct mlx5e_rep_priv *rpriv = priv->ppriv;
452         struct mlx5_eswitch_rep *rep = rpriv->rep;
453         struct mlx5e_channel *c;
454         int n, tc, num_sqs = 0;
455         int err = -ENOMEM;
456         u32 *sqs;
457
458         sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(*sqs), GFP_KERNEL);
459         if (!sqs)
460                 goto out;
461
462         for (n = 0; n < priv->channels.num; n++) {
463                 c = priv->channels.c[n];
464                 for (tc = 0; tc < c->num_tc; tc++)
465                         sqs[num_sqs++] = c->sq[tc].sqn;
466         }
467
468         err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs);
469         kfree(sqs);
470
471 out:
472         if (err)
473                 netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
474         return err;
475 }
476
477 void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
478 {
479         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
480         struct mlx5e_rep_priv *rpriv = priv->ppriv;
481         struct mlx5_eswitch_rep *rep = rpriv->rep;
482
483         mlx5e_sqs2vport_stop(esw, rep);
484 }
485
486 static int mlx5e_rep_open(struct net_device *dev)
487 {
488         struct mlx5e_priv *priv = netdev_priv(dev);
489         struct mlx5e_rep_priv *rpriv = priv->ppriv;
490         struct mlx5_eswitch_rep *rep = rpriv->rep;
491         int err;
492
493         mutex_lock(&priv->state_lock);
494         err = mlx5e_open_locked(dev);
495         if (err)
496                 goto unlock;
497
498         if (!mlx5_modify_vport_admin_state(priv->mdev,
499                                            MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
500                                            rep->vport, 1,
501                                            MLX5_VPORT_ADMIN_STATE_UP))
502                 netif_carrier_on(dev);
503
504 unlock:
505         mutex_unlock(&priv->state_lock);
506         return err;
507 }
508
509 static int mlx5e_rep_close(struct net_device *dev)
510 {
511         struct mlx5e_priv *priv = netdev_priv(dev);
512         struct mlx5e_rep_priv *rpriv = priv->ppriv;
513         struct mlx5_eswitch_rep *rep = rpriv->rep;
514         int ret;
515
516         mutex_lock(&priv->state_lock);
517         mlx5_modify_vport_admin_state(priv->mdev,
518                                       MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
519                                       rep->vport, 1,
520                                       MLX5_VPORT_ADMIN_STATE_DOWN);
521         ret = mlx5e_close_locked(dev);
522         mutex_unlock(&priv->state_lock);
523         return ret;
524 }
525
526 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
527 {
528         struct mlx5e_rep_priv *rpriv = priv->ppriv;
529         struct mlx5_eswitch_rep *rep;
530
531         if (!MLX5_ESWITCH_MANAGER(priv->mdev))
532                 return false;
533
534         if (!rpriv) /* non vport rep mlx5e instances don't use this field */
535                 return false;
536
537         rep = rpriv->rep;
538         return (rep->vport == MLX5_VPORT_UPLINK);
539 }
540
541 static bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
542 {
543         switch (attr_id) {
544         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
545                         return true;
546         }
547
548         return false;
549 }
550
551 static int
552 mlx5e_get_sw_stats64(const struct net_device *dev,
553                      struct rtnl_link_stats64 *stats)
554 {
555         struct mlx5e_priv *priv = netdev_priv(dev);
556
557         mlx5e_fold_sw_stats64(priv, stats);
558         return 0;
559 }
560
561 static int mlx5e_rep_get_offload_stats(int attr_id, const struct net_device *dev,
562                                        void *sp)
563 {
564         switch (attr_id) {
565         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
566                 return mlx5e_get_sw_stats64(dev, sp);
567         }
568
569         return -EINVAL;
570 }
571
572 static void
573 mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
574 {
575         struct mlx5e_priv *priv = netdev_priv(dev);
576
577         /* update HW stats in background for next time */
578         mlx5e_queue_update_stats(priv);
579         memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
580 }
581
582 static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu)
583 {
584         return mlx5e_change_mtu(netdev, new_mtu, NULL);
585 }
586
587 static int mlx5e_uplink_rep_change_mtu(struct net_device *netdev, int new_mtu)
588 {
589         return mlx5e_change_mtu(netdev, new_mtu, mlx5e_set_dev_port_mtu_ctx);
590 }
591
592 static int mlx5e_uplink_rep_set_mac(struct net_device *netdev, void *addr)
593 {
594         struct sockaddr *saddr = addr;
595
596         if (!is_valid_ether_addr(saddr->sa_data))
597                 return -EADDRNOTAVAIL;
598
599         ether_addr_copy(netdev->dev_addr, saddr->sa_data);
600         return 0;
601 }
602
603 static int mlx5e_uplink_rep_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
604                                         __be16 vlan_proto)
605 {
606         netdev_warn_once(dev, "legacy vf vlan setting isn't supported in switchdev mode\n");
607
608         if (vlan != 0)
609                 return -EOPNOTSUPP;
610
611         /* allow setting 0-vid for compatibility with libvirt */
612         return 0;
613 }
614
615 static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *dev)
616 {
617         struct mlx5e_priv *priv = netdev_priv(dev);
618         struct mlx5e_rep_priv *rpriv = priv->ppriv;
619
620         return &rpriv->dl_port;
621 }
622
623 static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
624 {
625         struct mlx5e_priv *priv = netdev_priv(dev);
626         struct mlx5e_rep_priv *rpriv = priv->ppriv;
627         struct mlx5_eswitch_rep *rep = rpriv->rep;
628         int err;
629
630         if (new_carrier) {
631                 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
632                                                     rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
633                 if (err)
634                         return err;
635                 netif_carrier_on(dev);
636         } else {
637                 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
638                                                     rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
639                 if (err)
640                         return err;
641                 netif_carrier_off(dev);
642         }
643         return 0;
644 }
645
646 static const struct net_device_ops mlx5e_netdev_ops_rep = {
647         .ndo_open                = mlx5e_rep_open,
648         .ndo_stop                = mlx5e_rep_close,
649         .ndo_start_xmit          = mlx5e_xmit,
650         .ndo_setup_tc            = mlx5e_rep_setup_tc,
651         .ndo_get_devlink_port    = mlx5e_rep_get_devlink_port,
652         .ndo_get_stats64         = mlx5e_rep_get_stats,
653         .ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
654         .ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
655         .ndo_change_mtu          = mlx5e_rep_change_mtu,
656         .ndo_change_carrier      = mlx5e_rep_change_carrier,
657 };
658
659 static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
660         .ndo_open                = mlx5e_open,
661         .ndo_stop                = mlx5e_close,
662         .ndo_start_xmit          = mlx5e_xmit,
663         .ndo_set_mac_address     = mlx5e_uplink_rep_set_mac,
664         .ndo_setup_tc            = mlx5e_rep_setup_tc,
665         .ndo_get_devlink_port    = mlx5e_rep_get_devlink_port,
666         .ndo_get_stats64         = mlx5e_get_stats,
667         .ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
668         .ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
669         .ndo_change_mtu          = mlx5e_uplink_rep_change_mtu,
670         .ndo_udp_tunnel_add      = udp_tunnel_nic_add_port,
671         .ndo_udp_tunnel_del      = udp_tunnel_nic_del_port,
672         .ndo_features_check      = mlx5e_features_check,
673         .ndo_set_vf_mac          = mlx5e_set_vf_mac,
674         .ndo_set_vf_rate         = mlx5e_set_vf_rate,
675         .ndo_get_vf_config       = mlx5e_get_vf_config,
676         .ndo_get_vf_stats        = mlx5e_get_vf_stats,
677         .ndo_set_vf_vlan         = mlx5e_uplink_rep_set_vf_vlan,
678         .ndo_set_features        = mlx5e_set_features,
679 };
680
681 bool mlx5e_eswitch_uplink_rep(struct net_device *netdev)
682 {
683         return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep;
684 }
685
686 bool mlx5e_eswitch_vf_rep(struct net_device *netdev)
687 {
688         return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
689 }
690
691 static void mlx5e_build_rep_params(struct net_device *netdev)
692 {
693         struct mlx5e_priv *priv = netdev_priv(netdev);
694         struct mlx5e_rep_priv *rpriv = priv->ppriv;
695         struct mlx5_eswitch_rep *rep = rpriv->rep;
696         struct mlx5_core_dev *mdev = priv->mdev;
697         struct mlx5e_params *params;
698
699         u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
700                                          MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
701                                          MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
702
703         params = &priv->channels.params;
704         params->hard_mtu    = MLX5E_ETH_HARD_MTU;
705         params->sw_mtu      = netdev->mtu;
706
707         /* SQ */
708         if (rep->vport == MLX5_VPORT_UPLINK)
709                 params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
710         else
711                 params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;
712
713         /* RQ */
714         mlx5e_build_rq_params(mdev, params);
715
716         /* CQ moderation params */
717         params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
718         mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
719
720         params->num_tc                = 1;
721         params->tunneled_offload_en = false;
722
723         mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
724
725         /* RSS */
726         mlx5e_build_rss_params(&priv->rss_params, params->num_channels);
727 }
728
729 static void mlx5e_build_rep_netdev(struct net_device *netdev)
730 {
731         struct mlx5e_priv *priv = netdev_priv(netdev);
732         struct mlx5e_rep_priv *rpriv = priv->ppriv;
733         struct mlx5_eswitch_rep *rep = rpriv->rep;
734         struct mlx5_core_dev *mdev = priv->mdev;
735
736         SET_NETDEV_DEV(netdev, mdev->device);
737         if (rep->vport == MLX5_VPORT_UPLINK) {
738                 netdev->netdev_ops = &mlx5e_netdev_ops_uplink_rep;
739                 /* we want a persistent mac for the uplink rep */
740                 mlx5_query_mac_address(mdev, netdev->dev_addr);
741                 netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
742                 mlx5e_vxlan_set_netdev_info(priv);
743                 mlx5e_dcbnl_build_rep_netdev(netdev);
744         } else {
745                 netdev->netdev_ops = &mlx5e_netdev_ops_rep;
746                 eth_hw_addr_random(netdev);
747                 netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
748         }
749
750         netdev->watchdog_timeo    = 15 * HZ;
751
752         netdev->features       |= NETIF_F_NETNS_LOCAL;
753
754         netdev->hw_features    |= NETIF_F_HW_TC;
755         netdev->hw_features    |= NETIF_F_SG;
756         netdev->hw_features    |= NETIF_F_IP_CSUM;
757         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
758         netdev->hw_features    |= NETIF_F_GRO;
759         netdev->hw_features    |= NETIF_F_TSO;
760         netdev->hw_features    |= NETIF_F_TSO6;
761         netdev->hw_features    |= NETIF_F_RXCSUM;
762
763         if (rep->vport == MLX5_VPORT_UPLINK)
764                 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
765         else
766                 netdev->features |= NETIF_F_VLAN_CHALLENGED;
767
768         netdev->features |= netdev->hw_features;
769 }
770
771 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
772                           struct net_device *netdev,
773                           const struct mlx5e_profile *profile,
774                           void *ppriv)
775 {
776         struct mlx5e_priv *priv = netdev_priv(netdev);
777         int err;
778
779         err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
780         if (err)
781                 return err;
782
783         priv->channels.params.num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
784
785         mlx5e_build_rep_params(netdev);
786         mlx5e_build_rep_netdev(netdev);
787
788         mlx5e_timestamp_init(priv);
789
790         return 0;
791 }
792
793 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
794 {
795         mlx5e_netdev_cleanup(priv->netdev, priv);
796 }
797
798 static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
799 {
800         struct mlx5e_rep_priv *rpriv = priv->ppriv;
801         struct mlx5_eswitch_rep *rep = rpriv->rep;
802         struct ttc_params ttc_params = {};
803         int tt, err;
804
805         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
806                                               MLX5_FLOW_NAMESPACE_KERNEL);
807
808         /* The inner_ttc in the ttc params is intentionally not set */
809         ttc_params.any_tt_tirn = priv->direct_tir[0].tirn;
810         mlx5e_set_ttc_ft_params(&ttc_params);
811
812         if (rep->vport != MLX5_VPORT_UPLINK)
813                 /* To give uplik rep TTC a lower level for chaining from root ft */
814                 ttc_params.ft_attr.level = MLX5E_TTC_FT_LEVEL + 1;
815
816         for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
817                 ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;
818
819         err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
820         if (err) {
821                 netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n", err);
822                 return err;
823         }
824         return 0;
825 }
826
827 static int mlx5e_create_rep_root_ft(struct mlx5e_priv *priv)
828 {
829         struct mlx5e_rep_priv *rpriv = priv->ppriv;
830         struct mlx5_eswitch_rep *rep = rpriv->rep;
831         struct mlx5_flow_table_attr ft_attr = {};
832         struct mlx5_flow_namespace *ns;
833         int err = 0;
834
835         if (rep->vport != MLX5_VPORT_UPLINK) {
836                 /* non uplik reps will skip any bypass tables and go directly to
837                  * their own ttc
838                  */
839                 rpriv->root_ft = priv->fs.ttc.ft.t;
840                 return 0;
841         }
842
843         /* uplink root ft will be used to auto chain, to ethtool or ttc tables */
844         ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
845         if (!ns) {
846                 netdev_err(priv->netdev, "Failed to get reps offloads namespace\n");
847                 return -EOPNOTSUPP;
848         }
849
850         ft_attr.max_fte = 0; /* Empty table, miss rule will always point to next table */
851         ft_attr.prio = 1;
852         ft_attr.level = 1;
853
854         rpriv->root_ft = mlx5_create_flow_table(ns, &ft_attr);
855         if (IS_ERR(rpriv->root_ft)) {
856                 err = PTR_ERR(rpriv->root_ft);
857                 rpriv->root_ft = NULL;
858         }
859
860         return err;
861 }
862
863 static void mlx5e_destroy_rep_root_ft(struct mlx5e_priv *priv)
864 {
865         struct mlx5e_rep_priv *rpriv = priv->ppriv;
866         struct mlx5_eswitch_rep *rep = rpriv->rep;
867
868         if (rep->vport != MLX5_VPORT_UPLINK)
869                 return;
870         mlx5_destroy_flow_table(rpriv->root_ft);
871 }
872
873 static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
874 {
875         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
876         struct mlx5e_rep_priv *rpriv = priv->ppriv;
877         struct mlx5_eswitch_rep *rep = rpriv->rep;
878         struct mlx5_flow_handle *flow_rule;
879         struct mlx5_flow_destination dest;
880
881         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
882         dest.ft = rpriv->root_ft;
883
884         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw, rep->vport, &dest);
885         if (IS_ERR(flow_rule))
886                 return PTR_ERR(flow_rule);
887         rpriv->vport_rx_rule = flow_rule;
888         return 0;
889 }
890
891 static void rep_vport_rx_rule_destroy(struct mlx5e_priv *priv)
892 {
893         struct mlx5e_rep_priv *rpriv = priv->ppriv;
894
895         if (!rpriv->vport_rx_rule)
896                 return;
897
898         mlx5_del_flow_rules(rpriv->vport_rx_rule);
899         rpriv->vport_rx_rule = NULL;
900 }
901
902 int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup)
903 {
904         rep_vport_rx_rule_destroy(priv);
905
906         return cleanup ? 0 : mlx5e_create_rep_vport_rx_rule(priv);
907 }
908
909 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
910 {
911         struct mlx5_core_dev *mdev = priv->mdev;
912         int err;
913
914         mlx5e_init_l2_addr(priv);
915
916         err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
917         if (err) {
918                 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
919                 return err;
920         }
921
922         err = mlx5e_create_indirect_rqt(priv);
923         if (err)
924                 goto err_close_drop_rq;
925
926         err = mlx5e_create_direct_rqts(priv, priv->direct_tir);
927         if (err)
928                 goto err_destroy_indirect_rqts;
929
930         err = mlx5e_create_indirect_tirs(priv, false);
931         if (err)
932                 goto err_destroy_direct_rqts;
933
934         err = mlx5e_create_direct_tirs(priv, priv->direct_tir);
935         if (err)
936                 goto err_destroy_indirect_tirs;
937
938         err = mlx5e_create_rep_ttc_table(priv);
939         if (err)
940                 goto err_destroy_direct_tirs;
941
942         err = mlx5e_create_rep_root_ft(priv);
943         if (err)
944                 goto err_destroy_ttc_table;
945
946         err = mlx5e_create_rep_vport_rx_rule(priv);
947         if (err)
948                 goto err_destroy_root_ft;
949
950         mlx5e_ethtool_init_steering(priv);
951
952         return 0;
953
954 err_destroy_root_ft:
955         mlx5e_destroy_rep_root_ft(priv);
956 err_destroy_ttc_table:
957         mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
958 err_destroy_direct_tirs:
959         mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
960 err_destroy_indirect_tirs:
961         mlx5e_destroy_indirect_tirs(priv);
962 err_destroy_direct_rqts:
963         mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
964 err_destroy_indirect_rqts:
965         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
966 err_close_drop_rq:
967         mlx5e_close_drop_rq(&priv->drop_rq);
968         return err;
969 }
970
971 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
972 {
973         mlx5e_ethtool_cleanup_steering(priv);
974         rep_vport_rx_rule_destroy(priv);
975         mlx5e_destroy_rep_root_ft(priv);
976         mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
977         mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
978         mlx5e_destroy_indirect_tirs(priv);
979         mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
980         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
981         mlx5e_close_drop_rq(&priv->drop_rq);
982 }
983
984 static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
985 {
986         mlx5e_create_q_counters(priv);
987         return mlx5e_init_rep_rx(priv);
988 }
989
990 static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
991 {
992         mlx5e_cleanup_rep_rx(priv);
993         mlx5e_destroy_q_counters(priv);
994 }
995
996 static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
997 {
998         struct mlx5_rep_uplink_priv *uplink_priv;
999         struct net_device *netdev;
1000         struct mlx5e_priv *priv;
1001         int err;
1002
1003         netdev = rpriv->netdev;
1004         priv = netdev_priv(netdev);
1005         uplink_priv = &rpriv->uplink_priv;
1006
1007         err = mlx5e_rep_tc_init(rpriv);
1008         if (err)
1009                 return err;
1010
1011         mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
1012
1013         mlx5e_rep_bond_init(rpriv);
1014         err = mlx5e_rep_tc_netdevice_event_register(rpriv);
1015         if (err) {
1016                 mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
1017                               err);
1018                 goto err_event_reg;
1019         }
1020
1021         return 0;
1022
1023 err_event_reg:
1024         mlx5e_rep_bond_cleanup(rpriv);
1025         mlx5e_rep_tc_cleanup(rpriv);
1026         return err;
1027 }
1028
1029 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
1030 {
1031         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1032         int err;
1033
1034         err = mlx5e_create_tises(priv);
1035         if (err) {
1036                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
1037                 return err;
1038         }
1039
1040         if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
1041                 err = mlx5e_init_uplink_rep_tx(rpriv);
1042                 if (err)
1043                         goto destroy_tises;
1044         }
1045
1046         return 0;
1047
1048 destroy_tises:
1049         mlx5e_destroy_tises(priv);
1050         return err;
1051 }
1052
1053 static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
1054 {
1055         mlx5e_rep_tc_netdevice_event_unregister(rpriv);
1056         mlx5e_rep_bond_cleanup(rpriv);
1057         mlx5e_rep_tc_cleanup(rpriv);
1058 }
1059
1060 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
1061 {
1062         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1063
1064         mlx5e_destroy_tises(priv);
1065
1066         if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
1067                 mlx5e_cleanup_uplink_rep_tx(rpriv);
1068 }
1069
1070 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
1071 {
1072         mlx5e_set_netdev_mtu_boundaries(priv);
1073 }
1074
1075 static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
1076 {
1077         return 0;
1078 }
1079
1080 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
1081 {
1082         struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
1083
1084         if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
1085                 struct mlx5_eqe *eqe = data;
1086
1087                 switch (eqe->sub_type) {
1088                 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
1089                 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
1090                         queue_work(priv->wq, &priv->update_carrier_work);
1091                         break;
1092                 default:
1093                         return NOTIFY_DONE;
1094                 }
1095
1096                 return NOTIFY_OK;
1097         }
1098
1099         if (event == MLX5_DEV_EVENT_PORT_AFFINITY)
1100                 return mlx5e_rep_tc_event_port_affinity(priv);
1101
1102         return NOTIFY_DONE;
1103 }
1104
1105 static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
1106 {
1107         struct net_device *netdev = priv->netdev;
1108         struct mlx5_core_dev *mdev = priv->mdev;
1109         u16 max_mtu;
1110
1111         netdev->min_mtu = ETH_MIN_MTU;
1112         mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
1113         netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
1114         mlx5e_set_dev_port_mtu(priv);
1115
1116         mlx5e_rep_tc_enable(priv);
1117
1118         mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
1119                                       0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
1120         mlx5_lag_add(mdev, netdev);
1121         priv->events_nb.notifier_call = uplink_rep_async_event;
1122         mlx5_notifier_register(mdev, &priv->events_nb);
1123         mlx5e_dcbnl_initialize(priv);
1124         mlx5e_dcbnl_init_app(priv);
1125 }
1126
1127 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1128 {
1129         struct mlx5_core_dev *mdev = priv->mdev;
1130
1131         mlx5e_dcbnl_delete_app(priv);
1132         mlx5_notifier_unregister(mdev, &priv->events_nb);
1133         mlx5e_rep_tc_disable(priv);
1134         mlx5_lag_remove(mdev);
1135 }
1136
1137 static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
1138 static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);
1139
1140 /* The stats groups order is opposite to the update_stats() order calls */
1141 static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
1142         &MLX5E_STATS_GRP(sw_rep),
1143         &MLX5E_STATS_GRP(vport_rep),
1144 };
1145
1146 static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
1147 {
1148         return ARRAY_SIZE(mlx5e_rep_stats_grps);
1149 }
1150
1151 /* The stats groups order is opposite to the update_stats() order calls */
1152 static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
1153         &MLX5E_STATS_GRP(sw),
1154         &MLX5E_STATS_GRP(qcnt),
1155         &MLX5E_STATS_GRP(vnic_env),
1156         &MLX5E_STATS_GRP(vport),
1157         &MLX5E_STATS_GRP(802_3),
1158         &MLX5E_STATS_GRP(2863),
1159         &MLX5E_STATS_GRP(2819),
1160         &MLX5E_STATS_GRP(phy),
1161         &MLX5E_STATS_GRP(eth_ext),
1162         &MLX5E_STATS_GRP(pcie),
1163         &MLX5E_STATS_GRP(per_prio),
1164         &MLX5E_STATS_GRP(pme),
1165         &MLX5E_STATS_GRP(channels),
1166         &MLX5E_STATS_GRP(per_port_buff_congest),
1167 };
1168
1169 static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
1170 {
1171         return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
1172 }
1173
1174 static const struct mlx5e_profile mlx5e_rep_profile = {
1175         .init                   = mlx5e_init_rep,
1176         .cleanup                = mlx5e_cleanup_rep,
1177         .init_rx                = mlx5e_init_rep_rx,
1178         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1179         .init_tx                = mlx5e_init_rep_tx,
1180         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1181         .enable                 = mlx5e_rep_enable,
1182         .update_rx              = mlx5e_update_rep_rx,
1183         .update_stats           = mlx5e_update_ndo_stats,
1184         .rx_handlers            = &mlx5e_rx_handlers_rep,
1185         .max_tc                 = 1,
1186         .rq_groups              = MLX5E_NUM_RQ_GROUPS(REGULAR),
1187         .stats_grps             = mlx5e_rep_stats_grps,
1188         .stats_grps_num         = mlx5e_rep_stats_grps_num,
1189 };
1190
1191 static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1192         .init                   = mlx5e_init_rep,
1193         .cleanup                = mlx5e_cleanup_rep,
1194         .init_rx                = mlx5e_init_ul_rep_rx,
1195         .cleanup_rx             = mlx5e_cleanup_ul_rep_rx,
1196         .init_tx                = mlx5e_init_rep_tx,
1197         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1198         .enable                 = mlx5e_uplink_rep_enable,
1199         .disable                = mlx5e_uplink_rep_disable,
1200         .update_rx              = mlx5e_update_rep_rx,
1201         .update_stats           = mlx5e_update_ndo_stats,
1202         .update_carrier         = mlx5e_update_carrier,
1203         .rx_handlers            = &mlx5e_rx_handlers_rep,
1204         .max_tc                 = MLX5E_MAX_NUM_TC,
1205         .rq_groups              = MLX5E_NUM_RQ_GROUPS(REGULAR),
1206         .stats_grps             = mlx5e_ul_rep_stats_grps,
1207         .stats_grps_num         = mlx5e_ul_rep_stats_grps_num,
1208 };
1209
1210 static bool
1211 is_devlink_port_supported(const struct mlx5_core_dev *dev,
1212                           const struct mlx5e_rep_priv *rpriv)
1213 {
1214         return rpriv->rep->vport == MLX5_VPORT_UPLINK ||
1215                rpriv->rep->vport == MLX5_VPORT_PF ||
1216                mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport);
1217 }
1218
1219 static int register_devlink_port(struct mlx5_core_dev *dev,
1220                                  struct mlx5e_rep_priv *rpriv)
1221 {
1222         struct mlx5_esw_offload *offloads = &dev->priv.eswitch->offloads;
1223         struct devlink *devlink = priv_to_devlink(dev);
1224         struct mlx5_eswitch_rep *rep = rpriv->rep;
1225         struct devlink_port_attrs attrs = {};
1226         struct netdev_phys_item_id ppid = {};
1227         unsigned int dl_port_index = 0;
1228         u32 controller_num = 0;
1229         bool external;
1230         u16 pfnum;
1231
1232         if (!is_devlink_port_supported(dev, rpriv))
1233                 return 0;
1234
1235         external = mlx5_core_is_ecpf_esw_manager(dev);
1236         if (external)
1237                 controller_num = offloads->host_number + 1;
1238         mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
1239         dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, rep->vport);
1240         pfnum = PCI_FUNC(dev->pdev->devfn);
1241         if (rep->vport == MLX5_VPORT_UPLINK) {
1242                 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
1243                 attrs.phys.port_number = pfnum;
1244                 memcpy(attrs.switch_id.id, &ppid.id[0], ppid.id_len);
1245                 attrs.switch_id.id_len = ppid.id_len;
1246                 devlink_port_attrs_set(&rpriv->dl_port, &attrs);
1247         } else if (rep->vport == MLX5_VPORT_PF) {
1248                 memcpy(rpriv->dl_port.attrs.switch_id.id, &ppid.id[0], ppid.id_len);
1249                 rpriv->dl_port.attrs.switch_id.id_len = ppid.id_len;
1250                 devlink_port_attrs_pci_pf_set(&rpriv->dl_port, controller_num,
1251                                               pfnum, external);
1252         } else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport)) {
1253                 memcpy(rpriv->dl_port.attrs.switch_id.id, &ppid.id[0], ppid.id_len);
1254                 rpriv->dl_port.attrs.switch_id.id_len = ppid.id_len;
1255                 devlink_port_attrs_pci_vf_set(&rpriv->dl_port, controller_num,
1256                                               pfnum, rep->vport - 1, external);
1257         }
1258         return devlink_port_register(devlink, &rpriv->dl_port, dl_port_index);
1259 }
1260
1261 static void unregister_devlink_port(struct mlx5_core_dev *dev,
1262                                     struct mlx5e_rep_priv *rpriv)
1263 {
1264         if (is_devlink_port_supported(dev, rpriv))
1265                 devlink_port_unregister(&rpriv->dl_port);
1266 }
1267
1268 /* e-Switch vport representors */
1269 static int
1270 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1271 {
1272         const struct mlx5e_profile *profile;
1273         struct mlx5e_rep_priv *rpriv;
1274         struct net_device *netdev;
1275         int nch, err;
1276
1277         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1278         if (!rpriv)
1279                 return -ENOMEM;
1280
1281         /* rpriv->rep to be looked up when profile->init() is called */
1282         rpriv->rep = rep;
1283
1284         nch = mlx5e_get_max_num_channels(dev);
1285         profile = (rep->vport == MLX5_VPORT_UPLINK) ?
1286                   &mlx5e_uplink_rep_profile : &mlx5e_rep_profile;
1287         netdev = mlx5e_create_netdev(dev, profile, nch, rpriv);
1288         if (!netdev) {
1289                 mlx5_core_warn(dev,
1290                                "Failed to create representor netdev for vport %d\n",
1291                                rep->vport);
1292                 kfree(rpriv);
1293                 return -EINVAL;
1294         }
1295
1296         dev_net_set(netdev, mlx5_core_net(dev));
1297         rpriv->netdev = netdev;
1298         rep->rep_data[REP_ETH].priv = rpriv;
1299         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1300
1301         if (rep->vport == MLX5_VPORT_UPLINK) {
1302                 err = mlx5e_create_mdev_resources(dev);
1303                 if (err)
1304                         goto err_destroy_netdev;
1305         }
1306
1307         err = mlx5e_attach_netdev(netdev_priv(netdev));
1308         if (err) {
1309                 netdev_warn(netdev,
1310                             "Failed to attach representor netdev for vport %d\n",
1311                             rep->vport);
1312                 goto err_destroy_mdev_resources;
1313         }
1314
1315         err = mlx5e_rep_neigh_init(rpriv);
1316         if (err) {
1317                 netdev_warn(netdev,
1318                             "Failed to initialized neighbours handling for vport %d\n",
1319                             rep->vport);
1320                 goto err_detach_netdev;
1321         }
1322
1323         err = register_devlink_port(dev, rpriv);
1324         if (err) {
1325                 netdev_warn(netdev, "Failed to register devlink port %d\n",
1326                             rep->vport);
1327                 goto err_neigh_cleanup;
1328         }
1329
1330         err = register_netdev(netdev);
1331         if (err) {
1332                 netdev_warn(netdev,
1333                             "Failed to register representor netdev for vport %d\n",
1334                             rep->vport);
1335                 goto err_devlink_cleanup;
1336         }
1337
1338         if (is_devlink_port_supported(dev, rpriv))
1339                 devlink_port_type_eth_set(&rpriv->dl_port, netdev);
1340         return 0;
1341
1342 err_devlink_cleanup:
1343         unregister_devlink_port(dev, rpriv);
1344
1345 err_neigh_cleanup:
1346         mlx5e_rep_neigh_cleanup(rpriv);
1347
1348 err_detach_netdev:
1349         mlx5e_detach_netdev(netdev_priv(netdev));
1350
1351 err_destroy_mdev_resources:
1352         if (rep->vport == MLX5_VPORT_UPLINK)
1353                 mlx5e_destroy_mdev_resources(dev);
1354
1355 err_destroy_netdev:
1356         mlx5e_destroy_netdev(netdev_priv(netdev));
1357         kfree(rpriv);
1358         return err;
1359 }
1360
1361 static void
1362 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1363 {
1364         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1365         struct net_device *netdev = rpriv->netdev;
1366         struct mlx5e_priv *priv = netdev_priv(netdev);
1367         struct mlx5_core_dev *dev = priv->mdev;
1368         void *ppriv = priv->ppriv;
1369
1370         if (is_devlink_port_supported(dev, rpriv))
1371                 devlink_port_type_clear(&rpriv->dl_port);
1372         unregister_netdev(netdev);
1373         unregister_devlink_port(dev, rpriv);
1374         mlx5e_rep_neigh_cleanup(rpriv);
1375         mlx5e_detach_netdev(priv);
1376         if (rep->vport == MLX5_VPORT_UPLINK)
1377                 mlx5e_destroy_mdev_resources(priv->mdev);
1378         mlx5e_destroy_netdev(priv);
1379         kfree(ppriv); /* mlx5e_rep_priv */
1380 }
1381
1382 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1383 {
1384         struct mlx5e_rep_priv *rpriv;
1385
1386         rpriv = mlx5e_rep_to_rep_priv(rep);
1387
1388         return rpriv->netdev;
1389 }
1390
1391 static const struct mlx5_eswitch_rep_ops rep_ops = {
1392         .load = mlx5e_vport_rep_load,
1393         .unload = mlx5e_vport_rep_unload,
1394         .get_proto_dev = mlx5e_vport_rep_get_proto_dev
1395 };
1396
1397 void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev)
1398 {
1399         struct mlx5_eswitch *esw = mdev->priv.eswitch;
1400
1401         mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1402 }
1403
1404 void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev)
1405 {
1406         struct mlx5_eswitch *esw = mdev->priv.eswitch;
1407
1408         mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
1409 }