diff options
author | David S. Miller <davem@davemloft.net> | 2018-10-12 11:23:45 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-12 11:23:45 -0700 |
commit | 139ce90a45700234fdd78bec1ffe780085989f52 (patch) | |
tree | 09c6ab334ceef11a69ab46020e5f8b91dcf01018 | |
parent | 5886d932e52acfbe12ea5aac8e7c3ad6f16364d1 (diff) | |
parent | 829edbd8d45e2f5c384a0b6c741cde46e0fa02a8 (diff) |
Merge branch 'hns3-promisc-next'
Salil Mehta says:
====================
Fixes & small enhancements related to the promisc mode in HNS3
This patch-set presents some fixes and enhancements related to promiscuous
mode and MAC VLAN Table full condition in HNS3 Ethernet Driver.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hnae3.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 84 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 9 |
5 files changed, 103 insertions, 14 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 3df62a5783ab..c3bd2a10bc7d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -503,6 +503,15 @@ struct hnae3_unic_private_info { #define HNAE3_SUPPORT_VF BIT(3) #define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4) +#define HNAE3_USER_UPE BIT(0) /* unicast promisc enabled by user */ +#define HNAE3_USER_MPE BIT(1) /* mulitcast promisc enabled by user */ +#define HNAE3_BPE BIT(2) /* broadcast promisc enable */ +#define HNAE3_OVERFLOW_UPE BIT(3) /* unicast mac vlan overflow */ +#define HNAE3_OVERFLOW_MPE BIT(4) /* multicast mac vlan overflow */ +#define HNAE3_VLAN_FLTR BIT(5) /* enable vlan filter */ +#define HNAE3_UPE (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE) +#define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE) + struct hnae3_handle { struct hnae3_client *client; struct pci_dev *pdev; @@ -521,6 +530,8 @@ struct hnae3_handle { }; u32 numa_node_mask; /* for multi-chip support */ + + u8 netdev_flags; }; #define hnae3_set_field(origin, mask, shift, val) \ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 9bbb53c93447..ce93fcce2732 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -459,23 +459,81 @@ static int hns3_nic_mc_unsync(struct net_device *netdev, return 0; } +static u8 hns3_get_netdev_flags(struct net_device *netdev) +{ + u8 flags = 0; + + if (netdev->flags & IFF_PROMISC) { + flags = HNAE3_USER_UPE | HNAE3_USER_MPE; + } else { + flags |= HNAE3_VLAN_FLTR; + if (netdev->flags & IFF_ALLMULTI) + flags |= HNAE3_USER_MPE; + } + + return flags; +} + static void hns3_nic_set_rx_mode(struct net_device *netdev) { struct hnae3_handle *h = hns3_get_handle(netdev); + u8 new_flags; + int ret; - if (h->ae_algo->ops->set_promisc_mode) { - if (netdev->flags & IFF_PROMISC) - h->ae_algo->ops->set_promisc_mode(h, true, true); - else if (netdev->flags & IFF_ALLMULTI) - h->ae_algo->ops->set_promisc_mode(h, false, true); - else - h->ae_algo->ops->set_promisc_mode(h, false, false); - } - if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync)) + new_flags = hns3_get_netdev_flags(netdev); + + ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync); + if (ret) { netdev_err(netdev, "sync uc address fail\n"); + if (ret == -ENOSPC) + new_flags |= HNAE3_OVERFLOW_UPE; + } + if (netdev->flags & IFF_MULTICAST) { - if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync)) + ret = __dev_mc_sync(netdev, hns3_nic_mc_sync, + hns3_nic_mc_unsync); + if (ret) { netdev_err(netdev, "sync mc address fail\n"); + if (ret == -ENOSPC) + new_flags |= HNAE3_OVERFLOW_MPE; + } + } + + hns3_update_promisc_mode(netdev, new_flags); + /* User mode Promisc mode enable and vlan filtering is disabled to + * let all packets in. MAC-VLAN Table overflow Promisc enabled and + * vlan fitering is enabled + */ + hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR); + h->netdev_flags = new_flags; +} + +void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; + + if (h->ae_algo->ops->set_promisc_mode) { + h->ae_algo->ops->set_promisc_mode(h, + promisc_flags & HNAE3_UPE, + promisc_flags & HNAE3_MPE); + } +} + +void hns3_enable_vlan_filter(struct net_device *netdev, bool enable) +{ + struct hns3_nic_priv *priv = netdev_priv(netdev); + struct hnae3_handle *h = priv->ae_handle; + bool last_state; + + if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) { + last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false; + if (enable != last_state) { + netdev_info(netdev, + "%s vlan filter\n", + enable ? "enable" : "disable"); + h->ae_algo->ops->enable_vlan_filter(h, enable); + } } } @@ -3607,11 +3665,15 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle) { struct net_device *netdev = handle->kinfo.netdev; struct hns3_nic_priv *priv = netdev_priv(netdev); + bool vlan_filter_enable; int ret; hns3_init_mac_addr(netdev, false); - hns3_nic_set_rx_mode(netdev); hns3_recover_hw_addr(netdev); + hns3_update_promisc_mode(netdev, handle->netdev_flags); + vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true; + hns3_enable_vlan_filter(netdev, vlan_filter_enable); + /* Hardware table is only clear when pf resets */ if (!(handle->flags & HNAE3_SUPPORT_VF)) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index ac881e8fc05d..f25b281ff2aa 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -640,6 +640,9 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector, void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector, u32 rl_value); +void hns3_enable_vlan_filter(struct net_device *netdev, bool enable); +void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags); + #ifdef CONFIG_HNS3_DCB void hns3_dcbnl_setup(struct hnae3_handle *handle); #else diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index f1354f61084f..a4762c2b8ba1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -71,6 +71,7 @@ struct hns3_link_mode_mapping { static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) { struct hnae3_handle *h = hns3_get_handle(ndev); + bool vlan_filter_enable; int ret; if (!h->ae_algo->ops->set_loopback || @@ -91,7 +92,14 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) if (ret) return ret; - h->ae_algo->ops->set_promisc_mode(h, en, en); + if (en) { + h->ae_algo->ops->set_promisc_mode(h, true, true); + } else { + /* recover promisc mode before loopback test */ + hns3_update_promisc_mode(ndev, h->netdev_flags); + vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true; + hns3_enable_vlan_filter(ndev, vlan_filter_enable); + } return ret; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index db97f6ab7221..1bd83e8268fc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -5606,6 +5606,10 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, HCLGE_FILTER_FE_EGRESS_V1_B, enable); } + if (enable) + handle->netdev_flags |= HNAE3_VLAN_FLTR; + else + handle->netdev_flags &= ~HNAE3_VLAN_FLTR; } static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid, @@ -5902,7 +5906,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) { #define HCLGE_DEF_VLAN_TYPE 0x8100 - struct hnae3_handle *handle; + struct hnae3_handle *handle = &hdev->vport[0].nic; struct hclge_vport *vport; int ret; int i; @@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) return ret; } + handle->netdev_flags |= HNAE3_VLAN_FLTR; + hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE; hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; @@ -5969,7 +5975,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) return ret; } - handle = &hdev->vport[0].nic; return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false); } |