From: Chiqijun chiqijun@huawei.com
driver inclusion category: feature bugzilla: 4472
-----------------------------------------------------------------------
Added support for trust mode on VFs. This allows the VM to change the MAC address of the VF on the host at run time.
Signed-off-by: Chiqijun chiqijun@huawei.com Reviewed-by: Luoshaokai luoshaokai@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/huawei/hinic/hinic_main.c | 8 ++++ drivers/net/ethernet/huawei/hinic/hinic_nic.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c | 45 ++++++++++++++++++++-- drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h | 5 +++ drivers/net/ethernet/huawei/hinic/hinic_sriov.c | 31 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_sriov.h | 4 ++ drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h | 2 + 7 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 83af4a8..910fed9 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -2127,6 +2127,14 @@ static void hinic_nic_set_rx_mode(struct net_device *netdev) #ifdef HAVE_VF_SPOOFCHK_CONFIGURE .ndo_set_vf_spoofchk = hinic_ndo_set_vf_spoofchk, #endif +#ifdef HAVE_NDO_SET_VF_TRUST +#ifdef HAVE_RHEL7_NET_DEVICE_OPS_EXT + .extended.ndo_set_vf_trust = hinic_ndo_set_vf_trust, +#else + .ndo_set_vf_trust = hinic_ndo_set_vf_trust, +#endif /* HAVE_RHEL7_NET_DEVICE_OPS_EXT */ +#endif /* HAVE_NDO_SET_VF_TRUST */ + .ndo_get_vf_config = hinic_ndo_get_vf_config, #endif
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic.h b/drivers/net/ethernet/huawei/hinic/hinic_nic.h index 5b5b094..f2fb937 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic.h @@ -64,6 +64,7 @@ struct vf_data_storage { bool link_forced; bool link_up; /* only valid if VF link is forced */ bool spoofchk; + bool trust; };
struct hinic_nic_cfg { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c index 6ddae36..f9e16ec 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c @@ -2432,7 +2432,8 @@ static int hinic_set_vf_mac_msg_handler(struct hinic_nic_io *nic_io, u16 vf, struct hinic_port_mac_set *mac_out = buf_out; int err;
- if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac)) { + if (vf_info->pf_set_mac && !(vf_info->trust) && + is_valid_ether_addr(mac_in->mac)) { nic_warn(nic_io->hwdev->dev_hdl, "PF has already set VF %d MAC address\n", HW_VF_ID_TO_OS(vf)); mac_out->status = HINIC_PF_SET_VF_ALREADY; @@ -2462,7 +2463,8 @@ static int hinic_del_vf_mac_msg_handler(struct hinic_nic_io *nic_io, u16 vf, struct hinic_port_mac_set *mac_out = buf_out; int err;
- if (vf_info->pf_set_mac && is_valid_ether_addr(mac_in->mac) && + if (vf_info->pf_set_mac && !(vf_info->trust) && + is_valid_ether_addr(mac_in->mac) && !memcmp(vf_info->vf_mac_addr, mac_in->mac, ETH_ALEN)) { nic_warn(nic_io->hwdev->dev_hdl, "PF has already set VF mac.\n"); mac_out->status = HINIC_PF_SET_VF_ALREADY; @@ -2497,7 +2499,7 @@ static int hinic_update_vf_mac_msg_handler(struct hinic_nic_io *nic_io, u16 vf, return -EINVAL; }
- if (vf_info->pf_set_mac) { + if (vf_info->pf_set_mac && !(vf_info->trust)) { nic_warn(nic_io->hwdev->dev_hdl, "PF has already set VF mac.\n"); mac_out->status = HINIC_PF_SET_VF_ALREADY; *out_size = sizeof(*mac_out); @@ -3026,6 +3028,10 @@ void hinic_get_vf_config(void *hwdev, u16 vf_id, struct ifla_vf_info *ivi) ivi->spoofchk = vfinfo->spoofchk; #endif
+#ifdef HAVE_NDO_SET_VF_TRUST + ivi->trusted = vfinfo->trust; +#endif + #ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE ivi->max_tx_rate = vfinfo->max_rate; ivi->min_tx_rate = vfinfo->min_rate; @@ -3063,6 +3069,11 @@ void hinic_clear_vf_infos(void *hwdev, u16 vf_id) if (vf_infos->spoofchk) hinic_set_vf_spoofchk(hwdev, vf_id, false);
+#ifdef HAVE_NDO_SET_VF_TRUST + if (vf_infos->trust) + hinic_set_vf_trust(hwdev, vf_id, false); +#endif + memset(vf_infos, 0, sizeof(*vf_infos)); /* set vf_infos to default */ hinic_init_vf_infos(hw_dev->nic_io, HW_VF_ID_TO_OS(vf_id)); @@ -3181,6 +3192,24 @@ int hinic_set_vf_spoofchk(void *hwdev, u16 vf_id, bool spoofchk) return err; }
+#ifdef HAVE_NDO_SET_VF_TRUST +int hinic_set_vf_trust(void *hwdev, u16 vf_id, bool trust) +{ + struct hinic_hwdev *hw_dev = hwdev; + struct hinic_nic_io *nic_io = NULL; + struct vf_data_storage *vf_infos = NULL; + + if (!hwdev) + return -EINVAL; + + nic_io = hw_dev->nic_io; + vf_infos = nic_io->vf_infos; + vf_infos[HW_VF_ID_TO_OS(vf_id)].trust = trust; + + return 0; +} +#endif + bool hinic_vf_info_spoofchk(void *hwdev, int vf_id) { struct hinic_nic_io *nic_io = ((struct hinic_hwdev *)hwdev)->nic_io; @@ -3189,6 +3218,16 @@ bool hinic_vf_info_spoofchk(void *hwdev, int vf_id) return spoofchk; }
+#ifdef HAVE_NDO_SET_VF_TRUST +bool hinic_vf_info_trust(void *hwdev, int vf_id) +{ + struct hinic_nic_io *nic_io = ((struct hinic_hwdev *)hwdev)->nic_io; + bool trust = nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].trust; + + return trust; +} +#endif + static int hinic_set_vf_rate_limit(void *hwdev, u16 vf_id, u32 tx_rate) { struct hinic_hwdev *hw_dev = hwdev; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h index eb060fb..427d469 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.h @@ -578,6 +578,11 @@ int hinic_get_rss_type(void *hwdev, u32 tmpl_idx,
bool hinic_vf_info_spoofchk(void *hwdev, int vf_id);
+#ifdef HAVE_NDO_SET_VF_TRUST +int hinic_set_vf_trust(void *hwdev, u16 vf_id, bool trust); +bool hinic_vf_info_trust(void *hwdev, int vf_id); +#endif + int hinic_set_vf_tx_rate(void *hwdev, u16 vf_id, u32 max_rate, u32 min_rate);
int hinic_init_vf_hw(void *hwdev, u16 start_vf_id, u16 end_vf_id); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c index 0ec12d9..37d0116 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c @@ -356,6 +356,37 @@ int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting) } #endif
+#ifdef HAVE_NDO_SET_VF_TRUST +int hinic_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting) +{ + struct hinic_nic_dev *adapter = netdev_priv(netdev); + struct hinic_sriov_info *sriov_info; + int err = 0; + bool cur_trust; + + sriov_info = hinic_get_sriov_info_by_pcidev(adapter->pdev); + if (vf >= sriov_info->num_vfs) + return -EINVAL; + + cur_trust = hinic_vf_info_trust(sriov_info->hwdev, + OS_VF_ID_TO_HW(vf)); + /* same request, so just return success */ + if ((setting && cur_trust) || (!setting && !cur_trust)) + return 0; + + err = hinic_set_vf_trust(sriov_info->hwdev, + OS_VF_ID_TO_HW(vf), setting); + if (!err) + nicif_info(adapter, drv, netdev, "Set VF %d trusted %s succeed\n", + vf, setting ? "on" : "off"); + else + nicif_err(adapter, drv, netdev, "Failed set VF %d trusted %s\n", + vf, setting ? "on" : "off"); + + return err; +} +#endif + int hinic_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi) { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.h b/drivers/net/ethernet/huawei/hinic/hinic_sriov.h index 6dc60d9..a1188fd 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.h @@ -59,6 +59,10 @@ int hinic_ndo_get_vf_config(struct net_device *netdev, int vf, int hinic_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); #endif
+#ifdef HAVE_NDO_SET_VF_TRUST +int hinic_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting); +#endif + int hinic_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link);
#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE diff --git a/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h b/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h index 8cdcb1d..f99e1db 100644 --- a/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h +++ b/drivers/net/ethernet/huawei/hinic/ossl_knl_linux.h @@ -265,6 +265,8 @@ enum ethtool_link_mode_bit_indices { #define HAVE_SKB_L4_RXHASH #endif
+#define HAVE_NDO_SET_VF_TRUST + /*****************************************************************************/ #define HAVE_ETHTOOL_GRXFHINDIR_SIZE #define HAVE_INT_NDO_VLAN_RX_ADD_VID