sfc: add ndo_set_vf_link_state() function for EF10
authorEdward Cree <ecree@solarflare.com>
Wed, 20 May 2015 10:12:13 +0000 (11:12 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 May 2015 22:43:54 +0000 (18:43 -0400)
Exercised with
"ip link set <PF intf> vf <vf_i> 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 <PF intf>";
output will include a line like
vf 0 MAC 12:34:56:78:9a:bc, link-state auto

Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/ef10_sriov.c
drivers/net/ethernet/sfc/ef10_sriov.h
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/mcdi_pcol.h
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/sriov.c
drivers/net/ethernet/sfc/sriov.h

index 525808f..e624ddd 100644 (file)
@@ -4135,6 +4135,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
        .sriov_set_vf_vlan = efx_ef10_sriov_set_vf_vlan,
        .sriov_set_vf_spoofchk = efx_ef10_sriov_set_vf_spoofchk,
        .sriov_get_vf_config = efx_ef10_sriov_get_vf_config,
+       .sriov_set_vf_link_state = efx_ef10_sriov_set_vf_link_state,
        .vswitching_probe = efx_ef10_vswitching_probe_pf,
        .vswitching_restore = efx_ef10_vswitching_restore_pf,
        .vswitching_remove = efx_ef10_vswitching_remove_pf,
index 49238fc..edc34f3 100644 (file)
@@ -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;
 }
index 0428265..91393a6 100644 (file)
@@ -58,6 +58,9 @@ static inline int efx_ef10_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf,
 int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i,
                                 struct ifla_vf_info *ivf);
 
+int efx_ef10_sriov_set_vf_link_state(struct efx_nic *efx, int vf_i,
+                                    int link_state);
+
 int efx_ef10_vswitching_probe_pf(struct efx_nic *efx);
 int efx_ef10_vswitching_probe_vf(struct efx_nic *efx);
 int efx_ef10_vswitching_restore_pf(struct efx_nic *efx);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge