Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: add ndo_set_vf_mac() function for EF10

Implement a response to this entrypoint.
The ndo_set_vf_mac() entrypoint is only exposed in the driver if
CONFIG_SFC_SRIOV is defined.

Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Shradha Shah and committed by
David S. Miller
e340be92 aa09a3da

+96 -7
+90
drivers/net/ethernet/sfc/ef10_sriov.c
··· 431 431 else 432 432 netif_dbg(efx, drv, efx->net_dev, "SRIOV disabled\n"); 433 433 } 434 + 435 + static int efx_ef10_vport_del_vf_mac(struct efx_nic *efx, unsigned int port_id, 436 + u8 *mac) 437 + { 438 + MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN); 439 + MCDI_DECLARE_BUF_ERR(outbuf); 440 + size_t outlen; 441 + int rc; 442 + 443 + MCDI_SET_DWORD(inbuf, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, port_id); 444 + ether_addr_copy(MCDI_PTR(inbuf, VPORT_DEL_MAC_ADDRESS_IN_MACADDR), mac); 445 + 446 + rc = efx_mcdi_rpc(efx, MC_CMD_VPORT_DEL_MAC_ADDRESS, inbuf, 447 + sizeof(inbuf), outbuf, sizeof(outbuf), &outlen); 448 + 449 + return rc; 450 + } 451 + 452 + int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, u8 *mac) 453 + { 454 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 455 + struct ef10_vf *vf; 456 + int rc; 457 + 458 + if (!nic_data->vf) 459 + return -EOPNOTSUPP; 460 + 461 + if (vf_i >= efx->vf_count) 462 + return -EINVAL; 463 + vf = nic_data->vf + vf_i; 464 + 465 + if (vf->efx) { 466 + efx_device_detach_sync(vf->efx); 467 + efx_net_stop(vf->efx->net_dev); 468 + 469 + down_write(&vf->efx->filter_sem); 470 + vf->efx->type->filter_table_remove(vf->efx); 471 + 472 + rc = efx_ef10_vadaptor_free(vf->efx, EVB_PORT_ID_ASSIGNED); 473 + if (rc) { 474 + up_write(&vf->efx->filter_sem); 475 + return rc; 476 + } 477 + } 478 + 479 + rc = efx_ef10_evb_port_assign(efx, EVB_PORT_ID_NULL, vf_i); 480 + if (rc) 481 + return rc; 482 + 483 + if (!is_zero_ether_addr(vf->mac)) { 484 + rc = efx_ef10_vport_del_vf_mac(efx, vf->vport_id, vf->mac); 485 + if (rc) 486 + return rc; 487 + } 488 + 489 + if (!is_zero_ether_addr(mac)) { 490 + rc = efx_ef10_vport_add_mac(efx, vf->vport_id, mac); 491 + if (rc) { 492 + eth_zero_addr(vf->mac); 493 + goto fail; 494 + } 495 + if (vf->efx) 496 + ether_addr_copy(vf->efx->net_dev->dev_addr, mac); 497 + } 498 + 499 + ether_addr_copy(vf->mac, mac); 500 + 501 + rc = efx_ef10_evb_port_assign(efx, vf->vport_id, vf_i); 502 + if (rc) 503 + goto fail; 504 + 505 + if (vf->efx) { 506 + /* VF cannot use the vport_id that the PF created */ 507 + rc = efx_ef10_vadaptor_alloc(vf->efx, EVB_PORT_ID_ASSIGNED); 508 + if (rc) { 509 + up_write(&vf->efx->filter_sem); 510 + return rc; 511 + } 512 + vf->efx->type->filter_table_probe(vf->efx); 513 + up_write(&vf->efx->filter_sem); 514 + efx_net_open(vf->efx->net_dev); 515 + netif_device_attach(vf->efx->net_dev); 516 + } 517 + 518 + return 0; 519 + 520 + fail: 521 + memset(vf->mac, 0, ETH_ALEN); 522 + return rc; 523 + }
+1 -5
drivers/net/ethernet/sfc/ef10_sriov.h
··· 41 41 void efx_ef10_sriov_fini(struct efx_nic *efx); 42 42 static inline void efx_ef10_sriov_flr(struct efx_nic *efx, unsigned vf_i) {} 43 43 44 - static inline int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf, 45 - u8 *mac) 46 - { 47 - return -EOPNOTSUPP; 48 - } 44 + int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf, u8 *mac); 49 45 50 46 static inline int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf, 51 47 u16 vlan, u8 qos)
+2 -2
drivers/net/ethernet/sfc/efx.c
··· 2113 2113 *************************************************************************/ 2114 2114 2115 2115 /* Context: process, rtnl_lock() held. */ 2116 - static int efx_net_open(struct net_device *net_dev) 2116 + int efx_net_open(struct net_device *net_dev) 2117 2117 { 2118 2118 struct efx_nic *efx = netdev_priv(net_dev); 2119 2119 int rc; ··· 2142 2142 * Note that the kernel will ignore our return code; this method 2143 2143 * should really be a void. 2144 2144 */ 2145 - static int efx_net_stop(struct net_device *net_dev) 2145 + int efx_net_stop(struct net_device *net_dev) 2146 2146 { 2147 2147 struct efx_nic *efx = netdev_priv(net_dev); 2148 2148
+3
drivers/net/ethernet/sfc/efx.h
··· 19 19 #define EFX_MEM_BAR 2 20 20 #define EFX_MEM_VF_BAR 0 21 21 22 + int efx_net_open(struct net_device *net_dev); 23 + int efx_net_stop(struct net_device *net_dev); 24 + 22 25 /* TX */ 23 26 int efx_probe_tx_queue(struct efx_tx_queue *tx_queue); 24 27 void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);