Commit 9b59e39f authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 0ae9fce3 012fcb52
...@@ -47,6 +47,8 @@ enum HCLGE_MBX_OPCODE { ...@@ -47,6 +47,8 @@ enum HCLGE_MBX_OPCODE {
HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */ 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_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 */ /* below are per-VF mac-vlan subcodes */
......
...@@ -2909,24 +2909,22 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget, ...@@ -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 *)) void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *))
{ {
#define RCB_NOF_ALLOC_RX_BUFF_ONCE 16 #define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
int recv_pkts, recv_bds, clean_count, err;
int unused_count = hns3_desc_unused(ring); int unused_count = hns3_desc_unused(ring);
struct sk_buff *skb = ring->skb; 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); 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 */ rmb(); /* Make sure num taken effect before the other data is touched */
recv_pkts = 0, recv_bds = 0, clean_count = 0;
num -= unused_count; num -= unused_count;
unused_count -= ring->pending_buf; unused_count -= ring->pending_buf;
while (recv_pkts < budget && recv_bds < num) { while (recv_pkts < budget && recv_bds < num) {
/* Reuse or realloc buffers */ /* Reuse or realloc buffers */
if (clean_count + unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) { if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
hns3_nic_alloc_rx_buffers(ring, hns3_nic_alloc_rx_buffers(ring, unused_count);
clean_count + unused_count);
clean_count = 0;
unused_count = hns3_desc_unused(ring) - unused_count = hns3_desc_unused(ring) -
ring->pending_buf; ring->pending_buf;
} }
...@@ -2940,7 +2938,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget, ...@@ -2940,7 +2938,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
goto out; goto out;
} else if (unlikely(err)) { /* Do jump the err */ } else if (unlikely(err)) { /* Do jump the err */
recv_bds += ring->pending_buf; recv_bds += ring->pending_buf;
clean_count += ring->pending_buf; unused_count += ring->pending_buf;
ring->skb = NULL; ring->skb = NULL;
ring->pending_buf = 0; ring->pending_buf = 0;
continue; continue;
...@@ -2948,7 +2946,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget, ...@@ -2948,7 +2946,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
rx_fn(ring, skb); rx_fn(ring, skb);
recv_bds += ring->pending_buf; recv_bds += ring->pending_buf;
clean_count += ring->pending_buf; unused_count += ring->pending_buf;
ring->skb = NULL; ring->skb = NULL;
ring->pending_buf = 0; ring->pending_buf = 0;
...@@ -2957,8 +2955,8 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget, ...@@ -2957,8 +2955,8 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
out: out:
/* Make all data has been write before submit */ /* Make all data has been write before submit */
if (clean_count + unused_count > 0) if (unused_count > 0)
hns3_nic_alloc_rx_buffers(ring, clean_count + unused_count); hns3_nic_alloc_rx_buffers(ring, unused_count);
return recv_pkts; return recv_pkts;
} }
...@@ -3588,7 +3586,7 @@ static int hns3_alloc_ring_memory(struct hns3_enet_ring *ring) ...@@ -3588,7 +3586,7 @@ static int hns3_alloc_ring_memory(struct hns3_enet_ring *ring)
return ret; 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); hns3_free_desc(ring);
devm_kfree(ring_to_dev(ring), ring->desc_cb); devm_kfree(ring_to_dev(ring), ring->desc_cb);
......
...@@ -75,7 +75,7 @@ enum hns3_nic_state { ...@@ -75,7 +75,7 @@ enum hns3_nic_state {
#define HNS3_TX_TIMEOUT (5 * HZ) #define HNS3_TX_TIMEOUT (5 * HZ)
#define HNS3_RING_NAME_LEN 16 #define HNS3_RING_NAME_LEN 16
#define HNS3_BUFFER_SIZE_2048 2048 #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_MIN_PENDING 24
#define HNS3_RING_BD_MULTIPLE 8 #define HNS3_RING_BD_MULTIPLE 8
/* max frame size of mac */ /* max frame size of mac */
...@@ -642,6 +642,7 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring); ...@@ -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_init_all_ring(struct hns3_nic_priv *priv);
int hns3_uninit_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); 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); netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
bool hns3_is_phys_func(struct pci_dev *pdev); bool hns3_is_phys_func(struct pci_dev *pdev);
int hns3_clean_rx_ring( int hns3_clean_rx_ring(
......
...@@ -867,8 +867,8 @@ static int hns3_get_rxnfc(struct net_device *netdev, ...@@ -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, static void hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv,
u32 tx_desc_num, u32 rx_desc_num) u32 tx_desc_num, u32 rx_desc_num)
{ {
struct hnae3_handle *h = priv->ae_handle; struct hnae3_handle *h = priv->ae_handle;
int i; int i;
...@@ -881,21 +881,29 @@ static int hns3_change_all_ring_bd_num(struct hns3_nic_priv *priv, ...@@ -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 = priv->ring_data[i + h->kinfo.num_tqps].ring->desc_num =
rx_desc_num; rx_desc_num;
} }
return hns3_init_all_ring(priv);
} }
static int hns3_set_ringparam(struct net_device *ndev, static struct hns3_enet_ring *hns3_backup_ringparam(struct hns3_nic_priv *priv)
struct ethtool_ringparam *param)
{ {
struct hns3_nic_priv *priv = netdev_priv(ndev); struct hnae3_handle *handle = priv->ae_handle;
struct hnae3_handle *h = priv->ae_handle; struct hns3_enet_ring *tmp_rings;
bool if_running = netif_running(ndev); int i;
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;
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)) if (hns3_nic_resetting(ndev))
return -EBUSY; return -EBUSY;
...@@ -911,6 +919,25 @@ static int hns3_set_ringparam(struct net_device *ndev, ...@@ -911,6 +919,25 @@ static int hns3_set_ringparam(struct net_device *ndev,
return -EINVAL; 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 */ /* Hardware requires that its descriptors must be multiple of eight */
new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE); new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE);
new_rx_desc_num = ALIGN(param->rx_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, ...@@ -920,6 +947,13 @@ static int hns3_set_ringparam(struct net_device *ndev,
old_rx_desc_num == new_rx_desc_num) old_rx_desc_num == new_rx_desc_num)
return 0; 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, netdev_info(ndev,
"Changing Tx/Rx ring depth from %d/%d to %d/%d\n", "Changing Tx/Rx ring depth from %d/%d to %d/%d\n",
old_tx_desc_num, old_rx_desc_num, old_tx_desc_num, old_rx_desc_num,
...@@ -928,22 +962,24 @@ static int hns3_set_ringparam(struct net_device *ndev, ...@@ -928,22 +962,24 @@ static int hns3_set_ringparam(struct net_device *ndev,
if (if_running) if (if_running)
ndev->netdev_ops->ndo_stop(ndev); ndev->netdev_ops->ndo_stop(ndev);
ret = hns3_uninit_all_ring(priv); hns3_change_all_ring_bd_num(priv, new_tx_desc_num, new_rx_desc_num);
if (ret) ret = hns3_init_all_ring(priv);
return ret;
ret = hns3_change_all_ring_bd_num(priv, new_tx_desc_num,
new_rx_desc_num);
if (ret) { if (ret) {
ret = hns3_change_all_ring_bd_num(priv, old_tx_desc_num, netdev_err(ndev, "Change bd num fail, revert to old value(%d)\n",
old_rx_desc_num); ret);
if (ret) {
netdev_err(ndev, hns3_change_all_ring_bd_num(priv, old_tx_desc_num,
"Revert to old bd num fail, ret=%d.\n", ret); old_rx_desc_num);
return ret; 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) if (if_running)
ret = ndev->netdev_ops->ndo_open(ndev); ret = ndev->netdev_ops->ndo_open(ndev);
......
...@@ -103,14 +103,17 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring) ...@@ -103,14 +103,17 @@ static void hclge_cmd_config_regs(struct hclge_cmq_ring *ring)
dma_addr_t dma = ring->desc_dma_addr; dma_addr_t dma = ring->desc_dma_addr;
struct hclge_dev *hdev = ring->dev; struct hclge_dev *hdev = ring->dev;
struct hclge_hw *hw = &hdev->hw; struct hclge_hw *hw = &hdev->hw;
u32 reg_val;
if (ring->ring_type == HCLGE_TYPE_CSQ) { if (ring->ring_type == HCLGE_TYPE_CSQ) {
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG, hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_L_REG,
lower_32_bits(dma)); lower_32_bits(dma));
hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG, hclge_write_dev(hw, HCLGE_NIC_CSQ_BASEADDR_H_REG,
upper_32_bits(dma)); upper_32_bits(dma));
hclge_write_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val = hclge_read_dev(hw, HCLGE_NIC_CSQ_DEPTH_REG);
ring->desc_num >> HCLGE_NIC_CMQ_DESC_NUM_S); 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_HEAD_REG, 0);
hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0); hclge_write_dev(hw, HCLGE_NIC_CSQ_TAIL_REG, 0);
} else { } else {
...@@ -383,6 +386,23 @@ int hclge_cmd_queue_init(struct hclge_dev *hdev) ...@@ -383,6 +386,23 @@ int hclge_cmd_queue_init(struct hclge_dev *hdev)
return ret; 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) int hclge_cmd_init(struct hclge_dev *hdev)
{ {
u32 version; u32 version;
...@@ -429,6 +449,15 @@ int hclge_cmd_init(struct hclge_dev *hdev) ...@@ -429,6 +449,15 @@ int hclge_cmd_init(struct hclge_dev *hdev)
hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK, hnae3_get_field(version, HNAE3_FW_VERSION_BYTE0_MASK,
HNAE3_FW_VERSION_BYTE0_SHIFT)); 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; return 0;
err_cmd_init: err_cmd_init:
......
...@@ -86,6 +86,7 @@ enum hclge_opcode_type { ...@@ -86,6 +86,7 @@ enum hclge_opcode_type {
HCLGE_OPC_QUERY_PF_RSRC = 0x0023, HCLGE_OPC_QUERY_PF_RSRC = 0x0023,
HCLGE_OPC_QUERY_VF_RSRC = 0x0024, HCLGE_OPC_QUERY_VF_RSRC = 0x0024,
HCLGE_OPC_GET_CFG_PARAM = 0x0025, HCLGE_OPC_GET_CFG_PARAM = 0x0025,
HCLGE_OPC_PF_RST_DONE = 0x0026,
HCLGE_OPC_STATS_64_BIT = 0x0030, HCLGE_OPC_STATS_64_BIT = 0x0030,
HCLGE_OPC_STATS_32_BIT = 0x0031, HCLGE_OPC_STATS_32_BIT = 0x0031,
...@@ -257,6 +258,7 @@ enum hclge_opcode_type { ...@@ -257,6 +258,7 @@ enum hclge_opcode_type {
/* M7 stats command */ /* M7 stats command */
HCLGE_OPC_M7_STATS_BD = 0x7012, HCLGE_OPC_M7_STATS_BD = 0x7012,
HCLGE_OPC_M7_STATS_INFO = 0x7013, HCLGE_OPC_M7_STATS_INFO = 0x7013,
HCLGE_OPC_M7_COMPAT_CFG = 0x701A,
/* SFP command */ /* SFP command */
HCLGE_OPC_GET_SFP_INFO = 0x7104, HCLGE_OPC_GET_SFP_INFO = 0x7104,
...@@ -827,7 +829,7 @@ struct hclge_mac_ethertype_idx_rd_cmd { ...@@ -827,7 +829,7 @@ struct hclge_mac_ethertype_idx_rd_cmd {
u8 flags; u8 flags;
u8 resp_code; u8 resp_code;
__le16 vlan_tag; __le16 vlan_tag;
u8 mac_add[6]; u8 mac_addr[6];
__le16 index; __le16 index;
__le16 ethter_type; __le16 ethter_type;
__le16 egress_port; __le16 egress_port;
...@@ -877,6 +879,13 @@ struct hclge_reset_cmd { ...@@ -877,6 +879,13 @@ struct hclge_reset_cmd {
u8 rsv[22]; 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_SERIAL_INNER_LOOP_B BIT(0)
#define HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B BIT(2) #define HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B BIT(2)
#define HCLGE_CMD_SERDES_DONE_B BIT(0) #define HCLGE_CMD_SERDES_DONE_B BIT(0)
...@@ -906,8 +915,11 @@ struct hclge_serdes_lb_cmd { ...@@ -906,8 +915,11 @@ struct hclge_serdes_lb_cmd {
#define HCLGE_NIC_CRQ_DEPTH_REG 0x27020 #define HCLGE_NIC_CRQ_DEPTH_REG 0x27020
#define HCLGE_NIC_CRQ_TAIL_REG 0x27024 #define HCLGE_NIC_CRQ_TAIL_REG 0x27024
#define HCLGE_NIC_CRQ_HEAD_REG 0x27028 #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 1024
#define HCLGE_NIC_CMQ_DESC_NUM_S 3 #define HCLGE_NIC_CMQ_DESC_NUM_S 3
...@@ -1009,6 +1021,13 @@ struct hclge_query_ppu_pf_other_int_dfx_cmd { ...@@ -1009,6 +1021,13 @@ struct hclge_query_ppu_pf_other_int_dfx_cmd {
u8 rsv[4]; 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); int hclge_cmd_init(struct hclge_dev *hdev);
static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value) 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) ...@@ -325,6 +325,12 @@ static void hclge_dbg_dump_tc(struct hclge_dev *hdev)
struct hclge_desc desc; struct hclge_desc desc;
int i, ret; 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); hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1); ret = hclge_cmd_send(&hdev->hw, &desc, 1);
...@@ -409,6 +415,12 @@ static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev) ...@@ -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]); 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; cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING;
hclge_cmd_setup_basic_desc(&desc, cmd, true); hclge_cmd_setup_basic_desc(&desc, cmd, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1); ret = hclge_cmd_send(&hdev->hw, &desc, 1);
...@@ -590,6 +602,12 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev, ...@@ -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", dev_info(&hdev->pdev->dev, "%04d | %04d | %02d | %02d\n",
queue_id, qset_id, pri_id, tc_id); 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; cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING;
bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data; bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
for (group_id = 0; group_id < 32; group_id++) { 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) ...@@ -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", dev_info(&hdev->pdev->dev, "rx_share_buf: 0x%x\n",
rx_buf_cmd->shared_buf); 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; cmd = HCLGE_OPC_RX_PRIV_WL_ALLOC;
hclge_cmd_setup_basic_desc(&desc[0], cmd, true); hclge_cmd_setup_basic_desc(&desc[0], cmd, true);
desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 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) ...@@ -723,7 +769,6 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev)
if (ret) if (ret)
goto err_qos_cmd_send; goto err_qos_cmd_send;
dev_info(&hdev->pdev->dev, "\n");
rx_priv_wl = (struct hclge_rx_priv_wl_buf *)desc[0].data; rx_priv_wl = (struct hclge_rx_priv_wl_buf *)desc[0].data;
for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++) for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++)
dev_info(&hdev->pdev->dev, dev_info(&hdev->pdev->dev,
...@@ -758,29 +803,6 @@ static void hclge_dbg_dump_qos_buf_cfg(struct hclge_dev *hdev) ...@@ -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_tc_%d: high: 0x%x, low: 0x%x\n", i + 4,
rx_com_thrd->com_thrd[i].high, rx_com_thrd->com_thrd[i].high,
rx_com_thrd->com_thrd[i].low); 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; return;
err_qos_cmd_send: err_qos_cmd_send:
...@@ -825,9 +847,9 @@ static void hclge_dbg_dump_mng_table(struct hclge_dev *hdev) ...@@ -825,9 +847,9 @@ static void hclge_dbg_dump_mng_table(struct hclge_dev *hdev)
memset(printf_buf, 0, HCLGE_DBG_BUF_LEN); memset(printf_buf, 0, HCLGE_DBG_BUF_LEN);
snprintf(printf_buf, HCLGE_DBG_BUF_LEN, snprintf(printf_buf, HCLGE_DBG_BUF_LEN,
"%02u |%02x:%02x:%02x:%02x:%02x:%02x|", "%02u |%02x:%02x:%02x:%02x:%02x:%02x|",
req0->index, req0->mac_add[0], req0->mac_add[1], req0->index, req0->mac_addr[0], req0->mac_addr[1],
req0->mac_add[2], req0->mac_add[3], req0->mac_add[4], req0->mac_addr[2], req0->mac_addr[3],
req0->mac_add[5]); req0->mac_addr[4], req0->mac_addr[5]);
snprintf(printf_buf + strlen(printf_buf), snprintf(printf_buf + strlen(printf_buf),
HCLGE_DBG_BUF_LEN - strlen(printf_buf), HCLGE_DBG_BUF_LEN - strlen(printf_buf),
......
...@@ -652,16 +652,11 @@ static void hclge_log_error(struct device *dev, char *reg, ...@@ -652,16 +652,11 @@ static void hclge_log_error(struct device *dev, char *reg,
* @desc: descriptor for describing the command * @desc: descriptor for describing the command
* @cmd: command opcode * @cmd: command opcode
* @flag: flag for extended command structure * @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 * This function query the error info from hw register/s using command
*/ */
static int hclge_cmd_query_error(struct hclge_dev *hdev, static int hclge_cmd_query_error(struct hclge_dev *hdev,
struct hclge_desc *desc, u32 cmd, struct hclge_desc *desc, u32 cmd, u16 flag)
u16 flag, u8 w_num,
enum hclge_err_int_type int_type)
{ {
struct device *dev = &hdev->pdev->dev; struct device *dev = &hdev->pdev->dev;
int desc_num = 1; int desc_num = 1;
...@@ -673,8 +668,6 @@ static int hclge_cmd_query_error(struct hclge_dev *hdev, ...@@ -673,8 +668,6 @@ static int hclge_cmd_query_error(struct hclge_dev *hdev,
hclge_cmd_setup_basic_desc(&desc[1], cmd, true); hclge_cmd_setup_basic_desc(&desc[1], cmd, true);
desc_num = 2; 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); ret = hclge_cmd_send(&hdev->hw, &desc[0], desc_num);
if (ret) if (ret)
...@@ -872,8 +865,7 @@ static int hclge_config_tm_hw_err_int(struct hclge_dev *hdev, bool en) ...@@ -872,8 +865,7 @@ static int hclge_config_tm_hw_err_int(struct hclge_dev *hdev, bool en)
} }
/* configure TM QCN hw errors */ /* configure TM QCN hw errors */
ret = hclge_cmd_query_error(hdev, &desc, HCLGE_TM_QCN_MEM_INT_CFG, ret = hclge_cmd_query_error(hdev, &desc, HCLGE_TM_QCN_MEM_INT_CFG, 0);
0, 0, 0);
if (ret) { if (ret) {
dev_err(dev, "fail(%d) to read TM QCN CFG status\n", ret); dev_err(dev, "fail(%d) to read TM QCN CFG status\n", ret);
return ret; return ret;
...@@ -1410,7 +1402,7 @@ static int hclge_log_rocee_ecc_error(struct hclge_dev *hdev) ...@@ -1410,7 +1402,7 @@ static int hclge_log_rocee_ecc_error(struct hclge_dev *hdev)
ret = hclge_cmd_query_error(hdev, &desc[0], ret = hclge_cmd_query_error(hdev, &desc[0],
HCLGE_QUERY_ROCEE_ECC_RAS_INFO_CMD, HCLGE_QUERY_ROCEE_ECC_RAS_INFO_CMD,
HCLGE_CMD_FLAG_NEXT, 0, 0); HCLGE_CMD_FLAG_NEXT);
if (ret) { if (ret) {
dev_err(dev, "failed(%d) to query ROCEE ECC error sts\n", ret); dev_err(dev, "failed(%d) to query ROCEE ECC error sts\n", ret);
return ret; return ret;
...@@ -1434,7 +1426,7 @@ static int hclge_log_rocee_ovf_error(struct hclge_dev *hdev) ...@@ -1434,7 +1426,7 @@ static int hclge_log_rocee_ovf_error(struct hclge_dev *hdev)
/* read overflow error status */ /* read overflow error status */
ret = hclge_cmd_query_error(hdev, &desc[0], HCLGE_ROCEE_PF_RAS_INT_CMD, ret = hclge_cmd_query_error(hdev, &desc[0], HCLGE_ROCEE_PF_RAS_INT_CMD,
0, 0, 0); 0);
if (ret) { if (ret) {
dev_err(dev, "failed(%d) to query ROCEE OVF error sts\n", ret); dev_err(dev, "failed(%d) to query ROCEE OVF error sts\n", ret);
return ret; return ret;
...@@ -1483,8 +1475,7 @@ hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev) ...@@ -1483,8 +1475,7 @@ hclge_log_and_clear_rocee_ras_error(struct hclge_dev *hdev)
/* read RAS error interrupt status */ /* read RAS error interrupt status */
ret = hclge_cmd_query_error(hdev, &desc[0], ret = hclge_cmd_query_error(hdev, &desc[0],
HCLGE_QUERY_CLEAR_ROCEE_RAS_INT, HCLGE_QUERY_CLEAR_ROCEE_RAS_INT, 0);
0, 0, 0);
if (ret) { if (ret) {
dev_err(dev, "failed(%d) to query ROCEE RAS INT SRC\n", ret); dev_err(dev, "failed(%d) to query ROCEE RAS INT SRC\n", ret);
/* reset everything for now */ /* reset everything for now */
......
...@@ -2517,7 +2517,7 @@ static void hclge_reset_task_schedule(struct hclge_dev *hdev) ...@@ -2517,7 +2517,7 @@ static void hclge_reset_task_schedule(struct hclge_dev *hdev)
&hdev->rst_service_task); &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) && if (!test_bit(HCLGE_STATE_DOWN, &hdev->state) &&
!test_bit(HCLGE_STATE_REMOVING, &hdev->state) && !test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
...@@ -2526,7 +2526,7 @@ static void hclge_task_schedule(struct hclge_dev *hdev) ...@@ -2526,7 +2526,7 @@ static void hclge_task_schedule(struct hclge_dev *hdev)
hdev->fd_arfs_expire_timer++; hdev->fd_arfs_expire_timer++;
mod_delayed_work_on(cpumask_first(&hdev->affinity_mask), mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
system_wq, &hdev->service_task, 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) ...@@ -2876,10 +2876,15 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
break; 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 || if (!clearval ||
event_cause == HCLGE_VECTOR0_EVENT_MBX) { event_cause == HCLGE_VECTOR0_EVENT_MBX) {
hclge_clear_event_cause(hdev, event_cause, clearval);
hclge_enable_vector(&hdev->misc_vector, true); hclge_enable_vector(&hdev->misc_vector, true);
} }
...@@ -3253,7 +3258,13 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev) ...@@ -3253,7 +3258,13 @@ static void hclge_clear_reset_cause(struct hclge_dev *hdev)
if (!clearval) if (!clearval)
return; 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); hclge_enable_vector(&hdev->misc_vector, true);
} }
...@@ -3274,6 +3285,19 @@ static int hclge_reset_prepare_down(struct hclge_dev *hdev) ...@@ -3274,6 +3285,19 @@ static int hclge_reset_prepare_down(struct hclge_dev *hdev)
return ret; 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) static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
{ {
#define HCLGE_RESET_SYNC_TIME 100 #define HCLGE_RESET_SYNC_TIME 100
...@@ -3322,8 +3346,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev) ...@@ -3322,8 +3346,7 @@ static int hclge_reset_prepare_wait(struct hclge_dev *hdev)
/* inform hardware that preparatory work is done */ /* inform hardware that preparatory work is done */
msleep(HCLGE_RESET_SYNC_TIME); msleep(HCLGE_RESET_SYNC_TIME);
hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, hclge_reset_handshake(hdev, true);
HCLGE_NIC_CMQ_ENABLE);
dev_info(&hdev->pdev->dev, "prepare wait ok\n"); dev_info(&hdev->pdev->dev, "prepare wait ok\n");
return ret; return ret;
...@@ -3354,10 +3377,26 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) ...@@ -3354,10 +3377,26 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
} }
hclge_clear_reset_cause(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"); dev_err(&hdev->pdev->dev, "Reset fail!\n");
return false; 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) static int hclge_reset_prepare_up(struct hclge_dev *hdev)
{ {
int ret = 0; int ret = 0;
...@@ -3368,10 +3407,18 @@ static int hclge_reset_prepare_up(struct hclge_dev *hdev) ...@@ -3368,10 +3407,18 @@ static int hclge_reset_prepare_up(struct hclge_dev *hdev)
case HNAE3_FLR_RESET: case HNAE3_FLR_RESET:
ret = hclge_set_all_vf_rst(hdev, false); ret = hclge_set_all_vf_rst(hdev, false);
break; break;
case HNAE3_GLOBAL_RESET:
/* fall through */
case HNAE3_IMP_RESET:
ret = hclge_set_rst_done(hdev);
break;
default: default:
break; break;
} }
/* clear up the handshake status after re-initialize done */
hclge_reset_handshake(hdev, false);
return ret; return ret;
} }
...@@ -3470,7 +3517,15 @@ static void hclge_reset(struct hclge_dev *hdev) ...@@ -3470,7 +3517,15 @@ static void hclge_reset(struct hclge_dev *hdev)
hdev->reset_fail_cnt = 0; hdev->reset_fail_cnt = 0;
hdev->rst_stats.reset_done_cnt++; hdev->rst_stats.reset_done_cnt++;
ae_dev->reset_type = HNAE3_NONE_RESET; 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; return;
...@@ -3505,9 +3560,10 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) ...@@ -3505,9 +3560,10 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
handle = &hdev->vport[0].nic; handle = &hdev->vport[0].nic;
if (time_before(jiffies, (hdev->last_reset_time + if (time_before(jiffies, (hdev->last_reset_time +
HCLGE_RESET_INTERVAL))) HCLGE_RESET_INTERVAL))) {
mod_timer(&hdev->reset_timer, jiffies + HCLGE_RESET_INTERVAL);
return; return;
else if (hdev->default_reset_request) } else if (hdev->default_reset_request)
hdev->reset_level = hdev->reset_level =
hclge_get_reset_level(ae_dev, hclge_get_reset_level(ae_dev,
&hdev->default_reset_request); &hdev->default_reset_request);
...@@ -3537,6 +3593,12 @@ static void hclge_reset_timer(struct timer_list *t) ...@@ -3537,6 +3593,12 @@ static void hclge_reset_timer(struct timer_list *t)
{ {
struct hclge_dev *hdev = from_timer(hdev, t, reset_timer); 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, dev_info(&hdev->pdev->dev,
"triggering reset in reset timer\n"); "triggering reset in reset timer\n");
hclge_reset_event(hdev->pdev, NULL); hclge_reset_event(hdev->pdev, NULL);
...@@ -3636,7 +3698,7 @@ static void hclge_service_task(struct work_struct *work) ...@@ -3636,7 +3698,7 @@ static void hclge_service_task(struct work_struct *work)
hdev->fd_arfs_expire_timer = 0; 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) 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) ...@@ -6175,7 +6237,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
if (enable) { if (enable) {
hclge_task_schedule(hdev); hclge_task_schedule(hdev, round_jiffies_relative(HZ));
} else { } else {
/* Set the DOWN flag here to disable the service to be /* Set the DOWN flag here to disable the service to be
* scheduled again * scheduled again
...@@ -6220,6 +6282,7 @@ static void hclge_ae_stop(struct hnae3_handle *handle) ...@@ -6220,6 +6282,7 @@ static void hclge_ae_stop(struct hnae3_handle *handle)
if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) && if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) &&
hdev->reset_type != HNAE3_FUNC_RESET) { hdev->reset_type != HNAE3_FUNC_RESET) {
hclge_mac_stop_phy(hdev); hclge_mac_stop_phy(hdev);
hclge_update_link_status(hdev);
return; return;
} }
...@@ -6267,7 +6330,6 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, ...@@ -6267,7 +6330,6 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
enum hclge_mac_vlan_tbl_opcode op) enum hclge_mac_vlan_tbl_opcode op)
{ {
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
int return_status = -EIO;
if (cmdq_resp) { if (cmdq_resp) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
...@@ -6278,52 +6340,53 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport, ...@@ -6278,52 +6340,53 @@ static int hclge_get_mac_vlan_cmd_status(struct hclge_vport *vport,
if (op == HCLGE_MAC_VLAN_ADD) { if (op == HCLGE_MAC_VLAN_ADD) {
if ((!resp_code) || (resp_code == 1)) { if ((!resp_code) || (resp_code == 1)) {
return_status = 0; return 0;
} else if (resp_code == HCLGE_ADD_UC_OVERFLOW) { } else if (resp_code == HCLGE_ADD_UC_OVERFLOW) {
return_status = -ENOSPC;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"add mac addr failed for uc_overflow.\n"); "add mac addr failed for uc_overflow.\n");
return -ENOSPC;
} else if (resp_code == HCLGE_ADD_MC_OVERFLOW) { } else if (resp_code == HCLGE_ADD_MC_OVERFLOW) {
return_status = -ENOSPC;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"add mac addr failed for mc_overflow.\n"); "add mac addr failed for mc_overflow.\n");
} else { return -ENOSPC;
dev_err(&hdev->pdev->dev,
"add mac addr failed for undefined, code=%d.\n",
resp_code);
} }
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) { } else if (op == HCLGE_MAC_VLAN_REMOVE) {
if (!resp_code) { if (!resp_code) {
return_status = 0; return 0;
} else if (resp_code == 1) { } else if (resp_code == 1) {
return_status = -ENOENT;
dev_dbg(&hdev->pdev->dev, dev_dbg(&hdev->pdev->dev,
"remove mac addr failed for miss.\n"); "remove mac addr failed for miss.\n");
} else { return -ENOENT;
dev_err(&hdev->pdev->dev,
"remove mac addr failed for undefined, code=%d.\n",
resp_code);
} }
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) { } else if (op == HCLGE_MAC_VLAN_LKUP) {
if (!resp_code) { if (!resp_code) {
return_status = 0; return 0;
} else if (resp_code == 1) { } else if (resp_code == 1) {
return_status = -ENOENT;
dev_dbg(&hdev->pdev->dev, dev_dbg(&hdev->pdev->dev,
"lookup mac addr failed for miss.\n"); "lookup mac addr failed for miss.\n");
} else { return -ENOENT;
dev_err(&hdev->pdev->dev,
"lookup mac addr failed for undefined, code=%d.\n",
resp_code);
} }
} else {
return_status = -EINVAL;
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"unknown opcode for get_mac_vlan_cmd_status,opcode=%d.\n", "lookup mac addr failed for undefined, code=%u.\n",
op); 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) static int hclge_update_desc_vfid(struct hclge_desc *desc, int vfid, bool clr)
......
...@@ -302,6 +302,13 @@ enum hclge_fc_mode { ...@@ -302,6 +302,13 @@ enum hclge_fc_mode {
HCLGE_FC_DEFAULT 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_PG_NUM 4
#define HCLGE_SCH_MODE_SP 0 #define HCLGE_SCH_MODE_SP 0
#define HCLGE_SCH_MODE_DWRR 1 #define HCLGE_SCH_MODE_DWRR 1
...@@ -1021,4 +1028,5 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, ...@@ -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, int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
u16 state, u16 vlan_tag, u16 qos, u16 state, u16 vlan_tag, u16 qos,
u16 vlan_proto); u16 vlan_proto);
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
#endif #endif
...@@ -545,6 +545,36 @@ static int hclge_get_rss_key(struct hclge_vport *vport, ...@@ -545,6 +545,36 @@ static int hclge_get_rss_key(struct hclge_vport *vport,
HCLGE_RSS_MBX_RESP_LEN); 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) static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
{ {
u32 tail = hclge_read_dev(hw, HCLGE_NIC_CRQ_TAIL_REG); 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) ...@@ -552,6 +582,15 @@ static bool hclge_cmd_crq_empty(struct hclge_hw *hw)
return tail == hw->cmq.crq.next_to_use; 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) void hclge_mbx_handler(struct hclge_dev *hdev)
{ {
struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq; struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq;
...@@ -707,6 +746,12 @@ void hclge_mbx_handler(struct hclge_dev *hdev) ...@@ -707,6 +746,12 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
"PF fail(%d) to media type for VF\n", "PF fail(%d) to media type for VF\n",
ret); ret);
break; 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: default:
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"un-supported mailbox message, code = %d\n", "un-supported mailbox message, code = %d\n",
......
...@@ -650,12 +650,8 @@ static void hclge_pfc_info_init(struct hclge_dev *hdev) ...@@ -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_pg_info_init(hdev);
hclge_tm_tc_info_init(hdev); hclge_tm_tc_info_init(hdev);
...@@ -663,8 +659,6 @@ static int hclge_tm_schd_info_init(struct hclge_dev *hdev) ...@@ -663,8 +659,6 @@ static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
hclge_tm_vport_info_update(hdev); hclge_tm_vport_info_update(hdev);
hclge_pfc_info_init(hdev); hclge_pfc_info_init(hdev);
return 0;
} }
static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev) 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) ...@@ -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 hclge_tm_schd_init(struct hclge_dev *hdev)
{ {
int ret;
/* fc_mode is HCLGE_FC_FULL on reset */ /* fc_mode is HCLGE_FC_FULL on reset */
hdev->tm_info.fc_mode = HCLGE_FC_FULL; hdev->tm_info.fc_mode = HCLGE_FC_FULL;
hdev->fc_mode_last_time = hdev->tm_info.fc_mode; hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
ret = hclge_tm_schd_info_init(hdev); if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE &&
if (ret) hdev->tm_info.num_pg != 1)
return ret; return -EINVAL;
hclge_tm_schd_info_init(hdev);
return hclge_tm_init_hw(hdev, true); return hclge_tm_init_hw(hdev, true);
} }
......
...@@ -97,7 +97,9 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring) ...@@ -97,7 +97,9 @@ static void hclgevf_cmd_config_regs(struct hclgevf_cmq_ring *ring)
reg_val = (u32)((ring->desc_dma_addr >> 31) >> 1); reg_val = (u32)((ring->desc_dma_addr >> 31) >> 1);
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_H_REG, reg_val); 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_DEPTH_REG, reg_val);
hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0);
......
...@@ -244,8 +244,11 @@ struct hclgevf_cfg_tx_queue_pointer_cmd { ...@@ -244,8 +244,11 @@ struct hclgevf_cfg_tx_queue_pointer_cmd {
#define HCLGEVF_NIC_CRQ_DEPTH_REG 0x27020 #define HCLGEVF_NIC_CRQ_DEPTH_REG 0x27020
#define HCLGEVF_NIC_CRQ_TAIL_REG 0x27024 #define HCLGEVF_NIC_CRQ_TAIL_REG 0x27024
#define HCLGEVF_NIC_CRQ_HEAD_REG 0x27028 #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 1024
#define HCLGEVF_NIC_CMQ_DESC_NUM_S 3 #define HCLGEVF_NIC_CMQ_DESC_NUM_S 3
#define HCLGEVF_NIC_CMDQ_INT_SRC_REG 0x27100 #define HCLGEVF_NIC_CMDQ_INT_SRC_REG 0x27100
......
...@@ -1396,19 +1396,22 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev) ...@@ -1396,19 +1396,22 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
u32 val; u32 val;
int ret; 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) if (hdev->reset_type == HNAE3_FLR_RESET)
return hclgevf_flr_poll_timeout(hdev, return hclgevf_flr_poll_timeout(hdev,
HCLGEVF_RESET_WAIT_US, HCLGEVF_RESET_WAIT_US,
HCLGEVF_RESET_WAIT_CNT); HCLGEVF_RESET_WAIT_CNT);
else if (hdev->reset_type == HNAE3_VF_RESET)
ret = readl_poll_timeout(hdev->hw.io_base + HCLGEVF_RST_ING, val, ret = readl_poll_timeout(hdev->hw.io_base +
!(val & HCLGEVF_RST_ING_BITS), HCLGEVF_VF_RST_ING, val,
HCLGEVF_RESET_WAIT_US, !(val & HCLGEVF_VF_RST_ING_BIT),
HCLGEVF_RESET_WAIT_TIMEOUT_US); 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 */ /* hardware completion status should be available by this time */
if (ret) { if (ret) {
...@@ -1426,6 +1429,20 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev) ...@@ -1426,6 +1429,20 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
return 0; 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) static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
{ {
int ret; int ret;
...@@ -1448,7 +1465,14 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev) ...@@ -1448,7 +1465,14 @@ static int hclgevf_reset_stack(struct hclgevf_dev *hdev)
if (ret) if (ret)
return 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) static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
...@@ -1474,8 +1498,7 @@ 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); set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
/* inform hardware that preparatory work is done */ /* inform hardware that preparatory work is done */
msleep(HCLGEVF_RESET_SYNC_TIME); msleep(HCLGEVF_RESET_SYNC_TIME);
hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CSQ_DEPTH_REG, hclgevf_reset_handshake(hdev, true);
HCLGEVF_NIC_CMQ_ENABLE);
dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n", dev_info(&hdev->pdev->dev, "prepare reset(%d) wait done, ret:%d\n",
hdev->reset_type, ret); hdev->reset_type, ret);
...@@ -1484,6 +1507,8 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) ...@@ -1484,6 +1507,8 @@ static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev)
static void hclgevf_reset_err_handle(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++; hdev->rst_stats.rst_fail_cnt++;
dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n", dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n",
hdev->rst_stats.rst_fail_cnt); hdev->rst_stats.rst_fail_cnt);
...@@ -1494,9 +1519,6 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) ...@@ -1494,9 +1519,6 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
if (hclgevf_is_reset_pending(hdev)) { if (hclgevf_is_reset_pending(hdev)) {
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
hclgevf_reset_task_schedule(hdev); 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) ...@@ -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, static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
u32 *clearval) u32 *clearval)
{ {
u32 cmdq_src_reg, rst_ing_reg; u32 val, cmdq_src_reg, rst_ing_reg;
/* fetch the events from their corresponding regs */ /* fetch the events from their corresponding regs */
cmdq_src_reg = hclgevf_read_dev(&hdev->hw, 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, ...@@ -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); cmdq_src_reg &= ~BIT(HCLGEVF_VECTOR0_RST_INT_B);
*clearval = cmdq_src_reg; *clearval = cmdq_src_reg;
hdev->rst_stats.vf_rst_cnt++; 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; return HCLGEVF_VECTOR0_EVENT_RST;
} }
......
...@@ -103,6 +103,9 @@ ...@@ -103,6 +103,9 @@
(HCLGEVF_FUN_RST_ING_BIT | HCLGEVF_GLOBAL_RST_ING_BIT | \ (HCLGEVF_FUN_RST_ING_BIT | HCLGEVF_GLOBAL_RST_ING_BIT | \
HCLGEVF_CORE_RST_ING_BIT | HCLGEVF_IMP_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_IND_TBL_SIZE 512
#define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff #define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff
#define HCLGEVF_RSS_KEY_SIZE 40 #define HCLGEVF_RSS_KEY_SIZE 40
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment