net/mlx5e: Offload TC eswitch rules for VFs belonging to different PFs
[sfrench/cifs-2.6.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 "fs_core.h"
46
47 #define MLX5E_REP_PARAMS_LOG_SQ_SIZE \
48         max(0x6, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
49 #define MLX5E_REP_PARAMS_LOG_RQ_SIZE \
50         max(0x6, MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)
51
52 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
53
54 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
55                                   struct ethtool_drvinfo *drvinfo)
56 {
57         strlcpy(drvinfo->driver, mlx5e_rep_driver_name,
58                 sizeof(drvinfo->driver));
59         strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
60 }
61
62 static const struct counter_desc sw_rep_stats_desc[] = {
63         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
64         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
65         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
66         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
67 };
68
69 #define NUM_VPORT_REP_COUNTERS  ARRAY_SIZE(sw_rep_stats_desc)
70
71 static void mlx5e_rep_get_strings(struct net_device *dev,
72                                   u32 stringset, uint8_t *data)
73 {
74         int i;
75
76         switch (stringset) {
77         case ETH_SS_STATS:
78                 for (i = 0; i < NUM_VPORT_REP_COUNTERS; i++)
79                         strcpy(data + (i * ETH_GSTRING_LEN),
80                                sw_rep_stats_desc[i].format);
81                 break;
82         }
83 }
84
85 static void mlx5e_rep_update_hw_counters(struct mlx5e_priv *priv)
86 {
87         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
88         struct mlx5e_rep_priv *rpriv = priv->ppriv;
89         struct mlx5_eswitch_rep *rep = rpriv->rep;
90         struct rtnl_link_stats64 *vport_stats;
91         struct ifla_vf_stats vf_stats;
92         int err;
93
94         err = mlx5_eswitch_get_vport_stats(esw, rep->vport, &vf_stats);
95         if (err) {
96                 pr_warn("vport %d error %d reading stats\n", rep->vport, err);
97                 return;
98         }
99
100         vport_stats = &priv->stats.vf_vport;
101         /* flip tx/rx as we are reporting the counters for the switch vport */
102         vport_stats->rx_packets = vf_stats.tx_packets;
103         vport_stats->rx_bytes   = vf_stats.tx_bytes;
104         vport_stats->tx_packets = vf_stats.rx_packets;
105         vport_stats->tx_bytes   = vf_stats.rx_bytes;
106 }
107
108 static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
109 {
110         struct mlx5e_sw_stats *s = &priv->stats.sw;
111         struct mlx5e_rq_stats *rq_stats;
112         struct mlx5e_sq_stats *sq_stats;
113         int i, j;
114
115         memset(s, 0, sizeof(*s));
116         for (i = 0; i < priv->channels.num; i++) {
117                 struct mlx5e_channel *c = priv->channels.c[i];
118
119                 rq_stats = &c->rq.stats;
120
121                 s->rx_packets   += rq_stats->packets;
122                 s->rx_bytes     += rq_stats->bytes;
123
124                 for (j = 0; j < priv->channels.params.num_tc; j++) {
125                         sq_stats = &c->sq[j].stats;
126
127                         s->tx_packets           += sq_stats->packets;
128                         s->tx_bytes             += sq_stats->bytes;
129                 }
130         }
131 }
132
133 static void mlx5e_rep_update_stats(struct mlx5e_priv *priv)
134 {
135         mlx5e_rep_update_sw_counters(priv);
136         mlx5e_rep_update_hw_counters(priv);
137 }
138
139 static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
140                                         struct ethtool_stats *stats, u64 *data)
141 {
142         struct mlx5e_priv *priv = netdev_priv(dev);
143         int i;
144
145         if (!data)
146                 return;
147
148         mutex_lock(&priv->state_lock);
149         if (test_bit(MLX5E_STATE_OPENED, &priv->state))
150                 mlx5e_rep_update_sw_counters(priv);
151         mutex_unlock(&priv->state_lock);
152
153         for (i = 0; i < NUM_VPORT_REP_COUNTERS; i++)
154                 data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
155                                                sw_rep_stats_desc, i);
156 }
157
158 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
159 {
160         switch (sset) {
161         case ETH_SS_STATS:
162                 return NUM_VPORT_REP_COUNTERS;
163         default:
164                 return -EOPNOTSUPP;
165         }
166 }
167
168 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
169         .get_drvinfo       = mlx5e_rep_get_drvinfo,
170         .get_link          = ethtool_op_get_link,
171         .get_strings       = mlx5e_rep_get_strings,
172         .get_sset_count    = mlx5e_rep_get_sset_count,
173         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
174 };
175
176 int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr)
177 {
178         struct mlx5e_priv *priv = netdev_priv(dev);
179         struct mlx5e_rep_priv *rpriv = priv->ppriv;
180         struct mlx5_eswitch_rep *rep = rpriv->rep;
181         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
182
183         if (esw->mode == SRIOV_NONE)
184                 return -EOPNOTSUPP;
185
186         switch (attr->id) {
187         case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
188                 attr->u.ppid.id_len = ETH_ALEN;
189                 ether_addr_copy(attr->u.ppid.id, rep->hw_id);
190                 break;
191         default:
192                 return -EOPNOTSUPP;
193         }
194
195         return 0;
196 }
197
198 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
199                                  struct mlx5_eswitch_rep *rep)
200 {
201         struct mlx5e_rep_sq *rep_sq, *tmp;
202         struct mlx5e_rep_priv *rpriv;
203
204         if (esw->mode != SRIOV_OFFLOADS)
205                 return;
206
207         rpriv = mlx5e_rep_to_rep_priv(rep);
208         list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) {
209                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
210                 list_del(&rep_sq->list);
211                 kfree(rep_sq);
212         }
213 }
214
215 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
216                                  struct mlx5_eswitch_rep *rep,
217                                  u32 *sqns_array, int sqns_num)
218 {
219         struct mlx5_flow_handle *flow_rule;
220         struct mlx5e_rep_priv *rpriv;
221         struct mlx5e_rep_sq *rep_sq;
222         int err;
223         int i;
224
225         if (esw->mode != SRIOV_OFFLOADS)
226                 return 0;
227
228         rpriv = mlx5e_rep_to_rep_priv(rep);
229         for (i = 0; i < sqns_num; i++) {
230                 rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL);
231                 if (!rep_sq) {
232                         err = -ENOMEM;
233                         goto out_err;
234                 }
235
236                 /* Add re-inject rule to the PF/representor sqs */
237                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw,
238                                                                 rep->vport,
239                                                                 sqns_array[i]);
240                 if (IS_ERR(flow_rule)) {
241                         err = PTR_ERR(flow_rule);
242                         kfree(rep_sq);
243                         goto out_err;
244                 }
245                 rep_sq->send_to_vport_rule = flow_rule;
246                 list_add(&rep_sq->list, &rpriv->vport_sqs_list);
247         }
248         return 0;
249
250 out_err:
251         mlx5e_sqs2vport_stop(esw, rep);
252         return err;
253 }
254
255 int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
256 {
257         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
258         struct mlx5e_rep_priv *rpriv = priv->ppriv;
259         struct mlx5_eswitch_rep *rep = rpriv->rep;
260         struct mlx5e_channel *c;
261         int n, tc, num_sqs = 0;
262         int err = -ENOMEM;
263         u32 *sqs;
264
265         sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(*sqs), GFP_KERNEL);
266         if (!sqs)
267                 goto out;
268
269         for (n = 0; n < priv->channels.num; n++) {
270                 c = priv->channels.c[n];
271                 for (tc = 0; tc < c->num_tc; tc++)
272                         sqs[num_sqs++] = c->sq[tc].sqn;
273         }
274
275         err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs);
276         kfree(sqs);
277
278 out:
279         if (err)
280                 netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
281         return err;
282 }
283
284 void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
285 {
286         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
287         struct mlx5e_rep_priv *rpriv = priv->ppriv;
288         struct mlx5_eswitch_rep *rep = rpriv->rep;
289
290         mlx5e_sqs2vport_stop(esw, rep);
291 }
292
293 static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv)
294 {
295 #if IS_ENABLED(CONFIG_IPV6)
296         unsigned long ipv6_interval = NEIGH_VAR(&nd_tbl.parms,
297                                                 DELAY_PROBE_TIME);
298 #else
299         unsigned long ipv6_interval = ~0UL;
300 #endif
301         unsigned long ipv4_interval = NEIGH_VAR(&arp_tbl.parms,
302                                                 DELAY_PROBE_TIME);
303         struct net_device *netdev = rpriv->netdev;
304         struct mlx5e_priv *priv = netdev_priv(netdev);
305
306         rpriv->neigh_update.min_interval = min_t(unsigned long, ipv6_interval, ipv4_interval);
307         mlx5_fc_update_sampling_interval(priv->mdev, rpriv->neigh_update.min_interval);
308 }
309
310 void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv)
311 {
312         struct mlx5e_rep_priv *rpriv = priv->ppriv;
313         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
314
315         mlx5_fc_queue_stats_work(priv->mdev,
316                                  &neigh_update->neigh_stats_work,
317                                  neigh_update->min_interval);
318 }
319
320 static void mlx5e_rep_neigh_stats_work(struct work_struct *work)
321 {
322         struct mlx5e_rep_priv *rpriv = container_of(work, struct mlx5e_rep_priv,
323                                                     neigh_update.neigh_stats_work.work);
324         struct net_device *netdev = rpriv->netdev;
325         struct mlx5e_priv *priv = netdev_priv(netdev);
326         struct mlx5e_neigh_hash_entry *nhe;
327
328         rtnl_lock();
329         if (!list_empty(&rpriv->neigh_update.neigh_list))
330                 mlx5e_rep_queue_neigh_stats_work(priv);
331
332         list_for_each_entry(nhe, &rpriv->neigh_update.neigh_list, neigh_list)
333                 mlx5e_tc_update_neigh_used_value(nhe);
334
335         rtnl_unlock();
336 }
337
338 static void mlx5e_rep_neigh_entry_hold(struct mlx5e_neigh_hash_entry *nhe)
339 {
340         refcount_inc(&nhe->refcnt);
341 }
342
343 static void mlx5e_rep_neigh_entry_release(struct mlx5e_neigh_hash_entry *nhe)
344 {
345         if (refcount_dec_and_test(&nhe->refcnt))
346                 kfree(nhe);
347 }
348
349 static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
350                                    struct mlx5e_encap_entry *e,
351                                    bool neigh_connected,
352                                    unsigned char ha[ETH_ALEN])
353 {
354         struct ethhdr *eth = (struct ethhdr *)e->encap_header;
355
356         ASSERT_RTNL();
357
358         if ((!neigh_connected && (e->flags & MLX5_ENCAP_ENTRY_VALID)) ||
359             !ether_addr_equal(e->h_dest, ha))
360                 mlx5e_tc_encap_flows_del(priv, e);
361
362         if (neigh_connected && !(e->flags & MLX5_ENCAP_ENTRY_VALID)) {
363                 ether_addr_copy(e->h_dest, ha);
364                 ether_addr_copy(eth->h_dest, ha);
365
366                 mlx5e_tc_encap_flows_add(priv, e);
367         }
368 }
369
370 static void mlx5e_rep_neigh_update(struct work_struct *work)
371 {
372         struct mlx5e_neigh_hash_entry *nhe =
373                 container_of(work, struct mlx5e_neigh_hash_entry, neigh_update_work);
374         struct neighbour *n = nhe->n;
375         struct mlx5e_encap_entry *e;
376         unsigned char ha[ETH_ALEN];
377         struct mlx5e_priv *priv;
378         bool neigh_connected;
379         bool encap_connected;
380         u8 nud_state, dead;
381
382         rtnl_lock();
383
384         /* If these parameters are changed after we release the lock,
385          * we'll receive another event letting us know about it.
386          * We use this lock to avoid inconsistency between the neigh validity
387          * and it's hw address.
388          */
389         read_lock_bh(&n->lock);
390         memcpy(ha, n->ha, ETH_ALEN);
391         nud_state = n->nud_state;
392         dead = n->dead;
393         read_unlock_bh(&n->lock);
394
395         neigh_connected = (nud_state & NUD_VALID) && !dead;
396
397         list_for_each_entry(e, &nhe->encap_list, encap_list) {
398                 encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
399                 priv = netdev_priv(e->out_dev);
400
401                 if (encap_connected != neigh_connected ||
402                     !ether_addr_equal(e->h_dest, ha))
403                         mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
404         }
405         mlx5e_rep_neigh_entry_release(nhe);
406         rtnl_unlock();
407         neigh_release(n);
408 }
409
410 static struct mlx5e_neigh_hash_entry *
411 mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
412                              struct mlx5e_neigh *m_neigh);
413
414 static int mlx5e_rep_netevent_event(struct notifier_block *nb,
415                                     unsigned long event, void *ptr)
416 {
417         struct mlx5e_rep_priv *rpriv = container_of(nb, struct mlx5e_rep_priv,
418                                                     neigh_update.netevent_nb);
419         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
420         struct net_device *netdev = rpriv->netdev;
421         struct mlx5e_priv *priv = netdev_priv(netdev);
422         struct mlx5e_neigh_hash_entry *nhe = NULL;
423         struct mlx5e_neigh m_neigh = {};
424         struct neigh_parms *p;
425         struct neighbour *n;
426         bool found = false;
427
428         switch (event) {
429         case NETEVENT_NEIGH_UPDATE:
430                 n = ptr;
431 #if IS_ENABLED(CONFIG_IPV6)
432                 if (n->tbl != &nd_tbl && n->tbl != &arp_tbl)
433 #else
434                 if (n->tbl != &arp_tbl)
435 #endif
436                         return NOTIFY_DONE;
437
438                 m_neigh.dev = n->dev;
439                 m_neigh.family = n->ops->family;
440                 memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
441
442                 /* We are in atomic context and can't take RTNL mutex, so use
443                  * spin_lock_bh to lookup the neigh table. bh is used since
444                  * netevent can be called from a softirq context.
445                  */
446                 spin_lock_bh(&neigh_update->encap_lock);
447                 nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
448                 if (!nhe) {
449                         spin_unlock_bh(&neigh_update->encap_lock);
450                         return NOTIFY_DONE;
451                 }
452
453                 /* This assignment is valid as long as the the neigh reference
454                  * is taken
455                  */
456                 nhe->n = n;
457
458                 /* Take a reference to ensure the neighbour and mlx5 encap
459                  * entry won't be destructed until we drop the reference in
460                  * delayed work.
461                  */
462                 neigh_hold(n);
463                 mlx5e_rep_neigh_entry_hold(nhe);
464
465                 if (!queue_work(priv->wq, &nhe->neigh_update_work)) {
466                         mlx5e_rep_neigh_entry_release(nhe);
467                         neigh_release(n);
468                 }
469                 spin_unlock_bh(&neigh_update->encap_lock);
470                 break;
471
472         case NETEVENT_DELAY_PROBE_TIME_UPDATE:
473                 p = ptr;
474
475                 /* We check the device is present since we don't care about
476                  * changes in the default table, we only care about changes
477                  * done per device delay prob time parameter.
478                  */
479 #if IS_ENABLED(CONFIG_IPV6)
480                 if (!p->dev || (p->tbl != &nd_tbl && p->tbl != &arp_tbl))
481 #else
482                 if (!p->dev || p->tbl != &arp_tbl)
483 #endif
484                         return NOTIFY_DONE;
485
486                 /* We are in atomic context and can't take RTNL mutex,
487                  * so use spin_lock_bh to walk the neigh list and look for
488                  * the relevant device. bh is used since netevent can be
489                  * called from a softirq context.
490                  */
491                 spin_lock_bh(&neigh_update->encap_lock);
492                 list_for_each_entry(nhe, &neigh_update->neigh_list, neigh_list) {
493                         if (p->dev == nhe->m_neigh.dev) {
494                                 found = true;
495                                 break;
496                         }
497                 }
498                 spin_unlock_bh(&neigh_update->encap_lock);
499                 if (!found)
500                         return NOTIFY_DONE;
501
502                 neigh_update->min_interval = min_t(unsigned long,
503                                                    NEIGH_VAR(p, DELAY_PROBE_TIME),
504                                                    neigh_update->min_interval);
505                 mlx5_fc_update_sampling_interval(priv->mdev,
506                                                  neigh_update->min_interval);
507                 break;
508         }
509         return NOTIFY_DONE;
510 }
511
512 static const struct rhashtable_params mlx5e_neigh_ht_params = {
513         .head_offset = offsetof(struct mlx5e_neigh_hash_entry, rhash_node),
514         .key_offset = offsetof(struct mlx5e_neigh_hash_entry, m_neigh),
515         .key_len = sizeof(struct mlx5e_neigh),
516         .automatic_shrinking = true,
517 };
518
519 static int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv)
520 {
521         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
522         int err;
523
524         err = rhashtable_init(&neigh_update->neigh_ht, &mlx5e_neigh_ht_params);
525         if (err)
526                 return err;
527
528         INIT_LIST_HEAD(&neigh_update->neigh_list);
529         spin_lock_init(&neigh_update->encap_lock);
530         INIT_DELAYED_WORK(&neigh_update->neigh_stats_work,
531                           mlx5e_rep_neigh_stats_work);
532         mlx5e_rep_neigh_update_init_interval(rpriv);
533
534         rpriv->neigh_update.netevent_nb.notifier_call = mlx5e_rep_netevent_event;
535         err = register_netevent_notifier(&rpriv->neigh_update.netevent_nb);
536         if (err)
537                 goto out_err;
538         return 0;
539
540 out_err:
541         rhashtable_destroy(&neigh_update->neigh_ht);
542         return err;
543 }
544
545 static void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv)
546 {
547         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
548         struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
549
550         unregister_netevent_notifier(&neigh_update->netevent_nb);
551
552         flush_workqueue(priv->wq); /* flush neigh update works */
553
554         cancel_delayed_work_sync(&rpriv->neigh_update.neigh_stats_work);
555
556         rhashtable_destroy(&neigh_update->neigh_ht);
557 }
558
559 static int mlx5e_rep_neigh_entry_insert(struct mlx5e_priv *priv,
560                                         struct mlx5e_neigh_hash_entry *nhe)
561 {
562         struct mlx5e_rep_priv *rpriv = priv->ppriv;
563         int err;
564
565         err = rhashtable_insert_fast(&rpriv->neigh_update.neigh_ht,
566                                      &nhe->rhash_node,
567                                      mlx5e_neigh_ht_params);
568         if (err)
569                 return err;
570
571         list_add(&nhe->neigh_list, &rpriv->neigh_update.neigh_list);
572
573         return err;
574 }
575
576 static void mlx5e_rep_neigh_entry_remove(struct mlx5e_priv *priv,
577                                          struct mlx5e_neigh_hash_entry *nhe)
578 {
579         struct mlx5e_rep_priv *rpriv = priv->ppriv;
580
581         spin_lock_bh(&rpriv->neigh_update.encap_lock);
582
583         list_del(&nhe->neigh_list);
584
585         rhashtable_remove_fast(&rpriv->neigh_update.neigh_ht,
586                                &nhe->rhash_node,
587                                mlx5e_neigh_ht_params);
588         spin_unlock_bh(&rpriv->neigh_update.encap_lock);
589 }
590
591 /* This function must only be called under RTNL lock or under the
592  * representor's encap_lock in case RTNL mutex can't be held.
593  */
594 static struct mlx5e_neigh_hash_entry *
595 mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
596                              struct mlx5e_neigh *m_neigh)
597 {
598         struct mlx5e_rep_priv *rpriv = priv->ppriv;
599         struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
600
601         return rhashtable_lookup_fast(&neigh_update->neigh_ht, m_neigh,
602                                       mlx5e_neigh_ht_params);
603 }
604
605 static int mlx5e_rep_neigh_entry_create(struct mlx5e_priv *priv,
606                                         struct mlx5e_encap_entry *e,
607                                         struct mlx5e_neigh_hash_entry **nhe)
608 {
609         int err;
610
611         *nhe = kzalloc(sizeof(**nhe), GFP_KERNEL);
612         if (!*nhe)
613                 return -ENOMEM;
614
615         memcpy(&(*nhe)->m_neigh, &e->m_neigh, sizeof(e->m_neigh));
616         INIT_WORK(&(*nhe)->neigh_update_work, mlx5e_rep_neigh_update);
617         INIT_LIST_HEAD(&(*nhe)->encap_list);
618         refcount_set(&(*nhe)->refcnt, 1);
619
620         err = mlx5e_rep_neigh_entry_insert(priv, *nhe);
621         if (err)
622                 goto out_free;
623         return 0;
624
625 out_free:
626         kfree(*nhe);
627         return err;
628 }
629
630 static void mlx5e_rep_neigh_entry_destroy(struct mlx5e_priv *priv,
631                                           struct mlx5e_neigh_hash_entry *nhe)
632 {
633         /* The neigh hash entry must be removed from the hash table regardless
634          * of the reference count value, so it won't be found by the next
635          * neigh notification call. The neigh hash entry reference count is
636          * incremented only during creation and neigh notification calls and
637          * protects from freeing the nhe struct.
638          */
639         mlx5e_rep_neigh_entry_remove(priv, nhe);
640         mlx5e_rep_neigh_entry_release(nhe);
641 }
642
643 int mlx5e_rep_encap_entry_attach(struct mlx5e_priv *priv,
644                                  struct mlx5e_encap_entry *e)
645 {
646         struct mlx5e_neigh_hash_entry *nhe;
647         int err;
648
649         nhe = mlx5e_rep_neigh_entry_lookup(priv, &e->m_neigh);
650         if (!nhe) {
651                 err = mlx5e_rep_neigh_entry_create(priv, e, &nhe);
652                 if (err)
653                         return err;
654         }
655         list_add(&e->encap_list, &nhe->encap_list);
656         return 0;
657 }
658
659 void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
660                                   struct mlx5e_encap_entry *e)
661 {
662         struct mlx5e_neigh_hash_entry *nhe;
663
664         list_del(&e->encap_list);
665         nhe = mlx5e_rep_neigh_entry_lookup(priv, &e->m_neigh);
666
667         if (list_empty(&nhe->encap_list))
668                 mlx5e_rep_neigh_entry_destroy(priv, nhe);
669 }
670
671 static int mlx5e_rep_open(struct net_device *dev)
672 {
673         struct mlx5e_priv *priv = netdev_priv(dev);
674         struct mlx5e_rep_priv *rpriv = priv->ppriv;
675         struct mlx5_eswitch_rep *rep = rpriv->rep;
676         int err;
677
678         mutex_lock(&priv->state_lock);
679         err = mlx5e_open_locked(dev);
680         if (err)
681                 goto unlock;
682
683         if (!mlx5_modify_vport_admin_state(priv->mdev,
684                                            MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
685                                            rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_UP))
686                 netif_carrier_on(dev);
687
688 unlock:
689         mutex_unlock(&priv->state_lock);
690         return err;
691 }
692
693 static int mlx5e_rep_close(struct net_device *dev)
694 {
695         struct mlx5e_priv *priv = netdev_priv(dev);
696         struct mlx5e_rep_priv *rpriv = priv->ppriv;
697         struct mlx5_eswitch_rep *rep = rpriv->rep;
698         int ret;
699
700         mutex_lock(&priv->state_lock);
701         mlx5_modify_vport_admin_state(priv->mdev,
702                                       MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
703                                       rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
704         ret = mlx5e_close_locked(dev);
705         mutex_unlock(&priv->state_lock);
706         return ret;
707 }
708
709 static int mlx5e_rep_get_phys_port_name(struct net_device *dev,
710                                         char *buf, size_t len)
711 {
712         struct mlx5e_priv *priv = netdev_priv(dev);
713         struct mlx5e_rep_priv *rpriv = priv->ppriv;
714         struct mlx5_eswitch_rep *rep = rpriv->rep;
715         int ret;
716
717         ret = snprintf(buf, len, "%d", rep->vport - 1);
718         if (ret >= len)
719                 return -EOPNOTSUPP;
720
721         return 0;
722 }
723
724 static int
725 mlx5e_rep_setup_tc_cls_flower(struct mlx5e_priv *priv,
726                               struct tc_cls_flower_offload *cls_flower)
727 {
728         switch (cls_flower->command) {
729         case TC_CLSFLOWER_REPLACE:
730                 return mlx5e_configure_flower(priv, cls_flower);
731         case TC_CLSFLOWER_DESTROY:
732                 return mlx5e_delete_flower(priv, cls_flower);
733         case TC_CLSFLOWER_STATS:
734                 return mlx5e_stats_flower(priv, cls_flower);
735         default:
736                 return -EOPNOTSUPP;
737         }
738 }
739
740 static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
741                                  void *cb_priv)
742 {
743         struct mlx5e_priv *priv = cb_priv;
744
745         if (!tc_cls_can_offload_and_chain0(priv->netdev, type_data))
746                 return -EOPNOTSUPP;
747
748         switch (type) {
749         case TC_SETUP_CLSFLOWER:
750                 return mlx5e_rep_setup_tc_cls_flower(priv, type_data);
751         default:
752                 return -EOPNOTSUPP;
753         }
754 }
755
756 static int mlx5e_rep_setup_tc_block(struct net_device *dev,
757                                     struct tc_block_offload *f)
758 {
759         struct mlx5e_priv *priv = netdev_priv(dev);
760
761         if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
762                 return -EOPNOTSUPP;
763
764         switch (f->command) {
765         case TC_BLOCK_BIND:
766                 return tcf_block_cb_register(f->block, mlx5e_rep_setup_tc_cb,
767                                              priv, priv);
768         case TC_BLOCK_UNBIND:
769                 tcf_block_cb_unregister(f->block, mlx5e_rep_setup_tc_cb, priv);
770                 return 0;
771         default:
772                 return -EOPNOTSUPP;
773         }
774 }
775
776 static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
777                               void *type_data)
778 {
779         switch (type) {
780         case TC_SETUP_BLOCK:
781                 return mlx5e_rep_setup_tc_block(dev, type_data);
782         default:
783                 return -EOPNOTSUPP;
784         }
785 }
786
787 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
788 {
789         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
790         struct mlx5e_rep_priv *rpriv = priv->ppriv;
791         struct mlx5_eswitch_rep *rep;
792
793         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
794                 return false;
795
796         rep = rpriv->rep;
797         if (esw->mode == SRIOV_OFFLOADS &&
798             rep && rep->vport == FDB_UPLINK_VPORT)
799                 return true;
800
801         return false;
802 }
803
804 static bool mlx5e_is_vf_vport_rep(struct mlx5e_priv *priv)
805 {
806         struct mlx5e_rep_priv *rpriv = priv->ppriv;
807         struct mlx5_eswitch_rep *rep = rpriv->rep;
808
809         if (rep && rep->vport != FDB_UPLINK_VPORT)
810                 return true;
811
812         return false;
813 }
814
815 bool mlx5e_has_offload_stats(const struct net_device *dev, int attr_id)
816 {
817         struct mlx5e_priv *priv = netdev_priv(dev);
818
819         switch (attr_id) {
820         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
821                 if (mlx5e_is_vf_vport_rep(priv) || mlx5e_is_uplink_rep(priv))
822                         return true;
823         }
824
825         return false;
826 }
827
828 static int
829 mlx5e_get_sw_stats64(const struct net_device *dev,
830                      struct rtnl_link_stats64 *stats)
831 {
832         struct mlx5e_priv *priv = netdev_priv(dev);
833         struct mlx5e_sw_stats *sstats = &priv->stats.sw;
834
835         stats->rx_packets = sstats->rx_packets;
836         stats->rx_bytes   = sstats->rx_bytes;
837         stats->tx_packets = sstats->tx_packets;
838         stats->tx_bytes   = sstats->tx_bytes;
839
840         stats->tx_dropped = sstats->tx_queue_dropped;
841
842         return 0;
843 }
844
845 int mlx5e_get_offload_stats(int attr_id, const struct net_device *dev,
846                             void *sp)
847 {
848         switch (attr_id) {
849         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
850                 return mlx5e_get_sw_stats64(dev, sp);
851         }
852
853         return -EINVAL;
854 }
855
856 static void
857 mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
858 {
859         struct mlx5e_priv *priv = netdev_priv(dev);
860
861         memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
862 }
863
864 static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
865         .switchdev_port_attr_get        = mlx5e_attr_get,
866 };
867
868 static const struct net_device_ops mlx5e_netdev_ops_rep = {
869         .ndo_open                = mlx5e_rep_open,
870         .ndo_stop                = mlx5e_rep_close,
871         .ndo_start_xmit          = mlx5e_xmit,
872         .ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
873         .ndo_setup_tc            = mlx5e_rep_setup_tc,
874         .ndo_get_stats64         = mlx5e_rep_get_stats,
875         .ndo_has_offload_stats   = mlx5e_has_offload_stats,
876         .ndo_get_offload_stats   = mlx5e_get_offload_stats,
877 };
878
879 static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
880                                    struct mlx5e_params *params, u16 mtu)
881 {
882         u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
883                                          MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
884                                          MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
885
886         params->hard_mtu    = MLX5E_ETH_HARD_MTU;
887         params->sw_mtu      = mtu;
888         params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE;
889         params->rq_wq_type  = MLX5_WQ_TYPE_LINKED_LIST;
890         params->log_rq_mtu_frames = MLX5E_REP_PARAMS_LOG_RQ_SIZE;
891
892         params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
893         mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
894
895         params->num_tc                = 1;
896         params->lro_wqe_sz            = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
897
898         mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
899 }
900
901 static void mlx5e_build_rep_netdev(struct net_device *netdev)
902 {
903         netdev->netdev_ops = &mlx5e_netdev_ops_rep;
904
905         netdev->watchdog_timeo    = 15 * HZ;
906
907         netdev->ethtool_ops       = &mlx5e_rep_ethtool_ops;
908
909         netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
910
911         netdev->features         |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
912         netdev->hw_features      |= NETIF_F_HW_TC;
913
914         eth_hw_addr_random(netdev);
915 }
916
917 static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
918                            struct net_device *netdev,
919                            const struct mlx5e_profile *profile,
920                            void *ppriv)
921 {
922         struct mlx5e_priv *priv = netdev_priv(netdev);
923
924         priv->mdev                         = mdev;
925         priv->netdev                       = netdev;
926         priv->profile                      = profile;
927         priv->ppriv                        = ppriv;
928
929         mutex_init(&priv->state_lock);
930
931         INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
932
933         priv->channels.params.num_channels = profile->max_nch(mdev);
934
935         mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu);
936         mlx5e_build_rep_netdev(netdev);
937
938         mlx5e_timestamp_init(priv);
939 }
940
941 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
942 {
943         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
944         struct mlx5e_rep_priv *rpriv = priv->ppriv;
945         struct mlx5_eswitch_rep *rep = rpriv->rep;
946         struct mlx5_flow_handle *flow_rule;
947         int err;
948
949         mlx5e_init_l2_addr(priv);
950
951         err = mlx5e_create_direct_rqts(priv);
952         if (err)
953                 return err;
954
955         err = mlx5e_create_direct_tirs(priv);
956         if (err)
957                 goto err_destroy_direct_rqts;
958
959         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
960                                                       rep->vport,
961                                                       priv->direct_tir[0].tirn);
962         if (IS_ERR(flow_rule)) {
963                 err = PTR_ERR(flow_rule);
964                 goto err_destroy_direct_tirs;
965         }
966         rpriv->vport_rx_rule = flow_rule;
967
968         err = mlx5e_tc_init(priv);
969         if (err)
970                 goto err_del_flow_rule;
971
972         return 0;
973
974 err_del_flow_rule:
975         mlx5_del_flow_rules(rpriv->vport_rx_rule);
976 err_destroy_direct_tirs:
977         mlx5e_destroy_direct_tirs(priv);
978 err_destroy_direct_rqts:
979         mlx5e_destroy_direct_rqts(priv);
980         return err;
981 }
982
983 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
984 {
985         struct mlx5e_rep_priv *rpriv = priv->ppriv;
986
987         mlx5e_tc_cleanup(priv);
988         mlx5_del_flow_rules(rpriv->vport_rx_rule);
989         mlx5e_destroy_direct_tirs(priv);
990         mlx5e_destroy_direct_rqts(priv);
991 }
992
993 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
994 {
995         int err;
996
997         err = mlx5e_create_tises(priv);
998         if (err) {
999                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
1000                 return err;
1001         }
1002         return 0;
1003 }
1004
1005 static int mlx5e_get_rep_max_num_channels(struct mlx5_core_dev *mdev)
1006 {
1007 #define MLX5E_PORT_REPRESENTOR_NCH 1
1008         return MLX5E_PORT_REPRESENTOR_NCH;
1009 }
1010
1011 static const struct mlx5e_profile mlx5e_rep_profile = {
1012         .init                   = mlx5e_init_rep,
1013         .init_rx                = mlx5e_init_rep_rx,
1014         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1015         .init_tx                = mlx5e_init_rep_tx,
1016         .cleanup_tx             = mlx5e_cleanup_nic_tx,
1017         .update_stats           = mlx5e_rep_update_stats,
1018         .max_nch                = mlx5e_get_rep_max_num_channels,
1019         .update_carrier         = NULL,
1020         .rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe_rep,
1021         .rx_handlers.handle_rx_cqe_mpwqe = NULL /* Not supported */,
1022         .max_tc                 = 1,
1023 };
1024
1025 /* e-Switch vport representors */
1026
1027 static int
1028 mlx5e_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1029 {
1030         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1031         struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
1032
1033         int err;
1034
1035         if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1036                 err = mlx5e_add_sqs_fwd_rules(priv);
1037                 if (err)
1038                         return err;
1039         }
1040
1041         err = mlx5e_rep_neigh_init(rpriv);
1042         if (err)
1043                 goto err_remove_sqs;
1044
1045         return 0;
1046
1047 err_remove_sqs:
1048         mlx5e_remove_sqs_fwd_rules(priv);
1049         return err;
1050 }
1051
1052 static void
1053 mlx5e_nic_rep_unload(struct mlx5_eswitch_rep *rep)
1054 {
1055         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1056         struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
1057
1058         if (test_bit(MLX5E_STATE_OPENED, &priv->state))
1059                 mlx5e_remove_sqs_fwd_rules(priv);
1060
1061         /* clean (and re-init) existing uplink offloaded TC rules */
1062         mlx5e_tc_cleanup(priv);
1063         mlx5e_tc_init(priv);
1064
1065         mlx5e_rep_neigh_cleanup(rpriv);
1066 }
1067
1068 static int
1069 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1070 {
1071         struct mlx5e_rep_priv *uplink_rpriv;
1072         struct mlx5e_rep_priv *rpriv;
1073         struct net_device *netdev;
1074         struct mlx5e_priv *upriv;
1075         int err;
1076
1077         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1078         if (!rpriv)
1079                 return -ENOMEM;
1080
1081         netdev = mlx5e_create_netdev(dev, &mlx5e_rep_profile, rpriv);
1082         if (!netdev) {
1083                 pr_warn("Failed to create representor netdev for vport %d\n",
1084                         rep->vport);
1085                 kfree(rpriv);
1086                 return -EINVAL;
1087         }
1088
1089         rpriv->netdev = netdev;
1090         rpriv->rep = rep;
1091         rep->rep_if[REP_ETH].priv = rpriv;
1092         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1093
1094         err = mlx5e_attach_netdev(netdev_priv(netdev));
1095         if (err) {
1096                 pr_warn("Failed to attach representor netdev for vport %d\n",
1097                         rep->vport);
1098                 goto err_destroy_netdev;
1099         }
1100
1101         err = mlx5e_rep_neigh_init(rpriv);
1102         if (err) {
1103                 pr_warn("Failed to initialized neighbours handling for vport %d\n",
1104                         rep->vport);
1105                 goto err_detach_netdev;
1106         }
1107
1108         uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch, REP_ETH);
1109         upriv = netdev_priv(uplink_rpriv->netdev);
1110         err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb,
1111                                          upriv);
1112         if (err)
1113                 goto err_neigh_cleanup;
1114
1115         err = register_netdev(netdev);
1116         if (err) {
1117                 pr_warn("Failed to register representor netdev for vport %d\n",
1118                         rep->vport);
1119                 goto err_egdev_cleanup;
1120         }
1121
1122         return 0;
1123
1124 err_egdev_cleanup:
1125         tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb,
1126                                      upriv);
1127
1128 err_neigh_cleanup:
1129         mlx5e_rep_neigh_cleanup(rpriv);
1130
1131 err_detach_netdev:
1132         mlx5e_detach_netdev(netdev_priv(netdev));
1133
1134 err_destroy_netdev:
1135         mlx5e_destroy_netdev(netdev_priv(netdev));
1136         kfree(rpriv);
1137         return err;
1138 }
1139
1140 static void
1141 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1142 {
1143         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1144         struct net_device *netdev = rpriv->netdev;
1145         struct mlx5e_priv *priv = netdev_priv(netdev);
1146         struct mlx5e_rep_priv *uplink_rpriv;
1147         void *ppriv = priv->ppriv;
1148         struct mlx5e_priv *upriv;
1149
1150         unregister_netdev(netdev);
1151         uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch,
1152                                                     REP_ETH);
1153         upriv = netdev_priv(uplink_rpriv->netdev);
1154         tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb,
1155                                      upriv);
1156         mlx5e_rep_neigh_cleanup(rpriv);
1157         mlx5e_detach_netdev(priv);
1158         mlx5e_destroy_netdev(priv);
1159         kfree(ppriv); /* mlx5e_rep_priv */
1160 }
1161
1162 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1163 {
1164         struct mlx5e_rep_priv *rpriv;
1165
1166         rpriv = mlx5e_rep_to_rep_priv(rep);
1167
1168         return rpriv->netdev;
1169 }
1170
1171 static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv)
1172 {
1173         struct mlx5_core_dev *mdev = priv->mdev;
1174         struct mlx5_eswitch *esw   = mdev->priv.eswitch;
1175         int total_vfs = MLX5_TOTAL_VPORTS(mdev);
1176         int vport;
1177
1178         for (vport = 1; vport < total_vfs; vport++) {
1179                 struct mlx5_eswitch_rep_if rep_if = {};
1180
1181                 rep_if.load = mlx5e_vport_rep_load;
1182                 rep_if.unload = mlx5e_vport_rep_unload;
1183                 rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
1184                 mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH);
1185         }
1186 }
1187
1188 static void mlx5e_rep_unregister_vf_vports(struct mlx5e_priv *priv)
1189 {
1190         struct mlx5_core_dev *mdev = priv->mdev;
1191         struct mlx5_eswitch *esw = mdev->priv.eswitch;
1192         int total_vfs = MLX5_TOTAL_VPORTS(mdev);
1193         int vport;
1194
1195         for (vport = 1; vport < total_vfs; vport++)
1196                 mlx5_eswitch_unregister_vport_rep(esw, vport, REP_ETH);
1197 }
1198
1199 void mlx5e_register_vport_reps(struct mlx5e_priv *priv)
1200 {
1201         struct mlx5_core_dev *mdev = priv->mdev;
1202         struct mlx5_eswitch *esw   = mdev->priv.eswitch;
1203         struct mlx5_eswitch_rep_if rep_if;
1204         struct mlx5e_rep_priv *rpriv;
1205
1206         rpriv = priv->ppriv;
1207         rpriv->netdev = priv->netdev;
1208
1209         rep_if.load = mlx5e_nic_rep_load;
1210         rep_if.unload = mlx5e_nic_rep_unload;
1211         rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
1212         rep_if.priv = rpriv;
1213         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1214         mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_ETH); /* UPLINK PF vport*/
1215
1216         mlx5e_rep_register_vf_vports(priv); /* VFs vports */
1217 }
1218
1219 void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv)
1220 {
1221         struct mlx5_core_dev *mdev = priv->mdev;
1222         struct mlx5_eswitch *esw   = mdev->priv.eswitch;
1223
1224         mlx5e_rep_unregister_vf_vports(priv); /* VFs vports */
1225         mlx5_eswitch_unregister_vport_rep(esw, 0, REP_ETH); /* UPLINK PF*/
1226 }
1227
1228 void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev)
1229 {
1230         struct mlx5_eswitch *esw = mdev->priv.eswitch;
1231         struct mlx5e_rep_priv *rpriv;
1232
1233         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1234         if (!rpriv)
1235                 return NULL;
1236
1237         rpriv->rep = &esw->offloads.vport_reps[0];
1238         return rpriv;
1239 }