Skip to content

Commit

Permalink
hinic: add log in exception handling processes
Browse files Browse the repository at this point in the history
improve the error message when functions return failure and dump
relevant registers in some exception handling processes

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Luo bin authored and David S. Miller committed Jul 29, 2020
1 parent c15850c commit 90f86b8
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 45 deletions.
27 changes: 25 additions & 2 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,26 @@ static u32 get_hw_cons_idx(struct hinic_api_cmd_chain *chain)
return HINIC_API_CMD_STATUS_GET(val, CONS_IDX);
}

static void dump_api_chain_reg(struct hinic_api_cmd_chain *chain)
{
u32 addr, val;

addr = HINIC_CSR_API_CMD_STATUS_ADDR(chain->chain_type);
val = hinic_hwif_read_reg(chain->hwif, addr);

dev_err(&chain->hwif->pdev->dev, "Chain type: 0x%x, cpld error: 0x%x, check error: 0x%x, current fsm: 0x%x\n",
chain->chain_type, HINIC_API_CMD_STATUS_GET(val, CPLD_ERR),
HINIC_API_CMD_STATUS_GET(val, CHKSUM_ERR),
HINIC_API_CMD_STATUS_GET(val, FSM));

dev_err(&chain->hwif->pdev->dev, "Chain hw current ci: 0x%x\n",
HINIC_API_CMD_STATUS_GET(val, CONS_IDX));

addr = HINIC_CSR_API_CMD_CHAIN_PI_ADDR(chain->chain_type);
val = hinic_hwif_read_reg(chain->hwif, addr);
dev_err(&chain->hwif->pdev->dev, "Chain hw current pi: 0x%x\n", val);
}

/**
* chain_busy - check if the chain is still processing last requests
* @chain: chain to check
Expand All @@ -131,8 +151,10 @@ static int chain_busy(struct hinic_api_cmd_chain *chain)

/* check for a space for a new command */
if (chain->cons_idx == MASKED_IDX(chain, prod_idx + 1)) {
dev_err(&pdev->dev, "API CMD chain %d is busy\n",
chain->chain_type);
dev_err(&pdev->dev, "API CMD chain %d is busy, cons_idx: %d, prod_idx: %d\n",
chain->chain_type, chain->cons_idx,
chain->prod_idx);
dump_api_chain_reg(chain);
return -EBUSY;
}
break;
Expand Down Expand Up @@ -332,6 +354,7 @@ static int wait_for_api_cmd_completion(struct hinic_api_cmd_chain *chain)
err = wait_for_status_poll(chain);
if (err) {
dev_err(&pdev->dev, "API CMD Poll status timeout\n");
dump_api_chain_reg(chain);
break;
}
break;
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,14 @@
HINIC_API_CMD_STATUS_HEADER_##member##_MASK)

#define HINIC_API_CMD_STATUS_CONS_IDX_SHIFT 0
#define HINIC_API_CMD_STATUS_FSM_SHIFT 24
#define HINIC_API_CMD_STATUS_CHKSUM_ERR_SHIFT 28
#define HINIC_API_CMD_STATUS_CPLD_ERR_SHIFT 30

#define HINIC_API_CMD_STATUS_CONS_IDX_MASK 0xFFFFFF
#define HINIC_API_CMD_STATUS_FSM_MASK 0xFU
#define HINIC_API_CMD_STATUS_CHKSUM_ERR_MASK 0x3
#define HINIC_API_CMD_STATUS_CPLD_ERR_MASK 0x1U

#define HINIC_API_CMD_STATUS_GET(val, member) \
(((val) >> HINIC_API_CMD_STATUS_##member##_SHIFT) & \
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,

spin_unlock_bh(&cmdq->cmdq_lock);

hinic_dump_ceq_info(cmdq->hwdev);
return -ETIMEDOUT;
}

Expand Down Expand Up @@ -807,6 +808,7 @@ static int init_cmdqs_ctxt(struct hinic_hwdev *hwdev,

cmdq_type = HINIC_CMDQ_SYNC;
for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
cmdqs->cmdq[cmdq_type].hwdev = hwdev;
err = init_cmdq(&cmdqs->cmdq[cmdq_type],
&cmdqs->saved_wqs[cmdq_type], cmdq_type,
db_area[cmdq_type]);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ struct hinic_cmdq_ctxt {
};

struct hinic_cmdq {
struct hinic_hwdev *hwdev;

struct hinic_wq *wq;

enum hinic_cmdq_type cmdq_type;
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ static int init_fw_ctxt(struct hinic_hwdev *hwdev)
&fw_ctxt, sizeof(fw_ctxt),
&fw_ctxt, &out_size);
if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) {
dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n",
fw_ctxt.status);
return -EFAULT;
dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n",
err, fw_ctxt.status, out_size);
return -EIO;
}

return 0;
Expand Down Expand Up @@ -425,9 +425,9 @@ static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn)
&cmd_base_qpn, sizeof(cmd_base_qpn),
&cmd_base_qpn, &out_size);
if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) {
dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n",
cmd_base_qpn.status);
return -EFAULT;
dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n",
err, cmd_base_qpn.status, out_size);
return -EIO;
}

*base_qpn = cmd_base_qpn.qpn;
Expand Down
39 changes: 39 additions & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,3 +953,42 @@ void hinic_ceqs_free(struct hinic_ceqs *ceqs)
for (q_id = 0; q_id < ceqs->num_ceqs; q_id++)
remove_eq(&ceqs->ceq[q_id]);
}

void hinic_dump_ceq_info(struct hinic_hwdev *hwdev)
{
struct hinic_eq *eq = NULL;
u32 addr, ci, pi;
int q_id;

for (q_id = 0; q_id < hwdev->func_to_io.ceqs.num_ceqs; q_id++) {
eq = &hwdev->func_to_io.ceqs.ceq[q_id];
addr = EQ_CONS_IDX_REG_ADDR(eq);
ci = hinic_hwif_read_reg(hwdev->hwif, addr);
addr = EQ_PROD_IDX_REG_ADDR(eq);
pi = hinic_hwif_read_reg(hwdev->hwif, addr);
dev_err(&hwdev->hwif->pdev->dev, "Ceq id: %d, ci: 0x%08x, sw_ci: 0x%08x, pi: 0x%x, tasklet_state: 0x%lx, wrap: %d, ceqe: 0x%x\n",
q_id, ci, eq->cons_idx, pi,
eq->ceq_tasklet.state,
eq->wrapped, be32_to_cpu(*(__be32 *)(GET_CURR_CEQ_ELEM(eq))));
}
}

