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

sfc: Enable a VF to get its own MAC address

A VF's MAC address is set by its parent PF and added to its vport.
To get this MAC address, the VF must use MC_CMD_ VPORT_GET_MAC_ADDRESSES.
In the current scheme, a VF's vport should only have one MAC address,
so warn if this is not the case.

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

authored by

Daniel Pieczko and committed by
David S. Miller
0d5e0fbb 0d322413

+34 -2
+33 -2
drivers/net/ethernet/sfc/ef10.c
··· 198 198 return rc > 0 ? rc : -ERANGE; 199 199 } 200 200 201 - static int efx_ef10_get_mac_address(struct efx_nic *efx, u8 *mac_address) 201 + static int efx_ef10_get_mac_address_pf(struct efx_nic *efx, u8 *mac_address) 202 202 { 203 203 MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN); 204 204 size_t outlen; ··· 215 215 216 216 ether_addr_copy(mac_address, 217 217 MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE)); 218 + return 0; 219 + } 220 + 221 + static int efx_ef10_get_mac_address_vf(struct efx_nic *efx, u8 *mac_address) 222 + { 223 + MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN); 224 + MCDI_DECLARE_BUF(outbuf, MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX); 225 + size_t outlen; 226 + int num_addrs, rc; 227 + 228 + MCDI_SET_DWORD(inbuf, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID, 229 + EVB_PORT_ID_ASSIGNED); 230 + rc = efx_mcdi_rpc(efx, MC_CMD_VPORT_GET_MAC_ADDRESSES, inbuf, 231 + sizeof(inbuf), outbuf, sizeof(outbuf), &outlen); 232 + 233 + if (rc) 234 + return rc; 235 + if (outlen < MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) 236 + return -EIO; 237 + 238 + num_addrs = MCDI_DWORD(outbuf, 239 + VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT); 240 + 241 + WARN_ON(num_addrs != 1); 242 + 243 + ether_addr_copy(mac_address, 244 + MCDI_PTR(outbuf, VPORT_GET_MAC_ADDRESSES_OUT_MACADDR)); 245 + 218 246 return 0; 219 247 } 220 248 ··· 327 299 goto fail3; 328 300 efx->port_num = rc; 329 301 330 - rc = efx_ef10_get_mac_address(efx, efx->net_dev->perm_addr); 302 + rc = efx->type->get_mac_address(efx, efx->net_dev->perm_addr); 331 303 if (rc) 332 304 goto fail3; 333 305 ··· 4010 3982 .vswitching_restore = efx_ef10_vswitching_restore_vf, 4011 3983 .vswitching_remove = efx_ef10_vswitching_remove_vf, 4012 3984 #endif 3985 + .get_mac_address = efx_ef10_get_mac_address_vf, 3986 + 4013 3987 .revision = EFX_REV_HUNT_A0, 4014 3988 .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH), 4015 3989 .rx_prefix_size = ES_DZ_RX_PREFIX_SIZE, ··· 4129 4099 .vswitching_restore = efx_ef10_vswitching_restore_pf, 4130 4100 .vswitching_remove = efx_ef10_vswitching_remove_pf, 4131 4101 #endif 4102 + .get_mac_address = efx_ef10_get_mac_address_pf, 4132 4103 4133 4104 .revision = EFX_REV_HUNT_A0, 4134 4105 .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH),
+1
drivers/net/ethernet/sfc/net_driver.h
··· 1351 1351 int (*vswitching_probe)(struct efx_nic *efx); 1352 1352 int (*vswitching_restore)(struct efx_nic *efx); 1353 1353 void (*vswitching_remove)(struct efx_nic *efx); 1354 + int (*get_mac_address)(struct efx_nic *efx, unsigned char *perm_addr); 1354 1355 1355 1356 int revision; 1356 1357 unsigned int txd_ptr_tbl_base;