Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Edward Cree and committed by
David S. Miller
4392dc69 2d432f20

+93
+1
drivers/net/ethernet/sfc/ef10.c
··· 4135 4135 .sriov_set_vf_vlan = efx_ef10_sriov_set_vf_vlan, 4136 4136 .sriov_set_vf_spoofchk = efx_ef10_sriov_set_vf_spoofchk, 4137 4137 .sriov_get_vf_config = efx_ef10_sriov_get_vf_config, 4138 + .sriov_set_vf_link_state = efx_ef10_sriov_set_vf_link_state, 4138 4139 .vswitching_probe = efx_ef10_vswitching_probe_pf, 4139 4140 .vswitching_restore = efx_ef10_vswitching_restore_pf, 4140 4141 .vswitching_remove = efx_ef10_vswitching_remove_pf,
+40
drivers/net/ethernet/sfc/ef10_sriov.c
··· 667 667 return rc ? rc : rc2; 668 668 } 669 669 670 + int efx_ef10_sriov_set_vf_link_state(struct efx_nic *efx, int vf_i, 671 + int link_state) 672 + { 673 + MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_STATE_MODE_IN_LEN); 674 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 675 + 676 + BUILD_BUG_ON(IFLA_VF_LINK_STATE_AUTO != 677 + MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO); 678 + BUILD_BUG_ON(IFLA_VF_LINK_STATE_ENABLE != 679 + MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP); 680 + BUILD_BUG_ON(IFLA_VF_LINK_STATE_DISABLE != 681 + MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN); 682 + MCDI_POPULATE_DWORD_2(inbuf, LINK_STATE_MODE_IN_FUNCTION, 683 + LINK_STATE_MODE_IN_FUNCTION_PF, 684 + nic_data->pf_index, 685 + LINK_STATE_MODE_IN_FUNCTION_VF, vf_i); 686 + MCDI_SET_DWORD(inbuf, LINK_STATE_MODE_IN_NEW_MODE, link_state); 687 + return efx_mcdi_rpc(efx, MC_CMD_LINK_STATE_MODE, inbuf, sizeof(inbuf), 688 + NULL, 0, NULL); /* don't care what old mode was */ 689 + } 690 + 670 691 int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i, 671 692 struct ifla_vf_info *ivf) 672 693 { 694 + MCDI_DECLARE_BUF(inbuf, MC_CMD_LINK_STATE_MODE_IN_LEN); 695 + MCDI_DECLARE_BUF(outbuf, MC_CMD_LINK_STATE_MODE_OUT_LEN); 696 + 673 697 struct efx_ef10_nic_data *nic_data = efx->nic_data; 674 698 struct ef10_vf *vf; 699 + size_t outlen; 700 + int rc; 675 701 676 702 if (vf_i >= efx->vf_count) 677 703 return -EINVAL; ··· 713 687 ether_addr_copy(ivf->mac, vf->mac); 714 688 ivf->vlan = (vf->vlan == EFX_EF10_NO_VLAN) ? 0 : vf->vlan; 715 689 ivf->qos = 0; 690 + 691 + MCDI_POPULATE_DWORD_2(inbuf, LINK_STATE_MODE_IN_FUNCTION, 692 + LINK_STATE_MODE_IN_FUNCTION_PF, 693 + nic_data->pf_index, 694 + LINK_STATE_MODE_IN_FUNCTION_VF, vf_i); 695 + MCDI_SET_DWORD(inbuf, LINK_STATE_MODE_IN_NEW_MODE, 696 + MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE); 697 + rc = efx_mcdi_rpc(efx, MC_CMD_LINK_STATE_MODE, inbuf, sizeof(inbuf), 698 + outbuf, sizeof(outbuf), &outlen); 699 + if (rc) 700 + return rc; 701 + if (outlen < MC_CMD_LINK_STATE_MODE_OUT_LEN) 702 + return -EIO; 703 + ivf->linkstate = MCDI_DWORD(outbuf, LINK_STATE_MODE_OUT_OLD_MODE); 716 704 717 705 return 0; 718 706 }
+3
drivers/net/ethernet/sfc/ef10_sriov.h
··· 58 58 int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf_i, 59 59 struct ifla_vf_info *ivf); 60 60 61 + int efx_ef10_sriov_set_vf_link_state(struct efx_nic *efx, int vf_i, 62 + int link_state); 63 + 61 64 int efx_ef10_vswitching_probe_pf(struct efx_nic *efx); 62 65 int efx_ef10_vswitching_probe_vf(struct efx_nic *efx); 63 66 int efx_ef10_vswitching_restore_pf(struct efx_nic *efx);
+1
drivers/net/ethernet/sfc/efx.c
··· 2281 2281 .ndo_set_vf_vlan = efx_sriov_set_vf_vlan, 2282 2282 .ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk, 2283 2283 .ndo_get_vf_config = efx_sriov_get_vf_config, 2284 + .ndo_set_vf_link_state = efx_sriov_set_vf_link_state, 2284 2285 #endif 2285 2286 #ifdef CONFIG_NET_POLL_CONTROLLER 2286 2287 .ndo_poll_controller = efx_netpoll,
+32
drivers/net/ethernet/sfc/mcdi_pcol.h
··· 4227 4227 4228 4228 4229 4229 /***********************************/ 4230 + /* MC_CMD_LINK_STATE_MODE 4231 + * Read/set link state mode of a VF 4232 + */ 4233 + #define MC_CMD_LINK_STATE_MODE 0x5c 4234 + 4235 + #define MC_CMD_0x5c_PRIVILEGE_CTG SRIOV_CTG_GENERAL 4236 + 4237 + /* MC_CMD_LINK_STATE_MODE_IN msgrequest */ 4238 + #define MC_CMD_LINK_STATE_MODE_IN_LEN 8 4239 + /* The target function to have its link state mode read or set, must be a VF 4240 + * e.g. VF 1,3 = 0x00030001 4241 + */ 4242 + #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_OFST 0 4243 + #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_LBN 0 4244 + #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_WIDTH 16 4245 + #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_LBN 16 4246 + #define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_WIDTH 16 4247 + /* New link state mode to be set */ 4248 + #define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4 4249 + #define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */ 4250 + #define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */ 4251 + #define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */ 4252 + /* enum: Use this value to just read the existing setting without modifying it. 4253 + */ 4254 + #define MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE 0xffffffff 4255 + 4256 + /* MC_CMD_LINK_STATE_MODE_OUT msgresponse */ 4257 + #define MC_CMD_LINK_STATE_MODE_OUT_LEN 4 4258 + #define MC_CMD_LINK_STATE_MODE_OUT_OLD_MODE_OFST 0 4259 + 4260 + 4261 + /***********************************/ 4230 4262 /* MC_CMD_READ_REGS 4231 4263 * Get a dump of the MCPU registers 4232 4264 */
+2
drivers/net/ethernet/sfc/net_driver.h
··· 1348 1348 bool spoofchk); 1349 1349 int (*sriov_get_vf_config)(struct efx_nic *efx, int vf_i, 1350 1350 struct ifla_vf_info *ivi); 1351 + int (*sriov_set_vf_link_state)(struct efx_nic *efx, int vf_i, 1352 + int link_state); 1351 1353 int (*vswitching_probe)(struct efx_nic *efx); 1352 1354 int (*vswitching_restore)(struct efx_nic *efx); 1353 1355 void (*vswitching_remove)(struct efx_nic *efx);
+12
drivers/net/ethernet/sfc/sriov.c
··· 58 58 else 59 59 return -EOPNOTSUPP; 60 60 } 61 + 62 + int efx_sriov_set_vf_link_state(struct net_device *net_dev, int vf_i, 63 + int link_state) 64 + { 65 + struct efx_nic *efx = netdev_priv(net_dev); 66 + 67 + if (efx->type->sriov_set_vf_link_state) 68 + return efx->type->sriov_set_vf_link_state(efx, vf_i, 69 + link_state); 70 + else 71 + return -EOPNOTSUPP; 72 + }
+2
drivers/net/ethernet/sfc/sriov.h
··· 21 21 bool spoofchk); 22 22 int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, 23 23 struct ifla_vf_info *ivi); 24 + int efx_sriov_set_vf_link_state(struct net_device *net_dev, int vf_i, 25 + int link_state); 24 26 25 27 #endif /* CONFIG_SFC_SRIOV */ 26 28