sfc: add ndo_set_vf_link_state() function for EF10
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>
This commit is contained in:
parent
2d432f20d2
commit
4392dc6900
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -2281,6 +2281,7 @@ static const struct net_device_ops efx_netdev_ops = {
|
||||
.ndo_set_vf_vlan = efx_sriov_set_vf_vlan,
|
||||
.ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk,
|
||||
.ndo_get_vf_config = efx_sriov_get_vf_config,
|
||||
.ndo_set_vf_link_state = efx_sriov_set_vf_link_state,
|
||||
#endif
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = efx_netpoll,
|
||||
|
@ -4226,6 +4226,38 @@
|
||||
#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35017 0x8
|
||||
|
||||
|
||||
/***********************************/
|
||||
/* MC_CMD_LINK_STATE_MODE
|
||||
* Read/set link state mode of a VF
|
||||
*/
|
||||
#define MC_CMD_LINK_STATE_MODE 0x5c
|
||||
|
||||
#define MC_CMD_0x5c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
|
||||
|
||||
/* MC_CMD_LINK_STATE_MODE_IN msgrequest */
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_LEN 8
|
||||
/* The target function to have its link state mode read or set, must be a VF
|
||||
* e.g. VF 1,3 = 0x00030001
|
||||
*/
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_OFST 0
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_LBN 0
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_WIDTH 16
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_LBN 16
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_WIDTH 16
|
||||
/* New link state mode to be set */
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */
|
||||
/* enum: Use this value to just read the existing setting without modifying it.
|
||||
*/
|
||||
#define MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE 0xffffffff
|
||||
|
||||
/* MC_CMD_LINK_STATE_MODE_OUT msgresponse */
|
||||
#define MC_CMD_LINK_STATE_MODE_OUT_LEN 4
|
||||
#define MC_CMD_LINK_STATE_MODE_OUT_OLD_MODE_OFST 0
|
||||
|
||||
|
||||
/***********************************/
|
||||
/* MC_CMD_READ_REGS
|
||||
* Get a dump of the MCPU registers
|
||||
|
@ -1348,6 +1348,8 @@ struct efx_nic_type {
|
||||
bool spoofchk);
|
||||
int (*sriov_get_vf_config)(struct efx_nic *efx, int vf_i,
|
||||
struct ifla_vf_info *ivi);
|
||||
int (*sriov_set_vf_link_state)(struct efx_nic *efx, int vf_i,
|
||||
int link_state);
|
||||
int (*vswitching_probe)(struct efx_nic *efx);
|
||||
int (*vswitching_restore)(struct efx_nic *efx);
|
||||
void (*vswitching_remove)(struct efx_nic *efx);
|
||||
|
@ -58,3 +58,15 @@ int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int efx_sriov_set_vf_link_state(struct net_device *net_dev, int vf_i,
|
||||
int link_state)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (efx->type->sriov_set_vf_link_state)
|
||||
return efx->type->sriov_set_vf_link_state(efx, vf_i,
|
||||
link_state);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
|
||||
bool spoofchk);
|
||||
int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
|
||||
struct ifla_vf_info *ivi);
|
||||
int efx_sriov_set_vf_link_state(struct net_device *net_dev, int vf_i,
|
||||
int link_state);
|
||||
|
||||
#endif /* CONFIG_SFC_SRIOV */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user