diff options
author | David S. Miller <davem@davemloft.net> | 2018-06-01 14:23:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-06-01 14:23:59 -0400 |
commit | 21ad1173589ef63a93f94e05c879393e2c27588c (patch) | |
tree | d38dcc3968bee7a0e04d0f71c2fdecee6fd5dce7 | |
parent | 07f7ee6ec0e2193f1abca36cd7154986aec4893e (diff) | |
parent | 3a678b5806e66d0b75086bf423ecaf80ff0237c7 (diff) |
Merge branch 'hns3-next'
Salil Mehta says:
====================
Misc. bug fixes & optimizations for HNS3 driver
This patch-set presents some bug fixes found out during the internal
review and system testing and some small optimizations.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
9 files changed, 441 insertions, 51 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h index 519e2bd6aa60..be9dc08ccf67 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h | |||
@@ -47,6 +47,8 @@ enum hclge_mbx_mac_vlan_subcode { | |||
47 | HCLGE_MBX_MAC_VLAN_MC_ADD, /* add new MC mac addr */ | 47 | HCLGE_MBX_MAC_VLAN_MC_ADD, /* add new MC mac addr */ |
48 | HCLGE_MBX_MAC_VLAN_MC_REMOVE, /* remove MC mac addr */ | 48 | HCLGE_MBX_MAC_VLAN_MC_REMOVE, /* remove MC mac addr */ |
49 | HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, /* config func MTA enable */ | 49 | HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, /* config func MTA enable */ |
50 | HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ, /* read func MTA type */ | ||
51 | HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE, /* update MTA status */ | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | /* below are per-VF vlan cfg subcodes */ | 54 | /* below are per-VF vlan cfg subcodes */ |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index f250c592a218..8acb1d116a02 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h | |||
@@ -316,7 +316,8 @@ struct hnae3_ae_ops { | |||
316 | int (*set_loopback)(struct hnae3_handle *handle, | 316 | int (*set_loopback)(struct hnae3_handle *handle, |
317 | enum hnae3_loop loop_mode, bool en); | 317 | enum hnae3_loop loop_mode, bool en); |
318 | 318 | ||
319 | void (*set_promisc_mode)(struct hnae3_handle *handle, u32 en); | 319 | void (*set_promisc_mode)(struct hnae3_handle *handle, bool en_uc_pmc, |
320 | bool en_mc_pmc); | ||
320 | int (*set_mtu)(struct hnae3_handle *handle, int new_mtu); | 321 | int (*set_mtu)(struct hnae3_handle *handle, int new_mtu); |
321 | 322 | ||
322 | void (*get_pauseparam)(struct hnae3_handle *handle, | 323 | void (*get_pauseparam)(struct hnae3_handle *handle, |
@@ -352,6 +353,7 @@ struct hnae3_ae_ops { | |||
352 | const unsigned char *addr); | 353 | const unsigned char *addr); |
353 | int (*rm_mc_addr)(struct hnae3_handle *handle, | 354 | int (*rm_mc_addr)(struct hnae3_handle *handle, |
354 | const unsigned char *addr); | 355 | const unsigned char *addr); |
356 | int (*update_mta_status)(struct hnae3_handle *handle); | ||
355 | 357 | ||
356 | void (*set_tso_stats)(struct hnae3_handle *handle, int enable); | 358 | void (*set_tso_stats)(struct hnae3_handle *handle, int enable); |
357 | void (*update_stats)(struct hnae3_handle *handle, | 359 | void (*update_stats)(struct hnae3_handle *handle, |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 05290129793f..f2b31d278bc9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | |||
@@ -415,15 +415,21 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev) | |||
415 | 415 | ||
416 | if (h->ae_algo->ops->set_promisc_mode) { | 416 | if (h->ae_algo->ops->set_promisc_mode) { |
417 | if (netdev->flags & IFF_PROMISC) | 417 | if (netdev->flags & IFF_PROMISC) |
418 | h->ae_algo->ops->set_promisc_mode(h, 1); | 418 | h->ae_algo->ops->set_promisc_mode(h, true, true); |
419 | else if (netdev->flags & IFF_ALLMULTI) | ||
420 | h->ae_algo->ops->set_promisc_mode(h, false, true); | ||
419 | else | 421 | else |
420 | h->ae_algo->ops->set_promisc_mode(h, 0); | 422 | h->ae_algo->ops->set_promisc_mode(h, false, false); |
421 | } | 423 | } |
422 | if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync)) | 424 | if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync)) |
423 | netdev_err(netdev, "sync uc address fail\n"); | 425 | netdev_err(netdev, "sync uc address fail\n"); |
424 | if (netdev->flags & IFF_MULTICAST) | 426 | if (netdev->flags & IFF_MULTICAST) { |
425 | if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync)) | 427 | if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync)) |
426 | netdev_err(netdev, "sync mc address fail\n"); | 428 | netdev_err(netdev, "sync mc address fail\n"); |
429 | |||
430 | if (h->ae_algo->ops->update_mta_status) | ||
431 | h->ae_algo->ops->update_mta_status(h); | ||
432 | } | ||
427 | } | 433 | } |
428 | 434 | ||
429 | static int hns3_set_tso(struct sk_buff *skb, u32 *paylen, | 435 | static int hns3_set_tso(struct sk_buff *skb, u32 *paylen, |
@@ -653,6 +659,32 @@ static void hns3_set_l2l3l4_len(struct sk_buff *skb, u8 ol4_proto, | |||
653 | } | 659 | } |
654 | } | 660 | } |
655 | 661 | ||
662 | /* when skb->encapsulation is 0, skb->ip_summed is CHECKSUM_PARTIAL | ||
663 | * and it is udp packet, which has a dest port as the IANA assigned. | ||
664 | * the hardware is expected to do the checksum offload, but the | ||
665 | * hardware will not do the checksum offload when udp dest port is | ||
666 | * 4789. | ||
667 | */ | ||
668 | static bool hns3_tunnel_csum_bug(struct sk_buff *skb) | ||
669 | { | ||
670 | #define IANA_VXLAN_PORT 4789 | ||
671 | union { | ||
672 | struct tcphdr *tcp; | ||
673 | struct udphdr *udp; | ||
674 | struct gre_base_hdr *gre; | ||
675 | unsigned char *hdr; | ||
676 | } l4; | ||
677 | |||
678 | l4.hdr = skb_transport_header(skb); | ||
679 | |||
680 | if (!(!skb->encapsulation && l4.udp->dest == htons(IANA_VXLAN_PORT))) | ||
681 | return false; | ||
682 | |||
683 | skb_checksum_help(skb); | ||
684 | |||
685 | return true; | ||
686 | } | ||
687 | |||
656 | static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto, | 688 | static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto, |
657 | u8 il4_proto, u32 *type_cs_vlan_tso, | 689 | u8 il4_proto, u32 *type_cs_vlan_tso, |
658 | u32 *ol_type_vlan_len_msec) | 690 | u32 *ol_type_vlan_len_msec) |
@@ -741,6 +773,9 @@ static int hns3_set_l3l4_type_csum(struct sk_buff *skb, u8 ol4_proto, | |||
741 | HNS3_L4T_TCP); | 773 | HNS3_L4T_TCP); |
742 | break; | 774 | break; |
743 | case IPPROTO_UDP: | 775 | case IPPROTO_UDP: |
776 | if (hns3_tunnel_csum_bug(skb)) | ||
777 | break; | ||
778 | |||
744 | hnae_set_field(*type_cs_vlan_tso, | 779 | hnae_set_field(*type_cs_vlan_tso, |
745 | HNS3_TXD_L4T_M, | 780 | HNS3_TXD_L4T_M, |
746 | HNS3_TXD_L4T_S, | 781 | HNS3_TXD_L4T_S, |
@@ -1130,6 +1165,12 @@ static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p) | |||
1130 | if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data)) | 1165 | if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data)) |
1131 | return -EADDRNOTAVAIL; | 1166 | return -EADDRNOTAVAIL; |
1132 | 1167 | ||
1168 | if (ether_addr_equal(netdev->dev_addr, mac_addr->sa_data)) { | ||
1169 | netdev_info(netdev, "already using mac address %pM\n", | ||
1170 | mac_addr->sa_data); | ||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1133 | ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data, false); | 1174 | ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data, false); |
1134 | if (ret) { | 1175 | if (ret) { |
1135 | netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret); | 1176 | netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret); |
@@ -2999,6 +3040,15 @@ static void hns3_init_mac_addr(struct net_device *netdev, bool init) | |||
2999 | 3040 | ||
3000 | } | 3041 | } |
3001 | 3042 | ||
3043 | static void hns3_uninit_mac_addr(struct net_device *netdev) | ||
3044 | { | ||
3045 | struct hns3_nic_priv *priv = netdev_priv(netdev); | ||
3046 | struct hnae3_handle *h = priv->ae_handle; | ||
3047 | |||
3048 | if (h->ae_algo->ops->rm_uc_addr) | ||
3049 | h->ae_algo->ops->rm_uc_addr(h, netdev->dev_addr); | ||
3050 | } | ||
3051 | |||
3002 | static void hns3_nic_set_priv_ops(struct net_device *netdev) | 3052 | static void hns3_nic_set_priv_ops(struct net_device *netdev) |
3003 | { | 3053 | { |
3004 | struct hns3_nic_priv *priv = netdev_priv(netdev); | 3054 | struct hns3_nic_priv *priv = netdev_priv(netdev); |
@@ -3127,6 +3177,8 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset) | |||
3127 | 3177 | ||
3128 | priv->ring_data = NULL; | 3178 | priv->ring_data = NULL; |
3129 | 3179 | ||
3180 | hns3_uninit_mac_addr(netdev); | ||
3181 | |||
3130 | free_netdev(netdev); | 3182 | free_netdev(netdev); |
3131 | } | 3183 | } |
3132 | 3184 | ||
@@ -3443,6 +3495,8 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle) | |||
3443 | 3495 | ||
3444 | priv->ring_data = NULL; | 3496 | priv->ring_data = NULL; |
3445 | 3497 | ||
3498 | hns3_uninit_mac_addr(netdev); | ||
3499 | |||
3446 | return ret; | 3500 | return ret; |
3447 | } | 3501 | } |
3448 | 3502 | ||
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 8f8cc2413656..40c0425b4023 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | |||
@@ -95,7 +95,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) | |||
95 | if (ret) | 95 | if (ret) |
96 | return ret; | 96 | return ret; |
97 | 97 | ||
98 | h->ae_algo->ops->set_promisc_mode(h, en); | 98 | h->ae_algo->ops->set_promisc_mode(h, en, en); |
99 | 99 | ||
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 69166858a6dc..2a801344eafb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | |||
@@ -2288,8 +2288,10 @@ static int hclge_mac_init(struct hclge_dev *hdev) | |||
2288 | struct net_device *netdev = handle->kinfo.netdev; | 2288 | struct net_device *netdev = handle->kinfo.netdev; |
2289 | struct hclge_mac *mac = &hdev->hw.mac; | 2289 | struct hclge_mac *mac = &hdev->hw.mac; |
2290 | u8 mac_mask[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 2290 | u8 mac_mask[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
2291 | struct hclge_vport *vport; | ||
2291 | int mtu; | 2292 | int mtu; |
2292 | int ret; | 2293 | int ret; |
2294 | int i; | ||
2293 | 2295 | ||
2294 | ret = hclge_cfg_mac_speed_dup(hdev, hdev->hw.mac.speed, HCLGE_MAC_FULL); | 2296 | ret = hclge_cfg_mac_speed_dup(hdev, hdev->hw.mac.speed, HCLGE_MAC_FULL); |
2295 | if (ret) { | 2297 | if (ret) { |
@@ -2301,7 +2303,6 @@ static int hclge_mac_init(struct hclge_dev *hdev) | |||
2301 | mac->link = 0; | 2303 | mac->link = 0; |
2302 | 2304 | ||
2303 | /* Initialize the MTA table work mode */ | 2305 | /* Initialize the MTA table work mode */ |
2304 | hdev->accept_mta_mc = true; | ||
2305 | hdev->enable_mta = true; | 2306 | hdev->enable_mta = true; |
2306 | hdev->mta_mac_sel_type = HCLGE_MAC_ADDR_47_36; | 2307 | hdev->mta_mac_sel_type = HCLGE_MAC_ADDR_47_36; |
2307 | 2308 | ||
@@ -2314,11 +2315,17 @@ static int hclge_mac_init(struct hclge_dev *hdev) | |||
2314 | return ret; | 2315 | return ret; |
2315 | } | 2316 | } |
2316 | 2317 | ||
2317 | ret = hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc); | 2318 | for (i = 0; i < hdev->num_alloc_vport; i++) { |
2318 | if (ret) { | 2319 | vport = &hdev->vport[i]; |
2319 | dev_err(&hdev->pdev->dev, | 2320 | vport->accept_mta_mc = false; |
2320 | "set mta filter mode fail ret=%d\n", ret); | 2321 | |
2321 | return ret; | 2322 | memset(vport->mta_shadow, 0, sizeof(vport->mta_shadow)); |
2323 | ret = hclge_cfg_func_mta_filter(hdev, vport->vport_id, false); | ||
2324 | if (ret) { | ||
2325 | dev_err(&hdev->pdev->dev, | ||
2326 | "set mta filter mode fail ret=%d\n", ret); | ||
2327 | return ret; | ||
2328 | } | ||
2322 | } | 2329 | } |
2323 | 2330 | ||
2324 | ret = hclge_set_default_mac_vlan_mask(hdev, true, mac_mask); | 2331 | ret = hclge_set_default_mac_vlan_mask(hdev, true, mac_mask); |
@@ -2580,16 +2587,18 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data) | |||
2580 | * mbx messages reported by this interrupt. | 2587 | * mbx messages reported by this interrupt. |
2581 | */ | 2588 | */ |
2582 | hclge_mbx_task_schedule(hdev); | 2589 | hclge_mbx_task_schedule(hdev); |
2583 | 2590 | break; | |
2584 | default: | 2591 | default: |
2585 | dev_dbg(&hdev->pdev->dev, | 2592 | dev_warn(&hdev->pdev->dev, |
2586 | "received unknown or unhandled event of vector0\n"); | 2593 | "received unknown or unhandled event of vector0\n"); |
2587 | break; | 2594 | break; |
2588 | } | 2595 | } |
2589 | 2596 | ||
2590 | /* we should clear the source of interrupt */ | 2597 | /* clear the source of interrupt if it is not cause by reset */ |
2591 | hclge_clear_event_cause(hdev, event_cause, clearval); | 2598 | if (event_cause != HCLGE_VECTOR0_EVENT_RST) { |
2592 | hclge_enable_vector(&hdev->misc_vector, true); | 2599 | hclge_clear_event_cause(hdev, event_cause, clearval); |
2600 | hclge_enable_vector(&hdev->misc_vector, true); | ||
2601 | } | ||
2593 | 2602 | ||
2594 | return IRQ_HANDLED; | 2603 | return IRQ_HANDLED; |
2595 | } | 2604 | } |
@@ -2777,6 +2786,33 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hclge_dev *hdev, | |||
2777 | return rst_level; | 2786 | return rst_level; |
2778 | } | 2787 | } |
2779 | 2788 | ||
2789 | static void hclge_clear_reset_cause(struct hclge_dev *hdev) | ||
2790 | { | ||
2791 | u32 clearval = 0; | ||
2792 | |||
2793 | switch (hdev->reset_type) { | ||
2794 | case HNAE3_IMP_RESET: | ||
2795 | clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); | ||
2796 | break; | ||
2797 | case HNAE3_GLOBAL_RESET: | ||
2798 | clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); | ||
2799 | break; | ||
2800 | case HNAE3_CORE_RESET: | ||
2801 | clearval = BIT(HCLGE_VECTOR0_CORERESET_INT_B); | ||
2802 | break; | ||
2803 | default: | ||
2804 | dev_warn(&hdev->pdev->dev, "Unsupported reset event to clear:%d", | ||
2805 | hdev->reset_type); | ||
2806 | break; | ||
2807 | } | ||
2808 | |||
2809 | if (!clearval) | ||
2810 | return; | ||
2811 | |||
2812 | hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, clearval); | ||
2813 | hclge_enable_vector(&hdev->misc_vector, true); | ||
2814 | } | ||
2815 | |||
2780 | static void hclge_reset(struct hclge_dev *hdev) | 2816 | static void hclge_reset(struct hclge_dev *hdev) |
2781 | { | 2817 | { |
2782 | /* perform reset of the stack & ae device for a client */ | 2818 | /* perform reset of the stack & ae device for a client */ |
@@ -2789,6 +2825,8 @@ static void hclge_reset(struct hclge_dev *hdev) | |||
2789 | hclge_reset_ae_dev(hdev->ae_dev); | 2825 | hclge_reset_ae_dev(hdev->ae_dev); |
2790 | hclge_notify_client(hdev, HNAE3_INIT_CLIENT); | 2826 | hclge_notify_client(hdev, HNAE3_INIT_CLIENT); |
2791 | rtnl_unlock(); | 2827 | rtnl_unlock(); |
2828 | |||
2829 | hclge_clear_reset_cause(hdev); | ||
2792 | } else { | 2830 | } else { |
2793 | /* schedule again to check pending resets later */ | 2831 | /* schedule again to check pending resets later */ |
2794 | set_bit(hdev->reset_type, &hdev->reset_pending); | 2832 | set_bit(hdev->reset_type, &hdev->reset_pending); |
@@ -3580,13 +3618,15 @@ void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc, | |||
3580 | param->vf_id = vport_id; | 3618 | param->vf_id = vport_id; |
3581 | } | 3619 | } |
3582 | 3620 | ||
3583 | static void hclge_set_promisc_mode(struct hnae3_handle *handle, u32 en) | 3621 | static void hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, |
3622 | bool en_mc_pmc) | ||
3584 | { | 3623 | { |
3585 | struct hclge_vport *vport = hclge_get_vport(handle); | 3624 | struct hclge_vport *vport = hclge_get_vport(handle); |
3586 | struct hclge_dev *hdev = vport->back; | 3625 | struct hclge_dev *hdev = vport->back; |
3587 | struct hclge_promisc_param param; | 3626 | struct hclge_promisc_param param; |
3588 | 3627 | ||
3589 | hclge_promisc_param_init(¶m, en, en, true, vport->vport_id); | 3628 | hclge_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, true, |
3629 | vport->vport_id); | ||
3590 | hclge_cmd_set_promisc_mode(hdev, ¶m); | 3630 | hclge_cmd_set_promisc_mode(hdev, ¶m); |
3591 | } | 3631 | } |
3592 | 3632 | ||
@@ -3728,9 +3768,6 @@ static int hclge_ae_start(struct hnae3_handle *handle) | |||
3728 | /* reset tqp stats */ | 3768 | /* reset tqp stats */ |
3729 | hclge_reset_tqp_stats(handle); | 3769 | hclge_reset_tqp_stats(handle); |
3730 | 3770 | ||
3731 | if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) | ||
3732 | return 0; | ||
3733 | |||
3734 | ret = hclge_mac_start_phy(hdev); | 3771 | ret = hclge_mac_start_phy(hdev); |
3735 | if (ret) | 3772 | if (ret) |
3736 | return ret; | 3773 | return ret; |
@@ -3746,9 +3783,12 @@ static void hclge_ae_stop(struct hnae3_handle *handle) | |||
3746 | 3783 | ||
3747 | del_timer_sync(&hdev->service_timer); | 3784 | del_timer_sync(&hdev->service_timer); |
3748 | cancel_work_sync(&hdev->service_task); | 3785 | cancel_work_sync(&hdev->service_task); |
3786 | clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state); | ||
3749 | 3787 | ||
3750 | if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) | 3788 | if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) { |
3789 | hclge_mac_stop_phy(hdev); | ||
3751 | return; | 3790 | return; |
3791 | } | ||
3752 | 3792 | ||
3753 | for (i = 0; i < vport->alloc_tqps; i++) | 3793 | for (i = 0; i < vport->alloc_tqps; i++) |
3754 | hclge_tqp_enable(hdev, i, 0, false); | 3794 | hclge_tqp_enable(hdev, i, 0, false); |
@@ -3972,9 +4012,88 @@ static int hclge_set_mta_table_item(struct hclge_vport *vport, | |||
3972 | return ret; | 4012 | return ret; |
3973 | } | 4013 | } |
3974 | 4014 | ||
4015 | if (enable) | ||
4016 | set_bit(idx, vport->mta_shadow); | ||
4017 | else | ||
4018 | clear_bit(idx, vport->mta_shadow); | ||
4019 | |||
3975 | return 0; | 4020 | return 0; |
3976 | } | 4021 | } |
3977 | 4022 | ||
4023 | static int hclge_update_mta_status(struct hnae3_handle *handle) | ||
4024 | { | ||
4025 | unsigned long mta_status[BITS_TO_LONGS(HCLGE_MTA_TBL_SIZE)]; | ||
4026 | struct hclge_vport *vport = hclge_get_vport(handle); | ||
4027 | struct net_device *netdev = handle->kinfo.netdev; | ||
4028 | struct netdev_hw_addr *ha; | ||
4029 | u16 tbl_idx; | ||
4030 | |||
4031 | memset(mta_status, 0, sizeof(mta_status)); | ||
4032 | |||
4033 | /* update mta_status from mc addr list */ | ||
4034 | netdev_for_each_mc_addr(ha, netdev) { | ||
4035 | tbl_idx = hclge_get_mac_addr_to_mta_index(vport, ha->addr); | ||
4036 | set_bit(tbl_idx, mta_status); | ||
4037 | } | ||
4038 | |||
4039 | return hclge_update_mta_status_common(vport, mta_status, | ||
4040 | 0, HCLGE_MTA_TBL_SIZE, true); | ||
4041 | } | ||
4042 | |||
4043 | int hclge_update_mta_status_common(struct hclge_vport *vport, | ||
4044 | unsigned long *status, | ||
4045 | u16 idx, | ||
4046 | u16 count, | ||
4047 | bool update_filter) | ||
4048 | { | ||
4049 | struct hclge_dev *hdev = vport->back; | ||
4050 | u16 update_max = idx + count; | ||
4051 | u16 check_max; | ||
4052 | int ret = 0; | ||
4053 | bool used; | ||
4054 | u16 i; | ||
4055 | |||
4056 | /* setup mta check range */ | ||
4057 | if (update_filter) { | ||
4058 | i = 0; | ||
4059 | check_max = HCLGE_MTA_TBL_SIZE; | ||
4060 | } else { | ||
4061 | i = idx; | ||
4062 | check_max = update_max; | ||
4063 | } | ||
4064 | |||
4065 | used = false; | ||
4066 | /* check and update all mta item */ | ||
4067 | for (; i < check_max; i++) { | ||
4068 | /* ignore unused item */ | ||
4069 | if (!test_bit(i, vport->mta_shadow)) | ||
4070 | continue; | ||
4071 | |||
4072 | /* if i in update range then update it */ | ||
4073 | if (i >= idx && i < update_max) | ||
4074 | if (!test_bit(i - idx, status)) | ||
4075 | hclge_set_mta_table_item(vport, i, false); | ||
4076 | |||
4077 | if (!used && test_bit(i, vport->mta_shadow)) | ||
4078 | used = true; | ||
4079 | } | ||
4080 | |||
4081 | /* no longer use mta, disable it */ | ||
4082 | if (vport->accept_mta_mc && update_filter && !used) { | ||
4083 | ret = hclge_cfg_func_mta_filter(hdev, | ||
4084 | vport->vport_id, | ||
4085 | false); | ||
4086 | if (ret) | ||
4087 | dev_err(&hdev->pdev->dev, | ||
4088 | "disable func mta filter fail ret=%d\n", | ||
4089 | ret); | ||
4090 | else | ||
4091 | vport->accept_mta_mc = false; | ||
4092 | } | ||
4093 | |||
4094 | return ret; | ||
4095 | } | ||
4096 | |||
3978 | static int hclge_remove_mac_vlan_tbl(struct hclge_vport *vport, | 4097 | static int hclge_remove_mac_vlan_tbl(struct hclge_vport *vport, |
3979 | struct hclge_mac_vlan_tbl_entry_cmd *req) | 4098 | struct hclge_mac_vlan_tbl_entry_cmd *req) |
3980 | { | 4099 | { |
@@ -4242,9 +4361,25 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport, | |||
4242 | status = hclge_add_mac_vlan_tbl(vport, &req, desc); | 4361 | status = hclge_add_mac_vlan_tbl(vport, &req, desc); |
4243 | } | 4362 | } |
4244 | 4363 | ||
4245 | /* Set MTA table for this MAC address */ | 4364 | /* If mc mac vlan table is full, use MTA table */ |
4246 | tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr); | 4365 | if (status == -ENOSPC) { |
4247 | status = hclge_set_mta_table_item(vport, tbl_idx, true); | 4366 | if (!vport->accept_mta_mc) { |
4367 | status = hclge_cfg_func_mta_filter(hdev, | ||
4368 | vport->vport_id, | ||
4369 | true); | ||
4370 | if (status) { | ||
4371 | dev_err(&hdev->pdev->dev, | ||
4372 | "set mta filter mode fail ret=%d\n", | ||
4373 | status); | ||
4374 | return status; | ||
4375 | } | ||
4376 | vport->accept_mta_mc = true; | ||
4377 | } | ||
4378 | |||
4379 | /* Set MTA table for this MAC address */ | ||
4380 | tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr); | ||
4381 | status = hclge_set_mta_table_item(vport, tbl_idx, true); | ||
4382 | } | ||
4248 | 4383 | ||
4249 | return status; | 4384 | return status; |
4250 | } | 4385 | } |
@@ -4264,7 +4399,6 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport, | |||
4264 | struct hclge_mac_vlan_tbl_entry_cmd req; | 4399 | struct hclge_mac_vlan_tbl_entry_cmd req; |
4265 | enum hclge_cmd_status status; | 4400 | enum hclge_cmd_status status; |
4266 | struct hclge_desc desc[3]; | 4401 | struct hclge_desc desc[3]; |
4267 | u16 tbl_idx; | ||
4268 | 4402 | ||
4269 | /* mac addr check */ | 4403 | /* mac addr check */ |
4270 | if (!is_multicast_ether_addr(addr)) { | 4404 | if (!is_multicast_ether_addr(addr)) { |
@@ -4293,17 +4427,15 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport, | |||
4293 | status = hclge_add_mac_vlan_tbl(vport, &req, desc); | 4427 | status = hclge_add_mac_vlan_tbl(vport, &req, desc); |
4294 | 4428 | ||
4295 | } else { | 4429 | } else { |
4296 | /* This mac addr do not exist, can't delete it */ | 4430 | /* Maybe this mac address is in mta table, but it cannot be |
4297 | dev_err(&hdev->pdev->dev, | 4431 | * deleted here because an entry of mta represents an address |
4298 | "Rm multicast mac addr failed, ret = %d.\n", | 4432 | * range rather than a specific address. the delete action to |
4299 | status); | 4433 | * all entries will take effect in update_mta_status called by |
4300 | return -EIO; | 4434 | * hns3_nic_set_rx_mode. |
4435 | */ | ||
4436 | status = 0; | ||
4301 | } | 4437 | } |
4302 | 4438 | ||
4303 | /* Set MTB table for this MAC address */ | ||
4304 | tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr); | ||
4305 | status = hclge_set_mta_table_item(vport, tbl_idx, false); | ||
4306 | |||
4307 | return status; | 4439 | return status; |
4308 | } | 4440 | } |
4309 | 4441 | ||
@@ -4525,9 +4657,16 @@ static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid, | |||
4525 | } | 4657 | } |
4526 | 4658 | ||
4527 | if (!is_kill) { | 4659 | if (!is_kill) { |
4660 | #define HCLGE_VF_VLAN_NO_ENTRY 2 | ||
4528 | if (!req0->resp_code || req0->resp_code == 1) | 4661 | if (!req0->resp_code || req0->resp_code == 1) |
4529 | return 0; | 4662 | return 0; |
4530 | 4663 | ||
4664 | if (req0->resp_code == HCLGE_VF_VLAN_NO_ENTRY) { | ||
4665 | dev_warn(&hdev->pdev->dev, | ||
4666 | "vf vlan table is full, vf vlan filter is disabled\n"); | ||
4667 | return 0; | ||
4668 | } | ||
4669 | |||
4531 | dev_err(&hdev->pdev->dev, | 4670 | dev_err(&hdev->pdev->dev, |
4532 | "Add vf vlan filter fail, ret =%d.\n", | 4671 | "Add vf vlan filter fail, ret =%d.\n", |
4533 | req0->resp_code); | 4672 | req0->resp_code); |
@@ -5651,9 +5790,6 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) | |||
5651 | return ret; | 5790 | return ret; |
5652 | } | 5791 | } |
5653 | 5792 | ||
5654 | /* Enable MISC vector(vector0) */ | ||
5655 | hclge_enable_vector(&hdev->misc_vector, true); | ||
5656 | |||
5657 | dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n", | 5793 | dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n", |
5658 | HCLGE_DRIVER_NAME); | 5794 | HCLGE_DRIVER_NAME); |
5659 | 5795 | ||
@@ -6100,6 +6236,7 @@ static const struct hnae3_ae_ops hclge_ops = { | |||
6100 | .rm_uc_addr = hclge_rm_uc_addr, | 6236 | .rm_uc_addr = hclge_rm_uc_addr, |
6101 | .add_mc_addr = hclge_add_mc_addr, | 6237 | .add_mc_addr = hclge_add_mc_addr, |
6102 | .rm_mc_addr = hclge_rm_mc_addr, | 6238 | .rm_mc_addr = hclge_rm_mc_addr, |
6239 | .update_mta_status = hclge_update_mta_status, | ||
6103 | .set_autoneg = hclge_set_autoneg, | 6240 | .set_autoneg = hclge_set_autoneg, |
6104 | .get_autoneg = hclge_get_autoneg, | 6241 | .get_autoneg = hclge_get_autoneg, |
6105 | .get_pauseparam = hclge_get_pauseparam, | 6242 | .get_pauseparam = hclge_get_pauseparam, |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 7fcabdeb4ce9..7488534528cd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | |||
@@ -61,6 +61,8 @@ | |||
61 | #define HCLGE_RSS_TC_SIZE_6 64 | 61 | #define HCLGE_RSS_TC_SIZE_6 64 |
62 | #define HCLGE_RSS_TC_SIZE_7 128 | 62 | #define HCLGE_RSS_TC_SIZE_7 128 |
63 | 63 | ||
64 | #define HCLGE_MTA_TBL_SIZE 4096 | ||
65 | |||
64 | #define HCLGE_TQP_RESET_TRY_TIMES 10 | 66 | #define HCLGE_TQP_RESET_TRY_TIMES 10 |
65 | 67 | ||
66 | #define HCLGE_PHY_PAGE_MDIX 0 | 68 | #define HCLGE_PHY_PAGE_MDIX 0 |
@@ -559,7 +561,6 @@ struct hclge_dev { | |||
559 | 561 | ||
560 | enum hclge_mta_dmac_sel_type mta_mac_sel_type; | 562 | enum hclge_mta_dmac_sel_type mta_mac_sel_type; |
561 | bool enable_mta; /* Mutilcast filter enable */ | 563 | bool enable_mta; /* Mutilcast filter enable */ |
562 | bool accept_mta_mc; /* Whether accept mta filter multicast */ | ||
563 | 564 | ||
564 | struct hclge_vlan_type_cfg vlan_type_cfg; | 565 | struct hclge_vlan_type_cfg vlan_type_cfg; |
565 | 566 | ||
@@ -620,6 +621,9 @@ struct hclge_vport { | |||
620 | struct hclge_dev *back; /* Back reference to associated dev */ | 621 | struct hclge_dev *back; /* Back reference to associated dev */ |
621 | struct hnae3_handle nic; | 622 | struct hnae3_handle nic; |
622 | struct hnae3_handle roce; | 623 | struct hnae3_handle roce; |
624 | |||
625 | bool accept_mta_mc; /* whether to accept mta filter multicast */ | ||
626 | unsigned long mta_shadow[BITS_TO_LONGS(HCLGE_MTA_TBL_SIZE)]; | ||
623 | }; | 627 | }; |
624 | 628 | ||
625 | void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc, | 629 | void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc, |
@@ -637,6 +641,12 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport, | |||
637 | int hclge_cfg_func_mta_filter(struct hclge_dev *hdev, | 641 | int hclge_cfg_func_mta_filter(struct hclge_dev *hdev, |
638 | u8 func_id, | 642 | u8 func_id, |
639 | bool enable); | 643 | bool enable); |
644 | int hclge_update_mta_status_common(struct hclge_vport *vport, | ||
645 | unsigned long *status, | ||
646 | u16 idx, | ||
647 | u16 count, | ||
648 | bool update_filter); | ||
649 | |||
640 | struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle); | 650 | struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle); |
641 | int hclge_bind_ring_with_vector(struct hclge_vport *vport, | 651 | int hclge_bind_ring_with_vector(struct hclge_vport *vport, |
642 | int vector_id, bool en, | 652 | int vector_id, bool en, |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 31f3d9a43d8d..7541cb9b71ce 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | |||
@@ -190,11 +190,12 @@ static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en, | |||
190 | static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, | 190 | static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, |
191 | struct hclge_mbx_vf_to_pf_cmd *req) | 191 | struct hclge_mbx_vf_to_pf_cmd *req) |
192 | { | 192 | { |
193 | bool en = req->msg[1] ? true : false; | 193 | bool en_uc = req->msg[1] ? true : false; |
194 | bool en_mc = req->msg[2] ? true : false; | ||
194 | struct hclge_promisc_param param; | 195 | struct hclge_promisc_param param; |
195 | 196 | ||
196 | /* always enable broadcast promisc bit */ | 197 | /* always enable broadcast promisc bit */ |
197 | hclge_promisc_param_init(¶m, en, en, true, vport->vport_id); | 198 | hclge_promisc_param_init(¶m, en_uc, en_mc, true, vport->vport_id); |
198 | return hclge_cmd_set_promisc_mode(vport->back, ¶m); | 199 | return hclge_cmd_set_promisc_mode(vport->back, ¶m); |
199 | } | 200 | } |
200 | 201 | ||
@@ -230,12 +231,51 @@ static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, | |||
230 | return 0; | 231 | return 0; |
231 | } | 232 | } |
232 | 233 | ||
234 | static int hclge_set_vf_mc_mta_status(struct hclge_vport *vport, | ||
235 | u8 *msg, u8 idx, bool is_end) | ||
236 | { | ||
237 | #define HCLGE_MTA_STATUS_MSG_SIZE 13 | ||
238 | #define HCLGE_MTA_STATUS_MSG_BITS \ | ||
239 | (HCLGE_MTA_STATUS_MSG_SIZE * BITS_PER_BYTE) | ||
240 | #define HCLGE_MTA_STATUS_MSG_END_BITS \ | ||
241 | (HCLGE_MTA_TBL_SIZE % HCLGE_MTA_STATUS_MSG_BITS) | ||
242 | unsigned long status[BITS_TO_LONGS(HCLGE_MTA_STATUS_MSG_BITS)]; | ||
243 | u16 tbl_cnt; | ||
244 | u16 tbl_idx; | ||
245 | u8 msg_ofs; | ||
246 | u8 msg_bit; | ||
247 | |||
248 | tbl_cnt = is_end ? HCLGE_MTA_STATUS_MSG_END_BITS : | ||
249 | HCLGE_MTA_STATUS_MSG_BITS; | ||
250 | |||
251 | /* set msg field */ | ||
252 | msg_ofs = 0; | ||
253 | msg_bit = 0; | ||
254 | memset(status, 0, sizeof(status)); | ||
255 | for (tbl_idx = 0; tbl_idx < tbl_cnt; tbl_idx++) { | ||
256 | if (msg[msg_ofs] & BIT(msg_bit)) | ||
257 | set_bit(tbl_idx, status); | ||
258 | |||
259 | msg_bit++; | ||
260 | if (msg_bit == BITS_PER_BYTE) { | ||
261 | msg_bit = 0; | ||
262 | msg_ofs++; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | return hclge_update_mta_status_common(vport, | ||
267 | status, idx * HCLGE_MTA_STATUS_MSG_BITS, | ||
268 | tbl_cnt, is_end); | ||
269 | } | ||
270 | |||
233 | static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, | 271 | static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, |
234 | struct hclge_mbx_vf_to_pf_cmd *mbx_req, | 272 | struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
235 | bool gen_resp) | 273 | bool gen_resp) |
236 | { | 274 | { |
237 | const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); | 275 | const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); |
238 | struct hclge_dev *hdev = vport->back; | 276 | struct hclge_dev *hdev = vport->back; |
277 | u8 resp_len = 0; | ||
278 | u8 resp_data; | ||
239 | int status; | 279 | int status; |
240 | 280 | ||
241 | if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_ADD) { | 281 | if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_ADD) { |
@@ -247,6 +287,22 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, | |||
247 | bool enable = mbx_req->msg[2]; | 287 | bool enable = mbx_req->msg[2]; |
248 | 288 | ||
249 | status = hclge_cfg_func_mta_filter(hdev, func_id, enable); | 289 | status = hclge_cfg_func_mta_filter(hdev, func_id, enable); |
290 | } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ) { | ||
291 | resp_data = hdev->mta_mac_sel_type; | ||
292 | resp_len = sizeof(u8); | ||
293 | gen_resp = true; | ||
294 | status = 0; | ||
295 | } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE) { | ||
296 | /* mta status update msg format | ||
297 | * msg[2.6 : 2.0] msg index | ||
298 | * msg[2.7] msg is end | ||
299 | * msg[15 : 3] mta status bits[103 : 0] | ||
300 | */ | ||
301 | bool is_end = (mbx_req->msg[2] & 0x80) ? true : false; | ||
302 | |||
303 | status = hclge_set_vf_mc_mta_status(vport, &mbx_req->msg[3], | ||
304 | mbx_req->msg[2] & 0x7F, | ||
305 | is_end); | ||
250 | } else { | 306 | } else { |
251 | dev_err(&hdev->pdev->dev, | 307 | dev_err(&hdev->pdev->dev, |
252 | "failed to set mcast mac addr, unknown subcode %d\n", | 308 | "failed to set mcast mac addr, unknown subcode %d\n", |
@@ -255,7 +311,8 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, | |||
255 | } | 311 | } |
256 | 312 | ||
257 | if (gen_resp) | 313 | if (gen_resp) |
258 | hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); | 314 | hclge_gen_resp_to_vf(vport, mbx_req, status, |
315 | &resp_data, resp_len); | ||
259 | 316 | ||
260 | return 0; | 317 | return 0; |
261 | } | 318 | } |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 266cdcba506e..dd8e8e6718dc 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | |||
@@ -654,7 +654,8 @@ static int hclgevf_put_vector(struct hnae3_handle *handle, int vector) | |||
654 | return 0; | 654 | return 0; |
655 | } | 655 | } |
656 | 656 | ||
657 | static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) | 657 | static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, |
658 | bool en_uc_pmc, bool en_mc_pmc) | ||
658 | { | 659 | { |
659 | struct hclge_mbx_vf_to_pf_cmd *req; | 660 | struct hclge_mbx_vf_to_pf_cmd *req; |
660 | struct hclgevf_desc desc; | 661 | struct hclgevf_desc desc; |
@@ -664,7 +665,8 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) | |||
664 | 665 | ||
665 | hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); | 666 | hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); |
666 | req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; | 667 | req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; |
667 | req->msg[1] = en; | 668 | req->msg[1] = en_uc_pmc ? 1 : 0; |
669 | req->msg[2] = en_mc_pmc ? 1 : 0; | ||
668 | 670 | ||
669 | status = hclgevf_cmd_send(&hdev->hw, &desc, 1); | 671 | status = hclgevf_cmd_send(&hdev->hw, &desc, 1); |
670 | if (status) | 672 | if (status) |
@@ -674,11 +676,12 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, u32 en) | |||
674 | return status; | 676 | return status; |
675 | } | 677 | } |
676 | 678 | ||
677 | static void hclgevf_set_promisc_mode(struct hnae3_handle *handle, u32 en) | 679 | static void hclgevf_set_promisc_mode(struct hnae3_handle *handle, |
680 | bool en_uc_pmc, bool en_mc_pmc) | ||
678 | { | 681 | { |
679 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | 682 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); |
680 | 683 | ||
681 | hclgevf_cmd_set_promisc_mode(hdev, en); | 684 | hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc); |
682 | } | 685 | } |
683 | 686 | ||
684 | static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, | 687 | static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id, |
@@ -736,6 +739,126 @@ static int hclgevf_cfg_func_mta_filter(struct hnae3_handle *handle, bool en) | |||
736 | msg, 1, false, NULL, 0); | 739 | msg, 1, false, NULL, 0); |
737 | } | 740 | } |
738 | 741 | ||
742 | static int hclgevf_cfg_func_mta_type(struct hclgevf_dev *hdev) | ||
743 | { | ||
744 | u8 resp_msg = HCLGEVF_MTA_TYPE_SEL_MAX; | ||
745 | int ret; | ||
746 | |||
747 | ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, | ||
748 | HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ, | ||
749 | NULL, 0, true, &resp_msg, sizeof(u8)); | ||
750 | |||
751 | if (ret) { | ||
752 | dev_err(&hdev->pdev->dev, | ||
753 | "Read mta type fail, ret=%d.\n", ret); | ||
754 | return ret; | ||
755 | } | ||
756 | |||
757 | if (resp_msg > HCLGEVF_MTA_TYPE_SEL_MAX) { | ||
758 | dev_err(&hdev->pdev->dev, | ||
759 | "Read mta type invalid, resp=%d.\n", resp_msg); | ||
760 | return -EINVAL; | ||
761 | } | ||
762 | |||
763 | hdev->mta_mac_sel_type = resp_msg; | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static u16 hclgevf_get_mac_addr_to_mta_index(struct hclgevf_dev *hdev, | ||
769 | const u8 *addr) | ||
770 | { | ||
771 | u32 rsh = HCLGEVF_MTA_TYPE_SEL_MAX - hdev->mta_mac_sel_type; | ||
772 | u16 high_val = addr[1] | (addr[0] << 8); | ||
773 | |||
774 | return (high_val >> rsh) & 0xfff; | ||
775 | } | ||
776 | |||
777 | static int hclgevf_do_update_mta_status(struct hclgevf_dev *hdev, | ||
778 | unsigned long *status) | ||
779 | { | ||
780 | #define HCLGEVF_MTA_STATUS_MSG_SIZE 13 | ||
781 | #define HCLGEVF_MTA_STATUS_MSG_BITS \ | ||
782 | (HCLGEVF_MTA_STATUS_MSG_SIZE * BITS_PER_BYTE) | ||
783 | #define HCLGEVF_MTA_STATUS_MSG_END_BITS \ | ||
784 | (HCLGEVF_MTA_TBL_SIZE % HCLGEVF_MTA_STATUS_MSG_BITS) | ||
785 | u16 tbl_cnt; | ||
786 | u16 tbl_idx; | ||
787 | u8 msg_cnt; | ||
788 | u8 msg_idx; | ||
789 | int ret; | ||
790 | |||
791 | msg_cnt = DIV_ROUND_UP(HCLGEVF_MTA_TBL_SIZE, | ||
792 | HCLGEVF_MTA_STATUS_MSG_BITS); | ||
793 | tbl_idx = 0; | ||
794 | msg_idx = 0; | ||
795 | while (msg_cnt--) { | ||
796 | u8 msg[HCLGEVF_MTA_STATUS_MSG_SIZE + 1]; | ||
797 | u8 *p = &msg[1]; | ||
798 | u8 msg_ofs; | ||
799 | u8 msg_bit; | ||
800 | |||
801 | memset(msg, 0, sizeof(msg)); | ||
802 | |||
803 | /* set index field */ | ||
804 | msg[0] = 0x7F & msg_idx; | ||
805 | |||
806 | /* set end flag field */ | ||
807 | if (msg_cnt == 0) { | ||
808 | msg[0] |= 0x80; | ||
809 | tbl_cnt = HCLGEVF_MTA_STATUS_MSG_END_BITS; | ||
810 | } else { | ||
811 | tbl_cnt = HCLGEVF_MTA_STATUS_MSG_BITS; | ||
812 | } | ||
813 | |||
814 | /* set status field */ | ||
815 | msg_ofs = 0; | ||
816 | msg_bit = 0; | ||
817 | while (tbl_cnt--) { | ||
818 | if (test_bit(tbl_idx, status)) | ||
819 | p[msg_ofs] |= BIT(msg_bit); | ||
820 | |||
821 | tbl_idx++; | ||
822 | |||
823 | msg_bit++; | ||
824 | if (msg_bit == BITS_PER_BYTE) { | ||
825 | msg_bit = 0; | ||
826 | msg_ofs++; | ||
827 | } | ||
828 | } | ||
829 | |||
830 | ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_MULTICAST, | ||
831 | HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE, | ||
832 | msg, sizeof(msg), false, NULL, 0); | ||
833 | if (ret) | ||
834 | break; | ||
835 | |||
836 | msg_idx++; | ||
837 | } | ||
838 | |||
839 | return ret; | ||
840 | } | ||
841 | |||
842 | static int hclgevf_update_mta_status(struct hnae3_handle *handle) | ||
843 | { | ||
844 | unsigned long mta_status[BITS_TO_LONGS(HCLGEVF_MTA_TBL_SIZE)]; | ||
845 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | ||
846 | struct net_device *netdev = hdev->nic.kinfo.netdev; | ||
847 | struct netdev_hw_addr *ha; | ||
848 | u16 tbl_idx; | ||
849 | |||
850 | /* clear status */ | ||
851 | memset(mta_status, 0, sizeof(mta_status)); | ||
852 | |||
853 | /* update status from mc addr list */ | ||
854 | netdev_for_each_mc_addr(ha, netdev) { | ||
855 | tbl_idx = hclgevf_get_mac_addr_to_mta_index(hdev, ha->addr); | ||
856 | set_bit(tbl_idx, mta_status); | ||
857 | } | ||
858 | |||
859 | return hclgevf_do_update_mta_status(hdev, mta_status); | ||
860 | } | ||
861 | |||
739 | static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) | 862 | static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) |
740 | { | 863 | { |
741 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | 864 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); |
@@ -1334,6 +1457,7 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle) | |||
1334 | hclgevf_reset_tqp_stats(handle); | 1457 | hclgevf_reset_tqp_stats(handle); |
1335 | del_timer_sync(&hdev->service_timer); | 1458 | del_timer_sync(&hdev->service_timer); |
1336 | cancel_work_sync(&hdev->service_task); | 1459 | cancel_work_sync(&hdev->service_task); |
1460 | clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); | ||
1337 | hclgevf_update_link_status(hdev, 0); | 1461 | hclgevf_update_link_status(hdev, 0); |
1338 | } | 1462 | } |
1339 | 1463 | ||
@@ -1665,12 +1789,11 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) | |||
1665 | goto err_config; | 1789 | goto err_config; |
1666 | } | 1790 | } |
1667 | 1791 | ||
1668 | /* Initialize VF's MTA */ | 1792 | /* Initialize mta type for this VF */ |
1669 | hdev->accept_mta_mc = true; | 1793 | ret = hclgevf_cfg_func_mta_type(hdev); |
1670 | ret = hclgevf_cfg_func_mta_filter(&hdev->nic, hdev->accept_mta_mc); | ||
1671 | if (ret) { | 1794 | if (ret) { |
1672 | dev_err(&hdev->pdev->dev, | 1795 | dev_err(&hdev->pdev->dev, |
1673 | "failed(%d) to set mta filter mode\n", ret); | 1796 | "failed(%d) to initialize MTA type\n", ret); |
1674 | goto err_config; | 1797 | goto err_config; |
1675 | } | 1798 | } |
1676 | 1799 | ||
@@ -1825,6 +1948,7 @@ static const struct hnae3_ae_ops hclgevf_ops = { | |||
1825 | .rm_uc_addr = hclgevf_rm_uc_addr, | 1948 | .rm_uc_addr = hclgevf_rm_uc_addr, |
1826 | .add_mc_addr = hclgevf_add_mc_addr, | 1949 | .add_mc_addr = hclgevf_add_mc_addr, |
1827 | .rm_mc_addr = hclgevf_rm_mc_addr, | 1950 | .rm_mc_addr = hclgevf_rm_mc_addr, |
1951 | .update_mta_status = hclgevf_update_mta_status, | ||
1828 | .get_stats = hclgevf_get_stats, | 1952 | .get_stats = hclgevf_get_stats, |
1829 | .update_stats = hclgevf_update_stats, | 1953 | .update_stats = hclgevf_update_stats, |
1830 | .get_strings = hclgevf_get_strings, | 1954 | .get_strings = hclgevf_get_strings, |
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 9763e742e6fb..0656e8e5c5f0 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | |||
@@ -48,6 +48,9 @@ | |||
48 | #define HCLGEVF_RSS_CFG_TBL_NUM \ | 48 | #define HCLGEVF_RSS_CFG_TBL_NUM \ |
49 | (HCLGEVF_RSS_IND_TBL_SIZE / HCLGEVF_RSS_CFG_TBL_SIZE) | 49 | (HCLGEVF_RSS_IND_TBL_SIZE / HCLGEVF_RSS_CFG_TBL_SIZE) |
50 | 50 | ||
51 | #define HCLGEVF_MTA_TBL_SIZE 4096 | ||
52 | #define HCLGEVF_MTA_TYPE_SEL_MAX 4 | ||
53 | |||
51 | /* states of hclgevf device & tasks */ | 54 | /* states of hclgevf device & tasks */ |
52 | enum hclgevf_states { | 55 | enum hclgevf_states { |
53 | /* device states */ | 56 | /* device states */ |
@@ -152,6 +155,7 @@ struct hclgevf_dev { | |||
152 | int *vector_irq; | 155 | int *vector_irq; |
153 | 156 | ||
154 | bool accept_mta_mc; /* whether to accept mta filter multicast */ | 157 | bool accept_mta_mc; /* whether to accept mta filter multicast */ |
158 | u8 mta_mac_sel_type; | ||
155 | bool mbx_event_pending; | 159 | bool mbx_event_pending; |
156 | struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */ | 160 | struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */ |
157 | struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */ | 161 | struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */ |