aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJian Shen <shenjian15@huawei.com>2018-10-12 10:34:04 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-12 14:23:45 -0400
commitc60edc17df391e33c9c3cd6e319eb1f32ce26730 (patch)
tree07d434f5945d26a1ff40dfd27d6fb3e27e5b811d
parent5886d932e52acfbe12ea5aac8e7c3ad6f16364d1 (diff)
net: hns3: Enable promisc mode when mac vlan table is full
Currently, the driver does nothing when mac vlan table is full. In this case, the packet with new mac address will be dropped by hardware. This patch adds check for the result of sync mac address, and enable promisc mode when mac vlan table is full. Furtherly, disable vlan filter when enable promisc by user command. Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") Signed-off-by: Jian Shen <shenjian15@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h11
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c78
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.h3
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c9
4 files changed, 89 insertions, 12 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 {
503#define HNAE3_SUPPORT_VF BIT(3) 503#define HNAE3_SUPPORT_VF BIT(3)
504#define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4) 504#define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4)
505 505
506#define HNAE3_USER_UPE BIT(0) /* unicast promisc enabled by user */
507#define HNAE3_USER_MPE BIT(1) /* mulitcast promisc enabled by user */
508#define HNAE3_BPE BIT(2) /* broadcast promisc enable */
509#define HNAE3_OVERFLOW_UPE BIT(3) /* unicast mac vlan overflow */
510#define HNAE3_OVERFLOW_MPE BIT(4) /* multicast mac vlan overflow */
511#define HNAE3_VLAN_FLTR BIT(5) /* enable vlan filter */
512#define HNAE3_UPE (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
513#define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
514
506struct hnae3_handle { 515struct hnae3_handle {
507 struct hnae3_client *client; 516 struct hnae3_client *client;
508 struct pci_dev *pdev; 517 struct pci_dev *pdev;
@@ -521,6 +530,8 @@ struct hnae3_handle {
521 }; 530 };
522 531
523 u32 numa_node_mask; /* for multi-chip support */ 532 u32 numa_node_mask; /* for multi-chip support */
533
534 u8 netdev_flags;
524}; 535};
525 536
526#define hnae3_set_field(origin, mask, shift, val) \ 537#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..bbd6197799f0 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,
459 return 0; 459 return 0;
460} 460}
461 461
462static u8 hns3_get_netdev_flags(struct net_device *netdev)
463{
464 u8 flags = 0;
465
466 if (netdev->flags & IFF_PROMISC) {
467 flags = HNAE3_USER_UPE | HNAE3_USER_MPE;
468 } else {
469 flags |= HNAE3_VLAN_FLTR;
470 if (netdev->flags & IFF_ALLMULTI)
471 flags |= HNAE3_USER_MPE;
472 }
473
474 return flags;
475}
476
462static void hns3_nic_set_rx_mode(struct net_device *netdev) 477static void hns3_nic_set_rx_mode(struct net_device *netdev)
463{ 478{
464 struct hnae3_handle *h = hns3_get_handle(netdev); 479 struct hnae3_handle *h = hns3_get_handle(netdev);
480 u8 new_flags;
481 int ret;
465 482
466 if (h->ae_algo->ops->set_promisc_mode) { 483 new_flags = hns3_get_netdev_flags(netdev);
467 if (netdev->flags & IFF_PROMISC) 484
468 h->ae_algo->ops->set_promisc_mode(h, true, true); 485 ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
469 else if (netdev->flags & IFF_ALLMULTI) 486 if (ret) {
470 h->ae_algo->ops->set_promisc_mode(h, false, true);
471 else
472 h->ae_algo->ops->set_promisc_mode(h, false, false);
473 }
474 if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync))
475 netdev_err(netdev, "sync uc address fail\n"); 487 netdev_err(netdev, "sync uc address fail\n");
488 if (ret == -ENOSPC)
489 new_flags |= HNAE3_OVERFLOW_UPE;
490 }
491
476 if (netdev->flags & IFF_MULTICAST) { 492 if (netdev->flags & IFF_MULTICAST) {
477 if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync)) 493 ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
494 hns3_nic_mc_unsync);
495 if (ret) {
478 netdev_err(netdev, "sync mc address fail\n"); 496 netdev_err(netdev, "sync mc address fail\n");
497 if (ret == -ENOSPC)
498 new_flags |= HNAE3_OVERFLOW_MPE;
499 }
500 }
501
502 hns3_update_promisc_mode(netdev, new_flags);
503 /* User mode Promisc mode enable and vlan filtering is disabled to
504 * let all packets in. MAC-VLAN Table overflow Promisc enabled and
505 * vlan fitering is enabled
506 */
507 hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
508 h->netdev_flags = new_flags;
509}
510
511void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
512{
513 struct hns3_nic_priv *priv = netdev_priv(netdev);
514 struct hnae3_handle *h = priv->ae_handle;
515
516 if (h->ae_algo->ops->set_promisc_mode) {
517 h->ae_algo->ops->set_promisc_mode(h,
518 promisc_flags & HNAE3_UPE,
519 promisc_flags & HNAE3_MPE);
520 }
521}
522
523void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
524{
525 struct hns3_nic_priv *priv = netdev_priv(netdev);
526 struct hnae3_handle *h = priv->ae_handle;
527 bool last_state;
528
529 if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) {
530 last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false;
531 if (enable != last_state) {
532 netdev_info(netdev,
533 "%s vlan filter\n",
534 enable ? "enable" : "disable");
535 h->ae_algo->ops->enable_vlan_filter(h, enable);
536 }
479 } 537 }
480} 538}
481 539
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,
640void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector, 640void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
641 u32 rl_value); 641 u32 rl_value);
642 642
643void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
644void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
645
643#ifdef CONFIG_HNS3_DCB 646#ifdef CONFIG_HNS3_DCB
644void hns3_dcbnl_setup(struct hnae3_handle *handle); 647void hns3_dcbnl_setup(struct hnae3_handle *handle);
645#else 648#else
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)
5606 hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, 5606 hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
5607 HCLGE_FILTER_FE_EGRESS_V1_B, enable); 5607 HCLGE_FILTER_FE_EGRESS_V1_B, enable);
5608 } 5608 }
5609 if (enable)
5610 handle->netdev_flags |= HNAE3_VLAN_FLTR;
5611 else
5612 handle->netdev_flags &= ~HNAE3_VLAN_FLTR;
5609} 5613}
5610 5614
5611static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid, 5615static 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)
5902{ 5906{
5903#define HCLGE_DEF_VLAN_TYPE 0x8100 5907#define HCLGE_DEF_VLAN_TYPE 0x8100
5904 5908
5905 struct hnae3_handle *handle; 5909 struct hnae3_handle *handle = &hdev->vport[0].nic;
5906 struct hclge_vport *vport; 5910 struct hclge_vport *vport;
5907 int ret; 5911 int ret;
5908 int i; 5912 int i;
@@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
5925 return ret; 5929 return ret;
5926 } 5930 }
5927 5931
5932 handle->netdev_flags |= HNAE3_VLAN_FLTR;
5933
5928 hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; 5934 hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
5929 hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE; 5935 hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
5930 hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; 5936 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)
5969 return ret; 5975 return ret;
5970 } 5976 }
5971 5977
5972 handle = &hdev->vport[0].nic;
5973 return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false); 5978 return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
5974} 5979}
5975 5980