Commit 4392dc69 authored by Edward Cree's avatar Edward Cree Committed by David S. Miller

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: default avatarShradha Shah <sshah@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2d432f20
...@@ -4135,6 +4135,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { ...@@ -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_vlan = efx_ef10_sriov_set_vf_vlan,
.sriov_set_vf_spoofchk = efx_ef10_sriov_set_vf_spoofchk, .sriov_set_vf_spoofchk = efx_ef10_sriov_set_vf_spoofchk,
.sriov_get_vf_config = efx_ef10_sriov_get_vf_config, .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_probe = efx_ef10_vswitching_probe_pf,
.vswitching_restore = efx_ef10_vswitching_restore_pf, .vswitching_restore = efx_ef10_vswitching_restore_pf,
.vswitching_remove = efx_ef10_vswitching_remove_pf, .vswitching_remove = efx_ef10_vswitching_remove_pf,
......
...@@ -667,11 +667,37 @@ int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan, ...@@ -667,11 +667,37 @@ int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, u16 vlan,
return rc ? rc : rc2; 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, int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i,
struct ifla_vf_info *ivf) 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 efx_ef10_nic_data *nic_data = efx->nic_data;
struct ef10_vf *vf; struct ef10_vf *vf;
size_t outlen;
int rc;
if (vf_i >= efx->vf_count) if (vf_i >= efx->vf_count)
return -EINVAL; return -EINVAL;
...@@ -688,5 +714,19 @@ int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i, ...@@ -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->vlan = (vf->vlan == EFX_EF10_NO_VLAN) ? 0 : vf->vlan;
ivf->qos = 0; 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; return 0;
} }
...@@ -58,6 +58,9 @@ static inline int efx_ef10_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf, ...@@ -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, int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i,
struct ifla_vf_info *ivf); 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_pf(struct efx_nic *efx);
int efx_ef10_vswitching_probe_vf(struct efx_nic *efx); int efx_ef10_vswitching_probe_vf(struct efx_nic *efx);
int efx_ef10_vswitching_restore_pf(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 = { ...@@ -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_vlan = efx_sriov_set_vf_vlan,
.ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk, .ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk,
.ndo_get_vf_config = efx_sriov_get_vf_config, .ndo_get_vf_config = efx_sriov_get_vf_config,
.ndo_set_vf_link_state = efx_sriov_set_vf_link_state,
#endif #endif
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = efx_netpoll, .ndo_poll_controller = efx_netpoll,
......
...@@ -4226,6 +4226,38 @@ ...@@ -4226,6 +4226,38 @@
#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35017 0x8 #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 /* MC_CMD_READ_REGS
* Get a dump of the MCPU registers * Get a dump of the MCPU registers
......
...@@ -1348,6 +1348,8 @@ struct efx_nic_type { ...@@ -1348,6 +1348,8 @@ struct efx_nic_type {
bool spoofchk); bool spoofchk);
int (*sriov_get_vf_config)(struct efx_nic *efx, int vf_i, int (*sriov_get_vf_config)(struct efx_nic *efx, int vf_i,
struct ifla_vf_info *ivi); 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_probe)(struct efx_nic *efx);
int (*vswitching_restore)(struct efx_nic *efx); int (*vswitching_restore)(struct efx_nic *efx);
void (*vswitching_remove)(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, ...@@ -58,3 +58,15 @@ int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
else else
return -EOPNOTSUPP; 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, ...@@ -21,6 +21,8 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
bool spoofchk); bool spoofchk);
int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
struct ifla_vf_info *ivi); 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 */ #endif /* CONFIG_SFC_SRIOV */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment