1 /* 2 * Copyright (c) 2015, 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/etherdevice.h> 34 #include <linux/mlx5/driver.h> 35 #include <linux/mlx5/mlx5_ifc.h> 36 #include <linux/mlx5/vport.h> 37 #include <linux/mlx5/fs.h> 38 #include <linux/mlx5/mpfs.h> 39 #include "esw/acl/lgcy.h" 40 #include "esw/legacy.h" 41 #include "esw/qos.h" 42 #include "mlx5_core.h" 43 #include "lib/eq.h" 44 #include "eswitch.h" 45 #include "fs_core.h" 46 #include "devlink.h" 47 #include "ecpf.h" 48 #include "en/mod_hdr.h" 49 50 enum { 51 MLX5_ACTION_NONE = 0, 52 MLX5_ACTION_ADD = 1, 53 MLX5_ACTION_DEL = 2, 54 }; 55 56 /* Vport UC/MC hash node */ 57 struct vport_addr { 58 struct l2addr_node node; 59 u8 action; 60 u16 vport; 61 struct mlx5_flow_handle *flow_rule; 62 bool mpfs; /* UC MAC was added to MPFs */ 63 /* A flag indicating that mac was added due to mc promiscuous vport */ 64 bool mc_promisc; 65 }; 66 67 static int mlx5_eswitch_check(const struct mlx5_core_dev *dev) 68 { 69 if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH) 70 return -EOPNOTSUPP; 71 72 if (!MLX5_ESWITCH_MANAGER(dev)) 73 return -EOPNOTSUPP; 74 75 return 0; 76 } 77 78 struct mlx5_eswitch *mlx5_devlink_eswitch_get(struct devlink *devlink) 79 { 80 struct mlx5_core_dev *dev = devlink_priv(devlink); 81 int err; 82 83 err = mlx5_eswitch_check(dev); 84 if (err) 85 return ERR_PTR(err); 86 87 return dev->priv.eswitch; 88 } 89 90 struct mlx5_vport *__must_check 91 mlx5_eswitch_get_vport(struct mlx5_eswitch *esw, u16 vport_num) 92 { 93 struct mlx5_vport *vport; 94 95 if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager)) 96 return ERR_PTR(-EPERM); 97 98 vport = xa_load(&esw->vports, vport_num); 99 if (!vport) { 100 esw_debug(esw->dev, "vport out of range: num(0x%x)\n", vport_num); 101 return ERR_PTR(-EINVAL); 102 } 103 return vport; 104 } 105 106 static int arm_vport_context_events_cmd(struct mlx5_core_dev *dev, u16 vport, 107 u32 events_mask) 108 { 109 u32 in[MLX5_ST_SZ_DW(modify_nic_vport_context_in)] = {}; 110 void *nic_vport_ctx; 111 112 MLX5_SET(modify_nic_vport_context_in, in, 113 opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT); 114 MLX5_SET(modify_nic_vport_context_in, in, field_select.change_event, 1); 115 MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); 116 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1); 117 nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, 118 in, nic_vport_context); 119 120 MLX5_SET(nic_vport_context, nic_vport_ctx, arm_change_event, 1); 121 122 if (events_mask & MLX5_VPORT_UC_ADDR_CHANGE) 123 MLX5_SET(nic_vport_context, nic_vport_ctx, 124 event_on_uc_address_change, 1); 125 if (events_mask & MLX5_VPORT_MC_ADDR_CHANGE) 126 MLX5_SET(nic_vport_context, nic_vport_ctx, 127 event_on_mc_address_change, 1); 128 if (events_mask & MLX5_VPORT_PROMISC_CHANGE) 129 MLX5_SET(nic_vport_context, nic_vport_ctx, 130 event_on_promisc_change, 1); 131 132 return mlx5_cmd_exec_in(dev, modify_nic_vport_context, in); 133 } 134 135 /* E-Switch vport context HW commands */ 136 int mlx5_eswitch_modify_esw_vport_context(struct mlx5_core_dev *dev, u16 vport, 137 bool other_vport, void *in) 138 { 139 MLX5_SET(modify_esw_vport_context_in, in, opcode, 140 MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT); 141 MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport); 142 MLX5_SET(modify_esw_vport_context_in, in, other_vport, other_vport); 143 return mlx5_cmd_exec_in(dev, modify_esw_vport_context, in); 144 } 145 146 static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u16 vport, 147 u16 vlan, u8 qos, u8 set_flags) 148 { 149 u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)] = {}; 150 151 if (!MLX5_CAP_ESW(dev, vport_cvlan_strip) || 152 !MLX5_CAP_ESW(dev, vport_cvlan_insert_if_not_exist)) 153 return -EOPNOTSUPP; 154 155 esw_debug(dev, "Set Vport[%d] VLAN %d qos %d set=%x\n", 156 vport, vlan, qos, set_flags); 157 158 if (set_flags & SET_VLAN_STRIP) 159 MLX5_SET(modify_esw_vport_context_in, in, 160 esw_vport_context.vport_cvlan_strip, 1); 161 162 if (set_flags & SET_VLAN_INSERT) { 163 /* insert only if no vlan in packet */ 164 MLX5_SET(modify_esw_vport_context_in, in, 165 esw_vport_context.vport_cvlan_insert, 1); 166 167 MLX5_SET(modify_esw_vport_context_in, in, 168 esw_vport_context.cvlan_pcp, qos); 169 MLX5_SET(modify_esw_vport_context_in, in, 170 esw_vport_context.cvlan_id, vlan); 171 } 172 173 MLX5_SET(modify_esw_vport_context_in, in, 174 field_select.vport_cvlan_strip, 1); 175 MLX5_SET(modify_esw_vport_context_in, in, 176 field_select.vport_cvlan_insert, 1); 177 178 return mlx5_eswitch_modify_esw_vport_context(dev, vport, true, in); 179 } 180 181 /* E-Switch FDB */ 182 static struct mlx5_flow_handle * 183 __esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u16 vport, bool rx_rule, 184 u8 mac_c[ETH_ALEN], u8 mac_v[ETH_ALEN]) 185 { 186 int match_header = (is_zero_ether_addr(mac_c) ? 0 : 187 MLX5_MATCH_OUTER_HEADERS); 188 struct mlx5_flow_handle *flow_rule = NULL; 189 struct mlx5_flow_act flow_act = {0}; 190 struct mlx5_flow_destination dest = {}; 191 struct mlx5_flow_spec *spec; 192 void *mv_misc = NULL; 193 void *mc_misc = NULL; 194 u8 *dmac_v = NULL; 195 u8 *dmac_c = NULL; 196 197 if (rx_rule) 198 match_header |= MLX5_MATCH_MISC_PARAMETERS; 199 200 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 201 if (!spec) 202 return NULL; 203 204 dmac_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, 205 outer_headers.dmac_47_16); 206 dmac_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 207 outer_headers.dmac_47_16); 208 209 if (match_header & MLX5_MATCH_OUTER_HEADERS) { 210 ether_addr_copy(dmac_v, mac_v); 211 ether_addr_copy(dmac_c, mac_c); 212 } 213 214 if (match_header & MLX5_MATCH_MISC_PARAMETERS) { 215 mv_misc = MLX5_ADDR_OF(fte_match_param, spec->match_value, 216 misc_parameters); 217 mc_misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 218 misc_parameters); 219 MLX5_SET(fte_match_set_misc, mv_misc, source_port, MLX5_VPORT_UPLINK); 220 MLX5_SET_TO_ONES(fte_match_set_misc, mc_misc, source_port); 221 } 222 223 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; 224 dest.vport.num = vport; 225 226 esw_debug(esw->dev, 227 "\tFDB add rule dmac_v(%pM) dmac_c(%pM) -> vport(%d)\n", 228 dmac_v, dmac_c, vport); 229 spec->match_criteria_enable = match_header; 230 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 231 flow_rule = 232 mlx5_add_flow_rules(esw->fdb_table.legacy.fdb, spec, 233 &flow_act, &dest, 1); 234 if (IS_ERR(flow_rule)) { 235 esw_warn(esw->dev, 236 "FDB: Failed to add flow rule: dmac_v(%pM) dmac_c(%pM) -> vport(%d), err(%ld)\n", 237 dmac_v, dmac_c, vport, PTR_ERR(flow_rule)); 238 flow_rule = NULL; 239 } 240 241 kvfree(spec); 242 return flow_rule; 243 } 244 245 static struct mlx5_flow_handle * 246 esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u8 mac[ETH_ALEN], u16 vport) 247 { 248 u8 mac_c[ETH_ALEN]; 249 250 eth_broadcast_addr(mac_c); 251 return __esw_fdb_set_vport_rule(esw, vport, false, mac_c, mac); 252 } 253 254 static struct mlx5_flow_handle * 255 esw_fdb_set_vport_allmulti_rule(struct mlx5_eswitch *esw, u16 vport) 256 { 257 u8 mac_c[ETH_ALEN]; 258 u8 mac_v[ETH_ALEN]; 259 260 eth_zero_addr(mac_c); 261 eth_zero_addr(mac_v); 262 mac_c[0] = 0x01; 263 mac_v[0] = 0x01; 264 return __esw_fdb_set_vport_rule(esw, vport, false, mac_c, mac_v); 265 } 266 267 static struct mlx5_flow_handle * 268 esw_fdb_set_vport_promisc_rule(struct mlx5_eswitch *esw, u16 vport) 269 { 270 u8 mac_c[ETH_ALEN]; 271 u8 mac_v[ETH_ALEN]; 272 273 eth_zero_addr(mac_c); 274 eth_zero_addr(mac_v); 275 return __esw_fdb_set_vport_rule(esw, vport, true, mac_c, mac_v); 276 } 277 278 /* E-Switch vport UC/MC lists management */ 279 typedef int (*vport_addr_action)(struct mlx5_eswitch *esw, 280 struct vport_addr *vaddr); 281 282 static int esw_add_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr) 283 { 284 u8 *mac = vaddr->node.addr; 285 u16 vport = vaddr->vport; 286 int err; 287 288 /* Skip mlx5_mpfs_add_mac for eswitch_managers, 289 * it is already done by its netdev in mlx5e_execute_l2_action 290 */ 291 if (mlx5_esw_is_manager_vport(esw, vport)) 292 goto fdb_add; 293 294 err = mlx5_mpfs_add_mac(esw->dev, mac); 295 if (err) { 296 esw_warn(esw->dev, 297 "Failed to add L2 table mac(%pM) for vport(0x%x), err(%d)\n", 298 mac, vport, err); 299 return err; 300 } 301 vaddr->mpfs = true; 302 303 fdb_add: 304 /* SRIOV is enabled: Forward UC MAC to vport */ 305 if (esw->fdb_table.legacy.fdb && esw->mode == MLX5_ESWITCH_LEGACY) 306 vaddr->flow_rule = esw_fdb_set_vport_rule(esw, mac, vport); 307 308 esw_debug(esw->dev, "\tADDED UC MAC: vport[%d] %pM fr(%p)\n", 309 vport, mac, vaddr->flow_rule); 310 311 return 0; 312 } 313 314 static int esw_del_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr) 315 { 316 u8 *mac = vaddr->node.addr; 317 u16 vport = vaddr->vport; 318 int err = 0; 319 320 /* Skip mlx5_mpfs_del_mac for eswitch managers, 321 * it is already done by its netdev in mlx5e_execute_l2_action 322 */ 323 if (!vaddr->mpfs || mlx5_esw_is_manager_vport(esw, vport)) 324 goto fdb_del; 325 326 err = mlx5_mpfs_del_mac(esw->dev, mac); 327 if (err) 328 esw_warn(esw->dev, 329 "Failed to del L2 table mac(%pM) for vport(%d), err(%d)\n", 330 mac, vport, err); 331 vaddr->mpfs = false; 332 333 fdb_del: 334 if (vaddr->flow_rule) 335 mlx5_del_flow_rules(vaddr->flow_rule); 336 vaddr->flow_rule = NULL; 337 338 return 0; 339 } 340 341 static void update_allmulti_vports(struct mlx5_eswitch *esw, 342 struct vport_addr *vaddr, 343 struct esw_mc_addr *esw_mc) 344 { 345 u8 *mac = vaddr->node.addr; 346 struct mlx5_vport *vport; 347 unsigned long i; 348 u16 vport_num; 349 350 mlx5_esw_for_each_vport(esw, i, vport) { 351 struct hlist_head *vport_hash = vport->mc_list; 352 struct vport_addr *iter_vaddr = 353 l2addr_hash_find(vport_hash, 354 mac, 355 struct vport_addr); 356 vport_num = vport->vport; 357 if (IS_ERR_OR_NULL(vport->allmulti_rule) || 358 vaddr->vport == vport_num) 359 continue; 360 switch (vaddr->action) { 361 case MLX5_ACTION_ADD: 362 if (iter_vaddr) 363 continue; 364 iter_vaddr = l2addr_hash_add(vport_hash, mac, 365 struct vport_addr, 366 GFP_KERNEL); 367 if (!iter_vaddr) { 368 esw_warn(esw->dev, 369 "ALL-MULTI: Failed to add MAC(%pM) to vport[%d] DB\n", 370 mac, vport_num); 371 continue; 372 } 373 iter_vaddr->vport = vport_num; 374 iter_vaddr->flow_rule = 375 esw_fdb_set_vport_rule(esw, 376 mac, 377 vport_num); 378 iter_vaddr->mc_promisc = true; 379 break; 380 case MLX5_ACTION_DEL: 381 if (!iter_vaddr) 382 continue; 383 mlx5_del_flow_rules(iter_vaddr->flow_rule); 384 l2addr_hash_del(iter_vaddr); 385 break; 386 } 387 } 388 } 389 390 static int esw_add_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr) 391 { 392 struct hlist_head *hash = esw->mc_table; 393 struct esw_mc_addr *esw_mc; 394 u8 *mac = vaddr->node.addr; 395 u16 vport = vaddr->vport; 396 397 if (!esw->fdb_table.legacy.fdb) 398 return 0; 399 400 esw_mc = l2addr_hash_find(hash, mac, struct esw_mc_addr); 401 if (esw_mc) 402 goto add; 403 404 esw_mc = l2addr_hash_add(hash, mac, struct esw_mc_addr, GFP_KERNEL); 405 if (!esw_mc) 406 return -ENOMEM; 407 408 esw_mc->uplink_rule = /* Forward MC MAC to Uplink */ 409 esw_fdb_set_vport_rule(esw, mac, MLX5_VPORT_UPLINK); 410 411 /* Add this multicast mac to all the mc promiscuous vports */ 412 update_allmulti_vports(esw, vaddr, esw_mc); 413 414 add: 415 /* If the multicast mac is added as a result of mc promiscuous vport, 416 * don't increment the multicast ref count 417 */ 418 if (!vaddr->mc_promisc) 419 esw_mc->refcnt++; 420 421 /* Forward MC MAC to vport */ 422 vaddr->flow_rule = esw_fdb_set_vport_rule(esw, mac, vport); 423 esw_debug(esw->dev, 424 "\tADDED MC MAC: vport[%d] %pM fr(%p) refcnt(%d) uplinkfr(%p)\n", 425 vport, mac, vaddr->flow_rule, 426 esw_mc->refcnt, esw_mc->uplink_rule); 427 return 0; 428 } 429 430 static int esw_del_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr) 431 { 432 struct hlist_head *hash = esw->mc_table; 433 struct esw_mc_addr *esw_mc; 434 u8 *mac = vaddr->node.addr; 435 u16 vport = vaddr->vport; 436 437 if (!esw->fdb_table.legacy.fdb) 438 return 0; 439 440 esw_mc = l2addr_hash_find(hash, mac, struct esw_mc_addr); 441 if (!esw_mc) { 442 esw_warn(esw->dev, 443 "Failed to find eswitch MC addr for MAC(%pM) vport(%d)", 444 mac, vport); 445 return -EINVAL; 446 } 447 esw_debug(esw->dev, 448 "\tDELETE MC MAC: vport[%d] %pM fr(%p) refcnt(%d) uplinkfr(%p)\n", 449 vport, mac, vaddr->flow_rule, esw_mc->refcnt, 450 esw_mc->uplink_rule); 451 452 if (vaddr->flow_rule) 453 mlx5_del_flow_rules(vaddr->flow_rule); 454 vaddr->flow_rule = NULL; 455 456 /* If the multicast mac is added as a result of mc promiscuous vport, 457 * don't decrement the multicast ref count. 458 */ 459 if (vaddr->mc_promisc || (--esw_mc->refcnt > 0)) 460 return 0; 461 462 /* Remove this multicast mac from all the mc promiscuous vports */ 463 update_allmulti_vports(esw, vaddr, esw_mc); 464 465 if (esw_mc->uplink_rule) 466 mlx5_del_flow_rules(esw_mc->uplink_rule); 467 468 l2addr_hash_del(esw_mc); 469 return 0; 470 } 471 472 /* Apply vport UC/MC list to HW l2 table and FDB table */ 473 static void esw_apply_vport_addr_list(struct mlx5_eswitch *esw, 474 struct mlx5_vport *vport, int list_type) 475 { 476 bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC; 477 vport_addr_action vport_addr_add; 478 vport_addr_action vport_addr_del; 479 struct vport_addr *addr; 480 struct l2addr_node *node; 481 struct hlist_head *hash; 482 struct hlist_node *tmp; 483 int hi; 484 485 vport_addr_add = is_uc ? esw_add_uc_addr : 486 esw_add_mc_addr; 487 vport_addr_del = is_uc ? esw_del_uc_addr : 488 esw_del_mc_addr; 489 490 hash = is_uc ? vport->uc_list : vport->mc_list; 491 for_each_l2hash_node(node, tmp, hash, hi) { 492 addr = container_of(node, struct vport_addr, node); 493 switch (addr->action) { 494 case MLX5_ACTION_ADD: 495 vport_addr_add(esw, addr); 496 addr->action = MLX5_ACTION_NONE; 497 break; 498 case MLX5_ACTION_DEL: 499 vport_addr_del(esw, addr); 500 l2addr_hash_del(addr); 501 break; 502 } 503 } 504 } 505 506 /* Sync vport UC/MC list from vport context */ 507 static void esw_update_vport_addr_list(struct mlx5_eswitch *esw, 508 struct mlx5_vport *vport, int list_type) 509 { 510 bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC; 511 u8 (*mac_list)[ETH_ALEN]; 512 struct l2addr_node *node; 513 struct vport_addr *addr; 514 struct hlist_head *hash; 515 struct hlist_node *tmp; 516 int size; 517 int err; 518 int hi; 519 int i; 520 521 size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) : 522 MLX5_MAX_MC_PER_VPORT(esw->dev); 523 524 mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL); 525 if (!mac_list) 526 return; 527 528 hash = is_uc ? vport->uc_list : vport->mc_list; 529 530 for_each_l2hash_node(node, tmp, hash, hi) { 531 addr = container_of(node, struct vport_addr, node); 532 addr->action = MLX5_ACTION_DEL; 533 } 534 535 if (!vport->enabled) 536 goto out; 537 538 err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type, 539 mac_list, &size); 540 if (err) 541 goto out; 542 esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n", 543 vport->vport, is_uc ? "UC" : "MC", size); 544 545 for (i = 0; i < size; i++) { 546 if (is_uc && !is_valid_ether_addr(mac_list[i])) 547 continue; 548 549 if (!is_uc && !is_multicast_ether_addr(mac_list[i])) 550 continue; 551 552 addr = l2addr_hash_find(hash, mac_list[i], struct vport_addr); 553 if (addr) { 554 addr->action = MLX5_ACTION_NONE; 555 /* If this mac was previously added because of allmulti 556 * promiscuous rx mode, its now converted to be original 557 * vport mac. 558 */ 559 if (addr->mc_promisc) { 560 struct esw_mc_addr *esw_mc = 561 l2addr_hash_find(esw->mc_table, 562 mac_list[i], 563 struct esw_mc_addr); 564 if (!esw_mc) { 565 esw_warn(esw->dev, 566 "Failed to MAC(%pM) in mcast DB\n", 567 mac_list[i]); 568 continue; 569 } 570 esw_mc->refcnt++; 571 addr->mc_promisc = false; 572 } 573 continue; 574 } 575 576 addr = l2addr_hash_add(hash, mac_list[i], struct vport_addr, 577 GFP_KERNEL); 578 if (!addr) { 579 esw_warn(esw->dev, 580 "Failed to add MAC(%pM) to vport[%d] DB\n", 581 mac_list[i], vport->vport); 582 continue; 583 } 584 addr->vport = vport->vport; 585 addr->action = MLX5_ACTION_ADD; 586 } 587 out: 588 kfree(mac_list); 589 } 590 591 /* Sync vport UC/MC list from vport context 592 * Must be called after esw_update_vport_addr_list 593 */ 594 static void esw_update_vport_mc_promisc(struct mlx5_eswitch *esw, 595 struct mlx5_vport *vport) 596 { 597 struct l2addr_node *node; 598 struct vport_addr *addr; 599 struct hlist_head *hash; 600 struct hlist_node *tmp; 601 int hi; 602 603 hash = vport->mc_list; 604 605 for_each_l2hash_node(node, tmp, esw->mc_table, hi) { 606 u8 *mac = node->addr; 607 608 addr = l2addr_hash_find(hash, mac, struct vport_addr); 609 if (addr) { 610 if (addr->action == MLX5_ACTION_DEL) 611 addr->action = MLX5_ACTION_NONE; 612 continue; 613 } 614 addr = l2addr_hash_add(hash, mac, struct vport_addr, 615 GFP_KERNEL); 616 if (!addr) { 617 esw_warn(esw->dev, 618 "Failed to add allmulti MAC(%pM) to vport[%d] DB\n", 619 mac, vport->vport); 620 continue; 621 } 622 addr->vport = vport->vport; 623 addr->action = MLX5_ACTION_ADD; 624 addr->mc_promisc = true; 625 } 626 } 627 628 /* Apply vport rx mode to HW FDB table */ 629 static void esw_apply_vport_rx_mode(struct mlx5_eswitch *esw, 630 struct mlx5_vport *vport, 631 bool promisc, bool mc_promisc) 632 { 633 struct esw_mc_addr *allmulti_addr = &esw->mc_promisc; 634 635 if (IS_ERR_OR_NULL(vport->allmulti_rule) != mc_promisc) 636 goto promisc; 637 638 if (mc_promisc) { 639 vport->allmulti_rule = 640 esw_fdb_set_vport_allmulti_rule(esw, vport->vport); 641 if (!allmulti_addr->uplink_rule) 642 allmulti_addr->uplink_rule = 643 esw_fdb_set_vport_allmulti_rule(esw, 644 MLX5_VPORT_UPLINK); 645 allmulti_addr->refcnt++; 646 } else if (vport->allmulti_rule) { 647 mlx5_del_flow_rules(vport->allmulti_rule); 648 vport->allmulti_rule = NULL; 649 650 if (--allmulti_addr->refcnt > 0) 651 goto promisc; 652 653 if (allmulti_addr->uplink_rule) 654 mlx5_del_flow_rules(allmulti_addr->uplink_rule); 655 allmulti_addr->uplink_rule = NULL; 656 } 657 658 promisc: 659 if (IS_ERR_OR_NULL(vport->promisc_rule) != promisc) 660 return; 661 662 if (promisc) { 663 vport->promisc_rule = 664 esw_fdb_set_vport_promisc_rule(esw, vport->vport); 665 } else if (vport->promisc_rule) { 666 mlx5_del_flow_rules(vport->promisc_rule); 667 vport->promisc_rule = NULL; 668 } 669 } 670 671 /* Sync vport rx mode from vport context */ 672 static void esw_update_vport_rx_mode(struct mlx5_eswitch *esw, 673 struct mlx5_vport *vport) 674 { 675 int promisc_all = 0; 676 int promisc_uc = 0; 677 int promisc_mc = 0; 678 int err; 679 680 err = mlx5_query_nic_vport_promisc(esw->dev, 681 vport->vport, 682 &promisc_uc, 683 &promisc_mc, 684 &promisc_all); 685 if (err) 686 return; 687 esw_debug(esw->dev, "vport[%d] context update rx mode promisc_all=%d, all_multi=%d\n", 688 vport->vport, promisc_all, promisc_mc); 689 690 if (!vport->info.trusted || !vport->enabled) { 691 promisc_uc = 0; 692 promisc_mc = 0; 693 promisc_all = 0; 694 } 695 696 esw_apply_vport_rx_mode(esw, vport, promisc_all, 697 (promisc_all || promisc_mc)); 698 } 699 700 void esw_vport_change_handle_locked(struct mlx5_vport *vport) 701 { 702 struct mlx5_core_dev *dev = vport->dev; 703 struct mlx5_eswitch *esw = dev->priv.eswitch; 704 u8 mac[ETH_ALEN]; 705 706 mlx5_query_nic_vport_mac_address(dev, vport->vport, true, mac); 707 esw_debug(dev, "vport[%d] Context Changed: perm mac: %pM\n", 708 vport->vport, mac); 709 710 if (vport->enabled_events & MLX5_VPORT_UC_ADDR_CHANGE) { 711 esw_update_vport_addr_list(esw, vport, MLX5_NVPRT_LIST_TYPE_UC); 712 esw_apply_vport_addr_list(esw, vport, MLX5_NVPRT_LIST_TYPE_UC); 713 } 714 715 if (vport->enabled_events & MLX5_VPORT_MC_ADDR_CHANGE) 716 esw_update_vport_addr_list(esw, vport, MLX5_NVPRT_LIST_TYPE_MC); 717 718 if (vport->enabled_events & MLX5_VPORT_PROMISC_CHANGE) { 719 esw_update_vport_rx_mode(esw, vport); 720 if (!IS_ERR_OR_NULL(vport->allmulti_rule)) 721 esw_update_vport_mc_promisc(esw, vport); 722 } 723 724 if (vport->enabled_events & (MLX5_VPORT_PROMISC_CHANGE | MLX5_VPORT_MC_ADDR_CHANGE)) 725 esw_apply_vport_addr_list(esw, vport, MLX5_NVPRT_LIST_TYPE_MC); 726 727 esw_debug(esw->dev, "vport[%d] Context Changed: Done\n", vport->vport); 728 if (vport->enabled) 729 arm_vport_context_events_cmd(dev, vport->vport, 730 vport->enabled_events); 731 } 732 733 static void esw_vport_change_handler(struct work_struct *work) 734 { 735 struct mlx5_vport *vport = 736 container_of(work, struct mlx5_vport, vport_change_handler); 737 struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 738 739 mutex_lock(&esw->state_lock); 740 esw_vport_change_handle_locked(vport); 741 mutex_unlock(&esw->state_lock); 742 } 743 744 static void node_guid_gen_from_mac(u64 *node_guid, const u8 *mac) 745 { 746 ((u8 *)node_guid)[7] = mac[0]; 747 ((u8 *)node_guid)[6] = mac[1]; 748 ((u8 *)node_guid)[5] = mac[2]; 749 ((u8 *)node_guid)[4] = 0xff; 750 ((u8 *)node_guid)[3] = 0xfe; 751 ((u8 *)node_guid)[2] = mac[3]; 752 ((u8 *)node_guid)[1] = mac[4]; 753 ((u8 *)node_guid)[0] = mac[5]; 754 } 755 756 static int esw_vport_setup_acl(struct mlx5_eswitch *esw, 757 struct mlx5_vport *vport) 758 { 759 if (esw->mode == MLX5_ESWITCH_LEGACY) 760 return esw_legacy_vport_acl_setup(esw, vport); 761 else 762 return esw_vport_create_offloads_acl_tables(esw, vport); 763 } 764 765 static void esw_vport_cleanup_acl(struct mlx5_eswitch *esw, 766 struct mlx5_vport *vport) 767 { 768 if (esw->mode == MLX5_ESWITCH_LEGACY) 769 esw_legacy_vport_acl_cleanup(esw, vport); 770 else 771 esw_vport_destroy_offloads_acl_tables(esw, vport); 772 } 773 774 static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport) 775 { 776 u16 vport_num = vport->vport; 777 int flags; 778 int err; 779 780 err = esw_vport_setup_acl(esw, vport); 781 if (err) 782 return err; 783 784 /* Attach vport to the eswitch rate limiter */ 785 mlx5_esw_qos_vport_enable(esw, vport, vport->qos.max_rate, vport->qos.bw_share); 786 787 if (mlx5_esw_is_manager_vport(esw, vport_num)) 788 return 0; 789 790 mlx5_modify_vport_admin_state(esw->dev, 791 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT, 792 vport_num, 1, 793 vport->info.link_state); 794 795 /* Host PF has its own mac/guid. */ 796 if (vport_num) { 797 mlx5_modify_nic_vport_mac_address(esw->dev, vport_num, 798 vport->info.mac); 799 mlx5_modify_nic_vport_node_guid(esw->dev, vport_num, 800 vport->info.node_guid); 801 } 802 803 flags = (vport->info.vlan || vport->info.qos) ? 804 SET_VLAN_STRIP | SET_VLAN_INSERT : 0; 805 modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan, 806 vport->info.qos, flags); 807 808 return 0; 809 } 810 811 /* Don't cleanup vport->info, it's needed to restore vport configuration */ 812 static void esw_vport_cleanup(struct mlx5_eswitch *esw, struct mlx5_vport *vport) 813 { 814 u16 vport_num = vport->vport; 815 816 if (!mlx5_esw_is_manager_vport(esw, vport_num)) 817 mlx5_modify_vport_admin_state(esw->dev, 818 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT, 819 vport_num, 1, 820 MLX5_VPORT_ADMIN_STATE_DOWN); 821 822 mlx5_esw_qos_vport_disable(esw, vport); 823 esw_vport_cleanup_acl(esw, vport); 824 } 825 826 int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num, 827 enum mlx5_eswitch_vport_event enabled_events) 828 { 829 struct mlx5_vport *vport; 830 int ret; 831 832 vport = mlx5_eswitch_get_vport(esw, vport_num); 833 if (IS_ERR(vport)) 834 return PTR_ERR(vport); 835 836 mutex_lock(&esw->state_lock); 837 WARN_ON(vport->enabled); 838 839 esw_debug(esw->dev, "Enabling VPORT(%d)\n", vport_num); 840 841 ret = esw_vport_setup(esw, vport); 842 if (ret) 843 goto done; 844 845 /* Sync with current vport context */ 846 vport->enabled_events = enabled_events; 847 vport->enabled = true; 848 849 /* Esw manager is trusted by default. Host PF (vport 0) is trusted as well 850 * in smartNIC as it's a vport group manager. 851 */ 852 if (mlx5_esw_is_manager_vport(esw, vport_num) || 853 (!vport_num && mlx5_core_is_ecpf(esw->dev))) 854 vport->info.trusted = true; 855 856 if (!mlx5_esw_is_manager_vport(esw, vport->vport) && 857 MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) { 858 ret = mlx5_esw_vport_vhca_id_set(esw, vport_num); 859 if (ret) 860 goto err_vhca_mapping; 861 } 862 863 /* External controller host PF has factory programmed MAC. 864 * Read it from the device. 865 */ 866 if (mlx5_core_is_ecpf(esw->dev) && vport_num == MLX5_VPORT_PF) 867 mlx5_query_nic_vport_mac_address(esw->dev, vport_num, true, vport->info.mac); 868 869 esw_vport_change_handle_locked(vport); 870 871 esw->enabled_vports++; 872 esw_debug(esw->dev, "Enabled VPORT(%d)\n", vport_num); 873 done: 874 mutex_unlock(&esw->state_lock); 875 return ret; 876 877 err_vhca_mapping: 878 esw_vport_cleanup(esw, vport); 879 mutex_unlock(&esw->state_lock); 880 return ret; 881 } 882 883 void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num) 884 { 885 struct mlx5_vport *vport; 886 887 vport = mlx5_eswitch_get_vport(esw, vport_num); 888 if (IS_ERR(vport)) 889 return; 890 891 mutex_lock(&esw->state_lock); 892 if (!vport->enabled) 893 goto done; 894 895 esw_debug(esw->dev, "Disabling vport(%d)\n", vport_num); 896 /* Mark this vport as disabled to discard new events */ 897 vport->enabled = false; 898 899 /* Disable events from this vport */ 900 arm_vport_context_events_cmd(esw->dev, vport->vport, 0); 901 902 if (!mlx5_esw_is_manager_vport(esw, vport->vport) && 903 MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) 904 mlx5_esw_vport_vhca_id_clear(esw, vport_num); 905 906 /* We don't assume VFs will cleanup after themselves. 907 * Calling vport change handler while vport is disabled will cleanup 908 * the vport resources. 909 */ 910 esw_vport_change_handle_locked(vport); 911 vport->enabled_events = 0; 912 esw_vport_cleanup(esw, vport); 913 esw->enabled_vports--; 914 915 done: 916 mutex_unlock(&esw->state_lock); 917 } 918 919 static int eswitch_vport_event(struct notifier_block *nb, 920 unsigned long type, void *data) 921 { 922 struct mlx5_eswitch *esw = mlx5_nb_cof(nb, struct mlx5_eswitch, nb); 923 struct mlx5_eqe *eqe = data; 924 struct mlx5_vport *vport; 925 u16 vport_num; 926 927 vport_num = be16_to_cpu(eqe->data.vport_change.vport_num); 928 vport = mlx5_eswitch_get_vport(esw, vport_num); 929 if (!IS_ERR(vport)) 930 queue_work(esw->work_queue, &vport->vport_change_handler); 931 return NOTIFY_OK; 932 } 933 934 /** 935 * mlx5_esw_query_functions - Returns raw output about functions state 936 * @dev: Pointer to device to query 937 * 938 * mlx5_esw_query_functions() allocates and returns functions changed 939 * raw output memory pointer from device on success. Otherwise returns ERR_PTR. 940 * Caller must free the memory using kvfree() when valid pointer is returned. 941 */ 942 const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) 943 { 944 int outlen = MLX5_ST_SZ_BYTES(query_esw_functions_out); 945 u32 in[MLX5_ST_SZ_DW(query_esw_functions_in)] = {}; 946 u32 *out; 947 int err; 948 949 out = kvzalloc(outlen, GFP_KERNEL); 950 if (!out) 951 return ERR_PTR(-ENOMEM); 952 953 MLX5_SET(query_esw_functions_in, in, opcode, 954 MLX5_CMD_OP_QUERY_ESW_FUNCTIONS); 955 956 err = mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); 957 if (!err) 958 return out; 959 960 kvfree(out); 961 return ERR_PTR(err); 962 } 963 964 static void mlx5_eswitch_event_handlers_register(struct mlx5_eswitch *esw) 965 { 966 MLX5_NB_INIT(&esw->nb, eswitch_vport_event, NIC_VPORT_CHANGE); 967 mlx5_eq_notifier_register(esw->dev, &esw->nb); 968 969 if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) { 970 MLX5_NB_INIT(&esw->esw_funcs.nb, mlx5_esw_funcs_changed_handler, 971 ESW_FUNCTIONS_CHANGED); 972 mlx5_eq_notifier_register(esw->dev, &esw->esw_funcs.nb); 973 } 974 } 975 976 static void mlx5_eswitch_event_handlers_unregister(struct mlx5_eswitch *esw) 977 { 978 if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) 979 mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); 980 981 mlx5_eq_notifier_unregister(esw->dev, &esw->nb); 982 983 flush_workqueue(esw->work_queue); 984 } 985 986 static void mlx5_eswitch_clear_vf_vports_info(struct mlx5_eswitch *esw) 987 { 988 struct mlx5_vport *vport; 989 unsigned long i; 990 991 mlx5_esw_for_each_vf_vport(esw, i, vport, esw->esw_funcs.num_vfs) { 992 memset(&vport->qos, 0, sizeof(vport->qos)); 993 memset(&vport->info, 0, sizeof(vport->info)); 994 vport->info.link_state = MLX5_VPORT_ADMIN_STATE_AUTO; 995 } 996 } 997 998 /* Public E-Switch API */ 999 int mlx5_eswitch_load_vport(struct mlx5_eswitch *esw, u16 vport_num, 1000 enum mlx5_eswitch_vport_event enabled_events) 1001 { 1002 int err; 1003 1004 err = mlx5_esw_vport_enable(esw, vport_num, enabled_events); 1005 if (err) 1006 return err; 1007 1008 err = esw_offloads_load_rep(esw, vport_num); 1009 if (err) 1010 goto err_rep; 1011 1012 return err; 1013 1014 err_rep: 1015 mlx5_esw_vport_disable(esw, vport_num); 1016 return err; 1017 } 1018 1019 void mlx5_eswitch_unload_vport(struct mlx5_eswitch *esw, u16 vport_num) 1020 { 1021 esw_offloads_unload_rep(esw, vport_num); 1022 mlx5_esw_vport_disable(esw, vport_num); 1023 } 1024 1025 void mlx5_eswitch_unload_vf_vports(struct mlx5_eswitch *esw, u16 num_vfs) 1026 { 1027 struct mlx5_vport *vport; 1028 unsigned long i; 1029 1030 mlx5_esw_for_each_vf_vport(esw, i, vport, num_vfs) { 1031 if (!vport->enabled) 1032 continue; 1033 mlx5_eswitch_unload_vport(esw, vport->vport); 1034 } 1035 } 1036 1037 int mlx5_eswitch_load_vf_vports(struct mlx5_eswitch *esw, u16 num_vfs, 1038 enum mlx5_eswitch_vport_event enabled_events) 1039 { 1040 struct mlx5_vport *vport; 1041 unsigned long i; 1042 int err; 1043 1044 mlx5_esw_for_each_vf_vport(esw, i, vport, num_vfs) { 1045 err = mlx5_eswitch_load_vport(esw, vport->vport, enabled_events); 1046 if (err) 1047 goto vf_err; 1048 } 1049 1050 return 0; 1051 1052 vf_err: 1053 mlx5_eswitch_unload_vf_vports(esw, num_vfs); 1054 return err; 1055 } 1056 1057 static int host_pf_enable_hca(struct mlx5_core_dev *dev) 1058 { 1059 if (!mlx5_core_is_ecpf(dev)) 1060 return 0; 1061 1062 /* Once vport and representor are ready, take out the external host PF 1063 * out of initializing state. Enabling HCA clears the iser->initializing 1064 * bit and host PF driver loading can progress. 1065 */ 1066 return mlx5_cmd_host_pf_enable_hca(dev); 1067 } 1068 1069 static void host_pf_disable_hca(struct mlx5_core_dev *dev) 1070 { 1071 if (!mlx5_core_is_ecpf(dev)) 1072 return; 1073 1074 mlx5_cmd_host_pf_disable_hca(dev); 1075 } 1076 1077 /* mlx5_eswitch_enable_pf_vf_vports() enables vports of PF, ECPF and VFs 1078 * whichever are present on the eswitch. 1079 */ 1080 int 1081 mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw, 1082 enum mlx5_eswitch_vport_event enabled_events) 1083 { 1084 int ret; 1085 1086 /* Enable PF vport */ 1087 ret = mlx5_eswitch_load_vport(esw, MLX5_VPORT_PF, enabled_events); 1088 if (ret) 1089 return ret; 1090 1091 /* Enable external host PF HCA */ 1092 ret = host_pf_enable_hca(esw->dev); 1093 if (ret) 1094 goto pf_hca_err; 1095 1096 /* Enable ECPF vport */ 1097 if (mlx5_ecpf_vport_exists(esw->dev)) { 1098 ret = mlx5_eswitch_load_vport(esw, MLX5_VPORT_ECPF, enabled_events); 1099 if (ret) 1100 goto ecpf_err; 1101 } 1102 1103 /* Enable VF vports */ 1104 ret = mlx5_eswitch_load_vf_vports(esw, esw->esw_funcs.num_vfs, 1105 enabled_events); 1106 if (ret) 1107 goto vf_err; 1108 return 0; 1109 1110 vf_err: 1111 if (mlx5_ecpf_vport_exists(esw->dev)) 1112 mlx5_eswitch_unload_vport(esw, MLX5_VPORT_ECPF); 1113 ecpf_err: 1114 host_pf_disable_hca(esw->dev); 1115 pf_hca_err: 1116 mlx5_eswitch_unload_vport(esw, MLX5_VPORT_PF); 1117 return ret; 1118 } 1119 1120 /* mlx5_eswitch_disable_pf_vf_vports() disables vports of PF, ECPF and VFs 1121 * whichever are previously enabled on the eswitch. 1122 */ 1123 void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw) 1124 { 1125 mlx5_eswitch_unload_vf_vports(esw, esw->esw_funcs.num_vfs); 1126 1127 if (mlx5_ecpf_vport_exists(esw->dev)) 1128 mlx5_eswitch_unload_vport(esw, MLX5_VPORT_ECPF); 1129 1130 host_pf_disable_hca(esw->dev); 1131 mlx5_eswitch_unload_vport(esw, MLX5_VPORT_PF); 1132 } 1133 1134 static void mlx5_eswitch_get_devlink_param(struct mlx5_eswitch *esw) 1135 { 1136 struct devlink *devlink = priv_to_devlink(esw->dev); 1137 union devlink_param_value val; 1138 int err; 1139 1140 err = devlink_param_driverinit_value_get(devlink, 1141 MLX5_DEVLINK_PARAM_ID_ESW_LARGE_GROUP_NUM, 1142 &val); 1143 if (!err) { 1144 esw->params.large_group_num = val.vu32; 1145 } else { 1146 esw_warn(esw->dev, 1147 "Devlink can't get param fdb_large_groups, uses default (%d).\n", 1148 ESW_OFFLOADS_DEFAULT_NUM_GROUPS); 1149 esw->params.large_group_num = ESW_OFFLOADS_DEFAULT_NUM_GROUPS; 1150 } 1151 } 1152 1153 static void 1154 mlx5_eswitch_update_num_of_vfs(struct mlx5_eswitch *esw, int num_vfs) 1155 { 1156 const u32 *out; 1157 1158 WARN_ON_ONCE(esw->mode != MLX5_ESWITCH_NONE); 1159 1160 if (num_vfs < 0) 1161 return; 1162 1163 if (!mlx5_core_is_ecpf_esw_manager(esw->dev)) { 1164 esw->esw_funcs.num_vfs = num_vfs; 1165 return; 1166 } 1167 1168 out = mlx5_esw_query_functions(esw->dev); 1169 if (IS_ERR(out)) 1170 return; 1171 1172 esw->esw_funcs.num_vfs = MLX5_GET(query_esw_functions_out, out, 1173 host_params_context.host_num_of_vfs); 1174 kvfree(out); 1175 } 1176 1177 static void mlx5_esw_mode_change_notify(struct mlx5_eswitch *esw, u16 mode) 1178 { 1179 struct mlx5_esw_event_info info = {}; 1180 1181 info.new_mode = mode; 1182 1183 blocking_notifier_call_chain(&esw->n_head, 0, &info); 1184 } 1185 1186 static int mlx5_esw_acls_ns_init(struct mlx5_eswitch *esw) 1187 { 1188 struct mlx5_core_dev *dev = esw->dev; 1189 int total_vports; 1190 int err; 1191 1192 total_vports = mlx5_eswitch_get_total_vports(dev); 1193 1194 if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) { 1195 err = mlx5_fs_egress_acls_init(dev, total_vports); 1196 if (err) 1197 return err; 1198 } else { 1199 esw_warn(dev, "engress ACL is not supported by FW\n"); 1200 } 1201 1202 if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) { 1203 err = mlx5_fs_ingress_acls_init(dev, total_vports); 1204 if (err) 1205 goto err; 1206 } else { 1207 esw_warn(dev, "ingress ACL is not supported by FW\n"); 1208 } 1209 return 0; 1210 1211 err: 1212 if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) 1213 mlx5_fs_egress_acls_cleanup(dev); 1214 return err; 1215 } 1216 1217 static void mlx5_esw_acls_ns_cleanup(struct mlx5_eswitch *esw) 1218 { 1219 struct mlx5_core_dev *dev = esw->dev; 1220 1221 if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) 1222 mlx5_fs_ingress_acls_cleanup(dev); 1223 if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) 1224 mlx5_fs_egress_acls_cleanup(dev); 1225 } 1226 1227 /** 1228 * mlx5_eswitch_enable_locked - Enable eswitch 1229 * @esw: Pointer to eswitch 1230 * @mode: Eswitch mode to enable 1231 * @num_vfs: Enable eswitch for given number of VFs. This is optional. 1232 * Valid value are 0, > 0 and MLX5_ESWITCH_IGNORE_NUM_VFS. 1233 * Caller should pass num_vfs > 0 when enabling eswitch for 1234 * vf vports. Caller should pass num_vfs = 0, when eswitch 1235 * is enabled without sriov VFs or when caller 1236 * is unaware of the sriov state of the host PF on ECPF based 1237 * eswitch. Caller should pass < 0 when num_vfs should be 1238 * completely ignored. This is typically the case when eswitch 1239 * is enabled without sriov regardless of PF/ECPF system. 1240 * mlx5_eswitch_enable_locked() Enables eswitch in either legacy or offloads 1241 * mode. If num_vfs >=0 is provided, it setup VF related eswitch vports. 1242 * It returns 0 on success or error code on failure. 1243 */ 1244 int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int mode, int num_vfs) 1245 { 1246 int err; 1247 1248 lockdep_assert_held(&esw->mode_lock); 1249 1250 if (!MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ft_support)) { 1251 esw_warn(esw->dev, "FDB is not supported, aborting ...\n"); 1252 return -EOPNOTSUPP; 1253 } 1254 1255 mlx5_eswitch_get_devlink_param(esw); 1256 1257 err = mlx5_esw_acls_ns_init(esw); 1258 if (err) 1259 return err; 1260 1261 mlx5_eswitch_update_num_of_vfs(esw, num_vfs); 1262 1263 mlx5_esw_qos_create(esw); 1264 1265 esw->mode = mode; 1266 1267 if (mode == MLX5_ESWITCH_LEGACY) { 1268 err = esw_legacy_enable(esw); 1269 } else { 1270 mlx5_rescan_drivers(esw->dev); 1271 err = esw_offloads_enable(esw); 1272 } 1273 1274 if (err) 1275 goto abort; 1276 1277 mlx5_eswitch_event_handlers_register(esw); 1278 1279 esw_info(esw->dev, "Enable: mode(%s), nvfs(%d), active vports(%d)\n", 1280 mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", 1281 esw->esw_funcs.num_vfs, esw->enabled_vports); 1282 1283 mlx5_esw_mode_change_notify(esw, mode); 1284 1285 return 0; 1286 1287 abort: 1288 esw->mode = MLX5_ESWITCH_NONE; 1289 1290 if (mode == MLX5_ESWITCH_OFFLOADS) 1291 mlx5_rescan_drivers(esw->dev); 1292 1293 mlx5_esw_qos_destroy(esw); 1294 mlx5_esw_acls_ns_cleanup(esw); 1295 return err; 1296 } 1297 1298 /** 1299 * mlx5_eswitch_enable - Enable eswitch 1300 * @esw: Pointer to eswitch 1301 * @num_vfs: Enable eswitch switch for given number of VFs. 1302 * Caller must pass num_vfs > 0 when enabling eswitch for 1303 * vf vports. 1304 * mlx5_eswitch_enable() returns 0 on success or error code on failure. 1305 */ 1306 int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) 1307 { 1308 bool toggle_lag; 1309 int ret; 1310 1311 if (!mlx5_esw_allowed(esw)) 1312 return 0; 1313 1314 toggle_lag = esw->mode == MLX5_ESWITCH_NONE; 1315 1316 if (toggle_lag) 1317 mlx5_lag_disable_change(esw->dev); 1318 1319 down_write(&esw->mode_lock); 1320 if (esw->mode == MLX5_ESWITCH_NONE) { 1321 ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs); 1322 } else { 1323 enum mlx5_eswitch_vport_event vport_events; 1324 1325 vport_events = (esw->mode == MLX5_ESWITCH_LEGACY) ? 1326 MLX5_LEGACY_SRIOV_VPORT_EVENTS : MLX5_VPORT_UC_ADDR_CHANGE; 1327 ret = mlx5_eswitch_load_vf_vports(esw, num_vfs, vport_events); 1328 if (!ret) 1329 esw->esw_funcs.num_vfs = num_vfs; 1330 } 1331 up_write(&esw->mode_lock); 1332 1333 if (toggle_lag) 1334 mlx5_lag_enable_change(esw->dev); 1335 1336 return ret; 1337 } 1338 1339 void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf) 1340 { 1341 int old_mode; 1342 1343 lockdep_assert_held_write(&esw->mode_lock); 1344 1345 if (esw->mode == MLX5_ESWITCH_NONE) 1346 return; 1347 1348 esw_info(esw->dev, "Disable: mode(%s), nvfs(%d), active vports(%d)\n", 1349 esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS", 1350 esw->esw_funcs.num_vfs, esw->enabled_vports); 1351 1352 /* Notify eswitch users that it is exiting from current mode. 1353 * So that it can do necessary cleanup before the eswitch is disabled. 1354 */ 1355 mlx5_esw_mode_change_notify(esw, MLX5_ESWITCH_NONE); 1356 1357 mlx5_eswitch_event_handlers_unregister(esw); 1358 1359 if (esw->mode == MLX5_ESWITCH_LEGACY) 1360 esw_legacy_disable(esw); 1361 else if (esw->mode == MLX5_ESWITCH_OFFLOADS) 1362 esw_offloads_disable(esw); 1363 1364 old_mode = esw->mode; 1365 esw->mode = MLX5_ESWITCH_NONE; 1366 1367 if (old_mode == MLX5_ESWITCH_OFFLOADS) 1368 mlx5_rescan_drivers(esw->dev); 1369 1370 mlx5_esw_qos_destroy(esw); 1371 mlx5_esw_acls_ns_cleanup(esw); 1372 1373 if (clear_vf) 1374 mlx5_eswitch_clear_vf_vports_info(esw); 1375 } 1376 1377 void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) 1378 { 1379 if (!mlx5_esw_allowed(esw)) 1380 return; 1381 1382 mlx5_lag_disable_change(esw->dev); 1383 down_write(&esw->mode_lock); 1384 mlx5_eswitch_disable_locked(esw, clear_vf); 1385 esw->esw_funcs.num_vfs = 0; 1386 up_write(&esw->mode_lock); 1387 mlx5_lag_enable_change(esw->dev); 1388 } 1389 1390 static int mlx5_query_hca_cap_host_pf(struct mlx5_core_dev *dev, void *out) 1391 { 1392 u16 opmod = (MLX5_CAP_GENERAL << 1) | (HCA_CAP_OPMOD_GET_MAX & 0x01); 1393 u8 in[MLX5_ST_SZ_BYTES(query_hca_cap_in)] = {}; 1394 1395 MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); 1396 MLX5_SET(query_hca_cap_in, in, op_mod, opmod); 1397 MLX5_SET(query_hca_cap_in, in, function_id, MLX5_VPORT_PF); 1398 MLX5_SET(query_hca_cap_in, in, other_function, true); 1399 return mlx5_cmd_exec_inout(dev, query_hca_cap, in, out); 1400 } 1401 1402 int mlx5_esw_sf_max_hpf_functions(struct mlx5_core_dev *dev, u16 *max_sfs, u16 *sf_base_id) 1403 1404 { 1405 int query_out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); 1406 void *query_ctx; 1407 void *hca_caps; 1408 int err; 1409 1410 if (!mlx5_core_is_ecpf(dev)) { 1411 *max_sfs = 0; 1412 return 0; 1413 } 1414 1415 query_ctx = kzalloc(query_out_sz, GFP_KERNEL); 1416 if (!query_ctx) 1417 return -ENOMEM; 1418 1419 err = mlx5_query_hca_cap_host_pf(dev, query_ctx); 1420 if (err) 1421 goto out_free; 1422 1423 hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); 1424 *max_sfs = MLX5_GET(cmd_hca_cap, hca_caps, max_num_sf); 1425 *sf_base_id = MLX5_GET(cmd_hca_cap, hca_caps, sf_base_id); 1426 1427 out_free: 1428 kfree(query_ctx); 1429 return err; 1430 } 1431 1432 static int mlx5_esw_vport_alloc(struct mlx5_eswitch *esw, struct mlx5_core_dev *dev, 1433 int index, u16 vport_num) 1434 { 1435 struct mlx5_vport *vport; 1436 int err; 1437 1438 vport = kzalloc(sizeof(*vport), GFP_KERNEL); 1439 if (!vport) 1440 return -ENOMEM; 1441 1442 vport->dev = esw->dev; 1443 vport->vport = vport_num; 1444 vport->index = index; 1445 vport->info.link_state = MLX5_VPORT_ADMIN_STATE_AUTO; 1446 INIT_WORK(&vport->vport_change_handler, esw_vport_change_handler); 1447 err = xa_insert(&esw->vports, vport_num, vport, GFP_KERNEL); 1448 if (err) 1449 goto insert_err; 1450 1451 esw->total_vports++; 1452 return 0; 1453 1454 insert_err: 1455 kfree(vport); 1456 return err; 1457 } 1458 1459 static void mlx5_esw_vport_free(struct mlx5_eswitch *esw, struct mlx5_vport *vport) 1460 { 1461 xa_erase(&esw->vports, vport->vport); 1462 kfree(vport); 1463 } 1464 1465 static void mlx5_esw_vports_cleanup(struct mlx5_eswitch *esw) 1466 { 1467 struct mlx5_vport *vport; 1468 unsigned long i; 1469 1470 mlx5_esw_for_each_vport(esw, i, vport) 1471 mlx5_esw_vport_free(esw, vport); 1472 xa_destroy(&esw->vports); 1473 } 1474 1475 static int mlx5_esw_vports_init(struct mlx5_eswitch *esw) 1476 { 1477 struct mlx5_core_dev *dev = esw->dev; 1478 u16 max_host_pf_sfs; 1479 u16 base_sf_num; 1480 int idx = 0; 1481 int err; 1482 int i; 1483 1484 xa_init(&esw->vports); 1485 1486 err = mlx5_esw_vport_alloc(esw, dev, idx, MLX5_VPORT_PF); 1487 if (err) 1488 goto err; 1489 if (esw->first_host_vport == MLX5_VPORT_PF) 1490 xa_set_mark(&esw->vports, idx, MLX5_ESW_VPT_HOST_FN); 1491 idx++; 1492 1493 for (i = 0; i < mlx5_core_max_vfs(dev); i++) { 1494 err = mlx5_esw_vport_alloc(esw, dev, idx, idx); 1495 if (err) 1496 goto err; 1497 xa_set_mark(&esw->vports, idx, MLX5_ESW_VPT_VF); 1498 xa_set_mark(&esw->vports, idx, MLX5_ESW_VPT_HOST_FN); 1499 idx++; 1500 } 1501 base_sf_num = mlx5_sf_start_function_id(dev); 1502 for (i = 0; i < mlx5_sf_max_functions(dev); i++) { 1503 err = mlx5_esw_vport_alloc(esw, dev, idx, base_sf_num + i); 1504 if (err) 1505 goto err; 1506 xa_set_mark(&esw->vports, base_sf_num + i, MLX5_ESW_VPT_SF); 1507 idx++; 1508 } 1509 1510 err = mlx5_esw_sf_max_hpf_functions(dev, &max_host_pf_sfs, &base_sf_num); 1511 if (err) 1512 goto err; 1513 for (i = 0; i < max_host_pf_sfs; i++) { 1514 err = mlx5_esw_vport_alloc(esw, dev, idx, base_sf_num + i); 1515 if (err) 1516 goto err; 1517 xa_set_mark(&esw->vports, base_sf_num + i, MLX5_ESW_VPT_SF); 1518 idx++; 1519 } 1520 1521 if (mlx5_ecpf_vport_exists(dev)) { 1522 err = mlx5_esw_vport_alloc(esw, dev, idx, MLX5_VPORT_ECPF); 1523 if (err) 1524 goto err; 1525 idx++; 1526 } 1527 err = mlx5_esw_vport_alloc(esw, dev, idx, MLX5_VPORT_UPLINK); 1528 if (err) 1529 goto err; 1530 return 0; 1531 1532 err: 1533 mlx5_esw_vports_cleanup(esw); 1534 return err; 1535 } 1536 1537 int mlx5_eswitch_init(struct mlx5_core_dev *dev) 1538 { 1539 struct mlx5_eswitch *esw; 1540 int err; 1541 1542 if (!MLX5_VPORT_MANAGER(dev)) 1543 return 0; 1544 1545 esw = kzalloc(sizeof(*esw), GFP_KERNEL); 1546 if (!esw) 1547 return -ENOMEM; 1548 1549 esw->dev = dev; 1550 esw->manager_vport = mlx5_eswitch_manager_vport(dev); 1551 esw->first_host_vport = mlx5_eswitch_first_host_vport_num(dev); 1552 1553 esw->work_queue = create_singlethread_workqueue("mlx5_esw_wq"); 1554 if (!esw->work_queue) { 1555 err = -ENOMEM; 1556 goto abort; 1557 } 1558 1559 err = mlx5_esw_vports_init(esw); 1560 if (err) 1561 goto abort; 1562 1563 err = esw_offloads_init_reps(esw); 1564 if (err) 1565 goto reps_err; 1566 1567 mutex_init(&esw->offloads.encap_tbl_lock); 1568 hash_init(esw->offloads.encap_tbl); 1569 mutex_init(&esw->offloads.decap_tbl_lock); 1570 hash_init(esw->offloads.decap_tbl); 1571 mlx5e_mod_hdr_tbl_init(&esw->offloads.mod_hdr); 1572 atomic64_set(&esw->offloads.num_flows, 0); 1573 ida_init(&esw->offloads.vport_metadata_ida); 1574 xa_init_flags(&esw->offloads.vhca_map, XA_FLAGS_ALLOC); 1575 mutex_init(&esw->state_lock); 1576 lockdep_register_key(&esw->mode_lock_key); 1577 init_rwsem(&esw->mode_lock); 1578 lockdep_set_class(&esw->mode_lock, &esw->mode_lock_key); 1579 1580 esw->enabled_vports = 0; 1581 esw->mode = MLX5_ESWITCH_NONE; 1582 esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE; 1583 if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) && 1584 MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)) 1585 esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC; 1586 else 1587 esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; 1588 1589 dev->priv.eswitch = esw; 1590 BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head); 1591 1592 esw_info(dev, 1593 "Total vports %d, per vport: max uc(%d) max mc(%d)\n", 1594 esw->total_vports, 1595 MLX5_MAX_UC_PER_VPORT(dev), 1596 MLX5_MAX_MC_PER_VPORT(dev)); 1597 return 0; 1598 1599 reps_err: 1600 mlx5_esw_vports_cleanup(esw); 1601 abort: 1602 if (esw->work_queue) 1603 destroy_workqueue(esw->work_queue); 1604 kfree(esw); 1605 return err; 1606 } 1607 1608 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) 1609 { 1610 if (!esw || !MLX5_VPORT_MANAGER(esw->dev)) 1611 return; 1612 1613 esw_info(esw->dev, "cleanup\n"); 1614 1615 esw->dev->priv.eswitch = NULL; 1616 destroy_workqueue(esw->work_queue); 1617 lockdep_unregister_key(&esw->mode_lock_key); 1618 mutex_destroy(&esw->state_lock); 1619 WARN_ON(!xa_empty(&esw->offloads.vhca_map)); 1620 xa_destroy(&esw->offloads.vhca_map); 1621 ida_destroy(&esw->offloads.vport_metadata_ida); 1622 mlx5e_mod_hdr_tbl_destroy(&esw->offloads.mod_hdr); 1623 mutex_destroy(&esw->offloads.encap_tbl_lock); 1624 mutex_destroy(&esw->offloads.decap_tbl_lock); 1625 esw_offloads_cleanup_reps(esw); 1626 mlx5_esw_vports_cleanup(esw); 1627 kfree(esw); 1628 } 1629 1630 /* Vport Administration */ 1631 static int 1632 mlx5_esw_set_vport_mac_locked(struct mlx5_eswitch *esw, 1633 struct mlx5_vport *evport, const u8 *mac) 1634 { 1635 u16 vport_num = evport->vport; 1636 u64 node_guid; 1637 int err = 0; 1638 1639 if (is_multicast_ether_addr(mac)) 1640 return -EINVAL; 1641 1642 if (evport->info.spoofchk && !is_valid_ether_addr(mac)) 1643 mlx5_core_warn(esw->dev, 1644 "Set invalid MAC while spoofchk is on, vport(%d)\n", 1645 vport_num); 1646 1647 err = mlx5_modify_nic_vport_mac_address(esw->dev, vport_num, mac); 1648 if (err) { 1649 mlx5_core_warn(esw->dev, 1650 "Failed to mlx5_modify_nic_vport_mac vport(%d) err=(%d)\n", 1651 vport_num, err); 1652 return err; 1653 } 1654 1655 node_guid_gen_from_mac(&node_guid, mac); 1656 err = mlx5_modify_nic_vport_node_guid(esw->dev, vport_num, node_guid); 1657 if (err) 1658 mlx5_core_warn(esw->dev, 1659 "Failed to set vport %d node guid, err = %d. RDMA_CM will not function properly for this VF.\n", 1660 vport_num, err); 1661 1662 ether_addr_copy(evport->info.mac, mac); 1663 evport->info.node_guid = node_guid; 1664 if (evport->enabled && esw->mode == MLX5_ESWITCH_LEGACY) 1665 err = esw_acl_ingress_lgcy_setup(esw, evport); 1666 1667 return err; 1668 } 1669 1670 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, 1671 u16 vport, const u8 *mac) 1672 { 1673 struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); 1674 int err = 0; 1675 1676 if (IS_ERR(evport)) 1677 return PTR_ERR(evport); 1678 1679 mutex_lock(&esw->state_lock); 1680 err = mlx5_esw_set_vport_mac_locked(esw, evport, mac); 1681 mutex_unlock(&esw->state_lock); 1682 return err; 1683 } 1684 1685 static bool mlx5_esw_check_port_type(struct mlx5_eswitch *esw, u16 vport_num, xa_mark_t mark) 1686 { 1687 struct mlx5_vport *vport; 1688 1689 vport = mlx5_eswitch_get_vport(esw, vport_num); 1690 if (IS_ERR(vport)) 1691 return false; 1692 1693 return xa_get_mark(&esw->vports, vport_num, mark); 1694 } 1695 1696 bool mlx5_eswitch_is_vf_vport(struct mlx5_eswitch *esw, u16 vport_num) 1697 { 1698 return mlx5_esw_check_port_type(esw, vport_num, MLX5_ESW_VPT_VF); 1699 } 1700 1701 bool mlx5_esw_is_sf_vport(struct mlx5_eswitch *esw, u16 vport_num) 1702 { 1703 return mlx5_esw_check_port_type(esw, vport_num, MLX5_ESW_VPT_SF); 1704 } 1705 1706 static bool 1707 is_port_function_supported(struct mlx5_eswitch *esw, u16 vport_num) 1708 { 1709 return vport_num == MLX5_VPORT_PF || 1710 mlx5_eswitch_is_vf_vport(esw, vport_num) || 1711 mlx5_esw_is_sf_vport(esw, vport_num); 1712 } 1713 1714 int mlx5_devlink_port_function_hw_addr_get(struct devlink_port *port, 1715 u8 *hw_addr, int *hw_addr_len, 1716 struct netlink_ext_ack *extack) 1717 { 1718 struct mlx5_eswitch *esw; 1719 struct mlx5_vport *vport; 1720 int err = -EOPNOTSUPP; 1721 u16 vport_num; 1722 1723 esw = mlx5_devlink_eswitch_get(port->devlink); 1724 if (IS_ERR(esw)) 1725 return PTR_ERR(esw); 1726 1727 vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index); 1728 if (!is_port_function_supported(esw, vport_num)) 1729 return -EOPNOTSUPP; 1730 1731 vport = mlx5_eswitch_get_vport(esw, vport_num); 1732 if (IS_ERR(vport)) { 1733 NL_SET_ERR_MSG_MOD(extack, "Invalid port"); 1734 return PTR_ERR(vport); 1735 } 1736 1737 mutex_lock(&esw->state_lock); 1738 if (vport->enabled) { 1739 ether_addr_copy(hw_addr, vport->info.mac); 1740 *hw_addr_len = ETH_ALEN; 1741 err = 0; 1742 } 1743 mutex_unlock(&esw->state_lock); 1744 return err; 1745 } 1746 1747 int mlx5_devlink_port_function_hw_addr_set(struct devlink_port *port, 1748 const u8 *hw_addr, int hw_addr_len, 1749 struct netlink_ext_ack *extack) 1750 { 1751 struct mlx5_eswitch *esw; 1752 struct mlx5_vport *vport; 1753 int err = -EOPNOTSUPP; 1754 u16 vport_num; 1755 1756 esw = mlx5_devlink_eswitch_get(port->devlink); 1757 if (IS_ERR(esw)) { 1758 NL_SET_ERR_MSG_MOD(extack, "Eswitch doesn't support set hw_addr"); 1759 return PTR_ERR(esw); 1760 } 1761 1762 vport_num = mlx5_esw_devlink_port_index_to_vport_num(port->index); 1763 if (!is_port_function_supported(esw, vport_num)) { 1764 NL_SET_ERR_MSG_MOD(extack, "Port doesn't support set hw_addr"); 1765 return -EINVAL; 1766 } 1767 vport = mlx5_eswitch_get_vport(esw, vport_num); 1768 if (IS_ERR(vport)) { 1769 NL_SET_ERR_MSG_MOD(extack, "Invalid port"); 1770 return PTR_ERR(vport); 1771 } 1772 1773 mutex_lock(&esw->state_lock); 1774 if (vport->enabled) 1775 err = mlx5_esw_set_vport_mac_locked(esw, vport, hw_addr); 1776 else 1777 NL_SET_ERR_MSG_MOD(extack, "Eswitch vport is disabled"); 1778 mutex_unlock(&esw->state_lock); 1779 return err; 1780 } 1781 1782 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, 1783 u16 vport, int link_state) 1784 { 1785 struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); 1786 int opmod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT; 1787 int other_vport = 1; 1788 int err = 0; 1789 1790 if (!mlx5_esw_allowed(esw)) 1791 return -EPERM; 1792 if (IS_ERR(evport)) 1793 return PTR_ERR(evport); 1794 1795 if (vport == MLX5_VPORT_UPLINK) { 1796 opmod = MLX5_VPORT_STATE_OP_MOD_UPLINK; 1797 other_vport = 0; 1798 vport = 0; 1799 } 1800 mutex_lock(&esw->state_lock); 1801 if (esw->mode != MLX5_ESWITCH_LEGACY) { 1802 err = -EOPNOTSUPP; 1803 goto unlock; 1804 } 1805 1806 err = mlx5_modify_vport_admin_state(esw->dev, opmod, vport, other_vport, link_state); 1807 if (err) { 1808 mlx5_core_warn(esw->dev, "Failed to set vport %d link state, opmod = %d, err = %d", 1809 vport, opmod, err); 1810 goto unlock; 1811 } 1812 1813 evport->info.link_state = link_state; 1814 1815 unlock: 1816 mutex_unlock(&esw->state_lock); 1817 return err; 1818 } 1819 1820 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, 1821 u16 vport, struct ifla_vf_info *ivi) 1822 { 1823 struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); 1824 1825 if (IS_ERR(evport)) 1826 return PTR_ERR(evport); 1827 1828 memset(ivi, 0, sizeof(*ivi)); 1829 ivi->vf = vport - 1; 1830 1831 mutex_lock(&esw->state_lock); 1832 ether_addr_copy(ivi->mac, evport->info.mac); 1833 ivi->linkstate = evport->info.link_state; 1834 ivi->vlan = evport->info.vlan; 1835 ivi->qos = evport->info.qos; 1836 ivi->spoofchk = evport->info.spoofchk; 1837 ivi->trusted = evport->info.trusted; 1838 ivi->min_tx_rate = evport->qos.min_rate; 1839 ivi->max_tx_rate = evport->qos.max_rate; 1840 mutex_unlock(&esw->state_lock); 1841 1842 return 0; 1843 } 1844 1845 int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, 1846 u16 vport, u16 vlan, u8 qos, u8 set_flags) 1847 { 1848 struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); 1849 int err = 0; 1850 1851 if (IS_ERR(evport)) 1852 return PTR_ERR(evport); 1853 if (vlan > 4095 || qos > 7) 1854 return -EINVAL; 1855 1856 err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags); 1857 if (err) 1858 return err; 1859 1860 evport->info.vlan = vlan; 1861 evport->info.qos = qos; 1862 if (evport->enabled && esw->mode == MLX5_ESWITCH_LEGACY) { 1863 err = esw_acl_ingress_lgcy_setup(esw, evport); 1864 if (err) 1865 return err; 1866 err = esw_acl_egress_lgcy_setup(esw, evport); 1867 } 1868 1869 return err; 1870 } 1871 1872 int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, 1873 u16 vport_num, 1874 struct ifla_vf_stats *vf_stats) 1875 { 1876 struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num); 1877 int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out); 1878 u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)] = {}; 1879 struct mlx5_vport_drop_stats stats = {}; 1880 int err = 0; 1881 u32 *out; 1882 1883 if (IS_ERR(vport)) 1884 return PTR_ERR(vport); 1885 1886 out = kvzalloc(outlen, GFP_KERNEL); 1887 if (!out) 1888 return -ENOMEM; 1889 1890 MLX5_SET(query_vport_counter_in, in, opcode, 1891 MLX5_CMD_OP_QUERY_VPORT_COUNTER); 1892 MLX5_SET(query_vport_counter_in, in, op_mod, 0); 1893 MLX5_SET(query_vport_counter_in, in, vport_number, vport->vport); 1894 MLX5_SET(query_vport_counter_in, in, other_vport, 1); 1895 1896 err = mlx5_cmd_exec_inout(esw->dev, query_vport_counter, in, out); 1897 if (err) 1898 goto free_out; 1899 1900 #define MLX5_GET_CTR(p, x) \ 1901 MLX5_GET64(query_vport_counter_out, p, x) 1902 1903 memset(vf_stats, 0, sizeof(*vf_stats)); 1904 vf_stats->rx_packets = 1905 MLX5_GET_CTR(out, received_eth_unicast.packets) + 1906 MLX5_GET_CTR(out, received_ib_unicast.packets) + 1907 MLX5_GET_CTR(out, received_eth_multicast.packets) + 1908 MLX5_GET_CTR(out, received_ib_multicast.packets) + 1909 MLX5_GET_CTR(out, received_eth_broadcast.packets); 1910 1911 vf_stats->rx_bytes = 1912 MLX5_GET_CTR(out, received_eth_unicast.octets) + 1913 MLX5_GET_CTR(out, received_ib_unicast.octets) + 1914 MLX5_GET_CTR(out, received_eth_multicast.octets) + 1915 MLX5_GET_CTR(out, received_ib_multicast.octets) + 1916 MLX5_GET_CTR(out, received_eth_broadcast.octets); 1917 1918 vf_stats->tx_packets = 1919 MLX5_GET_CTR(out, transmitted_eth_unicast.packets) + 1920 MLX5_GET_CTR(out, transmitted_ib_unicast.packets) + 1921 MLX5_GET_CTR(out, transmitted_eth_multicast.packets) + 1922 MLX5_GET_CTR(out, transmitted_ib_multicast.packets) + 1923 MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); 1924 1925 vf_stats->tx_bytes = 1926 MLX5_GET_CTR(out, transmitted_eth_unicast.octets) + 1927 MLX5_GET_CTR(out, transmitted_ib_unicast.octets) + 1928 MLX5_GET_CTR(out, transmitted_eth_multicast.octets) + 1929 MLX5_GET_CTR(out, transmitted_ib_multicast.octets) + 1930 MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); 1931 1932 vf_stats->multicast = 1933 MLX5_GET_CTR(out, received_eth_multicast.packets) + 1934 MLX5_GET_CTR(out, received_ib_multicast.packets); 1935 1936 vf_stats->broadcast = 1937 MLX5_GET_CTR(out, received_eth_broadcast.packets); 1938 1939 err = mlx5_esw_query_vport_drop_stats(esw->dev, vport, &stats); 1940 if (err) 1941 goto free_out; 1942 vf_stats->rx_dropped = stats.rx_dropped; 1943 vf_stats->tx_dropped = stats.tx_dropped; 1944 1945 free_out: 1946 kvfree(out); 1947 return err; 1948 } 1949 1950 u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev) 1951 { 1952 struct mlx5_eswitch *esw = dev->priv.eswitch; 1953 1954 return mlx5_esw_allowed(esw) ? esw->mode : MLX5_ESWITCH_NONE; 1955 } 1956 EXPORT_SYMBOL_GPL(mlx5_eswitch_mode); 1957 1958 enum devlink_eswitch_encap_mode 1959 mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev) 1960 { 1961 struct mlx5_eswitch *esw; 1962 1963 esw = dev->priv.eswitch; 1964 return (mlx5_eswitch_mode(dev) == MLX5_ESWITCH_OFFLOADS) ? esw->offloads.encap : 1965 DEVLINK_ESWITCH_ENCAP_MODE_NONE; 1966 } 1967 EXPORT_SYMBOL(mlx5_eswitch_get_encap_mode); 1968 1969 bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) 1970 { 1971 if ((dev0->priv.eswitch->mode == MLX5_ESWITCH_NONE && 1972 dev1->priv.eswitch->mode == MLX5_ESWITCH_NONE) || 1973 (dev0->priv.eswitch->mode == MLX5_ESWITCH_OFFLOADS && 1974 dev1->priv.eswitch->mode == MLX5_ESWITCH_OFFLOADS)) 1975 return true; 1976 1977 return false; 1978 } 1979 1980 bool mlx5_esw_multipath_prereq(struct mlx5_core_dev *dev0, 1981 struct mlx5_core_dev *dev1) 1982 { 1983 return (dev0->priv.eswitch->mode == MLX5_ESWITCH_OFFLOADS && 1984 dev1->priv.eswitch->mode == MLX5_ESWITCH_OFFLOADS); 1985 } 1986 1987 int mlx5_esw_event_notifier_register(struct mlx5_eswitch *esw, struct notifier_block *nb) 1988 { 1989 return blocking_notifier_chain_register(&esw->n_head, nb); 1990 } 1991 1992 void mlx5_esw_event_notifier_unregister(struct mlx5_eswitch *esw, struct notifier_block *nb) 1993 { 1994 blocking_notifier_chain_unregister(&esw->n_head, nb); 1995 } 1996 1997 /** 1998 * mlx5_esw_hold() - Try to take a read lock on esw mode lock. 1999 * @mdev: mlx5 core device. 2000 * 2001 * Should be called by esw resources callers. 2002 * 2003 * Return: true on success or false. 2004 */ 2005 bool mlx5_esw_hold(struct mlx5_core_dev *mdev) 2006 { 2007 struct mlx5_eswitch *esw = mdev->priv.eswitch; 2008 2009 /* e.g. VF doesn't have eswitch so nothing to do */ 2010 if (!mlx5_esw_allowed(esw)) 2011 return true; 2012 2013 if (down_read_trylock(&esw->mode_lock) != 0) 2014 return true; 2015 2016 return false; 2017 } 2018 2019 /** 2020 * mlx5_esw_release() - Release a read lock on esw mode lock. 2021 * @mdev: mlx5 core device. 2022 */ 2023 void mlx5_esw_release(struct mlx5_core_dev *mdev) 2024 { 2025 struct mlx5_eswitch *esw = mdev->priv.eswitch; 2026 2027 if (mlx5_esw_allowed(esw)) 2028 up_read(&esw->mode_lock); 2029 } 2030 2031 /** 2032 * mlx5_esw_get() - Increase esw user count. 2033 * @mdev: mlx5 core device. 2034 */ 2035 void mlx5_esw_get(struct mlx5_core_dev *mdev) 2036 { 2037 struct mlx5_eswitch *esw = mdev->priv.eswitch; 2038 2039 if (mlx5_esw_allowed(esw)) 2040 atomic64_inc(&esw->user_count); 2041 } 2042 2043 /** 2044 * mlx5_esw_put() - Decrease esw user count. 2045 * @mdev: mlx5 core device. 2046 */ 2047 void mlx5_esw_put(struct mlx5_core_dev *mdev) 2048 { 2049 struct mlx5_eswitch *esw = mdev->priv.eswitch; 2050 2051 if (mlx5_esw_allowed(esw)) 2052 atomic64_dec_if_positive(&esw->user_count); 2053 } 2054 2055 /** 2056 * mlx5_esw_try_lock() - Take a write lock on esw mode lock. 2057 * @esw: eswitch device. 2058 * 2059 * Should be called by esw mode change routine. 2060 * 2061 * Return: 2062 * * 0 - esw mode if successfully locked and refcount is 0. 2063 * * -EBUSY - refcount is not 0. 2064 * * -EINVAL - In the middle of switching mode or lock is already held. 2065 */ 2066 int mlx5_esw_try_lock(struct mlx5_eswitch *esw) 2067 { 2068 if (down_write_trylock(&esw->mode_lock) == 0) 2069 return -EINVAL; 2070 2071 if (atomic64_read(&esw->user_count) > 0) { 2072 up_write(&esw->mode_lock); 2073 return -EBUSY; 2074 } 2075 2076 return esw->mode; 2077 } 2078 2079 /** 2080 * mlx5_esw_unlock() - Release write lock on esw mode lock 2081 * @esw: eswitch device. 2082 */ 2083 void mlx5_esw_unlock(struct mlx5_eswitch *esw) 2084 { 2085 if (!mlx5_esw_allowed(esw)) 2086 return; 2087 up_write(&esw->mode_lock); 2088 } 2089 2090 /** 2091 * mlx5_esw_lock() - Take write lock on esw mode lock 2092 * @esw: eswitch device. 2093 */ 2094 void mlx5_esw_lock(struct mlx5_eswitch *esw) 2095 { 2096 if (!mlx5_esw_allowed(esw)) 2097 return; 2098 down_write(&esw->mode_lock); 2099 } 2100 2101 /** 2102 * mlx5_eswitch_get_total_vports - Get total vports of the eswitch 2103 * 2104 * @dev: Pointer to core device 2105 * 2106 * mlx5_eswitch_get_total_vports returns total number of eswitch vports. 2107 */ 2108 u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev) 2109 { 2110 struct mlx5_eswitch *esw; 2111 2112 esw = dev->priv.eswitch; 2113 return mlx5_esw_allowed(esw) ? esw->total_vports : 0; 2114 } 2115 EXPORT_SYMBOL_GPL(mlx5_eswitch_get_total_vports); 2116 2117 /** 2118 * mlx5_eswitch_get_core_dev - Get the mdev device 2119 * @esw : eswitch device. 2120 * 2121 * Return the mellanox core device which manages the eswitch. 2122 */ 2123 struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw) 2124 { 2125 return mlx5_esw_allowed(esw) ? esw->dev : NULL; 2126 } 2127 EXPORT_SYMBOL(mlx5_eswitch_get_core_dev); 2128