2 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
33 #include <linux/mlx5/fs.h>
34 #include <net/switchdev.h>
35 #include <net/pkt_cls.h>
36 #include <net/act_api.h>
37 #include <net/devlink.h>
38 #include <net/ipv6_stubs.h>
43 #include "en/params.h"
46 #include "en/rep/tc.h"
47 #include "en/rep/neigh.h"
48 #include "en/rep/bridge.h"
49 #include "en/devlink.h"
52 #include "lib/devcom.h"
53 #include "lib/vxlan.h"
54 #define CREATE_TRACE_POINTS
55 #include "diag/en_rep_tracepoint.h"
56 #include "diag/reporter_vnic.h"
57 #include "en_accel/ipsec.h"
58 #include "en/tc/int_port.h"
60 #include "en/fs_ethtool.h"
62 #define MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE \
63 max(0x7, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
64 #define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1
66 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
68 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
69 struct ethtool_drvinfo *drvinfo)
71 struct mlx5e_priv *priv = netdev_priv(dev);
72 struct mlx5_core_dev *mdev = priv->mdev;
74 strscpy(drvinfo->driver, mlx5e_rep_driver_name,
75 sizeof(drvinfo->driver));
76 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
78 fw_rev_maj(mdev), fw_rev_min(mdev),
79 fw_rev_sub(mdev), mdev->board_id);
82 static const struct counter_desc sw_rep_stats_desc[] = {
83 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
84 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
85 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
86 { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
89 static const struct counter_desc vport_rep_stats_desc[] = {
90 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats, vport_rx_packets) },
91 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats, vport_rx_bytes) },
92 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats, vport_tx_packets) },
93 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats, vport_tx_bytes) },
94 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats,
95 rx_vport_rdma_unicast_packets) },
96 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats, rx_vport_rdma_unicast_bytes) },
97 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats,
98 tx_vport_rdma_unicast_packets) },
99 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats, tx_vport_rdma_unicast_bytes) },
100 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats,
101 rx_vport_rdma_multicast_packets) },
102 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats,
103 rx_vport_rdma_multicast_bytes) },
104 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats,
105 tx_vport_rdma_multicast_packets) },
106 { MLX5E_DECLARE_STAT(struct mlx5e_rep_stats,
107 tx_vport_rdma_multicast_bytes) },
110 #define NUM_VPORT_REP_SW_COUNTERS ARRAY_SIZE(sw_rep_stats_desc)
111 #define NUM_VPORT_REP_HW_COUNTERS ARRAY_SIZE(vport_rep_stats_desc)
113 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(sw_rep)
115 return NUM_VPORT_REP_SW_COUNTERS;
118 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(sw_rep)
122 for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
123 strcpy(data + (idx++) * ETH_GSTRING_LEN,
124 sw_rep_stats_desc[i].format);
128 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(sw_rep)
132 for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
133 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
134 sw_rep_stats_desc, i);
138 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw_rep)
140 struct mlx5e_sw_stats *s = &priv->stats.sw;
141 struct rtnl_link_stats64 stats64 = {};
143 memset(s, 0, sizeof(*s));
144 mlx5e_fold_sw_stats64(priv, &stats64);
146 s->rx_packets = stats64.rx_packets;
147 s->rx_bytes = stats64.rx_bytes;
148 s->tx_packets = stats64.tx_packets;
149 s->tx_bytes = stats64.tx_bytes;
150 s->tx_queue_dropped = stats64.tx_dropped;
153 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(vport_rep)
155 return NUM_VPORT_REP_HW_COUNTERS;
158 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(vport_rep)
162 for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
163 strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_rep_stats_desc[i].format);
167 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(vport_rep)
171 for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
172 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.rep_stats,
173 vport_rep_stats_desc, i);
177 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(vport_rep)
179 struct mlx5e_rep_stats *rep_stats = &priv->stats.rep_stats;
180 int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
181 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
182 struct mlx5e_rep_priv *rpriv = priv->ppriv;
183 struct mlx5_eswitch_rep *rep = rpriv->rep;
187 out = kvzalloc(outlen, GFP_KERNEL);
191 err = mlx5_core_query_vport_counter(esw->dev, 1, rep->vport - 1, 0, out);
193 netdev_warn(priv->netdev, "vport %d error %d reading stats\n",
198 #define MLX5_GET_CTR(p, x) \
199 MLX5_GET64(query_vport_counter_out, p, x)
200 /* flip tx/rx as we are reporting the counters for the switch vport */
201 rep_stats->vport_rx_packets =
202 MLX5_GET_CTR(out, transmitted_ib_unicast.packets) +
203 MLX5_GET_CTR(out, transmitted_eth_unicast.packets) +
204 MLX5_GET_CTR(out, transmitted_ib_multicast.packets) +
205 MLX5_GET_CTR(out, transmitted_eth_multicast.packets) +
206 MLX5_GET_CTR(out, transmitted_eth_broadcast.packets);
208 rep_stats->vport_tx_packets =
209 MLX5_GET_CTR(out, received_ib_unicast.packets) +
210 MLX5_GET_CTR(out, received_eth_unicast.packets) +
211 MLX5_GET_CTR(out, received_ib_multicast.packets) +
212 MLX5_GET_CTR(out, received_eth_multicast.packets) +
213 MLX5_GET_CTR(out, received_eth_broadcast.packets);
215 rep_stats->vport_rx_bytes =
216 MLX5_GET_CTR(out, transmitted_ib_unicast.octets) +
217 MLX5_GET_CTR(out, transmitted_eth_unicast.octets) +
218 MLX5_GET_CTR(out, transmitted_ib_multicast.octets) +
219 MLX5_GET_CTR(out, transmitted_eth_broadcast.octets);
221 rep_stats->vport_tx_bytes =
222 MLX5_GET_CTR(out, received_ib_unicast.octets) +
223 MLX5_GET_CTR(out, received_eth_unicast.octets) +
224 MLX5_GET_CTR(out, received_ib_multicast.octets) +
225 MLX5_GET_CTR(out, received_eth_multicast.octets) +
226 MLX5_GET_CTR(out, received_eth_broadcast.octets);
228 rep_stats->rx_vport_rdma_unicast_packets =
229 MLX5_GET_CTR(out, transmitted_ib_unicast.packets);
230 rep_stats->tx_vport_rdma_unicast_packets =
231 MLX5_GET_CTR(out, received_ib_unicast.packets);
232 rep_stats->rx_vport_rdma_unicast_bytes =
233 MLX5_GET_CTR(out, transmitted_ib_unicast.octets);
234 rep_stats->tx_vport_rdma_unicast_bytes =
235 MLX5_GET_CTR(out, received_ib_unicast.octets);
236 rep_stats->rx_vport_rdma_multicast_packets =
237 MLX5_GET_CTR(out, transmitted_ib_multicast.packets);
238 rep_stats->tx_vport_rdma_multicast_packets =
239 MLX5_GET_CTR(out, received_ib_multicast.packets);
240 rep_stats->rx_vport_rdma_multicast_bytes =
241 MLX5_GET_CTR(out, transmitted_ib_multicast.octets);
242 rep_stats->tx_vport_rdma_multicast_bytes =
243 MLX5_GET_CTR(out, received_ib_multicast.octets);
249 static void mlx5e_rep_get_strings(struct net_device *dev,
250 u32 stringset, uint8_t *data)
252 struct mlx5e_priv *priv = netdev_priv(dev);
256 mlx5e_stats_fill_strings(priv, data);
261 static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
262 struct ethtool_stats *stats, u64 *data)
264 struct mlx5e_priv *priv = netdev_priv(dev);
266 mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
269 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
271 struct mlx5e_priv *priv = netdev_priv(dev);
275 return mlx5e_stats_total_num(priv);
282 mlx5e_rep_get_ringparam(struct net_device *dev,
283 struct ethtool_ringparam *param,
284 struct kernel_ethtool_ringparam *kernel_param,
285 struct netlink_ext_ack *extack)
287 struct mlx5e_priv *priv = netdev_priv(dev);
289 mlx5e_ethtool_get_ringparam(priv, param, kernel_param);
293 mlx5e_rep_set_ringparam(struct net_device *dev,
294 struct ethtool_ringparam *param,
295 struct kernel_ethtool_ringparam *kernel_param,
296 struct netlink_ext_ack *extack)
298 struct mlx5e_priv *priv = netdev_priv(dev);
300 return mlx5e_ethtool_set_ringparam(priv, param);
303 static void mlx5e_rep_get_channels(struct net_device *dev,
304 struct ethtool_channels *ch)
306 struct mlx5e_priv *priv = netdev_priv(dev);
308 mlx5e_ethtool_get_channels(priv, ch);
311 static int mlx5e_rep_set_channels(struct net_device *dev,
312 struct ethtool_channels *ch)
314 struct mlx5e_priv *priv = netdev_priv(dev);
316 return mlx5e_ethtool_set_channels(priv, ch);
319 static int mlx5e_rep_get_coalesce(struct net_device *netdev,
320 struct ethtool_coalesce *coal,
321 struct kernel_ethtool_coalesce *kernel_coal,
322 struct netlink_ext_ack *extack)
324 struct mlx5e_priv *priv = netdev_priv(netdev);
326 return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal);
329 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
330 struct ethtool_coalesce *coal,
331 struct kernel_ethtool_coalesce *kernel_coal,
332 struct netlink_ext_ack *extack)
334 struct mlx5e_priv *priv = netdev_priv(netdev);
336 return mlx5e_ethtool_set_coalesce(priv, coal, kernel_coal, extack);
339 static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
341 struct mlx5e_priv *priv = netdev_priv(netdev);
343 return mlx5e_ethtool_get_rxfh_key_size(priv);
346 static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
348 struct mlx5e_priv *priv = netdev_priv(netdev);
350 return mlx5e_ethtool_get_rxfh_indir_size(priv);
353 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
354 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
355 ETHTOOL_COALESCE_MAX_FRAMES |
356 ETHTOOL_COALESCE_USE_ADAPTIVE,
357 .get_drvinfo = mlx5e_rep_get_drvinfo,
358 .get_link = ethtool_op_get_link,
359 .get_strings = mlx5e_rep_get_strings,
360 .get_sset_count = mlx5e_rep_get_sset_count,
361 .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
362 .get_ringparam = mlx5e_rep_get_ringparam,
363 .set_ringparam = mlx5e_rep_set_ringparam,
364 .get_channels = mlx5e_rep_get_channels,
365 .set_channels = mlx5e_rep_set_channels,
366 .get_coalesce = mlx5e_rep_get_coalesce,
367 .set_coalesce = mlx5e_rep_set_coalesce,
368 .get_rxfh_key_size = mlx5e_rep_get_rxfh_key_size,
369 .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
372 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
373 struct mlx5_eswitch_rep *rep)
375 struct mlx5e_rep_sq *rep_sq, *tmp;
376 struct mlx5e_rep_priv *rpriv;
378 if (esw->mode != MLX5_ESWITCH_OFFLOADS)
381 rpriv = mlx5e_rep_to_rep_priv(rep);
382 list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) {
383 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
384 if (rep_sq->send_to_vport_rule_peer)
385 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
386 list_del(&rep_sq->list);
391 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
392 struct mlx5_eswitch_rep *rep,
393 u32 *sqns_array, int sqns_num)
395 struct mlx5_eswitch *peer_esw = NULL;
396 struct mlx5_flow_handle *flow_rule;
397 struct mlx5e_rep_priv *rpriv;
398 struct mlx5e_rep_sq *rep_sq;
402 if (esw->mode != MLX5_ESWITCH_OFFLOADS)
405 rpriv = mlx5e_rep_to_rep_priv(rep);
406 if (mlx5_devcom_is_paired(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS))
407 peer_esw = mlx5_devcom_get_peer_data(esw->dev->priv.devcom,
408 MLX5_DEVCOM_ESW_OFFLOADS);
410 for (i = 0; i < sqns_num; i++) {
411 rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL);
417 /* Add re-inject rule to the PF/representor sqs */
418 flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw, esw, rep,
420 if (IS_ERR(flow_rule)) {
421 err = PTR_ERR(flow_rule);
425 rep_sq->send_to_vport_rule = flow_rule;
426 rep_sq->sqn = sqns_array[i];
429 flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw,
431 if (IS_ERR(flow_rule)) {
432 err = PTR_ERR(flow_rule);
433 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
437 rep_sq->send_to_vport_rule_peer = flow_rule;
440 list_add(&rep_sq->list, &rpriv->vport_sqs_list);
444 mlx5_devcom_release_peer_data(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS);
449 mlx5e_sqs2vport_stop(esw, rep);
452 mlx5_devcom_release_peer_data(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS);
458 mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
460 int sqs_per_channel = mlx5e_get_dcb_num_tc(&priv->channels.params);
461 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
462 bool is_uplink_rep = mlx5e_is_uplink_rep(priv);
463 struct mlx5e_rep_priv *rpriv = priv->ppriv;
464 struct mlx5_eswitch_rep *rep = rpriv->rep;
465 int n, tc, nch, num_sqs = 0;
466 struct mlx5e_channel *c;
471 ptp_sq = !!(priv->channels.ptp &&
472 MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_TX_PORT_TS));
473 nch = priv->channels.num + ptp_sq;
474 /* +2 for xdpsqs, they don't exist on the ptp channel but will not be
475 * counted for by num_sqs.
478 sqs_per_channel += 2;
480 sqs = kvcalloc(nch * sqs_per_channel, sizeof(*sqs), GFP_KERNEL);
484 for (n = 0; n < priv->channels.num; n++) {
485 c = priv->channels.c[n];
486 for (tc = 0; tc < c->num_tc; tc++)
487 sqs[num_sqs++] = c->sq[tc].sqn;
491 sqs[num_sqs++] = c->rq_xdpsq.sqn;
493 sqs[num_sqs++] = c->xdpsq.sqn;
497 struct mlx5e_ptp *ptp_ch = priv->channels.ptp;
499 for (tc = 0; tc < ptp_ch->num_tc; tc++)
500 sqs[num_sqs++] = ptp_ch->ptpsq[tc].txqsq.sqn;
503 err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs);
508 netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
513 mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
515 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
516 struct mlx5e_rep_priv *rpriv = priv->ppriv;
517 struct mlx5_eswitch_rep *rep = rpriv->rep;
519 mlx5e_sqs2vport_stop(esw, rep);
523 mlx5e_rep_add_meta_tunnel_rule(struct mlx5e_priv *priv)
525 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
526 struct mlx5e_rep_priv *rpriv = priv->ppriv;
527 struct mlx5_eswitch_rep *rep = rpriv->rep;
528 struct mlx5_flow_handle *flow_rule;
529 struct mlx5_flow_group *g;
531 g = esw->fdb_table.offloads.send_to_vport_meta_grp;
535 flow_rule = mlx5_eswitch_add_send_to_vport_meta_rule(esw, rep->vport);
536 if (IS_ERR(flow_rule))
537 return PTR_ERR(flow_rule);
539 rpriv->send_to_vport_meta_rule = flow_rule;
545 mlx5e_rep_del_meta_tunnel_rule(struct mlx5e_priv *priv)
547 struct mlx5e_rep_priv *rpriv = priv->ppriv;
549 if (rpriv->send_to_vport_meta_rule)
550 mlx5_eswitch_del_send_to_vport_meta_rule(rpriv->send_to_vport_meta_rule);
553 void mlx5e_rep_activate_channels(struct mlx5e_priv *priv)
555 mlx5e_add_sqs_fwd_rules(priv);
556 mlx5e_rep_add_meta_tunnel_rule(priv);
559 void mlx5e_rep_deactivate_channels(struct mlx5e_priv *priv)
561 mlx5e_rep_del_meta_tunnel_rule(priv);
562 mlx5e_remove_sqs_fwd_rules(priv);
565 static int mlx5e_rep_open(struct net_device *dev)
567 struct mlx5e_priv *priv = netdev_priv(dev);
568 struct mlx5e_rep_priv *rpriv = priv->ppriv;
569 struct mlx5_eswitch_rep *rep = rpriv->rep;
572 mutex_lock(&priv->state_lock);
573 err = mlx5e_open_locked(dev);
577 if (!mlx5_modify_vport_admin_state(priv->mdev,
578 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
580 MLX5_VPORT_ADMIN_STATE_UP))
581 netif_carrier_on(dev);
584 mutex_unlock(&priv->state_lock);
588 static int mlx5e_rep_close(struct net_device *dev)
590 struct mlx5e_priv *priv = netdev_priv(dev);
591 struct mlx5e_rep_priv *rpriv = priv->ppriv;
592 struct mlx5_eswitch_rep *rep = rpriv->rep;
595 mutex_lock(&priv->state_lock);
596 mlx5_modify_vport_admin_state(priv->mdev,
597 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
599 MLX5_VPORT_ADMIN_STATE_DOWN);
600 ret = mlx5e_close_locked(dev);
601 mutex_unlock(&priv->state_lock);
605 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
607 struct mlx5e_rep_priv *rpriv = priv->ppriv;
608 struct mlx5_eswitch_rep *rep;
610 if (!MLX5_ESWITCH_MANAGER(priv->mdev))
613 if (!rpriv) /* non vport rep mlx5e instances don't use this field */
617 return (rep->vport == MLX5_VPORT_UPLINK);
620 bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
623 case IFLA_OFFLOAD_XSTATS_CPU_HIT:
631 mlx5e_get_sw_stats64(const struct net_device *dev,
632 struct rtnl_link_stats64 *stats)
634 struct mlx5e_priv *priv = netdev_priv(dev);
636 mlx5e_fold_sw_stats64(priv, stats);
640 int mlx5e_rep_get_offload_stats(int attr_id, const struct net_device *dev,
644 case IFLA_OFFLOAD_XSTATS_CPU_HIT:
645 return mlx5e_get_sw_stats64(dev, sp);
652 mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
654 struct mlx5e_priv *priv = netdev_priv(dev);
656 /* update HW stats in background for next time */
657 mlx5e_queue_update_stats(priv);
658 memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
661 static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu)
663 return mlx5e_change_mtu(netdev, new_mtu, NULL);
666 static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
668 struct mlx5e_priv *priv = netdev_priv(dev);
669 struct mlx5e_rep_priv *rpriv = priv->ppriv;
670 struct mlx5_eswitch_rep *rep = rpriv->rep;
674 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
675 rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
678 netif_carrier_on(dev);
680 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
681 rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
684 netif_carrier_off(dev);
689 static const struct net_device_ops mlx5e_netdev_ops_rep = {
690 .ndo_open = mlx5e_rep_open,
691 .ndo_stop = mlx5e_rep_close,
692 .ndo_start_xmit = mlx5e_xmit,
693 .ndo_setup_tc = mlx5e_rep_setup_tc,
694 .ndo_get_stats64 = mlx5e_rep_get_stats,
695 .ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
696 .ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
697 .ndo_change_mtu = mlx5e_rep_change_mtu,
698 .ndo_change_carrier = mlx5e_rep_change_carrier,
701 bool mlx5e_eswitch_uplink_rep(const struct net_device *netdev)
703 return netdev->netdev_ops == &mlx5e_netdev_ops &&
704 mlx5e_is_uplink_rep(netdev_priv(netdev));
707 bool mlx5e_eswitch_vf_rep(const struct net_device *netdev)
709 return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
712 /* One indirect TIR set for outer. Inner not supported in reps. */
713 #define REP_NUM_INDIR_TIRS MLX5E_NUM_INDIR_TIRS
715 static int mlx5e_rep_max_nch_limit(struct mlx5_core_dev *mdev)
717 int max_tir_num = 1 << MLX5_CAP_GEN(mdev, log_max_tir);
718 int num_vports = mlx5_eswitch_get_total_vports(mdev);
720 return (max_tir_num - mlx5e_get_pf_num_tirs(mdev)
721 - (num_vports * REP_NUM_INDIR_TIRS)) / num_vports;
724 static void mlx5e_build_rep_params(struct net_device *netdev)
726 struct mlx5e_priv *priv = netdev_priv(netdev);
727 struct mlx5e_rep_priv *rpriv = priv->ppriv;
728 struct mlx5_eswitch_rep *rep = rpriv->rep;
729 struct mlx5_core_dev *mdev = priv->mdev;
730 struct mlx5e_params *params;
732 u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
733 MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
734 MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
736 params = &priv->channels.params;
738 params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
739 params->hard_mtu = MLX5E_ETH_HARD_MTU;
740 params->sw_mtu = netdev->mtu;
743 if (rep->vport == MLX5_VPORT_UPLINK)
744 params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
746 params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;
749 mlx5e_build_rq_params(mdev, params);
751 /* update XDP supported features */
752 mlx5e_set_xdp_feature(netdev);
754 /* CQ moderation params */
755 params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
756 mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
758 params->mqprio.num_tc = 1;
759 if (rep->vport != MLX5_VPORT_UPLINK)
760 params->vlan_strip_disable = true;
762 mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode);
765 static void mlx5e_build_rep_netdev(struct net_device *netdev,
766 struct mlx5_core_dev *mdev)
768 SET_NETDEV_DEV(netdev, mdev->device);
769 netdev->netdev_ops = &mlx5e_netdev_ops_rep;
770 eth_hw_addr_random(netdev);
771 netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
773 netdev->watchdog_timeo = 15 * HZ;
775 #if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
776 netdev->hw_features |= NETIF_F_HW_TC;
778 netdev->hw_features |= NETIF_F_SG;
779 netdev->hw_features |= NETIF_F_IP_CSUM;
780 netdev->hw_features |= NETIF_F_IPV6_CSUM;
781 netdev->hw_features |= NETIF_F_GRO;
782 netdev->hw_features |= NETIF_F_TSO;
783 netdev->hw_features |= NETIF_F_TSO6;
784 netdev->hw_features |= NETIF_F_RXCSUM;
786 netdev->features |= netdev->hw_features;
787 netdev->features |= NETIF_F_NETNS_LOCAL;
790 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
791 struct net_device *netdev)
793 struct mlx5e_priv *priv = netdev_priv(netdev);
796 mlx5e_fs_init(priv->profile, mdev,
797 !test_bit(MLX5E_STATE_DESTROYING, &priv->state),
800 netdev_err(priv->netdev, "FS allocation failed\n");
804 mlx5e_build_rep_params(netdev);
805 mlx5e_timestamp_init(priv);
810 static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
811 struct net_device *netdev)
813 struct mlx5e_priv *priv = netdev_priv(netdev);
815 priv->fs = mlx5e_fs_init(priv->profile, mdev,
816 !test_bit(MLX5E_STATE_DESTROYING, &priv->state),
819 netdev_err(priv->netdev, "FS allocation failed\n");
823 mlx5e_vxlan_set_netdev_info(priv);
824 mlx5e_build_rep_params(netdev);
825 mlx5e_timestamp_init(priv);
829 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
831 mlx5e_fs_cleanup(priv->fs);
835 static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
837 struct mlx5e_rep_priv *rpriv = priv->ppriv;
838 struct mlx5_eswitch_rep *rep = rpriv->rep;
839 struct ttc_params ttc_params = {};
842 mlx5e_fs_set_ns(priv->fs,
843 mlx5_get_flow_namespace(priv->mdev,
844 MLX5_FLOW_NAMESPACE_KERNEL), false);
846 /* The inner_ttc in the ttc params is intentionally not set */
847 mlx5e_set_ttc_params(priv->fs, priv->rx_res, &ttc_params, false);
849 if (rep->vport != MLX5_VPORT_UPLINK)
850 /* To give uplik rep TTC a lower level for chaining from root ft */
851 ttc_params.ft_attr.level = MLX5E_TTC_FT_LEVEL + 1;
853 mlx5e_fs_set_ttc(priv->fs, mlx5_create_ttc_table(priv->mdev, &ttc_params), false);
854 if (IS_ERR(mlx5e_fs_get_ttc(priv->fs, false))) {
855 err = PTR_ERR(mlx5e_fs_get_ttc(priv->fs, false));
856 netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n",
863 static int mlx5e_create_rep_root_ft(struct mlx5e_priv *priv)
865 struct mlx5e_rep_priv *rpriv = priv->ppriv;
866 struct mlx5_eswitch_rep *rep = rpriv->rep;
867 struct mlx5_flow_table_attr ft_attr = {};
868 struct mlx5_flow_namespace *ns;
871 if (rep->vport != MLX5_VPORT_UPLINK) {
872 /* non uplik reps will skip any bypass tables and go directly to
875 rpriv->root_ft = mlx5_get_ttc_flow_table(mlx5e_fs_get_ttc(priv->fs, false));
879 /* uplink root ft will be used to auto chain, to ethtool or ttc tables */
880 ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
882 netdev_err(priv->netdev, "Failed to get reps offloads namespace\n");
886 ft_attr.max_fte = 0; /* Empty table, miss rule will always point to next table */
890 rpriv->root_ft = mlx5_create_flow_table(ns, &ft_attr);
891 if (IS_ERR(rpriv->root_ft)) {
892 err = PTR_ERR(rpriv->root_ft);
893 rpriv->root_ft = NULL;
899 static void mlx5e_destroy_rep_root_ft(struct mlx5e_priv *priv)
901 struct mlx5e_rep_priv *rpriv = priv->ppriv;
902 struct mlx5_eswitch_rep *rep = rpriv->rep;
904 if (rep->vport != MLX5_VPORT_UPLINK)
906 mlx5_destroy_flow_table(rpriv->root_ft);
909 static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
911 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
912 struct mlx5e_rep_priv *rpriv = priv->ppriv;
913 struct mlx5_eswitch_rep *rep = rpriv->rep;
914 struct mlx5_flow_handle *flow_rule;
915 struct mlx5_flow_destination dest;
917 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
918 dest.ft = rpriv->root_ft;
920 flow_rule = mlx5_eswitch_create_vport_rx_rule(esw, rep->vport, &dest);
921 if (IS_ERR(flow_rule))
922 return PTR_ERR(flow_rule);
923 rpriv->vport_rx_rule = flow_rule;
927 static void rep_vport_rx_rule_destroy(struct mlx5e_priv *priv)
929 struct mlx5e_rep_priv *rpriv = priv->ppriv;
931 if (!rpriv->vport_rx_rule)
934 mlx5_del_flow_rules(rpriv->vport_rx_rule);
935 rpriv->vport_rx_rule = NULL;
938 int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup)
940 rep_vport_rx_rule_destroy(priv);
942 return cleanup ? 0 : mlx5e_create_rep_vport_rx_rule(priv);
945 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
947 struct mlx5_core_dev *mdev = priv->mdev;
950 priv->rx_res = mlx5e_rx_res_alloc();
956 mlx5e_fs_init_l2_addr(priv->fs, priv->netdev);
958 err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
960 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
964 err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0,
965 priv->max_nch, priv->drop_rq.rqn,
966 &priv->channels.params.packet_merge,
967 priv->channels.params.num_channels);
969 goto err_close_drop_rq;
971 err = mlx5e_create_rep_ttc_table(priv);
973 goto err_destroy_rx_res;
975 err = mlx5e_create_rep_root_ft(priv);
977 goto err_destroy_ttc_table;
979 err = mlx5e_create_rep_vport_rx_rule(priv);
981 goto err_destroy_root_ft;
983 mlx5e_ethtool_init_steering(priv->fs);
988 mlx5e_destroy_rep_root_ft(priv);
989 err_destroy_ttc_table:
990 mlx5_destroy_ttc_table(mlx5e_fs_get_ttc(priv->fs, false));
992 mlx5e_rx_res_destroy(priv->rx_res);
994 mlx5e_close_drop_rq(&priv->drop_rq);
995 mlx5e_rx_res_free(priv->rx_res);
998 mlx5e_fs_cleanup(priv->fs);
1003 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
1005 mlx5e_ethtool_cleanup_steering(priv->fs);
1006 rep_vport_rx_rule_destroy(priv);
1007 mlx5e_destroy_rep_root_ft(priv);
1008 mlx5_destroy_ttc_table(mlx5e_fs_get_ttc(priv->fs, false));
1009 mlx5e_rx_res_destroy(priv->rx_res);
1010 mlx5e_close_drop_rq(&priv->drop_rq);
1011 mlx5e_rx_res_free(priv->rx_res);
1012 priv->rx_res = NULL;
1015 static void mlx5e_rep_mpesw_work(struct work_struct *work)
1017 struct mlx5_rep_uplink_priv *uplink_priv =
1018 container_of(work, struct mlx5_rep_uplink_priv,
1020 struct mlx5e_rep_priv *rpriv =
1021 container_of(uplink_priv, struct mlx5e_rep_priv,
1023 struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
1025 rep_vport_rx_rule_destroy(priv);
1026 mlx5e_create_rep_vport_rx_rule(priv);
1029 static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
1031 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1034 mlx5e_create_q_counters(priv);
1035 err = mlx5e_init_rep_rx(priv);
1039 mlx5e_tc_int_port_init_rep_rx(priv);
1041 INIT_WORK(&rpriv->uplink_priv.mpesw_work, mlx5e_rep_mpesw_work);
1047 static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
1049 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1051 cancel_work_sync(&rpriv->uplink_priv.mpesw_work);
1052 mlx5e_tc_int_port_cleanup_rep_rx(priv);
1053 mlx5e_cleanup_rep_rx(priv);
1054 mlx5e_destroy_q_counters(priv);
1057 static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
1059 struct mlx5_rep_uplink_priv *uplink_priv;
1060 struct net_device *netdev;
1061 struct mlx5e_priv *priv;
1064 netdev = rpriv->netdev;
1065 priv = netdev_priv(netdev);
1066 uplink_priv = &rpriv->uplink_priv;
1068 err = mlx5e_rep_tc_init(rpriv);
1072 mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
1074 mlx5e_rep_bond_init(rpriv);
1075 err = mlx5e_rep_tc_netdevice_event_register(rpriv);
1077 mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
1085 mlx5e_rep_bond_cleanup(rpriv);
1086 mlx5e_rep_tc_cleanup(rpriv);
1090 static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
1092 mlx5e_rep_tc_netdevice_event_unregister(rpriv);
1093 mlx5e_rep_bond_cleanup(rpriv);
1094 mlx5e_rep_tc_cleanup(rpriv);
1097 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
1099 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1102 err = mlx5e_create_tises(priv);
1104 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
1108 if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
1109 err = mlx5e_init_uplink_rep_tx(rpriv);
1114 err = mlx5e_tc_ht_init(&rpriv->tc_ht);
1121 if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
1122 mlx5e_cleanup_uplink_rep_tx(rpriv);
1124 mlx5e_destroy_tises(priv);
1128 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
1130 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1132 mlx5e_tc_ht_cleanup(&rpriv->tc_ht);
1134 if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
1135 mlx5e_cleanup_uplink_rep_tx(rpriv);
1137 mlx5e_destroy_tises(priv);
1140 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
1142 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1144 mlx5e_set_netdev_mtu_boundaries(priv);
1145 mlx5e_rep_neigh_init(rpriv);
1148 static void mlx5e_rep_disable(struct mlx5e_priv *priv)
1150 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1152 mlx5e_rep_neigh_cleanup(rpriv);
1155 static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
1160 static int mlx5e_rep_event_mpesw(struct mlx5e_priv *priv)
1162 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1163 struct mlx5_eswitch_rep *rep = rpriv->rep;
1165 if (rep->vport != MLX5_VPORT_UPLINK)
1168 queue_work(priv->wq, &rpriv->uplink_priv.mpesw_work);
1173 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
1175 struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
1177 if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
1178 struct mlx5_eqe *eqe = data;
1180 switch (eqe->sub_type) {
1181 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
1182 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
1183 queue_work(priv->wq, &priv->update_carrier_work);
1192 if (event == MLX5_DEV_EVENT_PORT_AFFINITY)
1193 return mlx5e_rep_tc_event_port_affinity(priv);
1194 else if (event == MLX5_DEV_EVENT_MULTIPORT_ESW)
1195 return mlx5e_rep_event_mpesw(priv);
1200 static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
1202 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1203 struct net_device *netdev = priv->netdev;
1204 struct mlx5_core_dev *mdev = priv->mdev;
1207 mlx5e_ipsec_init(priv);
1209 netdev->min_mtu = ETH_MIN_MTU;
1210 mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
1211 netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
1212 mlx5e_set_dev_port_mtu(priv);
1214 mlx5e_rep_tc_enable(priv);
1216 if (MLX5_CAP_GEN(mdev, uplink_follow))
1217 mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
1218 0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
1219 mlx5_lag_add_netdev(mdev, netdev);
1220 priv->events_nb.notifier_call = uplink_rep_async_event;
1221 mlx5_notifier_register(mdev, &priv->events_nb);
1222 mlx5e_dcbnl_initialize(priv);
1223 mlx5e_dcbnl_init_app(priv);
1224 mlx5e_rep_neigh_init(rpriv);
1225 mlx5e_rep_bridge_init(priv);
1227 netdev->wanted_features |= NETIF_F_HW_TC;
1230 if (netif_running(netdev))
1232 udp_tunnel_nic_reset_ntf(priv->netdev);
1233 netif_device_attach(netdev);
1237 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1239 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1240 struct mlx5_core_dev *mdev = priv->mdev;
1243 if (netif_running(priv->netdev))
1244 mlx5e_close(priv->netdev);
1245 netif_device_detach(priv->netdev);
1248 mlx5e_rep_bridge_cleanup(priv);
1249 mlx5e_rep_neigh_cleanup(rpriv);
1250 mlx5e_dcbnl_delete_app(priv);
1251 mlx5_notifier_unregister(mdev, &priv->events_nb);
1252 mlx5e_rep_tc_disable(priv);
1253 mlx5_lag_remove_netdev(mdev, priv->netdev);
1254 mlx5_vxlan_reset_to_default(mdev->vxlan);
1256 mlx5e_ipsec_cleanup(priv);
1259 static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
1260 static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);
1262 /* The stats groups order is opposite to the update_stats() order calls */
1263 static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
1264 &MLX5E_STATS_GRP(sw_rep),
1265 &MLX5E_STATS_GRP(vport_rep),
1268 static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
1270 return ARRAY_SIZE(mlx5e_rep_stats_grps);
1273 /* The stats groups order is opposite to the update_stats() order calls */
1274 static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
1275 &MLX5E_STATS_GRP(sw),
1276 &MLX5E_STATS_GRP(qcnt),
1277 &MLX5E_STATS_GRP(vnic_env),
1278 &MLX5E_STATS_GRP(vport),
1279 &MLX5E_STATS_GRP(802_3),
1280 &MLX5E_STATS_GRP(2863),
1281 &MLX5E_STATS_GRP(2819),
1282 &MLX5E_STATS_GRP(phy),
1283 &MLX5E_STATS_GRP(eth_ext),
1284 &MLX5E_STATS_GRP(pcie),
1285 &MLX5E_STATS_GRP(per_prio),
1286 &MLX5E_STATS_GRP(pme),
1287 &MLX5E_STATS_GRP(channels),
1288 &MLX5E_STATS_GRP(per_port_buff_congest),
1289 #ifdef CONFIG_MLX5_EN_IPSEC
1290 &MLX5E_STATS_GRP(ipsec_sw),
1292 &MLX5E_STATS_GRP(ptp),
1295 static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
1297 return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
1301 mlx5e_rep_vnic_reporter_diagnose(struct devlink_health_reporter *reporter,
1302 struct devlink_fmsg *fmsg,
1303 struct netlink_ext_ack *extack)
1305 struct mlx5e_rep_priv *rpriv = devlink_health_reporter_priv(reporter);
1306 struct mlx5_eswitch_rep *rep = rpriv->rep;
1308 return mlx5_reporter_vnic_diagnose_counters(rep->esw->dev, fmsg,
1312 static const struct devlink_health_reporter_ops mlx5_rep_vnic_reporter_ops = {
1314 .diagnose = mlx5e_rep_vnic_reporter_diagnose,
1317 static void mlx5e_rep_vnic_reporter_create(struct mlx5e_priv *priv,
1318 struct devlink_port *dl_port)
1320 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1321 struct devlink_health_reporter *reporter;
1323 reporter = devl_port_health_reporter_create(dl_port,
1324 &mlx5_rep_vnic_reporter_ops,
1326 if (IS_ERR(reporter)) {
1327 mlx5_core_err(priv->mdev,
1328 "Failed to create representor vnic reporter, err = %ld\n",
1333 rpriv->rep_vnic_reporter = reporter;
1336 static void mlx5e_rep_vnic_reporter_destroy(struct mlx5e_priv *priv)
1338 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1340 if (!IS_ERR_OR_NULL(rpriv->rep_vnic_reporter))
1341 devl_health_reporter_destroy(rpriv->rep_vnic_reporter);
1344 static const struct mlx5e_profile mlx5e_rep_profile = {
1345 .init = mlx5e_init_rep,
1346 .cleanup = mlx5e_cleanup_rep,
1347 .init_rx = mlx5e_init_rep_rx,
1348 .cleanup_rx = mlx5e_cleanup_rep_rx,
1349 .init_tx = mlx5e_init_rep_tx,
1350 .cleanup_tx = mlx5e_cleanup_rep_tx,
1351 .enable = mlx5e_rep_enable,
1352 .disable = mlx5e_rep_disable,
1353 .update_rx = mlx5e_update_rep_rx,
1354 .update_stats = mlx5e_stats_update_ndo_stats,
1355 .rx_handlers = &mlx5e_rx_handlers_rep,
1357 .stats_grps = mlx5e_rep_stats_grps,
1358 .stats_grps_num = mlx5e_rep_stats_grps_num,
1359 .max_nch_limit = mlx5e_rep_max_nch_limit,
1362 static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1363 .init = mlx5e_init_ul_rep,
1364 .cleanup = mlx5e_cleanup_rep,
1365 .init_rx = mlx5e_init_ul_rep_rx,
1366 .cleanup_rx = mlx5e_cleanup_ul_rep_rx,
1367 .init_tx = mlx5e_init_rep_tx,
1368 .cleanup_tx = mlx5e_cleanup_rep_tx,
1369 .enable = mlx5e_uplink_rep_enable,
1370 .disable = mlx5e_uplink_rep_disable,
1371 .update_rx = mlx5e_update_rep_rx,
1372 .update_stats = mlx5e_stats_update_ndo_stats,
1373 .update_carrier = mlx5e_update_carrier,
1374 .rx_handlers = &mlx5e_rx_handlers_rep,
1375 .max_tc = MLX5E_MAX_NUM_TC,
1376 .stats_grps = mlx5e_ul_rep_stats_grps,
1377 .stats_grps_num = mlx5e_ul_rep_stats_grps_num,
1380 /* e-Switch vport representors */
1382 mlx5e_vport_uplink_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1384 struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
1385 struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1387 rpriv->netdev = priv->netdev;
1388 return mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
1393 mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv)
1395 struct net_device *netdev = rpriv->netdev;
1396 struct mlx5e_priv *priv;
1398 priv = netdev_priv(netdev);
1400 mlx5e_netdev_attach_nic_profile(priv);
1404 mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1406 struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1407 const struct mlx5e_profile *profile;
1408 struct devlink_port *dl_port;
1409 struct net_device *netdev;
1410 struct mlx5e_priv *priv;
1413 profile = &mlx5e_rep_profile;
1414 netdev = mlx5e_create_netdev(dev, profile);
1417 "Failed to create representor netdev for vport %d\n",
1422 mlx5e_build_rep_netdev(netdev, dev);
1423 rpriv->netdev = netdev;
1425 priv = netdev_priv(netdev);
1426 priv->profile = profile;
1427 priv->ppriv = rpriv;
1428 err = profile->init(dev, netdev);
1430 netdev_warn(netdev, "rep profile init failed, %d\n", err);
1431 goto err_destroy_netdev;
1434 err = mlx5e_attach_netdev(netdev_priv(netdev));
1437 "Failed to attach representor netdev for vport %d\n",
1439 goto err_cleanup_profile;
1442 dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch,
1445 SET_NETDEV_DEVLINK_PORT(netdev, dl_port);
1446 mlx5e_rep_vnic_reporter_create(priv, dl_port);
1449 err = register_netdev(netdev);
1452 "Failed to register representor netdev for vport %d\n",
1454 goto err_detach_netdev;
1460 mlx5e_rep_vnic_reporter_destroy(priv);
1461 mlx5e_detach_netdev(netdev_priv(netdev));
1462 err_cleanup_profile:
1463 priv->profile->cleanup(priv);
1466 mlx5e_destroy_netdev(netdev_priv(netdev));
1471 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1473 struct mlx5e_rep_priv *rpriv;
1476 rpriv = kvzalloc(sizeof(*rpriv), GFP_KERNEL);
1480 /* rpriv->rep to be looked up when profile->init() is called */
1482 rep->rep_data[REP_ETH].priv = rpriv;
1483 INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1485 if (rep->vport == MLX5_VPORT_UPLINK)
1486 err = mlx5e_vport_uplink_rep_load(dev, rep);
1488 err = mlx5e_vport_vf_rep_load(dev, rep);
1497 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1499 struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1500 struct net_device *netdev = rpriv->netdev;
1501 struct mlx5e_priv *priv = netdev_priv(netdev);
1502 void *ppriv = priv->ppriv;
1504 if (rep->vport == MLX5_VPORT_UPLINK) {
1505 mlx5e_vport_uplink_rep_unload(rpriv);
1509 unregister_netdev(netdev);
1510 mlx5e_rep_vnic_reporter_destroy(priv);
1511 mlx5e_detach_netdev(priv);
1512 priv->profile->cleanup(priv);
1513 mlx5e_destroy_netdev(priv);
1515 kvfree(ppriv); /* mlx5e_rep_priv */
1518 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1520 struct mlx5e_rep_priv *rpriv;
1522 rpriv = mlx5e_rep_to_rep_priv(rep);
1524 return rpriv->netdev;
1527 static void mlx5e_vport_rep_event_unpair(struct mlx5_eswitch_rep *rep)
1529 struct mlx5e_rep_priv *rpriv;
1530 struct mlx5e_rep_sq *rep_sq;
1532 rpriv = mlx5e_rep_to_rep_priv(rep);
1533 list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1534 if (!rep_sq->send_to_vport_rule_peer)
1536 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
1537 rep_sq->send_to_vport_rule_peer = NULL;
1541 static int mlx5e_vport_rep_event_pair(struct mlx5_eswitch *esw,
1542 struct mlx5_eswitch_rep *rep,
1543 struct mlx5_eswitch *peer_esw)
1545 struct mlx5_flow_handle *flow_rule;
1546 struct mlx5e_rep_priv *rpriv;
1547 struct mlx5e_rep_sq *rep_sq;
1549 rpriv = mlx5e_rep_to_rep_priv(rep);
1550 list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1551 if (rep_sq->send_to_vport_rule_peer)
1553 flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw, rep, rep_sq->sqn);
1554 if (IS_ERR(flow_rule))
1556 rep_sq->send_to_vport_rule_peer = flow_rule;
1561 mlx5e_vport_rep_event_unpair(rep);
1562 return PTR_ERR(flow_rule);
1565 static int mlx5e_vport_rep_event(struct mlx5_eswitch *esw,
1566 struct mlx5_eswitch_rep *rep,
1567 enum mlx5_switchdev_event event,
1572 if (event == MLX5_SWITCHDEV_EVENT_PAIR)
1573 err = mlx5e_vport_rep_event_pair(esw, rep, data);
1574 else if (event == MLX5_SWITCHDEV_EVENT_UNPAIR)
1575 mlx5e_vport_rep_event_unpair(rep);
1580 static const struct mlx5_eswitch_rep_ops rep_ops = {
1581 .load = mlx5e_vport_rep_load,
1582 .unload = mlx5e_vport_rep_unload,
1583 .get_proto_dev = mlx5e_vport_rep_get_proto_dev,
1584 .event = mlx5e_vport_rep_event,
1587 static int mlx5e_rep_probe(struct auxiliary_device *adev,
1588 const struct auxiliary_device_id *id)
1590 struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
1591 struct mlx5_core_dev *mdev = edev->mdev;
1592 struct mlx5_eswitch *esw;
1594 esw = mdev->priv.eswitch;
1595 mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1599 static void mlx5e_rep_remove(struct auxiliary_device *adev)
1601 struct mlx5_adev *vdev = container_of(adev, struct mlx5_adev, adev);
1602 struct mlx5_core_dev *mdev = vdev->mdev;
1603 struct mlx5_eswitch *esw;
1605 esw = mdev->priv.eswitch;
1606 mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
1609 static const struct auxiliary_device_id mlx5e_rep_id_table[] = {
1610 { .name = MLX5_ADEV_NAME ".eth-rep", },
1614 MODULE_DEVICE_TABLE(auxiliary, mlx5e_rep_id_table);
1616 static struct auxiliary_driver mlx5e_rep_driver = {
1618 .probe = mlx5e_rep_probe,
1619 .remove = mlx5e_rep_remove,
1620 .id_table = mlx5e_rep_id_table,
1623 int mlx5e_rep_init(void)
1625 return auxiliary_driver_register(&mlx5e_rep_driver);
1628 void mlx5e_rep_cleanup(void)
1630 auxiliary_driver_unregister(&mlx5e_rep_driver);