Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
[linux-block.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/netevent.h>
39 #include <net/arp.h>
40
41 #include "eswitch.h"
42 #include "en.h"
43 #include "en_rep.h"
44 #include "en_tc.h"
45 #include "en/tc_tun.h"
46 #include "fs_core.h"
47 #include "lib/port_tun.h"
48
49 #define MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE \
50         max(0x7, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
51 #define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1
52
53 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
54
55 struct mlx5e_rep_indr_block_priv {
56         struct net_device *netdev;
57         struct mlx5e_rep_priv *rpriv;
58
59         struct list_head list;
60 };
61
62 static void mlx5e_rep_indr_unregister_block(struct mlx5e_rep_priv *rpriv,
63                                             struct net_device *netdev);
64
65 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
66                                   struct ethtool_drvinfo *drvinfo)
67 {
68         struct mlx5e_priv *priv = netdev_priv(dev);
69         struct mlx5_core_dev *mdev = priv->mdev;
70
71         strlcpy(drvinfo->driver, mlx5e_rep_driver_name,
72                 sizeof(drvinfo->driver));
73         strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
74         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
75                  "%d.%d.%04d (%.16s)",
76                  fw_rev_maj(mdev), fw_rev_min(mdev),
77                  fw_rev_sub(mdev), mdev->board_id);
78 }
79
80 static void mlx5e_uplink_rep_get_drvinfo(struct net_device *dev,
81                                          struct ethtool_drvinfo *drvinfo)
82 {
83         struct mlx5e_priv *priv = netdev_priv(dev);
84
85         mlx5e_rep_get_drvinfo(dev, drvinfo);
86         strlcpy(drvinfo->bus_info, pci_name(priv->mdev->pdev),
87                 sizeof(drvinfo->bus_info));
88 }
89
90 static const struct counter_desc sw_rep_stats_desc[] = {
91         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
92         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
93         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
94         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
95 };
96
97 struct vport_stats {
98         u64 vport_rx_packets;
99         u64 vport_tx_packets;
100         u64 vport_rx_bytes;
101         u64 vport_tx_bytes;
102 };
103
104 static const struct counter_desc vport_rep_stats_desc[] = {
105         { MLX5E_DECLARE_STAT(struct vport_stats, vport_rx_packets) },
106         { MLX5E_DECLARE_STAT(struct vport_stats, vport_rx_bytes) },
107         { MLX5E_DECLARE_STAT(struct vport_stats, vport_tx_packets) },
108         { MLX5E_DECLARE_STAT(struct vport_stats, vport_tx_bytes) },
109 };
110
111 #define NUM_VPORT_REP_SW_COUNTERS ARRAY_SIZE(sw_rep_stats_desc)
112 #define NUM_VPORT_REP_HW_COUNTERS ARRAY_SIZE(vport_rep_stats_desc)
113
114 static void mlx5e_rep_get_strings(struct net_device *dev,
115                                   u32 stringset, uint8_t *data)
116 {
117         int i, j;
118
119         switch (stringset) {
120         case ETH_SS_STATS:
121                 for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
122                         strcpy(data + (i * ETH_GSTRING_LEN),
123                                sw_rep_stats_desc[i].format);
124                 for (j = 0; j < NUM_VPORT_REP_HW_COUNTERS; j++, i++)
125                         strcpy(data + (i * ETH_GSTRING_LEN),
126                                vport_rep_stats_desc[j].format);
127                 break;
128         }
129 }
130
131 static void mlx5e_rep_update_hw_counters(struct mlx5e_priv *priv)
132 {
133         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
134         struct mlx5e_rep_priv *rpriv = priv->ppriv;
135         struct mlx5_eswitch_rep *rep = rpriv->rep;
136         struct rtnl_link_stats64 *vport_stats;
137         struct ifla_vf_stats vf_stats;
138         int err;
139
140         err = mlx5_eswitch_get_vport_stats(esw, rep->vport, &vf_stats);
141         if (err) {
142                 pr_warn("vport %d error %d reading stats\n", rep->vport, err);
143                 return;
144         }
145
146         vport_stats = &priv->stats.vf_vport;
147         /* flip tx/rx as we are reporting the counters for the switch vport */
148         vport_stats->rx_packets = vf_stats.tx_packets;
149         vport_stats->rx_bytes   = vf_stats.tx_bytes;
150         vport_stats->tx_packets = vf_stats.rx_packets;
151         vport_stats->tx_bytes   = vf_stats.rx_bytes;
152 }
153
154 static void mlx5e_uplink_rep_update_hw_counters(struct mlx5e_priv *priv)
155 {
156         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
157         struct rtnl_link_stats64 *vport_stats;
158
159         mlx5e_grp_802_3_update_stats(priv);
160
161         vport_stats = &priv->stats.vf_vport;
162
163         vport_stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok);
164         vport_stats->rx_bytes   = PPORT_802_3_GET(pstats, a_octets_received_ok);
165         vport_stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok);
166         vport_stats->tx_bytes   = PPORT_802_3_GET(pstats, a_octets_transmitted_ok);
167 }
168
169 static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
170 {
171         struct mlx5e_sw_stats *s = &priv->stats.sw;
172         struct rtnl_link_stats64 stats64 = {};
173
174         memset(s, 0, sizeof(*s));
175         mlx5e_fold_sw_stats64(priv, &stats64);
176
177         s->rx_packets = stats64.rx_packets;
178         s->rx_bytes   = stats64.rx_bytes;
179         s->tx_packets = stats64.tx_packets;
180         s->tx_bytes   = stats64.tx_bytes;
181         s->tx_queue_dropped = stats64.tx_dropped;
182 }
183
184 static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
185                                         struct ethtool_stats *stats, u64 *data)
186 {
187         struct mlx5e_priv *priv = netdev_priv(dev);
188         int i, j;
189
190         if (!data)
191                 return;
192
193         mutex_lock(&priv->state_lock);
194         mlx5e_rep_update_sw_counters(priv);
195         priv->profile->update_stats(priv);
196         mutex_unlock(&priv->state_lock);
197
198         for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
199                 data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
200                                                sw_rep_stats_desc, i);
201
202         for (j = 0; j < NUM_VPORT_REP_HW_COUNTERS; j++, i++)
203                 data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
204                                                vport_rep_stats_desc, j);
205 }
206
207 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
208 {
209         switch (sset) {
210         case ETH_SS_STATS:
211                 return NUM_VPORT_REP_SW_COUNTERS + NUM_VPORT_REP_HW_COUNTERS;
212         default:
213                 return -EOPNOTSUPP;
214         }
215 }
216
217 static void mlx5e_rep_get_ringparam(struct net_device *dev,
218                                 struct ethtool_ringparam *param)
219 {
220         struct mlx5e_priv *priv = netdev_priv(dev);
221
222         mlx5e_ethtool_get_ringparam(priv, param);
223 }
224
225 static int mlx5e_rep_set_ringparam(struct net_device *dev,
226                                struct ethtool_ringparam *param)
227 {
228         struct mlx5e_priv *priv = netdev_priv(dev);
229
230         return mlx5e_ethtool_set_ringparam(priv, param);
231 }
232
233 static int mlx5e_replace_rep_vport_rx_rule(struct mlx5e_priv *priv,
234                                            struct mlx5_flow_destination *dest)
235 {
236         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
237         struct mlx5e_rep_priv *rpriv = priv->ppriv;
238         struct mlx5_eswitch_rep *rep = rpriv->rep;
239         struct mlx5_flow_handle *flow_rule;
240
241         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
242                                                       rep->vport,
243                                                       dest);
244         if (IS_ERR(flow_rule))
245                 return PTR_ERR(flow_rule);
246
247         mlx5_del_flow_rules(rpriv->vport_rx_rule);
248         rpriv->vport_rx_rule = flow_rule;
249         return 0;
250 }
251
252 static void mlx5e_rep_get_channels(struct net_device *dev,
253                                    struct ethtool_channels *ch)
254 {
255         struct mlx5e_priv *priv = netdev_priv(dev);
256
257         mlx5e_ethtool_get_channels(priv, ch);
258 }
259
260 static int mlx5e_rep_set_channels(struct net_device *dev,
261                                   struct ethtool_channels *ch)
262 {
263         struct mlx5e_priv *priv = netdev_priv(dev);
264         u16 curr_channels_amount = priv->channels.params.num_channels;
265         u32 new_channels_amount = ch->combined_count;
266         struct mlx5_flow_destination new_dest;
267         int err = 0;
268
269         err = mlx5e_ethtool_set_channels(priv, ch);
270         if (err)
271                 return err;
272
273         if (curr_channels_amount == 1 && new_channels_amount > 1) {
274                 new_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
275                 new_dest.ft = priv->fs.ttc.ft.t;
276         } else if (new_channels_amount == 1 && curr_channels_amount > 1) {
277                 new_dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
278                 new_dest.tir_num = priv->direct_tir[0].tirn;
279         } else {
280                 return 0;
281         }
282
283         err = mlx5e_replace_rep_vport_rx_rule(priv, &new_dest);
284         if (err) {
285                 netdev_warn(priv->netdev, "Failed to update vport rx rule, when going from (%d) channels to (%d) channels\n",
286                             curr_channels_amount, new_channels_amount);
287                 return err;
288         }
289
290         return 0;
291 }
292
293 static int mlx5e_rep_get_coalesce(struct net_device *netdev,
294                                   struct ethtool_coalesce *coal)
295 {
296         struct mlx5e_priv *priv = netdev_priv(netdev);
297
298         return mlx5e_ethtool_get_coalesce(priv, coal);
299 }
300
301 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
302                                   struct ethtool_coalesce *coal)
303 {
304         struct mlx5e_priv *priv = netdev_priv(netdev);
305
306         return mlx5e_ethtool_set_coalesce(priv, coal);
307 }
308
309 static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
310 {
311         struct mlx5e_priv *priv = netdev_priv(netdev);
312
313         return mlx5e_ethtool_get_rxfh_key_size(priv);
314 }
315
316 static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
317 {
318         struct mlx5e_priv *priv = netdev_priv(netdev);
319
320         return mlx5e_ethtool_get_rxfh_indir_size(priv);
321 }
322
323 static void mlx5e_uplink_rep_get_pauseparam(struct net_device *netdev,
324                                             struct ethtool_pauseparam *pauseparam)
325 {
326         struct mlx5e_priv *priv = netdev_priv(netdev);
327
328         mlx5e_ethtool_get_pauseparam(priv, pauseparam);
329 }
330
331 static int mlx5e_uplink_rep_set_pauseparam(struct net_device *netdev,
332                                            struct ethtool_pauseparam *pauseparam)
333 {
334         struct mlx5e_priv *priv = netdev_priv(netdev);
335
336         return mlx5e_ethtool_set_pauseparam(priv, pauseparam);
337 }
338
339 static int mlx5e_uplink_rep_get_link_ksettings(struct net_device *netdev,
340                                                struct ethtool_link_ksettings *link_ksettings)
341 {
342         struct mlx5e_priv *priv = netdev_priv(netdev);
343
344         return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
345 }
346
347 static int mlx5e_uplink_rep_set_link_ksettings(struct net_device *netdev,
348                                                const struct ethtool_link_ksettings *link_ksettings)
349 {
350         struct mlx5e_priv *priv = netdev_priv(netdev);
351
352         return mlx5e_ethtool_set_link_ksettings(priv, link_ksettings);
353 }
354
355 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
356         .get_drvinfo       = mlx5e_rep_get_drvinfo,
357         .get_link          = ethtool_op_get_link,
358         .get_strings       = mlx5e_rep_get_strings,
359         .get_sset_count    = mlx5e_rep_get_sset_count,
360         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
361         .get_ringparam     = mlx5e_rep_get_ringparam,
362         .set_ringparam     = mlx5e_rep_set_ringparam,
363         .get_channels      = mlx5e_rep_get_channels,
364         .set_channels      = mlx5e_rep_set_channels,
365         .get_coalesce      = mlx5e_rep_get_coalesce,
366         .set_coalesce      = mlx5e_rep_set_coalesce,
367         .get_rxfh_key_size   = mlx5e_rep_get_rxfh_key_size,
368         .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
369 };
370
371 static const struct ethtool_ops mlx5e_uplink_rep_ethtool_ops = {
372         .get_drvinfo       = mlx5e_uplink_rep_get_drvinfo,
373         .get_link          = ethtool_op_get_link,
374         .get_strings       = mlx5e_rep_get_strings,
375         .get_sset_count    = mlx5e_rep_get_sset_count,
376         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
377         .get_ringparam     = mlx5e_rep_get_ringparam,
378         .set_ringparam     = mlx5e_rep_set_ringparam,
379         .get_channels      = mlx5e_rep_get_channels,
380         .set_channels      = mlx5e_rep_set_channels,
381         .get_coalesce      = mlx5e_rep_get_coalesce,
382         .set_coalesce      = mlx5e_rep_set_coalesce,
383         .get_link_ksettings = mlx5e_uplink_rep_get_link_ksettings,
384         .set_link_ksettings = mlx5e_uplink_rep_set_link_ksettings,
385         .get_rxfh_key_size   = mlx5e_rep_get_rxfh_key_size,
386         .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
387         .get_pauseparam    = mlx5e_uplink_rep_get_pauseparam,
388         .set_pauseparam    = mlx5e_uplink_rep_set_pauseparam,
389 };
390
391 static int mlx5e_rep_get_port_parent_id(struct net_device *dev,
392                                         struct netdev_phys_item_id *ppid)
393 {
394         struct mlx5_eswitch *esw;
395         struct mlx5e_priv *priv;
396         u64 parent_id;
397
398         priv = netdev_priv(dev);
399         esw = priv->mdev->priv.eswitch;
400
401         if (esw->mode == MLX5_ESWITCH_NONE)
402                 return -EOPNOTSUPP;
403
404         parent_id = mlx5_query_nic_system_image_guid(priv->mdev);
405         ppid->id_len = sizeof(parent_id);
406         memcpy(ppid->id, &parent_id, sizeof(parent_id));
407
408         return 0;
409 }
410
411 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
412                                  struct mlx5_eswitch_rep *rep)
413 {
414         struct mlx5e_rep_sq *rep_sq, *tmp;
415         struct mlx5e_rep_priv *rpriv;
416
417         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
418                 return;
419
420         rpriv = mlx5e_rep_to_rep_priv(rep);
421         list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) {
422                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
423                 list_del(&rep_sq->list);
424                 kfree(rep_sq);
425         }
426 }
427
428 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
429                                  struct mlx5_eswitch_rep *rep,
430                                  u32 *sqns_array, int sqns_num)
431 {
432         struct mlx5_flow_handle *flow_rule;
433         struct mlx5e_rep_priv *rpriv;
434         struct mlx5e_rep_sq *rep_sq;
435         int err;
436         int i;
437
438         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
439                 return 0;
440
441         rpriv = mlx5e_rep_to_rep_priv(rep);
442         for (i = 0; i < sqns_num; i++) {
443                 rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL);
444                 if (!rep_sq) {
445                         err = -ENOMEM;
446                         goto out_err;
447                 }
448
449                 /* Add re-inject rule to the PF/representor sqs */
450                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw,
451                                                                 rep->vport,
452                                                                 sqns_array[i]);
453                 if (IS_ERR(flow_rule)) {
454                         err = PTR_ERR(flow_rule);
455                         kfree(rep_sq);
456                         goto out_err;
457                 }
458                 rep_sq->send_to_vport_rule = flow_rule;
459                 list_add(&rep_sq->list, &rpriv->vport_sqs_list);
460         }
461         return 0;
462
463 out_err:
464         mlx5e_sqs2vport_stop(esw, rep);
465         return err;
466 }
467
468 int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
469 {
470         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
471         struct mlx5e_rep_priv *rpriv = priv->ppriv;
472         struct mlx5_eswitch_rep *rep = rpriv->rep;
473         struct mlx5e_channel *c;
474         int n, tc, num_sqs = 0;
475         int err = -ENOMEM;
476         u32 *sqs;
477
478         sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(*sqs), GFP_KERNEL);
479         if (!sqs)
480                 goto out;
481
482         for (n = 0; n < priv->channels.num; n++) {
483                 c = priv->channels.c[n];
484                 for (tc = 0; tc < c->num_tc; tc++)
485                         sqs[num_sqs++] = c->sq[tc].sqn;
486         }
487
488         err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs);
489         kfree(sqs);
490
491 out:
492         if (err)
493                 netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
494         return err;
495 }
496
497 void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
498 {
499         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
500         struct mlx5e_rep_priv *rpriv = priv->ppriv;
501         struct mlx5_eswitch_rep *rep = rpriv->rep;
502
503         mlx5e_sqs2vport_stop(esw, rep);
504 }
505
506 static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv)
507 {
508 #if IS_ENABLED(CONFIG_IPV6)
509         unsigned long ipv6_interval = NEIGH_VAR(&nd_tbl.parms,
510                                                 DELAY_PROBE_TIME);
511 #else
512         unsigned long ipv6_interval = ~0UL;
513 #endif
514         unsigned long ipv4_interval = NEIGH_VAR(&arp_tbl.parms,
515                                                 DELAY_PROBE_TIME);
516         struct net_device *netdev = rpriv->netdev;
517         struct mlx5e_priv *priv = netdev_priv(netdev);
518
519         rpriv->neigh_update.min_interval = min_t(unsigned long, ipv6_interval, ipv4_interval);
520         mlx5_fc_update_sampling_interval(priv->mdev, rpriv->neigh_update.min_interval);
521 }
522
523 void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv)
524 {
525         struct mlx5e_rep_priv *rpriv = priv->ppriv;
526         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
527
528         mlx5_fc_queue_stats_work(priv->mdev,
529                                  &neigh_update->neigh_stats_work,
530                                  neigh_update->min_interval);
531 }
532
533 static void mlx5e_rep_neigh_stats_work(struct work_struct *work)
534 {
535         struct mlx5e_rep_priv *rpriv = container_of(work, struct mlx5e_rep_priv,
536                                                     neigh_update.neigh_stats_work.work);
537         struct net_device *netdev = rpriv->netdev;
538         struct mlx5e_priv *priv = netdev_priv(netdev);
539         struct mlx5e_neigh_hash_entry *nhe;
540
541         rtnl_lock();
542         if (!list_empty(&rpriv->neigh_update.neigh_list))
543                 mlx5e_rep_queue_neigh_stats_work(priv);
544
545         list_for_each_entry(nhe, &rpriv->neigh_update.neigh_list, neigh_list)
546                 mlx5e_tc_update_neigh_used_value(nhe);
547
548         rtnl_unlock();
549 }
550
551 static void mlx5e_rep_neigh_entry_hold(struct mlx5e_neigh_hash_entry *nhe)
552 {
553         refcount_inc(&nhe->refcnt);
554 }
555
556 static void mlx5e_rep_neigh_entry_release(struct mlx5e_neigh_hash_entry *nhe)
557 {
558         if (refcount_dec_and_test(&nhe->refcnt))
559                 kfree(nhe);
560 }
561
562 static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
563                                    struct mlx5e_encap_entry *e,
564                                    bool neigh_connected,
565                                    unsigned char ha[ETH_ALEN])
566 {
567         struct ethhdr *eth = (struct ethhdr *)e->encap_header;
568
569         ASSERT_RTNL();
570
571         if ((e->flags & MLX5_ENCAP_ENTRY_VALID) &&
572             (!neigh_connected || !ether_addr_equal(e->h_dest, ha)))
573                 mlx5e_tc_encap_flows_del(priv, e);
574
575         if (neigh_connected && !(e->flags & MLX5_ENCAP_ENTRY_VALID)) {
576                 ether_addr_copy(e->h_dest, ha);
577                 ether_addr_copy(eth->h_dest, ha);
578                 /* Update the encap source mac, in case that we delete
579                  * the flows when encap source mac changed.
580                  */
581                 ether_addr_copy(eth->h_source, e->route_dev->dev_addr);
582
583                 mlx5e_tc_encap_flows_add(priv, e);
584         }
585 }
586
587 static void mlx5e_rep_neigh_update(struct work_struct *work)
588 {
589         struct mlx5e_neigh_hash_entry *nhe =
590                 container_of(work, struct mlx5e_neigh_hash_entry, neigh_update_work);
591         struct neighbour *n = nhe->n;
592         struct mlx5e_encap_entry *e;
593         unsigned char ha[ETH_ALEN];
594         struct mlx5e_priv *priv;
595         bool neigh_connected;
596         bool encap_connected;
597         u8 nud_state, dead;
598
599         rtnl_lock();
600
601         /* If these parameters are changed after we release the lock,
602          * we'll receive another event letting us know about it.
603          * We use this lock to avoid inconsistency between the neigh validity
604          * and it's hw address.
605          */
606         read_lock_bh(&n->lock);
607         memcpy(ha, n->ha, ETH_ALEN);
608         nud_state = n->nud_state;
609         dead = n->dead;
610         read_unlock_bh(&n->lock);
611
612         neigh_connected = (nud_state & NUD_VALID) && !dead;
613
614         list_for_each_entry(e, &nhe->encap_list, encap_list) {
615                 encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
616                 priv = netdev_priv(e->out_dev);
617
618                 if (encap_connected != neigh_connected ||
619                     !ether_addr_equal(e->h_dest, ha))
620                         mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
621         }
622         mlx5e_rep_neigh_entry_release(nhe);
623         rtnl_unlock();
624         neigh_release(n);
625 }
626
627 static struct mlx5e_rep_indr_block_priv *
628 mlx5e_rep_indr_block_priv_lookup(struct mlx5e_rep_priv *rpriv,
629                                  struct net_device *netdev)
630 {
631         struct mlx5e_rep_indr_block_priv *cb_priv;
632
633         /* All callback list access should be protected by RTNL. */
634         ASSERT_RTNL();
635
636         list_for_each_entry(cb_priv,
637                             &rpriv->uplink_priv.tc_indr_block_priv_list,
638                             list)
639                 if (cb_priv->netdev == netdev)
640                         return cb_priv;
641
642         return NULL;
643 }
644
645 static void mlx5e_rep_indr_clean_block_privs(struct mlx5e_rep_priv *rpriv)
646 {
647         struct mlx5e_rep_indr_block_priv *cb_priv, *temp;
648         struct list_head *head = &rpriv->uplink_priv.tc_indr_block_priv_list;
649
650         list_for_each_entry_safe(cb_priv, temp, head, list) {
651                 mlx5e_rep_indr_unregister_block(rpriv, cb_priv->netdev);
652                 kfree(cb_priv);
653         }
654 }
655
656 static int
657 mlx5e_rep_indr_offload(struct net_device *netdev,
658                        struct tc_cls_flower_offload *flower,
659                        struct mlx5e_rep_indr_block_priv *indr_priv)
660 {
661         struct mlx5e_priv *priv = netdev_priv(indr_priv->rpriv->netdev);
662         int flags = MLX5E_TC_EGRESS | MLX5E_TC_ESW_OFFLOAD;
663         int err = 0;
664
665         switch (flower->command) {
666         case TC_CLSFLOWER_REPLACE:
667                 err = mlx5e_configure_flower(netdev, priv, flower, flags);
668                 break;
669         case TC_CLSFLOWER_DESTROY:
670                 err = mlx5e_delete_flower(netdev, priv, flower, flags);
671                 break;
672         case TC_CLSFLOWER_STATS:
673                 err = mlx5e_stats_flower(netdev, priv, flower, flags);
674                 break;
675         default:
676                 err = -EOPNOTSUPP;
677         }
678
679         return err;
680 }
681
682 static int mlx5e_rep_indr_setup_block_cb(enum tc_setup_type type,
683                                          void *type_data, void *indr_priv)
684 {
685         struct mlx5e_rep_indr_block_priv *priv = indr_priv;
686
687         switch (type) {
688         case TC_SETUP_CLSFLOWER:
689                 return mlx5e_rep_indr_offload(priv->netdev, type_data, priv);
690         default:
691                 return -EOPNOTSUPP;
692         }
693 }
694
695 static int
696 mlx5e_rep_indr_setup_tc_block(struct net_device *netdev,
697                               struct mlx5e_rep_priv *rpriv,
698                               struct tc_block_offload *f)
699 {
700         struct mlx5e_rep_indr_block_priv *indr_priv;
701         int err = 0;
702
703         if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
704                 return -EOPNOTSUPP;
705
706         switch (f->command) {
707         case TC_BLOCK_BIND:
708                 indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, netdev);
709                 if (indr_priv)
710                         return -EEXIST;
711
712                 indr_priv = kmalloc(sizeof(*indr_priv), GFP_KERNEL);
713                 if (!indr_priv)
714                         return -ENOMEM;
715
716                 indr_priv->netdev = netdev;
717                 indr_priv->rpriv = rpriv;
718                 list_add(&indr_priv->list,
719                          &rpriv->uplink_priv.tc_indr_block_priv_list);
720
721                 err = tcf_block_cb_register(f->block,
722                                             mlx5e_rep_indr_setup_block_cb,
723                                             indr_priv, indr_priv, f->extack);
724                 if (err) {
725                         list_del(&indr_priv->list);
726                         kfree(indr_priv);
727                 }
728
729                 return err;
730         case TC_BLOCK_UNBIND:
731                 indr_priv = mlx5e_rep_indr_block_priv_lookup(rpriv, netdev);
732                 if (!indr_priv)
733                         return -ENOENT;
734
735                 tcf_block_cb_unregister(f->block,
736                                         mlx5e_rep_indr_setup_block_cb,
737                                         indr_priv);
738                 list_del(&indr_priv->list);
739                 kfree(indr_priv);
740
741                 return 0;
742         default:
743                 return -EOPNOTSUPP;
744         }
745         return 0;
746 }
747
748 static
749 int mlx5e_rep_indr_setup_tc_cb(struct net_device *netdev, void *cb_priv,
750                                enum tc_setup_type type, void *type_data)
751 {
752         switch (type) {
753         case TC_SETUP_BLOCK:
754                 return mlx5e_rep_indr_setup_tc_block(netdev, cb_priv,
755                                                       type_data);
756         default:
757                 return -EOPNOTSUPP;
758         }
759 }
760
761 static int mlx5e_rep_indr_register_block(struct mlx5e_rep_priv *rpriv,
762                                          struct net_device *netdev)
763 {
764         int err;
765
766         err = __tc_indr_block_cb_register(netdev, rpriv,
767                                           mlx5e_rep_indr_setup_tc_cb,
768                                           rpriv);
769         if (err) {
770                 struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
771
772                 mlx5_core_err(priv->mdev, "Failed to register remote block notifier for %s err=%d\n",
773                               netdev_name(netdev), err);
774         }
775         return err;
776 }
777
778 static void mlx5e_rep_indr_unregister_block(struct mlx5e_rep_priv *rpriv,
779                                             struct net_device *netdev)
780 {
781         __tc_indr_block_cb_unregister(netdev, mlx5e_rep_indr_setup_tc_cb,
782                                       rpriv);
783 }
784
785 static int mlx5e_nic_rep_netdevice_event(struct notifier_block *nb,
786                                          unsigned long event, void *ptr)
787 {
788         struct mlx5e_rep_priv *rpriv = container_of(nb, struct mlx5e_rep_priv,
789                                                      uplink_priv.netdevice_nb);
790         struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
791         struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
792
793         if (!mlx5e_tc_tun_device_to_offload(priv, netdev) &&
794             !(is_vlan_dev(netdev) && vlan_dev_real_dev(netdev) == rpriv->netdev))
795                 return NOTIFY_OK;
796
797         switch (event) {
798         case NETDEV_REGISTER:
799                 mlx5e_rep_indr_register_block(rpriv, netdev);
800                 break;
801         case NETDEV_UNREGISTER:
802                 mlx5e_rep_indr_unregister_block(rpriv, netdev);
803                 break;
804         }
805         return NOTIFY_OK;
806 }
807
808 static struct mlx5e_neigh_hash_entry *
809 mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
810                              struct mlx5e_neigh *m_neigh);
811
812 static int mlx5e_rep_netevent_event(struct notifier_block *nb,
813                                     unsigned long event, void *ptr)
814 {
815         struct mlx5e_rep_priv *rpriv = container_of(nb, struct mlx5e_rep_priv,
816                                                     neigh_update.netevent_nb);
817         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
818         struct net_device *netdev = rpriv->netdev;
819         struct mlx5e_priv *priv = netdev_priv(netdev);
820         struct mlx5e_neigh_hash_entry *nhe = NULL;
821         struct mlx5e_neigh m_neigh = {};
822         struct neigh_parms *p;
823         struct neighbour *n;
824         bool found = false;
825
826         switch (event) {
827         case NETEVENT_NEIGH_UPDATE:
828                 n = ptr;
829 #if IS_ENABLED(CONFIG_IPV6)
830                 if (n->tbl != &nd_tbl && n->tbl != &arp_tbl)
831 #else
832                 if (n->tbl != &arp_tbl)
833 #endif
834                         return NOTIFY_DONE;
835
836                 m_neigh.dev = n->dev;
837                 m_neigh.family = n->ops->family;
838                 memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
839
840                 /* We are in atomic context and can't take RTNL mutex, so use
841                  * spin_lock_bh to lookup the neigh table. bh is used since
842                  * netevent can be called from a softirq context.
843                  */
844                 spin_lock_bh(&neigh_update->encap_lock);
845                 nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
846                 if (!nhe) {
847                         spin_unlock_bh(&neigh_update->encap_lock);
848                         return NOTIFY_DONE;
849                 }
850
851                 /* This assignment is valid as long as the the neigh reference
852                  * is taken
853                  */
854                 nhe->n = n;
855
856                 /* Take a reference to ensure the neighbour and mlx5 encap
857                  * entry won't be destructed until we drop the reference in
858                  * delayed work.
859                  */
860                 neigh_hold(n);
861                 mlx5e_rep_neigh_entry_hold(nhe);
862
863                 if (!queue_work(priv->wq, &nhe->neigh_update_work)) {
864                         mlx5e_rep_neigh_entry_release(nhe);
865                         neigh_release(n);
866                 }
867                 spin_unlock_bh(&neigh_update->encap_lock);
868                 break;
869
870         case NETEVENT_DELAY_PROBE_TIME_UPDATE:
871                 p = ptr;
872
873                 /* We check the device is present since we don't care about
874                  * changes in the default table, we only care about changes
875                  * done per device delay prob time parameter.
876                  */
877 #if IS_ENABLED(CONFIG_IPV6)
878                 if (!p->dev || (p->tbl != &nd_tbl && p->tbl != &arp_tbl))
879 #else
880                 if (!p->dev || p->tbl != &arp_tbl)
881 #endif
882                         return NOTIFY_DONE;
883
884                 /* We are in atomic context and can't take RTNL mutex,
885                  * so use spin_lock_bh to walk the neigh list and look for
886                  * the relevant device. bh is used since netevent can be
887                  * called from a softirq context.
888                  */
889                 spin_lock_bh(&neigh_update->encap_lock);
890                 list_for_each_entry(nhe, &neigh_update->neigh_list, neigh_list) {
891                         if (p->dev == nhe->m_neigh.dev) {
892                                 found = true;
893                                 break;
894                         }
895                 }
896                 spin_unlock_bh(&neigh_update->encap_lock);
897                 if (!found)
898                         return NOTIFY_DONE;
899
900                 neigh_update->min_interval = min_t(unsigned long,
901                                                    NEIGH_VAR(p, DELAY_PROBE_TIME),
902                                                    neigh_update->min_interval);
903                 mlx5_fc_update_sampling_interval(priv->mdev,
904                                                  neigh_update->min_interval);
905                 break;
906         }
907         return NOTIFY_DONE;
908 }
909
910 static const struct rhashtable_params mlx5e_neigh_ht_params = {
911         .head_offset = offsetof(struct mlx5e_neigh_hash_entry, rhash_node),
912         .key_offset = offsetof(struct mlx5e_neigh_hash_entry, m_neigh),
913         .key_len = sizeof(struct mlx5e_neigh),
914         .automatic_shrinking = true,
915 };
916
917 static int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv)
918 {
919         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
920         int err;
921
922         err = rhashtable_init(&neigh_update->neigh_ht, &mlx5e_neigh_ht_params);
923         if (err)
924                 return err;
925
926         INIT_LIST_HEAD(&neigh_update->neigh_list);
927         spin_lock_init(&neigh_update->encap_lock);
928         INIT_DELAYED_WORK(&neigh_update->neigh_stats_work,
929                           mlx5e_rep_neigh_stats_work);
930         mlx5e_rep_neigh_update_init_interval(rpriv);
931
932         rpriv->neigh_update.netevent_nb.notifier_call = mlx5e_rep_netevent_event;
933         err = register_netevent_notifier(&rpriv->neigh_update.netevent_nb);
934         if (err)
935                 goto out_err;
936         return 0;
937
938 out_err:
939         rhashtable_destroy(&neigh_update->neigh_ht);
940         return err;
941 }
942
943 static void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv)
944 {
945         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
946         struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
947
948         unregister_netevent_notifier(&neigh_update->netevent_nb);
949
950         flush_workqueue(priv->wq); /* flush neigh update works */
951
952         cancel_delayed_work_sync(&rpriv->neigh_update.neigh_stats_work);
953
954         rhashtable_destroy(&neigh_update->neigh_ht);
955 }
956
957 static int mlx5e_rep_neigh_entry_insert(struct mlx5e_priv *priv,
958                                         struct mlx5e_neigh_hash_entry *nhe)
959 {
960         struct mlx5e_rep_priv *rpriv = priv->ppriv;
961         int err;
962
963         err = rhashtable_insert_fast(&rpriv->neigh_update.neigh_ht,
964                                      &nhe->rhash_node,
965                                      mlx5e_neigh_ht_params);
966         if (err)
967                 return err;
968
969         list_add(&nhe->neigh_list, &rpriv->neigh_update.neigh_list);
970
971         return err;
972 }
973
974 static void mlx5e_rep_neigh_entry_remove(struct mlx5e_priv *priv,
975                                          struct mlx5e_neigh_hash_entry *nhe)
976 {
977         struct mlx5e_rep_priv *rpriv = priv->ppriv;
978
979         spin_lock_bh(&rpriv->neigh_update.encap_lock);
980
981         list_del(&nhe->neigh_list);
982
983         rhashtable_remove_fast(&rpriv->neigh_update.neigh_ht,
984                                &nhe->rhash_node,
985                                mlx5e_neigh_ht_params);
986         spin_unlock_bh(&rpriv->neigh_update.encap_lock);
987 }
988
989 /* This function must only be called under RTNL lock or under the
990  * representor's encap_lock in case RTNL mutex can't be held.
991  */
992 static struct mlx5e_neigh_hash_entry *
993 mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
994                              struct mlx5e_neigh *m_neigh)
995 {
996         struct mlx5e_rep_priv *rpriv = priv->ppriv;
997         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
998
999         return rhashtable_lookup_fast(&neigh_update->neigh_ht, m_neigh,
1000                                       mlx5e_neigh_ht_params);
1001 }
1002
1003 static int mlx5e_rep_neigh_entry_create(struct mlx5e_priv *priv,
1004                                         struct mlx5e_encap_entry *e,
1005                                         struct mlx5e_neigh_hash_entry **nhe)
1006 {
1007         int err;
1008
1009         *nhe = kzalloc(sizeof(**nhe), GFP_KERNEL);
1010         if (!*nhe)
1011                 return -ENOMEM;
1012
1013         memcpy(&(*nhe)->m_neigh, &e->m_neigh, sizeof(e->m_neigh));
1014         INIT_WORK(&(*nhe)->neigh_update_work, mlx5e_rep_neigh_update);
1015         INIT_LIST_HEAD(&(*nhe)->encap_list);
1016         refcount_set(&(*nhe)->refcnt, 1);
1017
1018         err = mlx5e_rep_neigh_entry_insert(priv, *nhe);
1019         if (err)
1020                 goto out_free;
1021         return 0;
1022
1023 out_free:
1024         kfree(*nhe);
1025         return err;
1026 }
1027
1028 static void mlx5e_rep_neigh_entry_destroy(struct mlx5e_priv *priv,
1029                                           struct mlx5e_neigh_hash_entry *nhe)
1030 {
1031         /* The neigh hash entry must be removed from the hash table regardless
1032          * of the reference count value, so it won't be found by the next
1033          * neigh notification call. The neigh hash entry reference count is
1034          * incremented only during creation and neigh notification calls and
1035          * protects from freeing the nhe struct.
1036          */
1037         mlx5e_rep_neigh_entry_remove(priv, nhe);
1038         mlx5e_rep_neigh_entry_release(nhe);
1039 }
1040
1041 int mlx5e_rep_encap_entry_attach(struct mlx5e_priv *priv,
1042                                  struct mlx5e_encap_entry *e)
1043 {
1044         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1045         struct mlx5_rep_uplink_priv *uplink_priv = &rpriv->uplink_priv;
1046         struct mlx5_tun_entropy *tun_entropy = &uplink_priv->tun_entropy;
1047         struct mlx5e_neigh_hash_entry *nhe;
1048         int err;
1049
1050         err = mlx5_tun_entropy_refcount_inc(tun_entropy, e->reformat_type);
1051         if (err)
1052                 return err;
1053         nhe = mlx5e_rep_neigh_entry_lookup(priv, &e->m_neigh);
1054         if (!nhe) {
1055                 err = mlx5e_rep_neigh_entry_create(priv, e, &nhe);
1056                 if (err) {
1057                         mlx5_tun_entropy_refcount_dec(tun_entropy,
1058                                                       e->reformat_type);
1059                         return err;
1060                 }
1061         }
1062         list_add(&e->encap_list, &nhe->encap_list);
1063         return 0;
1064 }
1065
1066 void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
1067                                   struct mlx5e_encap_entry *e)
1068 {
1069         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1070         struct mlx5_rep_uplink_priv *uplink_priv = &rpriv->uplink_priv;
1071         struct mlx5_tun_entropy *tun_entropy = &uplink_priv->tun_entropy;
1072         struct mlx5e_neigh_hash_entry *nhe;
1073
1074         list_del(&e->encap_list);
1075         nhe = mlx5e_rep_neigh_entry_lookup(priv, &e->m_neigh);
1076
1077         if (list_empty(&nhe->encap_list))
1078                 mlx5e_rep_neigh_entry_destroy(priv, nhe);
1079         mlx5_tun_entropy_refcount_dec(tun_entropy, e->reformat_type);
1080 }
1081
1082 static int mlx5e_rep_open(struct net_device *dev)
1083 {
1084         struct mlx5e_priv *priv = netdev_priv(dev);
1085         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1086         struct mlx5_eswitch_rep *rep = rpriv->rep;
1087         int err;
1088
1089         mutex_lock(&priv->state_lock);
1090         err = mlx5e_open_locked(dev);
1091         if (err)
1092                 goto unlock;
1093
1094         if (!mlx5_modify_vport_admin_state(priv->mdev,
1095                                            MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
1096                                            rep->vport, 1,
1097                                            MLX5_VPORT_ADMIN_STATE_UP))
1098                 netif_carrier_on(dev);
1099
1100 unlock:
1101         mutex_unlock(&priv->state_lock);
1102         return err;
1103 }
1104
1105 static int mlx5e_rep_close(struct net_device *dev)
1106 {
1107         struct mlx5e_priv *priv = netdev_priv(dev);
1108         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1109         struct mlx5_eswitch_rep *rep = rpriv->rep;
1110         int ret;
1111
1112         mutex_lock(&priv->state_lock);
1113         mlx5_modify_vport_admin_state(priv->mdev,
1114                                       MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
1115                                       rep->vport, 1,
1116                                       MLX5_VPORT_ADMIN_STATE_DOWN);
1117         ret = mlx5e_close_locked(dev);
1118         mutex_unlock(&priv->state_lock);
1119         return ret;
1120 }
1121
1122 static int mlx5e_rep_get_phys_port_name(struct net_device *dev,
1123                                         char *buf, size_t len)
1124 {
1125         struct mlx5e_priv *priv = netdev_priv(dev);
1126         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1127         struct mlx5_eswitch_rep *rep = rpriv->rep;
1128         unsigned int fn;
1129         int ret;
1130
1131         fn = PCI_FUNC(priv->mdev->pdev->devfn);
1132         if (fn >= MLX5_MAX_PORTS)
1133                 return -EOPNOTSUPP;
1134
1135         if (rep->vport == MLX5_VPORT_UPLINK)
1136                 ret = snprintf(buf, len, "p%d", fn);
1137         else if (rep->vport == MLX5_VPORT_PF)
1138                 ret = snprintf(buf, len, "pf%d", fn);
1139         else
1140                 ret = snprintf(buf, len, "pf%dvf%d", fn, rep->vport - 1);
1141
1142         if (ret >= len)
1143                 return -EOPNOTSUPP;
1144
1145         return 0;
1146 }
1147
1148 static int
1149 mlx5e_rep_setup_tc_cls_flower(struct mlx5e_priv *priv,
1150                               struct tc_cls_flower_offload *cls_flower, int flags)
1151 {
1152         switch (cls_flower->command) {
1153         case TC_CLSFLOWER_REPLACE:
1154                 return mlx5e_configure_flower(priv->netdev, priv, cls_flower,
1155                                               flags);
1156         case TC_CLSFLOWER_DESTROY:
1157                 return mlx5e_delete_flower(priv->netdev, priv, cls_flower,
1158                                            flags);
1159         case TC_CLSFLOWER_STATS:
1160                 return mlx5e_stats_flower(priv->netdev, priv, cls_flower,
1161                                           flags);
1162         default:
1163                 return -EOPNOTSUPP;
1164         }
1165 }
1166
1167 static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
1168                                  void *cb_priv)
1169 {
1170         struct mlx5e_priv *priv = cb_priv;
1171
1172         switch (type) {
1173         case TC_SETUP_CLSFLOWER:
1174                 return mlx5e_rep_setup_tc_cls_flower(priv, type_data, MLX5E_TC_INGRESS |
1175                                                      MLX5E_TC_ESW_OFFLOAD);
1176         default:
1177                 return -EOPNOTSUPP;
1178         }
1179 }
1180
1181 static int mlx5e_rep_setup_tc_block(struct net_device *dev,
1182                                     struct tc_block_offload *f)
1183 {
1184         struct mlx5e_priv *priv = netdev_priv(dev);
1185
1186         if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
1187                 return -EOPNOTSUPP;
1188
1189         switch (f->command) {
1190         case TC_BLOCK_BIND:
1191                 return tcf_block_cb_register(f->block, mlx5e_rep_setup_tc_cb,
1192                                              priv, priv, f->extack);
1193         case TC_BLOCK_UNBIND:
1194                 tcf_block_cb_unregister(f->block, mlx5e_rep_setup_tc_cb, priv);
1195                 return 0;
1196         default:
1197                 return -EOPNOTSUPP;
1198         }
1199 }
1200
1201 static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
1202                               void *type_data)
1203 {
1204         switch (type) {
1205         case TC_SETUP_BLOCK:
1206                 return mlx5e_rep_setup_tc_block(dev, type_data);
1207         default:
1208                 return -EOPNOTSUPP;
1209         }
1210 }
1211
1212 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
1213 {
1214         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1215         struct mlx5_eswitch_rep *rep;
1216
1217         if (!MLX5_ESWITCH_MANAGER(priv->mdev))
1218                 return false;
1219
1220         if (!rpriv) /* non vport rep mlx5e instances don't use this field */
1221                 return false;
1222
1223         rep = rpriv->rep;
1224         return (rep->vport == MLX5_VPORT_UPLINK);
1225 }
1226
1227 static bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
1228 {
1229         switch (attr_id) {
1230         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
1231                         return true;
1232         }
1233
1234         return false;
1235 }
1236
1237 static int
1238 mlx5e_get_sw_stats64(const struct net_device *dev,
1239                      struct rtnl_link_stats64 *stats)
1240 {
1241         struct mlx5e_priv *priv = netdev_priv(dev);
1242
1243         mlx5e_fold_sw_stats64(priv, stats);
1244         return 0;
1245 }
1246
1247 static int mlx5e_rep_get_offload_stats(int attr_id, const struct net_device *dev,
1248                                        void *sp)
1249 {
1250         switch (attr_id) {
1251         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
1252                 return mlx5e_get_sw_stats64(dev, sp);
1253         }
1254
1255         return -EINVAL;
1256 }
1257
1258 static void
1259 mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
1260 {
1261         struct mlx5e_priv *priv = netdev_priv(dev);
1262
1263         /* update HW stats in background for next time */
1264         mlx5e_queue_update_stats(priv);
1265         memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
1266 }
1267
1268 static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu)
1269 {
1270         return mlx5e_change_mtu(netdev, new_mtu, NULL);
1271 }
1272
1273 static int mlx5e_uplink_rep_change_mtu(struct net_device *netdev, int new_mtu)
1274 {
1275         return mlx5e_change_mtu(netdev, new_mtu, mlx5e_set_dev_port_mtu);
1276 }
1277
1278 static int mlx5e_uplink_rep_set_mac(struct net_device *netdev, void *addr)
1279 {
1280         struct sockaddr *saddr = addr;
1281
1282         if (!is_valid_ether_addr(saddr->sa_data))
1283                 return -EADDRNOTAVAIL;
1284
1285         ether_addr_copy(netdev->dev_addr, saddr->sa_data);
1286         return 0;
1287 }
1288
1289 static int mlx5e_uplink_rep_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
1290                                         __be16 vlan_proto)
1291 {
1292         netdev_warn_once(dev, "legacy vf vlan setting isn't supported in switchdev mode\n");
1293
1294         if (vlan != 0)
1295                 return -EOPNOTSUPP;
1296
1297         /* allow setting 0-vid for compatibility with libvirt */
1298         return 0;
1299 }
1300
1301 static const struct net_device_ops mlx5e_netdev_ops_rep = {
1302         .ndo_open                = mlx5e_rep_open,
1303         .ndo_stop                = mlx5e_rep_close,
1304         .ndo_start_xmit          = mlx5e_xmit,
1305         .ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
1306         .ndo_setup_tc            = mlx5e_rep_setup_tc,
1307         .ndo_get_stats64         = mlx5e_rep_get_stats,
1308         .ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
1309         .ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
1310         .ndo_change_mtu          = mlx5e_rep_change_mtu,
1311         .ndo_get_port_parent_id  = mlx5e_rep_get_port_parent_id,
1312 };
1313
1314 static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
1315         .ndo_open                = mlx5e_open,
1316         .ndo_stop                = mlx5e_close,
1317         .ndo_start_xmit          = mlx5e_xmit,
1318         .ndo_set_mac_address     = mlx5e_uplink_rep_set_mac,
1319         .ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
1320         .ndo_setup_tc            = mlx5e_rep_setup_tc,
1321         .ndo_get_stats64         = mlx5e_get_stats,
1322         .ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
1323         .ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
1324         .ndo_change_mtu          = mlx5e_uplink_rep_change_mtu,
1325         .ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
1326         .ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
1327         .ndo_features_check      = mlx5e_features_check,
1328         .ndo_set_vf_mac          = mlx5e_set_vf_mac,
1329         .ndo_set_vf_rate         = mlx5e_set_vf_rate,
1330         .ndo_get_vf_config       = mlx5e_get_vf_config,
1331         .ndo_get_vf_stats        = mlx5e_get_vf_stats,
1332         .ndo_set_vf_vlan         = mlx5e_uplink_rep_set_vf_vlan,
1333         .ndo_get_port_parent_id  = mlx5e_rep_get_port_parent_id,
1334         .ndo_set_features        = mlx5e_set_features,
1335 };
1336
1337 bool mlx5e_eswitch_rep(struct net_device *netdev)
1338 {
1339         if (netdev->netdev_ops == &mlx5e_netdev_ops_rep ||
1340             netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep)
1341                 return true;
1342
1343         return false;
1344 }
1345
1346 static void mlx5e_build_rep_params(struct net_device *netdev)
1347 {
1348         struct mlx5e_priv *priv = netdev_priv(netdev);
1349         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1350         struct mlx5_eswitch_rep *rep = rpriv->rep;
1351         struct mlx5_core_dev *mdev = priv->mdev;
1352         struct mlx5e_params *params;
1353
1354         u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
1355                                          MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
1356                                          MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
1357
1358         params = &priv->channels.params;
1359         params->hard_mtu    = MLX5E_ETH_HARD_MTU;
1360         params->sw_mtu      = netdev->mtu;
1361
1362         /* SQ */
1363         if (rep->vport == MLX5_VPORT_UPLINK)
1364                 params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
1365         else
1366                 params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;
1367
1368         /* RQ */
1369         mlx5e_build_rq_params(mdev, params);
1370
1371         /* CQ moderation params */
1372         params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
1373         mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
1374
1375         params->num_tc                = 1;
1376         params->tunneled_offload_en = false;
1377
1378         mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
1379
1380         /* RSS */
1381         mlx5e_build_rss_params(&priv->rss_params, params->num_channels);
1382 }
1383
1384 static void mlx5e_build_rep_netdev(struct net_device *netdev)
1385 {
1386         struct mlx5e_priv *priv = netdev_priv(netdev);
1387         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1388         struct mlx5_eswitch_rep *rep = rpriv->rep;
1389         struct mlx5_core_dev *mdev = priv->mdev;
1390
1391         if (rep->vport == MLX5_VPORT_UPLINK) {
1392                 SET_NETDEV_DEV(netdev, mdev->device);
1393                 netdev->netdev_ops = &mlx5e_netdev_ops_uplink_rep;
1394                 /* we want a persistent mac for the uplink rep */
1395                 mlx5_query_mac_address(mdev, netdev->dev_addr);
1396                 netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
1397 #ifdef CONFIG_MLX5_CORE_EN_DCB
1398                 if (MLX5_CAP_GEN(mdev, qos))
1399                         netdev->dcbnl_ops = &mlx5e_dcbnl_ops;
1400 #endif
1401         } else {
1402                 netdev->netdev_ops = &mlx5e_netdev_ops_rep;
1403                 eth_hw_addr_random(netdev);
1404                 netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
1405         }
1406
1407         netdev->watchdog_timeo    = 15 * HZ;
1408
1409         netdev->features       |= NETIF_F_NETNS_LOCAL;
1410
1411         netdev->hw_features    |= NETIF_F_HW_TC;
1412         netdev->hw_features    |= NETIF_F_SG;
1413         netdev->hw_features    |= NETIF_F_IP_CSUM;
1414         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
1415         netdev->hw_features    |= NETIF_F_GRO;
1416         netdev->hw_features    |= NETIF_F_TSO;
1417         netdev->hw_features    |= NETIF_F_TSO6;
1418         netdev->hw_features    |= NETIF_F_RXCSUM;
1419
1420         if (rep->vport == MLX5_VPORT_UPLINK)
1421                 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
1422         else
1423                 netdev->features |= NETIF_F_VLAN_CHALLENGED;
1424
1425         netdev->features |= netdev->hw_features;
1426 }
1427
1428 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
1429                           struct net_device *netdev,
1430                           const struct mlx5e_profile *profile,
1431                           void *ppriv)
1432 {
1433         struct mlx5e_priv *priv = netdev_priv(netdev);
1434         int err;
1435
1436         err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
1437         if (err)
1438                 return err;
1439
1440         priv->channels.params.num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
1441
1442         mlx5e_build_rep_params(netdev);
1443         mlx5e_build_rep_netdev(netdev);
1444
1445         mlx5e_timestamp_init(priv);
1446
1447         return 0;
1448 }
1449
1450 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
1451 {
1452         mlx5e_netdev_cleanup(priv->netdev, priv);
1453 }
1454
1455 static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
1456 {
1457         struct ttc_params ttc_params = {};
1458         int tt, err;
1459
1460         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
1461                                               MLX5_FLOW_NAMESPACE_KERNEL);
1462
1463         /* The inner_ttc in the ttc params is intentionally not set */
1464         ttc_params.any_tt_tirn = priv->direct_tir[0].tirn;
1465         mlx5e_set_ttc_ft_params(&ttc_params);
1466         for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
1467                 ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;
1468
1469         err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
1470         if (err) {
1471                 netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n", err);
1472                 return err;
1473         }
1474         return 0;
1475 }
1476
1477 static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
1478 {
1479         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
1480         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1481         struct mlx5_eswitch_rep *rep = rpriv->rep;
1482         struct mlx5_flow_handle *flow_rule;
1483         struct mlx5_flow_destination dest;
1484
1485         dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1486         dest.tir_num = priv->direct_tir[0].tirn;
1487         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
1488                                                       rep->vport,
1489                                                       &dest);
1490         if (IS_ERR(flow_rule))
1491                 return PTR_ERR(flow_rule);
1492         rpriv->vport_rx_rule = flow_rule;
1493         return 0;
1494 }
1495
1496 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
1497 {
1498         struct mlx5_core_dev *mdev = priv->mdev;
1499         int err;
1500
1501         mlx5e_init_l2_addr(priv);
1502
1503         err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
1504         if (err) {
1505                 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
1506                 return err;
1507         }
1508
1509         err = mlx5e_create_indirect_rqt(priv);
1510         if (err)
1511                 goto err_close_drop_rq;
1512
1513         err = mlx5e_create_direct_rqts(priv);
1514         if (err)
1515                 goto err_destroy_indirect_rqts;
1516
1517         err = mlx5e_create_indirect_tirs(priv, false);
1518         if (err)
1519                 goto err_destroy_direct_rqts;
1520
1521         err = mlx5e_create_direct_tirs(priv);
1522         if (err)
1523                 goto err_destroy_indirect_tirs;
1524
1525         err = mlx5e_create_rep_ttc_table(priv);
1526         if (err)
1527                 goto err_destroy_direct_tirs;
1528
1529         err = mlx5e_create_rep_vport_rx_rule(priv);
1530         if (err)
1531                 goto err_destroy_ttc_table;
1532
1533         return 0;
1534
1535 err_destroy_ttc_table:
1536         mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
1537 err_destroy_direct_tirs:
1538         mlx5e_destroy_direct_tirs(priv);
1539 err_destroy_indirect_tirs:
1540         mlx5e_destroy_indirect_tirs(priv, false);
1541 err_destroy_direct_rqts:
1542         mlx5e_destroy_direct_rqts(priv);
1543 err_destroy_indirect_rqts:
1544         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
1545 err_close_drop_rq:
1546         mlx5e_close_drop_rq(&priv->drop_rq);
1547         return err;
1548 }
1549
1550 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
1551 {
1552         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1553
1554         mlx5_del_flow_rules(rpriv->vport_rx_rule);
1555         mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
1556         mlx5e_destroy_direct_tirs(priv);
1557         mlx5e_destroy_indirect_tirs(priv, false);
1558         mlx5e_destroy_direct_rqts(priv);
1559         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
1560         mlx5e_close_drop_rq(&priv->drop_rq);
1561 }
1562
1563 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
1564 {
1565         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1566         struct mlx5_rep_uplink_priv *uplink_priv;
1567         int tc, err;
1568
1569         err = mlx5e_create_tises(priv);
1570         if (err) {
1571                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
1572                 return err;
1573         }
1574
1575         if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
1576                 uplink_priv = &rpriv->uplink_priv;
1577
1578                 INIT_LIST_HEAD(&uplink_priv->unready_flows);
1579
1580                 /* init shared tc flow table */
1581                 err = mlx5e_tc_esw_init(&uplink_priv->tc_ht);
1582                 if (err)
1583                         goto destroy_tises;
1584
1585                 mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
1586
1587                 /* init indirect block notifications */
1588                 INIT_LIST_HEAD(&uplink_priv->tc_indr_block_priv_list);
1589                 uplink_priv->netdevice_nb.notifier_call = mlx5e_nic_rep_netdevice_event;
1590                 err = register_netdevice_notifier(&uplink_priv->netdevice_nb);
1591                 if (err) {
1592                         mlx5_core_err(priv->mdev, "Failed to register netdev notifier\n");
1593                         goto tc_esw_cleanup;
1594                 }
1595         }
1596
1597         return 0;
1598
1599 tc_esw_cleanup:
1600         mlx5e_tc_esw_cleanup(&uplink_priv->tc_ht);
1601 destroy_tises:
1602         for (tc = 0; tc < priv->profile->max_tc; tc++)
1603                 mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
1604         return err;
1605 }
1606
1607 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
1608 {
1609         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1610         int tc;
1611
1612         for (tc = 0; tc < priv->profile->max_tc; tc++)
1613                 mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
1614
1615         if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
1616                 /* clean indirect TC block notifications */
1617                 unregister_netdevice_notifier(&rpriv->uplink_priv.netdevice_nb);
1618                 mlx5e_rep_indr_clean_block_privs(rpriv);
1619
1620                 /* delete shared tc flow table */
1621                 mlx5e_tc_esw_cleanup(&rpriv->uplink_priv.tc_ht);
1622         }
1623 }
1624
1625 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
1626 {
1627         mlx5e_set_netdev_mtu_boundaries(priv);
1628 }
1629
1630 static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
1631 {
1632         return 0;
1633 }
1634
1635 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
1636 {
1637         struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
1638
1639         if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
1640                 struct mlx5_eqe *eqe = data;
1641
1642                 switch (eqe->sub_type) {
1643                 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
1644                 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
1645                         queue_work(priv->wq, &priv->update_carrier_work);
1646                         break;
1647                 default:
1648                         return NOTIFY_DONE;
1649                 }
1650
1651                 return NOTIFY_OK;
1652         }
1653
1654         if (event == MLX5_DEV_EVENT_PORT_AFFINITY) {
1655                 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1656
1657                 queue_work(priv->wq, &rpriv->uplink_priv.reoffload_flows_work);
1658
1659                 return NOTIFY_OK;
1660         }
1661
1662         return NOTIFY_DONE;
1663 }
1664
1665 static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
1666 {
1667         struct net_device *netdev = priv->netdev;
1668         struct mlx5_core_dev *mdev = priv->mdev;
1669         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1670         u16 max_mtu;
1671
1672         netdev->min_mtu = ETH_MIN_MTU;
1673         mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
1674         netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
1675         mlx5e_set_dev_port_mtu(priv);
1676
1677         INIT_WORK(&rpriv->uplink_priv.reoffload_flows_work,
1678                   mlx5e_tc_reoffload_flows_work);
1679
1680         mlx5_lag_add(mdev, netdev);
1681         priv->events_nb.notifier_call = uplink_rep_async_event;
1682         mlx5_notifier_register(mdev, &priv->events_nb);
1683 #ifdef CONFIG_MLX5_CORE_EN_DCB
1684         mlx5e_dcbnl_initialize(priv);
1685         mlx5e_dcbnl_init_app(priv);
1686 #endif
1687 }
1688
1689 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1690 {
1691         struct mlx5_core_dev *mdev = priv->mdev;
1692         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1693
1694 #ifdef CONFIG_MLX5_CORE_EN_DCB
1695         mlx5e_dcbnl_delete_app(priv);
1696 #endif
1697         mlx5_notifier_unregister(mdev, &priv->events_nb);
1698         cancel_work_sync(&rpriv->uplink_priv.reoffload_flows_work);
1699         mlx5_lag_remove(mdev);
1700 }
1701
1702 static const struct mlx5e_profile mlx5e_rep_profile = {
1703         .init                   = mlx5e_init_rep,
1704         .cleanup                = mlx5e_cleanup_rep,
1705         .init_rx                = mlx5e_init_rep_rx,
1706         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1707         .init_tx                = mlx5e_init_rep_tx,
1708         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1709         .enable                 = mlx5e_rep_enable,
1710         .update_rx              = mlx5e_update_rep_rx,
1711         .update_stats           = mlx5e_rep_update_hw_counters,
1712         .rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe_rep,
1713         .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
1714         .max_tc                 = 1,
1715 };
1716
1717 static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1718         .init                   = mlx5e_init_rep,
1719         .cleanup                = mlx5e_cleanup_rep,
1720         .init_rx                = mlx5e_init_rep_rx,
1721         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1722         .init_tx                = mlx5e_init_rep_tx,
1723         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1724         .enable                 = mlx5e_uplink_rep_enable,
1725         .disable                = mlx5e_uplink_rep_disable,
1726         .update_rx              = mlx5e_update_rep_rx,
1727         .update_stats           = mlx5e_uplink_rep_update_hw_counters,
1728         .update_carrier         = mlx5e_update_carrier,
1729         .rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe_rep,
1730         .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
1731         .max_tc                 = MLX5E_MAX_NUM_TC,
1732 };
1733
1734 /* e-Switch vport representors */
1735 static int
1736 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1737 {
1738         const struct mlx5e_profile *profile;
1739         struct mlx5e_rep_priv *rpriv;
1740         struct net_device *netdev;
1741         int nch, err;
1742
1743         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1744         if (!rpriv)
1745                 return -ENOMEM;
1746
1747         /* rpriv->rep to be looked up when profile->init() is called */
1748         rpriv->rep = rep;
1749
1750         nch = mlx5e_get_max_num_channels(dev);
1751         profile = (rep->vport == MLX5_VPORT_UPLINK) ?
1752                   &mlx5e_uplink_rep_profile : &mlx5e_rep_profile;
1753         netdev = mlx5e_create_netdev(dev, profile, nch, rpriv);
1754         if (!netdev) {
1755                 pr_warn("Failed to create representor netdev for vport %d\n",
1756                         rep->vport);
1757                 kfree(rpriv);
1758                 return -EINVAL;
1759         }
1760
1761         rpriv->netdev = netdev;
1762         rep->rep_data[REP_ETH].priv = rpriv;
1763         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1764
1765         if (rep->vport == MLX5_VPORT_UPLINK) {
1766                 err = mlx5e_create_mdev_resources(dev);
1767                 if (err)
1768                         goto err_destroy_netdev;
1769         }
1770
1771         err = mlx5e_attach_netdev(netdev_priv(netdev));
1772         if (err) {
1773                 pr_warn("Failed to attach representor netdev for vport %d\n",
1774                         rep->vport);
1775                 goto err_destroy_mdev_resources;
1776         }
1777
1778         err = mlx5e_rep_neigh_init(rpriv);
1779         if (err) {
1780                 pr_warn("Failed to initialized neighbours handling for vport %d\n",
1781                         rep->vport);
1782                 goto err_detach_netdev;
1783         }
1784
1785         err = register_netdev(netdev);
1786         if (err) {
1787                 pr_warn("Failed to register representor netdev for vport %d\n",
1788                         rep->vport);
1789                 goto err_neigh_cleanup;
1790         }
1791
1792         return 0;
1793
1794 err_neigh_cleanup:
1795         mlx5e_rep_neigh_cleanup(rpriv);
1796
1797 err_detach_netdev:
1798         mlx5e_detach_netdev(netdev_priv(netdev));
1799
1800 err_destroy_mdev_resources:
1801         if (rep->vport == MLX5_VPORT_UPLINK)
1802                 mlx5e_destroy_mdev_resources(dev);
1803
1804 err_destroy_netdev:
1805         mlx5e_destroy_netdev(netdev_priv(netdev));
1806         kfree(rpriv);
1807         return err;
1808 }
1809
1810 static void
1811 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1812 {
1813         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1814         struct net_device *netdev = rpriv->netdev;
1815         struct mlx5e_priv *priv = netdev_priv(netdev);
1816         void *ppriv = priv->ppriv;
1817
1818         unregister_netdev(netdev);
1819         mlx5e_rep_neigh_cleanup(rpriv);
1820         mlx5e_detach_netdev(priv);
1821         if (rep->vport == MLX5_VPORT_UPLINK)
1822                 mlx5e_destroy_mdev_resources(priv->mdev);
1823         mlx5e_destroy_netdev(priv);
1824         kfree(ppriv); /* mlx5e_rep_priv */
1825 }
1826
1827 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1828 {
1829         struct mlx5e_rep_priv *rpriv;
1830
1831         rpriv = mlx5e_rep_to_rep_priv(rep);
1832
1833         return rpriv->netdev;
1834 }
1835
1836 static const struct mlx5_eswitch_rep_ops rep_ops = {
1837         .load = mlx5e_vport_rep_load,
1838         .unload = mlx5e_vport_rep_unload,
1839         .get_proto_dev = mlx5e_vport_rep_get_proto_dev
1840 };
1841
1842 void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev)
1843 {
1844         struct mlx5_eswitch *esw = mdev->priv.eswitch;
1845
1846         mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1847 }
1848
1849 void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev)
1850 {
1851         struct mlx5_eswitch *esw = mdev->priv.eswitch;
1852
1853         mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
1854 }