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