diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 18e42082ecc49e10c853a30a532da809537356a5..10d1e85f843900dc89c19a2b3d4325a1cc056851 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -607,6 +607,10 @@ struct hnae3_ae_dev { * Execute debugfs read command. * request_flush_qb_config * Request to update queue bonding configuration + * request_pfc_storm_config + * Request to update pfc storm configuration + * get_pfc_storm_config + * Get pfc storm config * query_fd_qb_state * Query whether hw queue bonding enabled * set_tx_hwts_info @@ -809,6 +813,9 @@ struct hnae3_ae_ops { int (*set_phy_link_ksettings)(struct hnae3_handle *handle, const struct ethtool_link_ksettings *cmd); void (*request_flush_qb_config)(struct hnae3_handle *handle); + void (*request_pfc_storm_config)(struct hnae3_handle *handle, + bool enable); + int (*get_pfc_storm_config)(struct hnae3_handle *handle, bool *enable); bool (*query_fd_qb_state)(struct hnae3_handle *handle); bool (*set_tx_hwts_info)(struct hnae3_handle *handle, struct sk_buff *skb); @@ -936,6 +943,7 @@ enum hnae3_pflag { HNAE3_PFLAG_LIMIT_PROMISC, HNAE3_PFLAG_FD_QB_ENABLE, HNAE3_PFLAG_ROH_ARP_PROXY_ENABLE, + HNAE3_PFLAG_PFC_STORM_PREVENT_ENABLE, HNAE3_PFLAG_MAX }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index d031060a7e70a327eeaa9252dd02e0c61cca8a1b..c41cc91d980b2f16e9f75c813d2c1a7546686f94 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -5600,6 +5600,18 @@ static void hns3_state_init(struct hnae3_handle *handle) &handle->supported_pflags); set_bit(HNAE3_PFLAG_ROH_ARP_PROXY_ENABLE, &handle->priv_flags); } + + if (handle->ae_algo->ops->get_pfc_storm_config) { + bool enable = true; + int ret = handle->ae_algo->ops->get_pfc_storm_config(handle, + &enable); + + set_bit(HNAE3_PFLAG_PFC_STORM_PREVENT_ENABLE, + &handle->supported_pflags); + if (!ret && enable) + set_bit(HNAE3_PFLAG_PFC_STORM_PREVENT_ENABLE, + &handle->priv_flags); + } } static void hns3_state_uninit(struct hnae3_handle *handle) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index f49bce6fc053802ffcbce8c2b9411c0a631f608d..271b2c4435a7a9dd56e6e29a7e10cc8a0bf629f1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -499,10 +499,22 @@ static void hns3_update_roh_arp_proxy_enable(struct net_device *netdev, enable ? "enable" : "disable"); } +static void hns3_update_pfc_storm_prevent_enable(struct net_device *netdev, + bool enable) +{ + struct hnae3_handle *handle = hns3_get_handle(netdev); + + if (!handle->ae_algo->ops->request_pfc_storm_config) + return; + + handle->ae_algo->ops->request_pfc_storm_config(handle, enable); +} + static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = { { "limit_promisc", hns3_update_limit_promisc_mode }, { "qb_enable", hns3_update_fd_qb_state }, { "roh_arp_proxy_enable", hns3_update_roh_arp_proxy_enable }, + { "pfc_storm_prevent_enable", hns3_update_pfc_storm_prevent_enable }, }; static int hns3_get_sset_count(struct net_device *netdev, int stringset) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 21cfe5d44cd34be5f5bf6a102eb613fa83822bbf..d2fb21fd2354e8e18149e35f5ea226926c3b458a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -925,6 +925,15 @@ struct hclge_query_wol_supported_cmd { u8 rsv[20]; }; +struct hclge_pfc_storm_para_cmd { + __le32 dir; + __le32 enable; + __le32 period_ms; + __le32 times; + __le32 recovery_period_ms; + __le32 rsv; +}; + struct hclge_hw; int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h index 5aca6b097e42fc85cf4d8c0a490ff2d660405694..250eb0f06353122135b7cd528a51a2801aa4d2f3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ext.h @@ -77,15 +77,6 @@ struct hclge_port_num_info_cmd { u8 rsv[20]; }; -struct hclge_pfc_storm_para_cmd { - __le32 dir; - __le32 enable; - __le32 period_ms; - __le32 times; - __le32 recovery_period_ms; - __le32 rsv; -}; - struct hclge_notify_pkt_param_cmd { __le32 cfg; __le32 ipg; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index e105ab8a0296b45f469f62f792d9be898d3d297b..7460eabc28a28c44c1bd602f6e08b965d49ca942 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -5498,6 +5498,86 @@ static void hclge_flush_qb_config(struct hnae3_handle *handle) set_bit(HCLGE_VPORT_STATE_QB_CHANGE, &vport->state); } +static int +hclge_get_pfc_storm_prevent(struct hclge_dev *hdev, int dir, bool *enable) +{ + struct hclge_pfc_storm_para_cmd *para_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PAUSE_STORM_PARA, true); + para_cmd = (struct hclge_pfc_storm_para_cmd *)desc.data; + para_cmd->dir = cpu_to_le32(dir); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + return ret; + + *enable = !!le32_to_cpu(para_cmd->enable); + return 0; +} + +static int hclge_get_pfc_storm_config(struct hnae3_handle *handle, bool *enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + bool enable_tx, enable_rx; + int ret; + + ret = hclge_get_pfc_storm_prevent(hdev, HCLGE_DIR_TX, &enable_tx); + if (ret) { + dev_err(&hdev->pdev->dev, "failed to get tx pfc storm prevent, ret=%d\n", + ret); + return ret; + } + ret = hclge_get_pfc_storm_prevent(hdev, HCLGE_DIR_RX, &enable_rx); + if (ret) { + dev_err(&hdev->pdev->dev, "failed to get rx pfc storm prevent, ret=%d\n", + ret); + return ret; + } + + *enable = enable_tx || enable_rx; + return 0; +} + +static int +hclge_enable_pfc_storm_prevent(struct hclge_dev *hdev, int dir, bool enable) +{ + struct hclge_pfc_storm_para_cmd *para_cmd; + struct hclge_desc desc; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PAUSE_STORM_PARA, + false); + para_cmd = (struct hclge_pfc_storm_para_cmd *)desc.data; + para_cmd->dir = cpu_to_le32(dir); + para_cmd->enable = cpu_to_le32(enable); + + return hclge_cmd_send(&hdev->hw, &desc, 1); +} + +static void +hclge_request_pfc_storm_config(struct hnae3_handle *handle, bool enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + int ret; + + ret = hclge_enable_pfc_storm_prevent(hdev, HCLGE_DIR_TX, enable); + if (ret) { + dev_err(&hdev->pdev->dev, "failed to %s tx pfc storm prevent, ret=%d\n", + enable ? "enable" : "disable", ret); + return; + } + + ret = hclge_enable_pfc_storm_prevent(hdev, HCLGE_DIR_RX, enable); + if (ret) + dev_err(&hdev->pdev->dev, "failed to %s rx pfc storm prevent, ret=%d\n", + enable ? "enable" : "disable", ret); + else + dev_info(&hdev->pdev->dev, "pfc storm prevent %s\n", + enable ? "enabled" : "disabled"); +} + static void hclge_sync_fd_state(struct hclge_dev *hdev) { struct hclge_vport *vport = &hdev->vport[0]; @@ -10203,33 +10283,35 @@ static bool hclge_need_enable_vport_vlan_filter(struct hclge_vport *vport) return false; } -int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) +static int __hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) { - struct hclge_dev *hdev = vport->back; bool need_en; int ret; - mutex_lock(&hdev->vport_lock); - - vport->req_vlan_fltr_en = request_en; - need_en = hclge_need_enable_vport_vlan_filter(vport); - if (need_en == vport->cur_vlan_fltr_en) { - mutex_unlock(&hdev->vport_lock); + if (need_en == vport->cur_vlan_fltr_en) return 0; - } ret = hclge_set_vport_vlan_filter(vport, need_en); - if (ret) { - mutex_unlock(&hdev->vport_lock); + if (ret) return ret; - } vport->cur_vlan_fltr_en = need_en; + return 0; +} + +int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en) +{ + struct hclge_dev *hdev = vport->back; + int ret; + + mutex_lock(&hdev->vport_lock); + vport->req_vlan_fltr_en = request_en; + ret = __hclge_enable_vport_vlan_filter(vport, request_en); mutex_unlock(&hdev->vport_lock); - return 0; + return ret; } static int hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) @@ -11251,16 +11333,19 @@ static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev) &vport->state)) continue; - ret = hclge_enable_vport_vlan_filter(vport, - vport->req_vlan_fltr_en); + mutex_lock(&hdev->vport_lock); + ret = __hclge_enable_vport_vlan_filter(vport, + vport->req_vlan_fltr_en); if (ret) { dev_err(&hdev->pdev->dev, "failed to sync vlan filter state for vport%u, ret = %d\n", vport->vport_id, ret); set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE, &vport->state); + mutex_unlock(&hdev->vport_lock); return; } + mutex_unlock(&hdev->vport_lock); } } @@ -12248,8 +12333,8 @@ static void hclge_reset_done(struct hnae3_ae_dev *ae_dev) dev_err(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", ret); hdev->reset_type = HNAE3_NONE_RESET; - clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); - up(&hdev->reset_sem); + if (test_and_clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) + up(&hdev->reset_sem); } static void hclge_clear_resetting_state(struct hclge_dev *hdev) @@ -13510,6 +13595,8 @@ struct hnae3_ae_ops hclge_ops = { .set_promisc_mode = hclge_set_promisc_mode, .request_update_promisc_mode = hclge_request_update_promisc_mode, .request_flush_qb_config = hclge_flush_qb_config, + .request_pfc_storm_config = hclge_request_pfc_storm_config, + .get_pfc_storm_config = hclge_get_pfc_storm_config, .query_fd_qb_state = hclge_query_fd_qb_state, .set_loopback = hclge_set_loopback, .start = hclge_ae_start, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 969c469210ea6fe5bb435067c5c5e4ec521d02cb..dcc928dedc8cea8c228f92c56d4bf1ef8894f041 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -347,6 +347,9 @@ enum hclge_link_fail_code { #define HCLGE_LINK_STATUS_DOWN 0 #define HCLGE_LINK_STATUS_UP 1 +#define HCLGE_DIR_RX 0 +#define HCLGE_DIR_TX 1 + #define HCLGE_PG_NUM 4 #define HCLGE_SCH_MODE_SP 0 #define HCLGE_SCH_MODE_DWRR 1 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c index 0ddf102c76f7ca9d27eac1e37029987c485e0a44..e7a112ff1ad632b28f5909df02a6ca1434e53bad 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c @@ -487,7 +487,7 @@ int hclge_ptp_init(struct hclge_dev *hdev) ret = hclge_ptp_get_cycle(hdev); if (ret) - return ret; + goto out; } ret = hclge_ptp_int_en(hdev, true); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c index 43c1c18fa81f8d572d37d15f2c7cc6d4dcbf3391..8c057192aae6e16abe24fdd1bbed3f088c111f8e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c @@ -510,9 +510,9 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data) static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, struct hnae3_knic_private_info *kinfo) { -#define HCLGE_RING_REG_OFFSET 0x200 #define HCLGE_RING_INT_REG_OFFSET 0x4 + struct hnae3_queue *tqp; int i, j, reg_num; int data_num_sum; u32 *reg = data; @@ -533,10 +533,11 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, reg_num = ARRAY_SIZE(ring_reg_addr_list); for (j = 0; j < kinfo->num_tqps; j++) { reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); + tqp = kinfo->tqp[j]; for (i = 0; i < reg_num; i++) - *reg++ = hclge_read_dev(&hdev->hw, - ring_reg_addr_list[i] + - HCLGE_RING_REG_OFFSET * j); + *reg++ = readl_relaxed(tqp->io_base - + HCLGE_TQP_REG_OFFSET + + ring_reg_addr_list[i]); } data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 3d851f6119fa0477e084dcb0c175ba32fc972e0b..a43c4999145b760e7f9c93ec1ed85d337289583f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -1841,8 +1841,8 @@ static void hclgevf_reset_done(struct hnae3_ae_dev *ae_dev) ret); hdev->reset_type = HNAE3_NONE_RESET; - clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); - up(&hdev->reset_sem); + if (test_and_clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) + up(&hdev->reset_sem); } static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c index 65b9dcd3813756f9d9d64aeac2c560a669765b5d..637d83a400d3e981fcf361b2b8a2b89eaa6b0bb4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c @@ -123,40 +123,41 @@ int hclgevf_get_regs_len(struct hnae3_handle *handle) void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, void *data) { -#define HCLGEVF_RING_REG_OFFSET 0x200 #define HCLGEVF_RING_INT_REG_OFFSET 0x4 struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); - int i, j, reg_um; + struct hnae3_queue *tqp; + int i, j, reg_num; u32 *reg = data; *version = hdev->fw_version; reg += hclgevf_reg_get_header(reg); /* fetching per-VF registers values from VF PCIe register space */ - reg_um = sizeof(cmdq_reg_addr_list) / sizeof(u32); - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_um, reg); - for (i = 0; i < reg_um; i++) + reg_num = sizeof(cmdq_reg_addr_list) / sizeof(u32); + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_CMDQ, reg_num, reg); + for (i = 0; i < reg_num; i++) *reg++ = hclgevf_read_dev(&hdev->hw, cmdq_reg_addr_list[i]); - reg_um = sizeof(common_reg_addr_list) / sizeof(u32); - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_um, reg); - for (i = 0; i < reg_um; i++) + reg_num = sizeof(common_reg_addr_list) / sizeof(u32); + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_COMMON, reg_num, reg); + for (i = 0; i < reg_num; i++) *reg++ = hclgevf_read_dev(&hdev->hw, common_reg_addr_list[i]); - reg_um = sizeof(ring_reg_addr_list) / sizeof(u32); + reg_num = sizeof(ring_reg_addr_list) / sizeof(u32); for (j = 0; j < hdev->num_tqps; j++) { - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); - for (i = 0; i < reg_um; i++) - *reg++ = hclgevf_read_dev(&hdev->hw, - ring_reg_addr_list[i] + - HCLGEVF_RING_REG_OFFSET * j); + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_num, reg); + tqp = &hdev->htqp[j].q; + for (i = 0; i < reg_num; i++) + *reg++ = readl_relaxed(tqp->io_base - + HCLGEVF_TQP_REG_OFFSET + + ring_reg_addr_list[i]); } - reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); + reg_num = sizeof(tqp_intr_reg_addr_list) / sizeof(u32); for (j = 0; j < hdev->num_msi_used - 1; j++) { - reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_um, reg); - for (i = 0; i < reg_um; i++) + reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_TQP_INTR, reg_num, reg); + for (i = 0; i < reg_num; i++) *reg++ = hclgevf_read_dev(&hdev->hw, tqp_intr_reg_addr_list[i] + HCLGEVF_RING_INT_REG_OFFSET * j); diff --git a/drivers/ptp/ptp_hisi.c b/drivers/ptp/ptp_hisi.c index 0eb1ebf44dc899d2f1853249d7d118368ffd0dda..c53bcdd08747610e0083e5020a64bad9b40d4d69 100644 --- a/drivers/ptp/ptp_hisi.c +++ b/drivers/ptp/ptp_hisi.c @@ -15,10 +15,6 @@ #include #include -#ifndef PTP_CLOCK_NAME_LEN -#define PTP_CLOCK_NAME_LEN 32 -#endif - #define HISI_PTP_VERSION "22.10.2" #define HISI_PTP_NAME "hisi_ptp" @@ -588,7 +584,7 @@ static int hisi_ptp_create_clock(struct hisi_ptp_pdev *ptp) { dev_info(ptp->ptp_tx->dev, "register ptp clock\n"); - snprintf(ptp->info.name, PTP_CLOCK_NAME_LEN, "%s", HISI_PTP_NAME); + snprintf(ptp->info.name, sizeof(ptp->info.name), "%s", HISI_PTP_NAME); ptp->info.owner = THIS_MODULE; ptp->info.adjfine = hisi_ptp_adjfine; ptp->info.adjtime = hisi_ptp_adjtime;