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