void hinic_dump_aeq_info(struct hinic_hwdev *hwdev)
{
struct hinic_aeq_elem *aeqe_pos = NULL;
struct hinic_eq *eq = NULL;
u32 addr, ci, pi;
int q_id;

for (q_id = 0; q_id < hwdev->aeqs.num_aeqs; q_id++) {
eq = &hwdev->aeqs.aeq[q_id];
addr = EQ_CONS_IDX_REG_ADDR(eq);
ci = hinic_hwif_read_reg(hwdev->hwif, addr);
addr = EQ_PROD_IDX_REG_ADDR(eq);
pi = hinic_hwif_read_reg(hwdev->hwif, addr);
aeqe_pos = GET_CURR_AEQ_ELEM(eq);
dev_err(&hwdev->hwif->pdev->dev, "Aeq id: %d, ci: 0x%08x, pi: 0x%x, work_state: 0x%x, wrap: %d, desc: 0x%x\n",
q_id, ci, pi, work_busy(&eq->aeq_work.work),
eq->wrapped, be32_to_cpu(aeqe_pos->desc));
}
}
6 changes: 5 additions & 1 deletion drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ enum hinic_eqe_state {

struct hinic_aeq_elem {
u8 data[HINIC_AEQE_DATA_SIZE];
u32 desc;
__be32 desc;
};

struct hinic_eq_work {
Expand Down Expand Up @@ -254,4 +254,8 @@ int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,

void hinic_ceqs_free(struct hinic_ceqs *ceqs);

void hinic_dump_ceq_info(struct hinic_hwdev *hwdev);

void hinic_dump_aeq_info(struct hinic_hwdev *hwdev);

#endif
23 changes: 23 additions & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#define WAIT_HWIF_READY_TIMEOUT 10000

#define HINIC_SELFTEST_RESULT 0x883C

/**
* hinic_msix_attr_set - set message attribute for msix entry
* @hwif: the HW interface of a pci function device
Expand Down Expand Up @@ -369,6 +371,26 @@ u16 hinic_pf_id_of_vf_hw(struct hinic_hwif *hwif)
return HINIC_FA0_GET(attr0, PF_IDX);
}

static void __print_selftest_reg(struct hinic_hwif *hwif)
{
u32 addr, attr0, attr1;

addr = HINIC_CSR_FUNC_ATTR1_ADDR;
attr1 = hinic_hwif_read_reg(hwif, addr);

if (attr1 == HINIC_PCIE_LINK_DOWN) {
dev_err(&hwif->pdev->dev, "PCIE is link down\n");
return;
}

addr = HINIC_CSR_FUNC_ATTR0_ADDR;
attr0 = hinic_hwif_read_reg(hwif, addr);
if (HINIC_FA0_GET(attr0, FUNC_TYPE) != HINIC_VF &&
!HINIC_FA0_GET(attr0, PCI_INTF_IDX))
dev_err(&hwif->pdev->dev, "Selftest reg: 0x%08x\n",
hinic_hwif_read_reg(hwif, HINIC_SELFTEST_RESULT));
}

/**
* hinic_init_hwif - initialize the hw interface
* @hwif: the HW interface of a pci function device
Expand Down Expand Up @@ -398,6 +420,7 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
err = wait_hwif_ready(hwif);
if (err) {
dev_err(&pdev->dev, "HW interface is not ready\n");
__print_selftest_reg(hwif);
goto err_hwif_ready;
}

Expand Down
10 changes: 8 additions & 2 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <linux/types.h>
#include <asm/byteorder.h>

#define HINIC_PCIE_LINK_DOWN 0xFFFFFFFF

#define HINIC_DMA_ATTR_ST_SHIFT 0
#define HINIC_DMA_ATTR_AT_SHIFT 8
#define HINIC_DMA_ATTR_PH_SHIFT 10
Expand Down Expand Up @@ -249,13 +251,17 @@ struct hinic_hwif {

static inline u32 hinic_hwif_read_reg(struct hinic_hwif *hwif, u32 reg)
{
return be32_to_cpu(readl(hwif->cfg_regs_bar + reg));
u32 out = readl(hwif->cfg_regs_bar + reg);

return be32_to_cpu(*(__be32 *)&out);
}

static inline void hinic_hwif_write_reg(struct hinic_hwif *hwif, u32 reg,
u32 val)
{
writel(cpu_to_be32(val), hwif->cfg_regs_bar + reg);
__be32 in = cpu_to_be32(val);

writel(*(u32 *)&in, hwif->cfg_regs_bar + reg);
}

int hinic_msix_attr_set(struct hinic_hwif *hwif, u16 msix_index,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ wait_for_mbox_seg_completion(struct hinic_mbox_func_to_func *func_to_func,
if (!wait_for_completion_timeout(done, jif)) {
dev_err(&hwdev->hwif->pdev->dev, "Send mailbox segment timeout\n");
dump_mox_reg(hwdev);
hinic_dump_aeq_info(hwdev);
return -ETIMEDOUT;
}

Expand Down Expand Up @@ -897,6 +898,7 @@ int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
dev_err(&func_to_func->hwif->pdev->dev,
"Send mbox msg timeout, msg_id: %d\n", msg_info.msg_id);
hinic_dump_aeq_info(func_to_func->hwdev);
err = -ETIMEDOUT;
goto err_send_mbox;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt,

if (!wait_for_completion_timeout(recv_done, timeo)) {
dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
hinic_dump_aeq_info(pf_to_mgmt->hwdev);
err = -ETIMEDOUT;
goto unlock_sync_msg;
}
Expand Down
Loading

0 comments on commit 90f86b8

Please sign in to comment.