shenhao (4): net: hns3: adds support for extended VLAN mode and 'QOS' in vlan 802.1Q protocol. net: hns3: Increase vlan tag0 when close the port_base_vlan net: hns3: add dumping vlan filter config in debugfs net: hns3: update the number of version
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 6 +- .../hisilicon/hns3/hns3_cae/hns3_cae_version.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 1 + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 + drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 3 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 2 + .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 57 ++++ .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 288 ++++++++++++++++----- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 11 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 9 - .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 2 +- 13 files changed, 311 insertions(+), 80 deletions(-)
From: shenhao shenhao21@huawei.com
driver inclusion category: Feature bugzilla: NA CVE: NA
--------------------------------------------------- This patch adds support for extended VLAN mode, as we call dynamic vlan mode. In this mode, vf vlan filter will be switch between enable and disable, according to user configuration.
This patch also adds support for QOS in vlan 802.1Q protocol.
Signed-off-by: liaoguojia liaoguojia@huawei.com Signed-off-by: shenhao shenhao21@huawei.com Reviewed-by: Zhong Zhaohui zhongzhaohui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 4 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 + drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 3 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 2 + .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 280 ++++++++++++++++----- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 8 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 9 - .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 + 8 files changed, 239 insertions(+), 75 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 855274b..9882039 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -650,10 +650,12 @@ struct hnae3_unic_private_info { #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_VLAN_FLTR BIT(5) /* enable vlan filter by promisc mode */ +#define HNAE3_VF_VLAN_EN BIT(6) /* enable vf vlan filter by vlan used */ #define HNAE3_UPE (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE) #define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE) #define HNAE3_OVERFLOW_UMPE (HNAE3_OVERFLOW_UPE | HNAE3_OVERFLOW_MPE) +#define HNAE3_VLAN_FLTR_EN (HNAE3_VLAN_FLTR | HNAE3_VF_VLAN_EN)
struct hnae3_handle { struct hnae3_client *client; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 74499a5..eb24440 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -583,6 +583,7 @@ static int hns3_nic_mc_unsync(struct net_device *netdev,
static u8 hns3_get_netdev_flags(struct net_device *netdev) { + struct hnae3_handle *h = hns3_get_handle(netdev); u8 flags = 0;
if (netdev->flags & IFF_PROMISC) { @@ -593,6 +594,8 @@ static u8 hns3_get_netdev_flags(struct net_device *netdev) flags |= HNAE3_USER_MPE; }
+ flags |= (h->netdev_flags & HNAE3_VF_VLAN_EN); + return flags; }
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 5e7bf03..1ecbc1f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -115,7 +115,8 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) } else { /* recover promisc mode before loopback test */ hns3_request_update_promisc_mode(h); - vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true; + vlan_filter_enable = (h->netdev_flags & HNAE3_VLAN_FLTR_EN) ? + false : true; hns3_enable_vlan_filter(ndev, vlan_filter_enable); }
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 5bcc30d..1e35d89 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -494,6 +494,8 @@ struct hclge_pf_res_cmd { #define HCLGE_CFG_RSS_SIZE_M GENMASK(31, 24) #define HCLGE_CFG_SPEED_ABILITY_S 0 #define HCLGE_CFG_SPEED_ABILITY_M GENMASK(7, 0) +#define HCLGE_CFG_VLAN_MODE_S 8 +#define HCLGE_CFG_VLAN_MODE_M GENMASK(9, 8) #define HCLGE_CFG_UMV_TBL_SPACE_S 16 #define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index aaf3512..cfec96f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -70,6 +70,7 @@ static void hclge_sync_mac_table(struct hclge_dev *hdev); static int hclge_restore_hw_table(struct hclge_dev *hdev); static void hclge_sync_promisc_mode(struct hclge_dev *hdev); +static int hclge_vf_vlan_filter_switch(struct hclge_vport *vport);
struct hnae3_ae_algo ae_algo;
@@ -1305,6 +1306,9 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) cfg->speed_ability = hnae3_get_field(__le32_to_cpu(req->param[1]), HCLGE_CFG_SPEED_ABILITY_M, HCLGE_CFG_SPEED_ABILITY_S); + cfg->vlan_mode_sel = hnae3_get_field(__le32_to_cpu(req->param[1]), + HCLGE_CFG_VLAN_MODE_M, + HCLGE_CFG_VLAN_MODE_S); cfg->umv_space = hnae3_get_field(__le32_to_cpu(req->param[1]), HCLGE_CFG_UMV_TBL_SPACE_M, HCLGE_CFG_UMV_TBL_SPACE_S); @@ -1406,6 +1410,7 @@ static int hclge_configure(struct hclge_dev *hdev) hdev->tc_max = cfg.tc_num; hdev->tm_info.hw_pfc_map = 0; hdev->wanted_umv_size = cfg.umv_space; + hdev->vlan_mode = cfg.vlan_mode_sel;
if (hnae3_dev_fd_supported(hdev)) { hdev->fd_en = true; @@ -8268,6 +8273,18 @@ static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr, return phy_mii_ioctl(hdev->hw.mac.phydev, ifr, cmd); }
+#define HCLGE_FILTER_TYPE_VF 0 +#define HCLGE_FILTER_TYPE_PORT 1 +#define HCLGE_FILTER_FE_EGRESS_V1_B BIT(0) +#define HCLGE_FILTER_FE_NIC_INGRESS_B BIT(0) +#define HCLGE_FILTER_FE_NIC_EGRESS_B BIT(1) +#define HCLGE_FILTER_FE_ROCE_INGRESS_B BIT(2) +#define HCLGE_FILTER_FE_ROCE_EGRESS_B BIT(3) +#define HCLGE_FILTER_FE_EGRESS (HCLGE_FILTER_FE_NIC_EGRESS_B \ + | HCLGE_FILTER_FE_ROCE_EGRESS_B) +#define HCLGE_FILTER_FE_INGRESS (HCLGE_FILTER_FE_NIC_INGRESS_B \ + | HCLGE_FILTER_FE_ROCE_INGRESS_B) + static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type, u8 fe_type, bool filter_en, u8 vf_id) { @@ -8275,33 +8292,40 @@ static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type, struct hclge_desc desc; int ret;
- hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, false); + /* if vlan_mode set as dynamic mode, + * port vlan filter needn't to enable + */ + if (vlan_type == HCLGE_FILTER_TYPE_PORT && + hdev->vlan_mode == HCLGE_VLAN_DYNAMIC_MODE) + return 0; + + /* read current vlan filter parameter */ + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, true);
req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data; req->vlan_type = vlan_type; - req->vlan_fe = filter_en ? fe_type : 0; req->vf_id = vf_id;
ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get vlan filter config, ret = %d.\n", ret); + return ret; + } + + /* modify and write new config parameter */ + hclge_cmd_reuse_desc(&desc, false); + req->vlan_fe = filter_en ? + (req->vlan_fe | fe_type) : (req->vlan_fe & ~fe_type); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) - dev_err(&hdev->pdev->dev, "set vlan filter fail, ret =%d.\n", + dev_err(&hdev->pdev->dev, "failed to set vlan filter, ret = %d.\n", ret);
return ret; }
-#define HCLGE_FILTER_TYPE_VF 0 -#define HCLGE_FILTER_TYPE_PORT 1 -#define HCLGE_FILTER_FE_EGRESS_V1_B BIT(0) -#define HCLGE_FILTER_FE_NIC_INGRESS_B BIT(0) -#define HCLGE_FILTER_FE_NIC_EGRESS_B BIT(1) -#define HCLGE_FILTER_FE_ROCE_INGRESS_B BIT(2) -#define HCLGE_FILTER_FE_ROCE_EGRESS_B BIT(3) -#define HCLGE_FILTER_FE_EGRESS (HCLGE_FILTER_FE_NIC_EGRESS_B \ - | HCLGE_FILTER_FE_ROCE_EGRESS_B) -#define HCLGE_FILTER_FE_INGRESS (HCLGE_FILTER_FE_NIC_INGRESS_B \ - | HCLGE_FILTER_FE_ROCE_INGRESS_B) - static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) { struct hclge_vport *vport = hclge_get_vport(handle); @@ -8443,6 +8467,41 @@ static int hclge_set_port_vlan_filter(struct hclge_dev *hdev, __be16 proto, return ret; }
+static bool hclge_need_update_port_vlan(struct hclge_dev *hdev, u16 vport_id, + u16 vlan_id, bool is_kill) +{ + /* vlan 0 may be added twice when 8021q module is enabled */ + if (!is_kill && !vlan_id && + test_bit(vport_id, hdev->vlan_table[vlan_id])) + return false; + + if (!is_kill && test_and_set_bit(vport_id, hdev->vlan_table[vlan_id])) { + dev_warn(&hdev->pdev->dev, + "Add port vlan failed, vport %u is already in vlan %u\n", + vport_id, vlan_id); + return false; + } + + /* if the vlan id is not in the port vlan table, just return 0, it's + * unnecessary to retry. + */ + if (is_kill && + !test_and_clear_bit(vport_id, hdev->vlan_table[vlan_id])) { + dev_warn(&hdev->pdev->dev, + "Delete port vlan failed, vport %u is not in vlan %u\n", + vport_id, vlan_id); + return false; + } + + /* if vlan mode set as HCLGE_VLAN_DYNAMIC_MODE, + * needn't to write the vlan tag to port vlan fitler + */ + if (hdev->vlan_mode == HCLGE_VLAN_DYNAMIC_MODE) + return false; + + return true; +} + static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto, u16 vport_id, u16 vlan_id, bool is_kill) @@ -8462,26 +8521,9 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto, return ret; }
- /* vlan 0 may be added twice when 8021q module is enabled */ - if (!is_kill && !vlan_id && - test_bit(vport_id, hdev->vlan_table[vlan_id])) + if (!hclge_need_update_port_vlan(hdev, vport_id, vlan_id, is_kill)) return 0;
- if (!is_kill && test_and_set_bit(vport_id, hdev->vlan_table[vlan_id])) { - dev_err(&hdev->pdev->dev, - "Add port vlan failed, vport %u is already in vlan %u\n", - vport_id, vlan_id); - return -EINVAL; - } - - if (is_kill && - !test_and_clear_bit(vport_id, hdev->vlan_table[vlan_id])) { - dev_err(&hdev->pdev->dev, - "Delete port vlan failed, vlan %u is not in vport %u\n", - vlan_id, vport_id); - return -EINVAL; - } - for_each_set_bit(vport_idx, hdev->vlan_table[vlan_id], HCLGE_VPORT_NUM) vport_num++;
@@ -8573,7 +8615,7 @@ static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport)
static int hclge_vlan_offload_cfg(struct hclge_vport *vport, u16 port_base_vlan_state, - u16 vlan_tag) + u16 vlan_tag, u8 qos) { int ret;
@@ -8584,7 +8626,8 @@ static int hclge_vlan_offload_cfg(struct hclge_vport *vport, } else { vport->txvlan_cfg.accept_tag1 = false; vport->txvlan_cfg.insert_tag1_en = true; - vport->txvlan_cfg.default_tag1 = vlan_tag; + vport->txvlan_cfg.default_tag1 = (qos << VLAN_PRIO_SHIFT) | + vlan_tag; }
vport->txvlan_cfg.accept_untag1 = true; @@ -8671,6 +8714,12 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) /* for revision 0x21, vf vlan filter is per function */ for (i = 0; i < hdev->num_alloc_vport; i++) { vport = &hdev->vport[i]; + vport->vf_vlan_en = + hdev->vlan_mode == HCLGE_VLAN_DEFAULT_MODE; + + if (!vport->vf_vlan_en) + continue; + ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, HCLGE_FILTER_FE_EGRESS, @@ -8708,13 +8757,15 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
for (i = 0; i < hdev->num_alloc_vport; i++) { u16 vlan_tag; + u8 qos;
vport = &hdev->vport[i]; vlan_tag = vport->port_base_vlan_cfg.vlan_info.vlan_tag; + qos = vport->port_base_vlan_cfg.vlan_info.qos;
ret = hclge_vlan_offload_cfg(vport, vport->port_base_vlan_cfg.state, - vlan_tag); + vlan_tag, qos); if (ret) return ret; } @@ -8873,6 +8924,7 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport) vlan->hd_tbl_status = true; } } + hclge_vf_vlan_filter_switch(vport); }
/* For global reset and imp reset, hardware will clear the mac table, @@ -8937,6 +8989,51 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) return hclge_set_vlan_rx_offload_cfg(vport); }
+static bool hclge_has_vlan_used(struct hclge_dev *hdev, u16 vport_id) +{ +#define VLAN_CHECK_START_NUM 1 + u16 vlan_id; + + /* if set as vlan normal mode, vf vlan filter always on */ + if (hdev->vlan_mode == HCLGE_VLAN_DEFAULT_MODE) + return true; + + /* check all vlan tag in vf vlan table except 0 */ + for (vlan_id = VLAN_CHECK_START_NUM; vlan_id < VLAN_N_VID; vlan_id++) + if (test_bit(vport_id, hdev->vlan_table[vlan_id])) + return true; + + return false; +} + +static int hclge_vf_vlan_filter_switch(struct hclge_vport *vport) +{ + struct hnae3_handle *nic = &vport->nic; + struct hclge_dev *hdev = vport->back; + u8 filter_en; + int ret; + + filter_en = hclge_has_vlan_used(hdev, vport->vport_id) || + vport->port_base_vlan_cfg.state == HNAE3_PORT_BASE_VLAN_ENABLE; + + if (filter_en == vport->vf_vlan_en) + return 0; + + ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, + HCLGE_FILTER_FE_EGRESS, + filter_en, vport->vport_id); + if (ret) + return ret; + + vport->vf_vlan_en = filter_en; + if (filter_en) + nic->netdev_flags |= HNAE3_VF_VLAN_EN; + else + nic->netdev_flags &= ~HNAE3_VF_VLAN_EN; + + return 0; +} + static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, u16 port_base_vlan_state, struct hclge_vlan_info *new_info, @@ -8947,6 +9044,9 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_ENABLE) { hclge_rm_vport_all_vlan_table(vport, false); + /* force clear vlan 0 */ + hclge_set_vf_vlan_common(hdev, vport->vport_id, true, 0, + htons(ETH_P_8021Q)); return hclge_set_vlan_filter_hw(hdev, htons(new_info->vlan_proto), vport->vport_id, @@ -8974,10 +9074,15 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
old_vlan_info = &vport->port_base_vlan_cfg.vlan_info;
- ret = hclge_vlan_offload_cfg(vport, state, vlan_info->vlan_tag); + ret = hclge_vlan_offload_cfg(vport, state, vlan_info->vlan_tag, + vlan_info->qos); if (ret) return ret;
+ /* if needn't to update vlan tag, return */ + if (old_vlan_info->vlan_tag == vlan_info->vlan_tag) + goto update; + if (state == HNAE3_PORT_BASE_VLAN_MODIFY) { /* add new VLAN tag */ ret = hclge_set_vlan_filter_hw(hdev, @@ -8989,13 +9094,22 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, return ret; vport->port_base_vlan_cfg.tbl_sta = false; /* remove old VLAN tag */ - ret = hclge_set_vlan_filter_hw(hdev, - htons(old_vlan_info->vlan_proto), - vport->vport_id, - old_vlan_info->vlan_tag, - true); - if (ret) + if (old_vlan_info->vlan_tag == 0) + ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, + true, 0, + htons(ETH_P_8021Q)); + else + ret = hclge_set_vlan_filter_hw(hdev, + htons(ETH_P_8021Q), + vport->vport_id, + old_vlan_info->vlan_tag, + true); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to clear vport%u port base vlan %u, ret = %d.\n", + vport->vport_id, old_vlan_info->vlan_tag, ret); return ret; + }
goto update; } @@ -9024,25 +9138,26 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, vport->port_base_vlan_cfg.vlan_info.vlan_proto = vlan_info->vlan_proto; vport->port_base_vlan_cfg.tbl_sta = true;
- return 0; + return hclge_vf_vlan_filter_switch(vport); }
static u16 hclge_get_port_base_vlan_state(struct hclge_vport *vport, enum hnae3_port_base_vlan_state state, - u16 vlan) + u16 vlan, u8 qos) { if (state == HNAE3_PORT_BASE_VLAN_DISABLE) { - if (!vlan) + if (!vlan && !qos) return HNAE3_PORT_BASE_VLAN_NOCHANGE; - else - return HNAE3_PORT_BASE_VLAN_ENABLE; + + return HNAE3_PORT_BASE_VLAN_ENABLE; } else { - if (!vlan) + if (!vlan && !qos) return HNAE3_PORT_BASE_VLAN_DISABLE; - else if (vport->port_base_vlan_cfg.vlan_info.vlan_tag == vlan) + if (vport->port_base_vlan_cfg.vlan_info.vlan_tag == vlan && + vport->port_base_vlan_cfg.vlan_info.qos == qos) return HNAE3_PORT_BASE_VLAN_NOCHANGE; - else - return HNAE3_PORT_BASE_VLAN_MODIFY; + + return HNAE3_PORT_BASE_VLAN_MODIFY; } }
@@ -9070,7 +9185,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
state = hclge_get_port_base_vlan_state(vport, vport->port_base_vlan_cfg.state, - vlan); + vlan, qos); if (state == HNAE3_PORT_BASE_VLAN_NOCHANGE) return 0;
@@ -9078,16 +9193,43 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, vlan_info.qos = qos; vlan_info.vlan_proto = ntohs(proto);
- if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { - return hclge_update_port_base_vlan_cfg(vport, state, - &vlan_info); - } else { - ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0], - vport->vport_id, state, - vlan, qos, - ntohs(proto)); + ret = hclge_update_port_base_vlan_cfg(vport, state, &vlan_info); + if (ret) { + dev_err(&hdev->pdev->dev, + "update port base vlan for vf %d failed, ret = %d\n", + vfid, ret); return ret; } + + if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) + return hclge_push_vf_port_base_vlan_info(&hdev->vport[0], + vport->vport_id, + state, vlan, qos, + ntohs(proto)); + + return 0; +} + +static void hclge_clear_vf_vlan(struct hclge_dev *hdev) +{ + struct hclge_vlan_info *vlan_info; + struct hclge_vport *vport; + int ret; + int vf; + + /* clear port base vlan for all vf */ + for (vf = HCLGE_VF_VPORT_START_NUM; vf < hdev->num_alloc_vport; vf++) { + vport = &hdev->vport[vf]; + vlan_info = &vport->port_base_vlan_cfg.vlan_info; + + ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), + vport->vport_id, + vlan_info->vlan_tag, true); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to clear vf vlan for vf%d, ret = %d.\n", + vf - HCLGE_VF_VPORT_START_NUM, ret); + } }
int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, @@ -9132,7 +9274,13 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, */ set_bit(vlan_id, vport->vlan_del_fail_bmap); } - return ret; + + if (ret) { + dev_info(&hdev->pdev->dev, "failed to set vf vlan, ret = %d!\n", + ret); + } + + return hclge_vf_vlan_filter_switch(vport); }
static void hclge_sync_vlan_filter(struct hclge_dev *hdev) @@ -10528,6 +10676,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) struct hclge_mac *mac = &hdev->hw.mac;
hclge_reset_vf_rate(hdev); + hclge_clear_vf_vlan(hdev); hclge_misc_affinity_teardown(hdev); hclge_state_uninit(hdev); hclge_uninit_vport_mac_table(hdev); @@ -11162,6 +11311,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev) struct hclge_vport *vport = &hdev->vport[0]; struct hnae3_handle *handle = &vport->nic; u8 tmp_flags = 0; + u32 filter_en; int ret;
if (vport->last_promisc_flags != vport->overflow_promisc_flags) { @@ -11175,8 +11325,10 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev) tmp_flags & HNAE3_MPE); if (!ret) { clear_bit(HCLGE_STATE_PROMISC_CHANGED, &hdev->state); - hclge_enable_vlan_filter(handle, - tmp_flags & HNAE3_VLAN_FLTR); + /* promisc set for pf, so vport id as 0 */ + filter_en = hclge_has_vlan_used(hdev, 0) ? + HNAE3_VLAN_FLTR : 0; + hclge_enable_vlan_filter(handle, tmp_flags & filter_en); } } } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index ff4d7d1..c03e43c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -316,6 +316,11 @@ enum hclge_fc_mode { HCLGE_FC_DEFAULT };
+enum hclge_vlan_mode_sel { + HCLGE_VLAN_DEFAULT_MODE, + HCLGE_VLAN_DYNAMIC_MODE, +}; + enum hclge_link_fail_code { HCLGE_LF_NORMAL, HCLGE_LF_REF_CLOCK_LOST, @@ -353,6 +358,7 @@ struct hclge_cfg { u8 default_speed; u32 numa_node_map; u8 speed_ability; + u8 vlan_mode_sel; u16 umv_space; };
@@ -829,6 +835,7 @@ struct hclge_dev { unsigned long fd_bmap[BITS_TO_LONGS(MAX_FD_FILTER_NUM)]; enum HCLGE_FD_ACTIVE_RULE_TYPE fd_active_type; u8 fd_en; + u8 vlan_mode;
u16 wanted_umv_size; /* max available unicast mac vlan space */ @@ -935,6 +942,7 @@ struct hclge_vport { u32 bw_limit; /* VSI BW Limit (0 = disabled) */ u8 dwrr;
+ u8 vf_vlan_en; unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)]; struct list_head vlan_list; /* Store VF vlan table */ struct hclge_port_base_vlan_config port_base_vlan_cfg; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index bc86207..d55b999 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -488,15 +488,6 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, bool en = msg_cmd->is_kill ? true : false;
status = hclge_en_hw_strip_rxvtag(handle, en); - } else if (msg_cmd->subcode == HCLGE_MBX_PORT_BASE_VLAN_CFG) { - struct hclge_vlan_info *vlan_info; - u16 *state; - - state = (u16 *)&mbx_req->msg.data[HCLGE_MBX_VLAN_STATE_OFFSET]; - vlan_info = (struct hclge_vlan_info *) - &mbx_req->msg.data[HCLGE_MBX_VLAN_INFO_OFFSET]; - status = hclge_update_port_base_vlan_cfg(vport, *state, - vlan_info); } else if (msg_cmd->subcode == HCLGE_MBX_GET_PORT_BASE_VLAN_STATE) { resp_msg->data[0] = vport->port_base_vlan_cfg.state; resp_msg->len = sizeof(u8); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index f758a0c..76fabe1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2940,6 +2940,11 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev) return ret; }
+ /* get current port based vlan state from PF */ + ret = hclgevf_get_port_base_vlan_filter_state(hdev); + if (ret) + return ret; + set_bit(HCLGEVF_STATE_PROMISC_CHANGED, &hdev->state);
dev_info(&hdev->pdev->dev, "Reset done\n");
From: shenhao shenhao21@huawei.com
driver inclusion category: debug bugzilla: NA CVE: NA
----------------------------------------------------------
This patch increase vlan tag0 when close the port_base_vlan
Signed-off-by: liaoguojia liaoguojia@huawei.com Signed-off-by: shenhao shenhao21@huawei.com Reviewed-by: Zhong Zhaohui zhongzhaohui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index cfec96f..4e53361 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -9045,8 +9045,10 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_ENABLE) { hclge_rm_vport_all_vlan_table(vport, false); /* force clear vlan 0 */ - hclge_set_vf_vlan_common(hdev, vport->vport_id, true, 0, - htons(ETH_P_8021Q)); + ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, true, 0, + htons(ETH_P_8021Q)); + if (ret) + return ret; return hclge_set_vlan_filter_hw(hdev, htons(new_info->vlan_proto), vport->vport_id, @@ -9055,6 +9057,12 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, } vport->port_base_vlan_cfg.tbl_sta = false;
+ /* force add vlan 0 */ + ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, false, 0, + htons(ETH_P_8021Q)); + if (ret) + return ret; + ret = hclge_set_vlan_filter_hw(hdev, htons(old_info->vlan_proto), vport->vport_id, old_info->vlan_tag, true);
From: shenhao shenhao21@huawei.com
driver inclusion category: debug bugzilla: NA CVE: NA
----------------------------------------------------
This patch adds dumping vlan filter config in debugfs to add more DFX method about vlan filter.
Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: shenhao shenhao21@huawei.com Reviewed-by: Zhong Zhaohui zhongzhaohui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 1 + .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 57 ++++++++++++++++++++++ .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 1 + 4 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index e018029..9f4a849 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -265,6 +265,7 @@ static void hns3_dbg_help(struct hnae3_handle *h) dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); dev_info(&h->pdev->dev, "dump uc mac list <func id>\n"); dev_info(&h->pdev->dev, "dump mc mac list <func id>\n"); + dev_info(&h->pdev->dev, "dump vlan filter <func id>\n");
memset(printf_buf, 0, HNS3_DBG_BUF_LEN); strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]", diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index ebccce1..6278ff6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -1497,10 +1497,63 @@ static int hclge_dbg_dump_mac_list(struct hclge_dev *hdev, const char *cmd_buf, return 0; }
+static void hclge_dbg_dump_vlan_filter(struct hclge_dev *hdev, + const char *cmd_buf) +{ + struct hclge_vlan_filter_ctrl_cmd *req; + struct hclge_vport *vport; + struct hclge_desc desc; + bool has_vlan_used; + int vf_id; + int ret; + + ret = kstrtouint(cmd_buf, 0, &vf_id); + if (ret < 0) { + dev_err(&hdev->pdev->dev, + "dump vlan filter: bad command string, ret=%d\n", ret); + return; + } + + if (vf_id >= hdev->num_alloc_vport) { + dev_err(&hdev->pdev->dev, + "vf id(%u) is out of range(0-%u)\n", vf_id, + hdev->num_alloc_vport - 1); + return; + } + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, true); + req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data; + req->vf_id = vf_id; + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get vlan filter config, ret=%d\n", ret); + return; + } + + vport = &hdev->vport[vf_id]; + has_vlan_used = hclge_has_vlan_used(hdev, vport->vport_id); + + dev_info(&hdev->pdev->dev, "vf_id:%u\n", req->vf_id); + dev_info(&hdev->pdev->dev, "vlan_type:%u\n", req->vlan_type); + dev_info(&hdev->pdev->dev, "vlan_fe:%u\n", req->vlan_fe); + dev_info(&hdev->pdev->dev, "vf_vlan_en:%u\n", vport->vf_vlan_en); + dev_info(&hdev->pdev->dev, "vlan_mode:%s\n", + (hdev->vlan_mode == HCLGE_VLAN_DEFAULT_MODE) ? "default" : + "dynamic"); + dev_info(&hdev->pdev->dev, "netdev_flags:%x\n", + vport->nic.netdev_flags); + dev_info(&hdev->pdev->dev, "has_vlan_used:%s\n", + has_vlan_used ? "true" : "false"); + dev_info(&hdev->pdev->dev, "port_base_vlan_cfg_state:%u\n", + vport->port_base_vlan_cfg.state); +} + int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) { #define DUMP_REG "dump reg" #define DUMP_LOOPBACK "dump loopback" +#define DUMP_VLAN_FILTER "dump vlan filter"
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -1550,6 +1603,10 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) hclge_dbg_dump_mac_list(hdev, &cmd_buf[sizeof("dump mc mac list")], false); + } else if (strncmp(cmd_buf, DUMP_VLAN_FILTER, + strlen(DUMP_VLAN_FILTER)) == 0) { + hclge_dbg_dump_vlan_filter(hdev, + &cmd_buf[sizeof(DUMP_VLAN_FILTER)]); } else { dev_info(&hdev->pdev->dev, "unknown command\n"); return -EINVAL; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 4e53361..c05b595 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -8989,7 +8989,7 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) return hclge_set_vlan_rx_offload_cfg(vport); }
-static bool hclge_has_vlan_used(struct hclge_dev *hdev, u16 vport_id) +bool hclge_has_vlan_used(struct hclge_dev *hdev, u16 vport_id) { #define VLAN_CHECK_START_NUM 1 u16 vlan_id; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index c03e43c..1f8f4f9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -1045,4 +1045,5 @@ int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, struct hclge_desc *desc); void hclge_inform_vf_promisc_info(struct hclge_vport *vport); void hclge_dbg_dump_rst_info(struct hclge_dev *hdev); +bool hclge_has_vlan_used(struct hclge_dev *hdev, u16 vport_id); #endif
From: shenhao shenhao21@huawei.com
driver inclusion category: debug bugzilla: NA CVE: NA
--------------------------------------------- This patch update the number of version
Signed-off-by: shenhao shenhao21@huawei.com Reviewed-by: Zhong Zhaohui zhongzhaohui@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 9882039..7eba126 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -30,7 +30,7 @@ #include <linux/pci.h> #include <linux/types.h>
-#define HNAE3_MOD_VERSION "1.9.37.1" +#define HNAE3_MOD_VERSION "1.9.37.2"
#define HNAE3_MIN_VECTOR_NUM 2 /* one for msi-x, another for IO */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h b/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h index b48627e..1fe5c08 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_cae/hns3_cae_version.h @@ -4,7 +4,7 @@ #ifndef __HNS3_CAE_VERSION_H__ #define __HNS3_CAE_VERSION_H__
-#define HNS3_CAE_MOD_VERSION "1.9.37.1" +#define HNS3_CAE_MOD_VERSION "1.9.37.2"
#define CMT_ID_LEN 8 #define RESV_LEN 3 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index f5aa085..8329b5e7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -8,7 +8,7 @@
#include "hnae3.h"
-#define HNS3_MOD_VERSION "1.9.37.1" +#define HNS3_MOD_VERSION "1.9.37.2"
extern char hns3_driver_version[];
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 1f8f4f9..b2b4826 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -12,7 +12,7 @@ #include "hclge_cmd.h" #include "hnae3.h"
-#define HCLGE_MOD_VERSION "1.9.37.1" +#define HCLGE_MOD_VERSION "1.9.37.2" #define HCLGE_DRIVER_NAME "hclge"
#define HCLGE_MAX_PF_NUM 8 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index e5a1450..78e296e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -10,7 +10,7 @@ #include "hclgevf_cmd.h" #include "hnae3.h"
-#define HCLGEVF_MOD_VERSION "1.9.37.1" +#define HCLGEVF_MOD_VERSION "1.9.37.2" #define HCLGEVF_DRIVER_NAME "hclgevf"
#define HCLGEVF_MAX_VLAN_ID 4095