From 4392dc6900618c1d5137a3cd43805d746a2c563a Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Wed, 20 May 2015 11:12:13 +0100 Subject: sfc: add ndo_set_vf_link_state() function for EF10 Exercised with "ip link set vf state {auto|enable|disable}" Sets the reporting policy for VF link state to either - mirror physical link state - always up - always down get VF link state mode in efx_ef10_sriov_get_vf_config Exercised by "ip link show "; output will include a line like vf 0 MAC 12:34:56:78:9a:bc, link-state auto Signed-off-by: Shradha Shah Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef10_sriov.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers/net/ethernet/sfc/ef10_sriov.c') diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c index 49238fc5f0f1..edc34f39fa3a 100644 --- a/drivers/net/ethernet/sfc/ef10_sriov.c +++ b/drivers/net/ethernet/sfc/ef10_sriov.c @@ -667,11 +667,37 @@ reset_nic: return rc ? rc : rc2; } +int efx_ef10_sriov_set_vf_link_state(struct efx_nic *efx, int vf_i, + int link_state) +{ + MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_STATE_MODE_IN_LEN); + struct efx_ef10_nic_data *nic_data = efx->nic_data; + + BUILD_BUG_ON(IFLA_VF_LINK_STATE_AUTO != + MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO); + BUILD_BUG_ON(IFLA_VF_LINK_STATE_ENABLE != + MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP); + BUILD_BUG_ON(IFLA_VF_LINK_STATE_DISABLE != + MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN); + MCDI_POPULATE_DWORD_2(inbuf, LINK_STATE_MODE_IN_FUNCTION, + LINK_STATE_MODE_IN_FUNCTION_PF, + nic_data->pf_index, + LINK_STATE_MODE_IN_FUNCTION_VF, vf_i); + MCDI_SET_DWORD(inbuf, LINK_STATE_MODE_IN_NEW_MODE, link_state); + return efx_mcdi_rpc(efx, MC_CMD_LINK_STATE_MODE, inbuf, sizeof(inbuf), + NULL, 0, NULL); /* don't care what old mode was */ +} + int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i, struct ifla_vf_info *ivf) { + MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_STATE_MODE_IN_LEN); + MCDI_DECLARE_BUF(outbuf, MC_CMD_LINK_STATE_MODE_OUT_LEN); + struct efx_ef10_nic_data *nic_data = efx->nic_data; struct ef10_vf *vf; + size_t outlen; + int rc; if (vf_i >= efx->vf_count) return -EINVAL; @@ -688,5 +714,19 @@ int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i, ivf->vlan = (vf->vlan == EFX_EF10_NO_VLAN) ? 0 : vf->vlan; ivf->qos = 0; + MCDI_POPULATE_DWORD_2(inbuf, LINK_STATE_MODE_IN_FUNCTION, + LINK_STATE_MODE_IN_FUNCTION_PF, + nic_data->pf_index, + LINK_STATE_MODE_IN_FUNCTION_VF, vf_i); + MCDI_SET_DWORD(inbuf, LINK_STATE_MODE_IN_NEW_MODE, + MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE); + rc = efx_mcdi_rpc(efx, MC_CMD_LINK_STATE_MODE, inbuf, sizeof(inbuf), + outbuf, sizeof(outbuf), &outlen); + if (rc) + return rc; + if (outlen < MC_CMD_LINK_STATE_MODE_OUT_LEN) + return -EIO; + ivf->linkstate = MCDI_DWORD(outbuf, LINK_STATE_MODE_OUT_OLD_MODE); + return 0; } -- cgit v1.2.3