summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/ef10.c
diff options
context:
space:
mode:
authorDaniel Pieczko2015-05-20 12:10:20 +0200
committerDavid S. Miller2015-05-22 00:43:53 +0200
commit0d5e0fbba0ced95cc642d89a95120dcc9ec5be57 (patch)
treee30e86dcabb730c65fbb069cecff6c3bac37e0b5 /drivers/net/ethernet/sfc/ef10.c
parentsfc: protect filter table against use-after-free (diff)
downloadkernel-qcow2-linux-0d5e0fbba0ced95cc642d89a95120dcc9ec5be57.tar.gz
kernel-qcow2-linux-0d5e0fbba0ced95cc642d89a95120dcc9ec5be57.tar.xz
kernel-qcow2-linux-0d5e0fbba0ced95cc642d89a95120dcc9ec5be57.zip
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>
Diffstat (limited to 'drivers/net/ethernet/sfc/ef10.c')
-rw-r--r--drivers/net/ethernet/sfc/ef10.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index 9e2e8e14313b..40586265de61 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -198,7 +198,7 @@ static int efx_ef10_get_sysclk_freq(struct efx_nic *efx)
return rc > 0 ? rc : -ERANGE;
}
-static int efx_ef10_get_mac_address(struct efx_nic *efx, u8 *mac_address)
+static int efx_ef10_get_mac_address_pf(struct efx_nic *efx, u8 *mac_address)
{
MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
size_t outlen;
@@ -218,6 +218,34 @@ static int efx_ef10_get_mac_address(struct efx_nic *efx, u8 *mac_address)
return 0;
}
+static int efx_ef10_get_mac_address_vf(struct efx_nic *efx, u8 *mac_address)
+{
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN);
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX);
+ size_t outlen;
+ int num_addrs, rc;
+
+ MCDI_SET_DWORD(inbuf, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+ rc = efx_mcdi_rpc(efx, MC_CMD_VPORT_GET_MAC_ADDRESSES, inbuf,
+ sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
+
+ if (rc)
+ return rc;
+ if (outlen < MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN)
+ return -EIO;
+
+ num_addrs = MCDI_DWORD(outbuf,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT);
+
+ WARN_ON(num_addrs != 1);
+
+ ether_addr_copy(mac_address,
+ MCDI_PTR(outbuf, VPORT_GET_MAC_ADDRESSES_OUT_MACADDR));
+
+ return 0;
+}
+
static int efx_ef10_probe(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data;
@@ -299,7 +327,7 @@ static int efx_ef10_probe(struct efx_nic *efx)
goto fail3;
efx->port_num = rc;
- rc = efx_ef10_get_mac_address(efx, efx->net_dev->perm_addr);
+ rc = efx->type->get_mac_address(efx, efx->net_dev->perm_addr);
if (rc)
goto fail3;
@@ -3982,6 +4010,8 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.vswitching_restore = efx_ef10_vswitching_restore_vf,
.vswitching_remove = efx_ef10_vswitching_remove_vf,
#endif
+ .get_mac_address = efx_ef10_get_mac_address_vf,
+
.revision = EFX_REV_HUNT_A0,
.max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH),
.rx_prefix_size = ES_DZ_RX_PREFIX_SIZE,
@@ -4099,6 +4129,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.vswitching_restore = efx_ef10_vswitching_restore_pf,
.vswitching_remove = efx_ef10_vswitching_remove_pf,
#endif
+ .get_mac_address = efx_ef10_get_mac_address_pf,
.revision = EFX_REV_HUNT_A0,
.max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH),