mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-19 02:27:51 +07:00
Merge branch 'net-hns3-some-code-optimizations-bugfixes-features'
Huazhong Tan says: ==================== net: hns3: some code optimizations & bugfixes & features This patch-set includes code optimizations, bugfixes and features for the HNS3 ethernet controller driver. [patch 01/12] adds support for reporting link change event. [patch 02/12] adds handler for NCSI error. [patch 03/12] fixes bug related to debugfs. [patch 04/12] adds a code optimization for setting ring parameters. [patch 05/12 - 09/12] adds some cleanups. [patch 10/12 - 12/12] adds some patches related to reset issue. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9b59e39f09
@ -47,6 +47,8 @@ enum HCLGE_MBX_OPCODE {
|
||||
HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */
|
||||
|
||||
HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */
|
||||
HCLGE_MBX_PUSH_LINK_STATUS, /* (M7 -> PF) get port link status */
|
||||
HCLGE_MBX_NCSI_ERROR, /* (M7 -> PF) receive a NCSI error */
|
||||
};
|
||||
|
||||
/* below are per-VF mac-vlan subcodes */
|
||||
|
@ -2909,24 +2909,22 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
|
||||
void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *))
|
||||
{
|
||||
#define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
|
||||
int recv_pkts, recv_bds, clean_count, err;
|
||||
int unused_count = hns3_desc_unused(ring);
|
||||
struct sk_buff *skb = ring->skb;
|
||||
int num;
|
||||
int recv_pkts = 0;
|
||||
int recv_bds = 0;
|
||||
int err, num;
|
||||
|
||||
num = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_FBDNUM_REG);
|
||||
rmb(); /* Make sure num taken effect before the other data is touched */
|
||||
|
||||
recv_pkts = 0, recv_bds = 0, clean_count = 0;
|
||||
num -= unused_count;
|
||||
unused_count -= ring->pending_buf;
|
||||
|
||||
while (recv_pkts < budget && recv_bds < num) {
|
||||
/* Reuse or realloc buffers */
|
||||
if (clean_count + unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
|
||||
hns3_nic_alloc_rx_buffers(ring,
|
||||
clean_count + unused_count);
|
||||
clean_count = 0;
|
||||
if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
|
||||
hns3_nic_alloc_rx_buffers(ring, unused_count);
|
||||
unused_count = hns3_desc_unused(ring) -
|
||||
ring->pending_buf;
|
||||
}
|
||||
@ -2940,7 +2938,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
|
||||
goto out;
|
||||
} else if (unlikely(err)) { /* Do jump the err */
|
||||
recv_bds += ring->pending_buf;
|
||||
clean_count += ring->pending_buf;
|
||||
unused_count += ring->pending_buf;
|
||||
ring->skb = NULL;
|
||||
ring->pending_buf = 0;
|
||||
continue;
|
||||
@ -2948,7 +2946,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
|
||||
|
||||
rx_fn(ring, skb);
|
||||
recv_bds += ring->pending_buf;
|
||||
clean_count += ring->pending_buf;
|
||||
unused_count += ring->pending_buf;
|
||||
ring->skb = NULL;
|
||||
ring->pending_buf = 0;
|
||||
|
||||
@ -2957,8 +2955,8 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
|
||||
|
||||
out:
|
||||
/* Make all data has been write before submit */
|
||||
if (clean_count + unused_count > 0)
|
||||
hns3_nic_alloc_rx_buffers(ring, clean_count + unused_count);
|
||||
if (unused_count > 0)
|
||||
hns3_nic_alloc_rx_buffers(ring, unused_count);
|
||||
|
||||
return recv_pkts;
|
||||
}
|
||||
@ -3588,7 +3586,7 @@ static int hns3_alloc_ring_memory(struct hns3_enet_ring *ring)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hns3_fini_ring(struct hns3_enet_ring *ring)
|
||||
void hns3_fini_ring(struct hns3_enet_ring *ring)
|
||||
{
|
||||
hns3_free_desc(ring);
|
||||
devm_kfree(ring_to_dev(ring), ring->desc_cb);
|
||||
|
@ -75,7 +75,7 @@ enum hns3_nic_state {
|
||||
#define HNS3_TX_TIMEOUT (5 * HZ)
|
||||
#define HNS3_RING_NAME_LEN 16
|
||||
#define HNS3_BUFFER_SIZE_2048 2048
|
||||
#define HNS3_RING_MAX_PENDING 32768
|
||||
#define HNS3_RING_MAX_PENDING 32760
|
||||
#define HNS3_RING_MIN_PENDING 24
|
||||
#define HNS3_RING_BD_MULTIPLE 8
|
||||
/* max frame size of mac */
|
||||
@ -642,6 +642,7 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring);
|
||||
int hns3_init_all_ring(struct hns3_nic_priv *priv);
|
||||
int hns3_uninit_all_ring(struct hns3_nic_priv *priv);
|
||||
int hns3_nic_reset_all_ring(struct hnae3_handle *h);
|
||||
void hns3_fini_ring(struct hns3_enet_ring *ring);
|
||||
netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
|
||||
bool hns3_is_phys_func(struct pci_dev *pdev);
|
||||
int hns3_clean_rx_ring(
|
||||
|
@ -867,8 +867,8 @@ static int hns3_get_rxnfc(struct net_device *netdev,
|
||||
}
|
||||
}
|
||||
|
||||
static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
|
||||
u32 tx_desc_num, u32 rx_desc_num)
|
||||
static void hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
|
||||
u32 tx_desc_num, u32 rx_desc_num)
|
||||
{
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
int i;
|
||||
@ -881,21 +881,29 @@ static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
|
||||
priv->ring_data[i + h->kinfo.num_tqps].ring->desc_num =
|
||||
rx_desc_num;
|
||||
}
|
||||
|
||||
return hns3_init_all_ring(priv);
|
||||
}
|
||||
|
||||
static int hns3_set_ringparam(struct net_device *ndev,
|
||||
struct ethtool_ringparam *param)
|
||||
static struct hns3_enet_ring *hns3_backup_ringparam(struct hns3_nic_priv *priv)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(ndev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
bool if_running = netif_running(ndev);
|
||||
u32 old_tx_desc_num, new_tx_desc_num;
|
||||
u32 old_rx_desc_num, new_rx_desc_num;
|
||||
int queue_num = h->kinfo.num_tqps;
|
||||
int ret;
|
||||
struct hnae3_handle *handle = priv->ae_handle;
|
||||
struct hns3_enet_ring *tmp_rings;
|
||||
int i;
|
||||
|
||||
tmp_rings = kcalloc(handle->kinfo.num_tqps * 2,
|
||||
sizeof(struct hns3_enet_ring), GFP_KERNEL);
|
||||
if (!tmp_rings)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < handle->kinfo.num_tqps * 2; i++)
|
||||
memcpy(&tmp_rings[i], priv->ring_data[i].ring,
|
||||
sizeof(struct hns3_enet_ring));
|
||||
|
||||
return tmp_rings;
|
||||
}
|
||||
|
||||
static int hns3_check_ringparam(struct net_device *ndev,
|
||||
struct ethtool_ringparam *param)
|
||||
{
|
||||
if (hns3_nic_resetting(ndev))
|
||||
return -EBUSY;
|
||||
|
||||
@ -911,6 +919,25 @@ static int hns3_set_ringparam(struct net_device *ndev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_set_ringparam(struct net_device *ndev,
|
||||
struct ethtool_ringparam *param)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(ndev);
|
||||
struct hnae3_handle *h = priv->ae_handle;
|
||||
struct hns3_enet_ring *tmp_rings;
|
||||
bool if_running = netif_running(ndev);
|
||||
u32 old_tx_desc_num, new_tx_desc_num;
|
||||
u32 old_rx_desc_num, new_rx_desc_num;
|
||||
u16 queue_num = h->kinfo.num_tqps;
|
||||
int ret, i;
|
||||
|
||||
ret = hns3_check_ringparam(ndev, param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Hardware requires that its descriptors must be multiple of eight */
|
||||
new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE);
|
||||
new_rx_desc_num = ALIGN(param->rx_pending, HNS3_RING_BD_MULTIPLE);
|
||||
@ -920,6 +947,13 @@ static int hns3_set_ringparam(struct net_device *ndev,
|
||||
old_rx_desc_num == new_rx_desc_num)
|
||||
return 0;
|
||||
|
||||
tmp_rings = hns3_backup_ringparam(priv);
|
||||
if (!tmp_rings) {
|
||||
netdev_err(ndev,
|
||||
"backup ring param failed by allocating memory fail\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
netdev_info(ndev,
|
||||
"Changing Tx/Rx ring depth from %d/%d to %d/%d\n",
|
||||
old_tx_desc_num, old_rx_desc_num,
|
||||
@ -928,22 +962,24 @@ static int hns3_set_ringparam(struct net_device *ndev,
|
||||
if (if_running)
|
||||
ndev->netdev_ops->ndo_stop(ndev);
|
||||
|
||||
ret = hns3_uninit_all_ring(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hns3_change_all_ring_bd_num(priv, new_tx_desc_num,
|
||||
new_rx_desc_num);
|
||||
hns3_change_all_ring_bd_num(priv, new_tx_desc_num, new_rx_desc_num);
|
||||
ret = hns3_init_all_ring(priv);
|
||||
if (ret) {
|
||||
ret = hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
|
||||
old_rx_desc_num);
|
||||
if (ret) {
|
||||
netdev_err(ndev,
|
||||
"Revert to old bd num fail, ret=%d.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
netdev_err(ndev, "Change bd num fail, revert to old value(%d)\n",
|
||||
ret);
|
||||
|
||||
hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
|
||||
old_rx_desc_num);
|
||||
for (i = 0; i < h->kinfo.num_tqps * 2; i++)
|
||||
memcpy(priv->ring_data[i].ring, &tmp_rings[i],
|
||||
sizeof(struct hns3_enet_ring));
|
||||
} else {
|
||||
for (i = 0; i < h->kinfo.num_tqps * 2; i++)
|
||||
hns3_fini_ring(&tmp_rings[i]);
|
||||
}
|
||||
|
||||
kfree(tmp_rings);
|
||||
|
||||
if (if_running)
|
||||
ret = ndev->netdev_ops->ndo_open(ndev);
|
||||
|
||||
|
@ -103,14 +103,17 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
|
||||
dma_addr_t dma = ring->desc_dma_addr;
|
||||
struct hclge_dev *hdev = ring->dev;
|
||||
struct hclge_hw *hw = &hdev->hw;
|
||||
u32 reg_val;
|
||||
|
||||
if (ring->ring_type == HCLGE_TYPE_CSQ) {
|
||||
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG,
|
||||
lower_32_bits(dma));
|
||||
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG,
|
||||
upper_32_bits(dma));
|
||||
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG,
|
||||
ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S);
|
||||
reg_val = hclge_read_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG);
|
||||
reg_val &= HCLGE_NIC_SW_RST_RDY;
|
||||
reg_val |= ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S;
|
||||
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
|
||||
hclge_write_dev(hw, HCLGE_NIC_CSQ_HEAD_REG, 0);
|
||||
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
|
||||
} else {
|
||||
@ -383,6 +386,23 @@ int hclge_cmd_queue_init(struct hclge_dev *hdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hclge_firmware_compat_config(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_firmware_compat_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
u32 compat = 0;
|
||||
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_M7_COMPAT_CFG, false);
|
||||
|
||||
req = (struct hclge_firmware_compat_cmd *)desc.data;
|
||||
|
||||
hnae3_set_bit(compat, HCLGE_LINK_EVENT_REPORT_EN_B, 1);
|
||||
hnae3_set_bit(compat, HCLGE_NCSI_ERROR_REPORT_EN_B, 1);
|
||||
req->compat = cpu_to_le32(compat);
|
||||
|
||||
return hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
}
|
||||
|
||||
int hclge_cmd_init(struct hclge_dev *hdev)
|
||||
{
|
||||
u32 version;
|
||||
@ -429,6 +449,15 @@ int hclge_cmd_init(struct hclge_dev *hdev)
|
||||
hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK,
|
||||
HNAE3_FW_VERSION_BYTE0_SHIFT));
|
||||
|
||||
/* ask the firmware to enable some features, driver can work without
|
||||
* it.
|
||||
*/
|
||||
ret = hclge_firmware_compat_config(hdev);
|
||||
if (ret)
|
||||
dev_warn(&hdev->pdev->dev,
|
||||
"Firmware compatible features not enabled(%d).\n",
|
||||
ret);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cmd_init:
|
||||
|
@ -86,6 +86,7 @@ enum hclge_opcode_type {
|
||||
HCLGE_OPC_QUERY_PF_RSRC = 0x0023,
|
||||
HCLGE_OPC_QUERY_VF_RSRC = 0x0024,
|
||||
HCLGE_OPC_GET_CFG_PARAM = 0x0025,
|
||||
HCLGE_OPC_PF_RST_DONE = 0x0026,
|
||||
|
||||
HCLGE_OPC_STATS_64_BIT = 0x0030,
|
||||
HCLGE_OPC_STATS_32_BIT = 0x0031,
|
||||
@ -257,6 +258,7 @@ enum hclge_opcode_type {
|
||||
/* M7 stats command */
|
||||
HCLGE_OPC_M7_STATS_BD = 0x7012,
|
||||
HCLGE_OPC_M7_STATS_INFO = 0x7013,
|
||||
HCLGE_OPC_M7_COMPAT_CFG = 0x701A,
|
||||
|
||||
/* SFP command */
|
||||
HCLGE_OPC_GET_SFP_INFO = 0x7104,
|
||||
@ -827,7 +829,7 @@ struct hclge_mac_ethertype_idx_rd_cmd {
|
||||
u8 flags;
|
||||
u8 resp_code;
|
||||
__le16 vlan_tag;
|
||||
u8 mac_add[6];
|
||||
u8 mac_addr[6];
|
||||
__le16 index;
|
||||
__le16 ethter_type;
|
||||
__le16 egress_port;
|
||||
@ -877,6 +879,13 @@ struct hclge_reset_cmd {
|
||||
u8 rsv[22];
|
||||
};
|
||||
|
||||
#define HCLGE_PF_RESET_DONE_BIT BIT(0)
|
||||
|
||||
struct hclge_pf_rst_done_cmd {
|
||||
u8 pf_rst_done;
|
||||
u8 rsv[23];
|
||||
};
|
||||
|
||||
#define HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B BIT(0)
|
||||
#define HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B BIT(2)
|
||||
#define HCLGE_CMD_SERDES_DONE_B BIT(0)
|
||||
@ -906,8 +915,11 @@ struct hclge_serdes_lb_cmd {
|
||||
#define HCLGE_NIC_CRQ_DEPTH_REG 0x27020
|
||||
#define HCLGE_NIC_CRQ_TAIL_REG 0x27024
|
||||
#define HCLGE_NIC_CRQ_HEAD_REG 0x27028
|
||||
#define HCLGE_NIC_CMQ_EN_B 16
|
||||
#define HCLGE_NIC_CMQ_ENABLE BIT(HCLGE_NIC_CMQ_EN_B)
|
||||
|
||||
/* this bit indicates that the driver is ready for hardware reset */
|
||||
#define HCLGE_NIC_SW_RST_RDY_B 16
|
||||
#define HCLGE_NIC_SW_RST_RDY BIT(HCLGE_NIC_SW_RST_RDY_B)
|
||||
|
||||
#define HCLGE_NIC_CMQ_DESC_NUM 1024
|
||||
#define HCLGE_NIC_CMQ_DESC_NUM_S 3
|
||||
|
||||
@ -1009,6 +1021,13 @@ struct hclge_query_ppu_pf_other_int_dfx_cmd {
|
||||
u8 rsv[4];
|
||||
};
|
||||
|
||||
#define HCLGE_LINK_EVENT_REPORT_EN_B 0
|
||||
#define HCLGE_NCSI_ERROR_REPORT_EN_B 1
|
||||
struct hclge_firmware_compat_cmd {
|
||||
__le32 compat;
|
||||
u8 rsv[20];
|
||||
};
|
||||
|
||||
int hclge_cmd_init(struct hclge_dev *hdev);
|
||||
static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value)
|
||||
{
|
||||
|
@ -325,6 +325,12 @@ static void hclge_dbg_dump_tc(struct hclge_dev *hdev)
|
||||
struct hclge_desc desc;
|
||||
int i, ret;
|
||||
|
||||
if (!hnae3_dev_dcb_supported(hdev)) {
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"Only DCB-supported dev supports tc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, true);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
@ -409,6 +415,12 @@ static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev)
|
||||
|
||||
dev_info(&hdev->pdev->dev, "QS_SCH qs_id: %u\n", desc.data[0]);
|
||||
|
||||
if (!hnae3_dev_dcb_supported(hdev)) {
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"Only DCB-supported dev supports tm mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING;
|
||||
hclge_cmd_setup_basic_desc(&desc, cmd, true);
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
@ -590,6 +602,12 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev,
|
||||
dev_info(&hdev->pdev->dev, "%04d | %04d | %02d | %02d\n",
|
||||
queue_id, qset_id, pri_id, tc_id);
|
||||
|
||||
if (!hnae3_dev_dcb_supported(hdev)) {
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"Only DCB-supported dev supports tm mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING;
|
||||
bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
|
||||
for (group_id = 0; group_id < 32; group_id++) {
|
||||
@ -715,6 +733,34 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
|
||||
dev_info(&hdev->pdev->dev, "rx_share_buf: 0x%x\n",
|
||||
rx_buf_cmd->shared_buf);
|
||||
|
||||
cmd = HCLGE_OPC_RX_COM_WL_ALLOC;
|
||||
hclge_cmd_setup_basic_desc(desc, cmd, true);
|
||||
ret = hclge_cmd_send(&hdev->hw, desc, 1);
|
||||
if (ret)
|
||||
goto err_qos_cmd_send;
|
||||
|
||||
rx_com_wl = (struct hclge_rx_com_wl *)desc[0].data;
|
||||
dev_info(&hdev->pdev->dev, "\n");
|
||||
dev_info(&hdev->pdev->dev, "rx_com_wl: high: 0x%x, low: 0x%x\n",
|
||||
rx_com_wl->com_wl.high, rx_com_wl->com_wl.low);
|
||||
|
||||
cmd = HCLGE_OPC_RX_GBL_PKT_CNT;
|
||||
hclge_cmd_setup_basic_desc(desc, cmd, true);
|
||||
ret = hclge_cmd_send(&hdev->hw, desc, 1);
|
||||
if (ret)
|
||||
goto err_qos_cmd_send;
|
||||
|
||||
rx_packet_cnt = (struct hclge_rx_com_wl *)desc[0].data;
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"rx_global_packet_cnt: high: 0x%x, low: 0x%x\n",
|
||||
rx_packet_cnt->com_wl.high, rx_packet_cnt->com_wl.low);
|
||||
dev_info(&hdev->pdev->dev, "\n");
|
||||
|
||||
if (!hnae3_dev_dcb_supported(hdev)) {
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"Only DCB-supported dev supports rx priv wl\n");
|
||||
return;
|
||||
}
|
||||
cmd = HCLGE_OPC_RX_PRIV_WL_ALLOC;
|
||||
hclge_cmd_setup_basic_desc(&desc[0], cmd, true);
|
||||
desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
|
||||
@ -723,7 +769,6 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
|
||||
if (ret)
|
||||
goto err_qos_cmd_send;
|
||||
|
||||
dev_info(&hdev->pdev->dev, "\n");
|
||||
rx_priv_wl = (struct hclge_rx_priv_wl_buf *)desc[0].data;
|
||||
for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++)
|
||||
dev_info(&hdev->pdev->dev,
|
||||
@ -758,29 +803,6 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
|
||||
"rx_com_thrd_tc_%d: high: 0x%x, low: 0x%x\n", i + 4,
|
||||
rx_com_thrd->com_thrd[i].high,
|
||||
rx_com_thrd->com_thrd[i].low);
|
||||
|
||||
cmd = HCLGE_OPC_RX_COM_WL_ALLOC;
|
||||
hclge_cmd_setup_basic_desc(desc, cmd, true);
|
||||
ret = hclge_cmd_send(&hdev->hw, desc, 1);
|
||||
if (ret)
|
||||
goto err_qos_cmd_send;
|
||||
|
||||
rx_com_wl = (struct hclge_rx_com_wl *)desc[0].data;
|
||||
dev_info(&hdev->pdev->dev, "\n");
|
||||
dev_info(&hdev->pdev->dev, "rx_com_wl: high: 0x%x, low: 0x%x\n",
|
||||
rx_com_wl->com_wl.high, rx_com_wl->com_wl.low);
|
||||
|
||||
cmd = HCLGE_OPC_RX_GBL_PKT_CNT;
|
||||
hclge_cmd_setup_basic_desc(desc, cmd, true);
|
||||
ret = hclge_cmd_send(&hdev->hw, desc, 1);
|
||||
if (ret)
|
||||
goto err_qos_cmd_send;
|
||||
|
||||
rx_packet_cnt = (struct hclge_rx_com_wl *)desc[0].data;
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"rx_global_packet_cnt: high: 0x%x, low: 0x%x\n",
|
||||
rx_packet_cnt->com_wl.high, rx_packet_cnt->com_wl.low);
|
||||
|
||||
return;
|
||||
|
||||
err_qos_cmd_send:
|
||||
@ -825,9 +847,9 @@ static void hclge_dbg_dump_mng_table(struct hclge_dev *hdev)
|
||||
memset(printf_buf, 0, HCLGE_DBG_BUF_LEN);
|
||||
snprintf(printf_buf, HCLGE_DBG_BUF_LEN,
|
||||
"%02u |%02x:%02x:%02x:%02x:%02x:%02x|",
|
||||
req0->index, req0->mac_add[0], req0->mac_add[1],
|
||||
req0->mac_add[2], req0->mac_add[3], req0->mac_add[4],
|
||||
req0->mac_add[5]);
|
||||
req0->index, req0->mac_addr[0], req0->mac_addr[1],
|
||||
req0->mac_addr[2], req0->mac_addr[3],
|
||||
req0->mac_addr[4], req0->mac_addr[5]);
|
||||
|
||||
snprintf(printf_buf + strlen(printf_buf),
|
||||
HCLGE_DBG_BUF_LEN - strlen(printf_buf),
|
||||
|
@ -652,16 +652,11 @@ static void hclge_log_error(struct device *dev, char *reg,
|
||||
* @desc: descriptor for describing the command
|
||||
* @cmd: command opcode
|
||||
* @flag: flag for extended command structure
|
||||
* @w_num: offset for setting the read interrupt type.
|
||||
* @int_type: select which type of the interrupt for which the error
|
||||
* info will be read(RAS-CE/RAS-NFE/RAS-FE etc).
|
||||
*
|
||||
* This function query the error info from hw register/s using command
|
||||
*/
|
||||
static int hclge_cmd_query_error(struct hclge_dev *hdev,
|
||||
struct hclge_desc *desc, u32 cmd,
|
||||
u16 flag, u8 w_num,
|
||||
enum hclge_err_int_type int_type)
|
||||
struct hclge_desc *desc, u32 cmd, u16 flag)
|
||||
{
|
||||
struct device *dev = &hdev->pdev->dev;
|
||||
int desc_num = 1;
|
||||
@ -673,8 +668,6 @@ static int hclge_cmd_query_error(struct hclge_dev *hdev,
|
||||
hclge_cmd_setup_basic_desc(&desc[1], cmd, true);
|
||||
desc_num = 2;
|
||||
}
|
||||
if (w_num)
|
||||
desc[0].data[w_num] = cpu_to_le32(int_type);
|
||||
|
||||
ret = hclge_cmd_send(&hdev->hw, &desc[0], desc_num);
|
||||
if (ret)
|
||||
@ -872,8 +865,7 @@ static int hclge_config_tm_hw_err_int(struct hclge_dev *hdev, bool en)
|
||||
}
|
||||
|
||||
/* configure TM QCN hw errors */
|
||||
ret = hclge_cmd_query_error(hdev, &desc, HCLGE_TM_QCN_MEM_INT_CFG,
|
||||
0, 0, 0);
|
||||
ret = hclge_cmd_query_error(hdev, &desc, HCLGE_TM_QCN_MEM_INT_CFG, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "fail(%d) to read TM QCN CFG status\n", ret);
|
||||
return ret;
|
||||
@ -1410,7 +1402,7 @@ static int hclge_log_rocee_ecc_error(struct hclge_dev *hdev)
|
||||
|
||||
ret = hclge_cmd_query_error(hdev, &desc[0],
|
||||
HCLGE_QUERY_ROCEE_ECC_RAS_INFO_CMD,
|
||||
HCLGE_CMD_FLAG_NEXT, 0, 0);
|
||||
HCLGE_CMD_FLAG_NEXT);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed(%d) to query ROCEE ECC error sts\n", ret);
|
||||
return ret;
|
||||
@ -1434,7 +1426,7 @@ static int hclge_log_rocee_ovf_error(struct hclge_dev *hdev)
|
||||
|
||||
/* read overflow error status */
|
||||
ret = hclge_cmd_query_error(hdev, &desc[0], HCLGE_ROCEE_PF_RAS_INT_CMD,
|
||||
0, 0, 0);
|
||||
0);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed(%d) to query ROCEE OVF error sts\n", ret);
|
||||
return ret;
|
||||
@ -1483,8 +1475,7 @@ hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
|
||||
|
||||
/* read RAS error interrupt status */
|
||||
ret = hclge_cmd_query_error(hdev, &desc[0],
|
||||
HCLGE_QUERY_CLEAR_ROCEE_RAS_INT,
|
||||
0, 0, 0);
|
||||
HCLGE_QUERY_CLEAR_ROCEE_RAS_INT, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed(%d) to query ROCEE RAS INT SRC\n", ret);
|
||||
/* reset everything for now */
|
||||
|
@ -2517,7 +2517,7 @@ static void hclge_reset_task_schedule(struct hclge_dev *hdev)
|
||||
&hdev->rst_service_task);
|
||||
}
|
||||
|
||||
static void hclge_task_schedule(struct hclge_dev *hdev)
|
||||
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time)
|
||||
{
|
||||
if (!test_bit(HCLGE_STATE_DOWN, &hdev->state) &&
|
||||
!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
|
||||
@ -2526,7 +2526,7 @@ static void hclge_task_schedule(struct hclge_dev *hdev)
|
||||
hdev->fd_arfs_expire_timer++;
|
||||
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
|
||||
system_wq, &hdev->service_task,
|
||||
round_jiffies_relative(HZ));
|
||||
delay_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2876,10 +2876,15 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear the source of interrupt if it is not cause by reset */
|
||||
hclge_clear_event_cause(hdev, event_cause, clearval);
|
||||
|
||||
/* Enable interrupt if it is not cause by reset. And when
|
||||
* clearval equal to 0, it means interrupt status may be
|
||||
* cleared by hardware before driver reads status register.
|
||||
* For this case, vector0 interrupt also should be enabled.
|
||||
*/
|
||||
if (!clearval ||
|
||||
event_cause == HCLGE_VECTOR0_EVENT_MBX) {
|
||||
hclge_clear_event_cause(hdev, event_cause, clearval);
|
||||
hclge_enable_vector(&hdev->misc_vector, true);
|
||||
}
|
||||
|
||||
@ -3253,7 +3258,13 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev)
|
||||
if (!clearval)
|
||||
return;
|
||||
|
||||
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, clearval);
|
||||
/* For revision 0x20, the reset interrupt source
|
||||
* can only be cleared after hardware reset done
|
||||
*/
|
||||
if (hdev->pdev->revision == 0x20)
|
||||
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG,
|
||||
clearval);
|
||||
|
||||
hclge_enable_vector(&hdev->misc_vector, true);
|
||||
}
|
||||
|
||||
@ -3274,6 +3285,19 @@ static int hclge_reset_prepare_down(struct hclge_dev *hdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable)
|
||||
{
|
||||
u32 reg_val;
|
||||
|
||||
reg_val = hclge_read_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG);
|
||||
if (enable)
|
||||
reg_val |= HCLGE_NIC_SW_RST_RDY;
|
||||
else
|
||||
reg_val &= ~HCLGE_NIC_SW_RST_RDY;
|
||||
|
||||
hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val);
|
||||
}
|
||||
|
||||
static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
|
||||
{
|
||||
#define HCLGE_RESET_SYNC_TIME 100
|
||||
@ -3322,8 +3346,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
|
||||
|
||||
/* inform hardware that preparatory work is done */
|
||||
msleep(HCLGE_RESET_SYNC_TIME);
|
||||
hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG,
|
||||
HCLGE_NIC_CMQ_ENABLE);
|
||||
hclge_reset_handshake(hdev, true);
|
||||
dev_info(&hdev->pdev->dev, "prepare wait ok\n");
|
||||
|
||||
return ret;
|
||||
@ -3354,10 +3377,26 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
|
||||
}
|
||||
|
||||
hclge_clear_reset_cause(hdev);
|
||||
|
||||
/* recover the handshake status when reset fail */
|
||||
hclge_reset_handshake(hdev, true);
|
||||
|
||||
dev_err(&hdev->pdev->dev, "Reset fail!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static int hclge_set_rst_done(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_pf_rst_done_cmd *req;
|
||||
struct hclge_desc desc;
|
||||
|
||||
req = (struct hclge_pf_rst_done_cmd *)desc.data;
|
||||
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PF_RST_DONE, false);
|
||||
req->pf_rst_done |= HCLGE_PF_RESET_DONE_BIT;
|
||||
|
||||
return hclge_cmd_send(&hdev->hw, &desc, 1);
|
||||
}
|
||||
|
||||
static int hclge_reset_prepare_up(struct hclge_dev *hdev)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -3368,10 +3407,18 @@ static int hclge_reset_prepare_up(struct hclge_dev *hdev)
|
||||
case HNAE3_FLR_RESET:
|
||||
ret = hclge_set_all_vf_rst(hdev, false);
|
||||
break;
|
||||
case HNAE3_GLOBAL_RESET:
|
||||
/* fall through */
|
||||
case HNAE3_IMP_RESET:
|
||||
ret = hclge_set_rst_done(hdev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear up the handshake status after re-initialize done */
|
||||
hclge_reset_handshake(hdev, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3470,7 +3517,15 @@ static void hclge_reset(struct hclge_dev *hdev)
|
||||
hdev->reset_fail_cnt = 0;
|
||||
hdev->rst_stats.reset_done_cnt++;
|
||||
ae_dev->reset_type = HNAE3_NONE_RESET;
|
||||
del_timer(&hdev->reset_timer);
|
||||
|
||||
/* if default_reset_request has a higher level reset request,
|
||||
* it should be handled as soon as possible. since some errors
|
||||
* need this kind of reset to fix.
|
||||
*/
|
||||
hdev->reset_level = hclge_get_reset_level(ae_dev,
|
||||
&hdev->default_reset_request);
|
||||
if (hdev->reset_level != HNAE3_NONE_RESET)
|
||||
set_bit(hdev->reset_level, &hdev->reset_request);
|
||||
|
||||
return;
|
||||
|
||||
@ -3505,9 +3560,10 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
|
||||
handle = &hdev->vport[0].nic;
|
||||
|
||||
if (time_before(jiffies, (hdev->last_reset_time +
|
||||
HCLGE_RESET_INTERVAL)))
|
||||
HCLGE_RESET_INTERVAL))) {
|
||||
mod_timer(&hdev->reset_timer, jiffies + HCLGE_RESET_INTERVAL);
|
||||
return;
|
||||
else if (hdev->default_reset_request)
|
||||
} else if (hdev->default_reset_request)
|
||||
hdev->reset_level =
|
||||
hclge_get_reset_level(ae_dev,
|
||||
&hdev->default_reset_request);
|
||||
@ -3537,6 +3593,12 @@ static void hclge_reset_timer(struct timer_list *t)
|
||||
{
|
||||
struct hclge_dev *hdev = from_timer(hdev, t, reset_timer);
|
||||
|
||||
/* if default_reset_request has no value, it means that this reset
|
||||
* request has already be handled, so just return here
|
||||
*/
|
||||
if (!hdev->default_reset_request)
|
||||
return;
|
||||
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"triggering reset in reset timer\n");
|
||||
hclge_reset_event(hdev->pdev, NULL);
|
||||
@ -3636,7 +3698,7 @@ static void hclge_service_task(struct work_struct *work)
|
||||
hdev->fd_arfs_expire_timer = 0;
|
||||
}
|
||||
|
||||
hclge_task_schedule(hdev);
|
||||
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
|
||||
}
|
||||
|
||||
struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle)
|
||||
@ -6175,7 +6237,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
|
||||
if (enable) {
|
||||
hclge_task_schedule(hdev);
|
||||
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
|
||||
} else {
|
||||
/* Set the DOWN flag here to disable the service to be
|
||||
* scheduled again
|
||||
@ -6220,6 +6282,7 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
|
||||
if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) &&
|
||||
hdev->reset_type != HNAE3_FUNC_RESET) {
|
||||
hclge_mac_stop_phy(hdev);
|
||||
hclge_update_link_status(hdev);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6267,7 +6330,6 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
|
||||
enum hclge_mac_vlan_tbl_opcode op)
|
||||
{
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
int return_status = -EIO;
|
||||
|
||||
if (cmdq_resp) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
@ -6278,52 +6340,53 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
|
||||
|
||||
if (op == HCLGE_MAC_VLAN_ADD) {
|
||||
if ((!resp_code) || (resp_code == 1)) {
|
||||
return_status = 0;
|
||||
return 0;
|
||||
} else if (resp_code == HCLGE_ADD_UC_OVERFLOW) {
|
||||
return_status = -ENOSPC;
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"add mac addr failed for uc_overflow.\n");
|
||||
return -ENOSPC;
|
||||
} else if (resp_code == HCLGE_ADD_MC_OVERFLOW) {
|
||||
return_status = -ENOSPC;
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"add mac addr failed for mc_overflow.\n");
|
||||
} else {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"add mac addr failed for undefined, code=%d.\n",
|
||||
resp_code);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"add mac addr failed for undefined, code=%u.\n",
|
||||
resp_code);
|
||||
return -EIO;
|
||||
} else if (op == HCLGE_MAC_VLAN_REMOVE) {
|
||||
if (!resp_code) {
|
||||
return_status = 0;
|
||||
return 0;
|
||||
} else if (resp_code == 1) {
|
||||
return_status = -ENOENT;
|
||||
dev_dbg(&hdev->pdev->dev,
|
||||
"remove mac addr failed for miss.\n");
|
||||
} else {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"remove mac addr failed for undefined, code=%d.\n",
|
||||
resp_code);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"remove mac addr failed for undefined, code=%u.\n",
|
||||
resp_code);
|
||||
return -EIO;
|
||||
} else if (op == HCLGE_MAC_VLAN_LKUP) {
|
||||
if (!resp_code) {
|
||||
return_status = 0;
|
||||
return 0;
|
||||
} else if (resp_code == 1) {
|
||||
return_status = -ENOENT;
|
||||
dev_dbg(&hdev->pdev->dev,
|
||||
"lookup mac addr failed for miss.\n");
|
||||
} else {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"lookup mac addr failed for undefined, code=%d.\n",
|
||||
resp_code);
|
||||
return -ENOENT;
|
||||
}
|
||||
} else {
|
||||
return_status = -EINVAL;
|
||||
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"unknown opcode for get_mac_vlan_cmd_status,opcode=%d.\n",
|
||||
op);
|
||||
"lookup mac addr failed for undefined, code=%u.\n",
|
||||
resp_code);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return return_status;
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"unknown opcode for get_mac_vlan_cmd_status, opcode=%d.\n", op);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hclge_update_desc_vfid(struct hclge_desc *desc, int vfid, bool clr)
|
||||
|
@ -302,6 +302,13 @@ enum hclge_fc_mode {
|
||||
HCLGE_FC_DEFAULT
|
||||
};
|
||||
|
||||
enum hclge_link_fail_code {
|
||||
HCLGE_LF_NORMAL,
|
||||
HCLGE_LF_REF_CLOCK_LOST,
|
||||
HCLGE_LF_XSFP_TX_DISABLE,
|
||||
HCLGE_LF_XSFP_ABSENT,
|
||||
};
|
||||
|
||||
#define HCLGE_PG_NUM 4
|
||||
#define HCLGE_SCH_MODE_SP 0
|
||||
#define HCLGE_SCH_MODE_DWRR 1
|
||||
@ -1021,4 +1028,5 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
|
||||
int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
|
||||
u16 state, u16 vlan_tag, u16 qos,
|
||||
u16 vlan_proto);
|
||||
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
|
||||
#endif
|
||||
|
@ -545,6 +545,36 @@ static int hclge_get_rss_key(struct hclge_vport *vport,
|
||||
HCLGE_RSS_MBX_RESP_LEN);
|
||||
}
|
||||
|
||||
static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code)
|
||||
{
|
||||
switch (link_fail_code) {
|
||||
case HCLGE_LF_REF_CLOCK_LOST:
|
||||
dev_warn(&hdev->pdev->dev, "Reference clock lost!\n");
|
||||
break;
|
||||
case HCLGE_LF_XSFP_TX_DISABLE:
|
||||
dev_warn(&hdev->pdev->dev, "SFP tx is disabled!\n");
|
||||
break;
|
||||
case HCLGE_LF_XSFP_ABSENT:
|
||||
dev_warn(&hdev->pdev->dev, "SFP is absent!\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void hclge_handle_link_change_event(struct hclge_dev *hdev,
|
||||
struct hclge_mbx_vf_to_pf_cmd *req)
|
||||
{
|
||||
#define LINK_STATUS_OFFSET 1
|
||||
#define LINK_FAIL_CODE_OFFSET 2
|
||||
|
||||
clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state);
|
||||
hclge_task_schedule(hdev, 0);
|
||||
|
||||
if (!req->msg[LINK_STATUS_OFFSET])
|
||||
hclge_link_fail_parse(hdev, req->msg[LINK_FAIL_CODE_OFFSET]);
|
||||
}
|
||||
|
||||
static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
|
||||
{
|
||||
u32 tail = hclge_read_dev(hw, HCLGE_NIC_CRQ_TAIL_REG);
|
||||
@ -552,6 +582,15 @@ static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
|
||||
return tail == hw->cmq.crq.next_to_use;
|
||||
}
|
||||
|
||||
static void hclge_handle_ncsi_error(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
|
||||
|
||||
ae_dev->ops->set_default_reset_request(ae_dev, HNAE3_GLOBAL_RESET);
|
||||
dev_warn(&hdev->pdev->dev, "requesting reset due to NCSI error\n");
|
||||
ae_dev->ops->reset_event(hdev->pdev, NULL);
|
||||
}
|
||||
|
||||
void hclge_mbx_handler(struct hclge_dev *hdev)
|
||||
{
|
||||
struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq;
|
||||
@ -707,6 +746,12 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
|
||||
"PF fail(%d) to media type for VF\n",
|
||||
ret);
|
||||
break;
|
||||
case HCLGE_MBX_PUSH_LINK_STATUS:
|
||||
hclge_handle_link_change_event(hdev, req);
|
||||
break;
|
||||
case HCLGE_MBX_NCSI_ERROR:
|
||||
hclge_handle_ncsi_error(hdev);
|
||||
break;
|
||||
default:
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"un-supported mailbox message, code = %d\n",
|
||||
|
@ -650,12 +650,8 @@ static void hclge_pfc_info_init(struct hclge_dev *hdev)
|
||||
}
|
||||
}
|
||||
|
||||
static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
|
||||
static void hclge_tm_schd_info_init(struct hclge_dev *hdev)
|
||||
{
|
||||
if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
|
||||
(hdev->tm_info.num_pg != 1))
|
||||
return -EINVAL;
|
||||
|
||||
hclge_tm_pg_info_init(hdev);
|
||||
|
||||
hclge_tm_tc_info_init(hdev);
|
||||
@ -663,8 +659,6 @@ static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
|
||||
hclge_tm_vport_info_update(hdev);
|
||||
|
||||
hclge_pfc_info_init(hdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev)
|
||||
@ -1428,15 +1422,15 @@ int hclge_tm_init_hw(struct hclge_dev *hdev, bool init)
|
||||
|
||||
int hclge_tm_schd_init(struct hclge_dev *hdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* fc_mode is HCLGE_FC_FULL on reset */
|
||||
hdev->tm_info.fc_mode = HCLGE_FC_FULL;
|
||||
hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
|
||||
|
||||
ret = hclge_tm_schd_info_init(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE &&
|
||||
hdev->tm_info.num_pg != 1)
|
||||
return -EINVAL;
|
||||
|
||||
hclge_tm_schd_info_init(hdev);
|
||||
|
||||
return hclge_tm_init_hw(hdev, true);
|
||||
}
|
||||
|
@ -97,7 +97,9 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
|
||||
reg_val = (u32)((ring->desc_dma_addr >> 31) >> 1);
|
||||
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_H_REG, reg_val);
|
||||
|
||||
reg_val = (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S);
|
||||
reg_val = hclgevf_read_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG);
|
||||
reg_val &= HCLGEVF_NIC_SW_RST_RDY;
|
||||
reg_val |= (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S);
|
||||
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG, reg_val);
|
||||
|
||||
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0);
|
||||
|
@ -244,8 +244,11 @@ struct hclgevf_cfg_tx_queue_pointer_cmd {
|
||||
#define HCLGEVF_NIC_CRQ_DEPTH_REG 0x27020
|
||||
#define HCLGEVF_NIC_CRQ_TAIL_REG 0x27024
|
||||
#define HCLGEVF_NIC_CRQ_HEAD_REG 0x27028
|
||||
#define HCLGEVF_NIC_CMQ_EN_B 16
|
||||
#define HCLGEVF_NIC_CMQ_ENABLE BIT(HCLGEVF_NIC_CMQ_EN_B)
|
||||
|
||||
/* this bit indicates that the driver is ready for hardware reset */
|
||||
#define HCLGEVF_NIC_SW_RST_RDY_B 16
|
||||
#define HCLGEVF_NIC_SW_RST_RDY BIT(HCLGEVF_NIC_SW_RST_RDY_B)
|
||||
|
||||
#define HCLGEVF_NIC_CMQ_DESC_NUM 1024
|
||||
#define HCLGEVF_NIC_CMQ_DESC_NUM_S 3
|
||||
#define HCLGEVF_NIC_CMDQ_INT_SRC_REG 0x27100
|
||||
|
@ -1396,19 +1396,22 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/* wait to check the hardware reset completion status */
|
||||
val = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
|
||||
dev_info(&hdev->pdev->dev, "checking vf resetting status: %x\n", val);
|
||||
|
||||
if (hdev->reset_type == HNAE3_FLR_RESET)
|
||||
return hclgevf_flr_poll_timeout(hdev,
|
||||
HCLGEVF_RESET_WAIT_US,
|
||||
HCLGEVF_RESET_WAIT_CNT);
|
||||
|
||||
ret = readl_poll_timeout(hdev->hw.io_base + HCLGEVF_RST_ING, val,
|
||||
!(val & HCLGEVF_RST_ING_BITS),
|
||||
HCLGEVF_RESET_WAIT_US,
|
||||
HCLGEVF_RESET_WAIT_TIMEOUT_US);
|
||||
else if (hdev->reset_type == HNAE3_VF_RESET)
|
||||
ret = readl_poll_timeout(hdev->hw.io_base +
|
||||
HCLGEVF_VF_RST_ING, val,
|
||||
!(val & HCLGEVF_VF_RST_ING_BIT),
|
||||
HCLGEVF_RESET_WAIT_US,
|
||||
HCLGEVF_RESET_WAIT_TIMEOUT_US);
|
||||
else
|
||||
ret = readl_poll_timeout(hdev->hw.io_base +
|
||||
HCLGEVF_RST_ING, val,
|
||||
!(val & HCLGEVF_RST_ING_BITS),
|
||||
HCLGEVF_RESET_WAIT_US,
|
||||
HCLGEVF_RESET_WAIT_TIMEOUT_US);
|
||||
|
||||
/* hardware completion status should be available by this time */
|
||||
if (ret) {
|
||||
@ -1426,6 +1429,20 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hclgevf_reset_handshake(struct hclgevf_dev *hdev, bool enable)
|
||||
{
|
||||
u32 reg_val;
|
||||
|
||||
reg_val = hclgevf_read_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG);
|
||||
if (enable)
|
||||
reg_val |= HCLGEVF_NIC_SW_RST_RDY;
|
||||
else
|
||||
reg_val &= ~HCLGEVF_NIC_SW_RST_RDY;
|
||||
|
||||
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
|
||||
reg_val);
|
||||
}
|
||||
|
||||
static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
|
||||
{
|
||||
int ret;
|
||||
@ -1448,7 +1465,14 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return hclgevf_notify_client(hdev, HNAE3_RESTORE_CLIENT);
|
||||
ret = hclgevf_notify_client(hdev, HNAE3_RESTORE_CLIENT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* clear handshake status with IMP */
|
||||
hclgevf_reset_handshake(hdev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
|
||||
@ -1474,8 +1498,7 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
|
||||
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
|
||||
/* inform hardware that preparatory work is done */
|
||||
msleep(HCLGEVF_RESET_SYNC_TIME);
|
||||
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
|
||||
HCLGEVF_NIC_CMQ_ENABLE);
|
||||
hclgevf_reset_handshake(hdev, true);
|
||||
dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n",
|
||||
hdev->reset_type, ret);
|
||||
|
||||
@ -1484,6 +1507,8 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
|
||||
|
||||
static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
|
||||
{
|
||||
/* recover handshake status with IMP when reset fail */
|
||||
hclgevf_reset_handshake(hdev, true);
|
||||
hdev->rst_stats.rst_fail_cnt++;
|
||||
dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n",
|
||||
hdev->rst_stats.rst_fail_cnt);
|
||||
@ -1494,9 +1519,6 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
|
||||
if (hclgevf_is_reset_pending(hdev)) {
|
||||
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
|
||||
hclgevf_reset_task_schedule(hdev);
|
||||
} else {
|
||||
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG,
|
||||
HCLGEVF_NIC_CMQ_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1867,7 +1889,7 @@ static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr)
|
||||
static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
|
||||
u32 *clearval)
|
||||
{
|
||||
u32 cmdq_src_reg, rst_ing_reg;
|
||||
u32 val, cmdq_src_reg, rst_ing_reg;
|
||||
|
||||
/* fetch the events from their corresponding regs */
|
||||
cmdq_src_reg = hclgevf_read_dev(&hdev->hw,
|
||||
@ -1883,6 +1905,12 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
|
||||
cmdq_src_reg &= ~BIT(HCLGEVF_VECTOR0_RST_INT_B);
|
||||
*clearval = cmdq_src_reg;
|
||||
hdev->rst_stats.vf_rst_cnt++;
|
||||
/* set up VF hardware reset status, its PF will clear
|
||||
* this status when PF has initialized done.
|
||||
*/
|
||||
val = hclgevf_read_dev(&hdev->hw, HCLGEVF_VF_RST_ING);
|
||||
hclgevf_write_dev(&hdev->hw, HCLGEVF_VF_RST_ING,
|
||||
val | HCLGEVF_VF_RST_ING_BIT);
|
||||
return HCLGEVF_VECTOR0_EVENT_RST;
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,9 @@
|
||||
(HCLGEVF_FUN_RST_ING_BIT | HCLGEVF_GLOBAL_RST_ING_BIT | \
|
||||
HCLGEVF_CORE_RST_ING_BIT | HCLGEVF_IMP_RST_ING_BIT)
|
||||
|
||||
#define HCLGEVF_VF_RST_ING 0x07008
|
||||
#define HCLGEVF_VF_RST_ING_BIT BIT(16)
|
||||
|
||||
#define HCLGEVF_RSS_IND_TBL_SIZE 512
|
||||
#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff
|
||||
#define HCLGEVF_RSS_KEY_SIZE 40
|
||||
|
Loading…
Reference in New Issue
Block a user