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