Merge branch 'hinic-BugFixes'
Luo bin says: ==================== hinic: BugFixes Fix a number of bugs which have been present since the first commit. The bugs fixed in these patchs are hardly exposed unless given very specific conditions. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4abe5a1b96
|
@ -389,7 +389,8 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,
|
|||
|
||||
spin_unlock_bh(&cmdq->cmdq_lock);
|
||||
|
||||
if (!wait_for_completion_timeout(&done, CMDQ_TIMEOUT)) {
|
||||
if (!wait_for_completion_timeout(&done,
|
||||
msecs_to_jiffies(CMDQ_TIMEOUT))) {
|
||||
spin_lock_bh(&cmdq->cmdq_lock);
|
||||
|
||||
if (cmdq->errcode[curr_prod_idx] == &errcode)
|
||||
|
@ -623,6 +624,8 @@ static int cmdq_cmd_ceq_handler(struct hinic_cmdq *cmdq, u16 ci,
|
|||
if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info)))
|
||||
return -EBUSY;
|
||||
|
||||
dma_rmb();
|
||||
|
||||
errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL);
|
||||
|
||||
cmdq_sync_cmd_handler(cmdq, ci, errcode);
|
||||
|
|
|
@ -360,50 +360,6 @@ static int wait_for_db_state(struct hinic_hwdev *hwdev)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
static int wait_for_io_stopped(struct hinic_hwdev *hwdev)
|
||||
{
|
||||
struct hinic_cmd_io_status cmd_io_status;
|
||||
struct hinic_hwif *hwif = hwdev->hwif;
|
||||
struct pci_dev *pdev = hwif->pdev;
|
||||
struct hinic_pfhwdev *pfhwdev;
|
||||
unsigned long end;
|
||||
u16 out_size;
|
||||
int err;
|
||||
|
||||
if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
|
||||
dev_err(&pdev->dev, "Unsupported PCI Function type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
|
||||
|
||||
cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
|
||||
|
||||
end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT);
|
||||
do {
|
||||
err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
|
||||
HINIC_COMM_CMD_IO_STATUS_GET,
|
||||
&cmd_io_status, sizeof(cmd_io_status),
|
||||
&cmd_io_status, &out_size,
|
||||
HINIC_MGMT_MSG_SYNC);
|
||||
if ((err) || (out_size != sizeof(cmd_io_status))) {
|
||||
dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (cmd_io_status.status == IO_STOPPED) {
|
||||
dev_info(&pdev->dev, "IO stopped\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
msleep(20);
|
||||
} while (time_before(jiffies, end));
|
||||
|
||||
dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* clear_io_resource - set the IO resources as not active in the NIC
|
||||
* @hwdev: the NIC HW device
|
||||
|
@ -423,11 +379,8 @@ static int clear_io_resources(struct hinic_hwdev *hwdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = wait_for_io_stopped(hwdev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "IO has not stopped yet\n");
|
||||
return err;
|
||||
}
|
||||
/* sleep 100ms to wait for firmware stopping I/O */
|
||||
msleep(100);
|
||||
|
||||
cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ static u8 eq_cons_idx_checksum_set(u32 val)
|
|||
* eq_update_ci - update the HW cons idx of event queue
|
||||
* @eq: the event queue to update the cons idx for
|
||||
**/
|
||||
static void eq_update_ci(struct hinic_eq *eq)
|
||||
static void eq_update_ci(struct hinic_eq *eq, u32 arm_state)
|
||||
{
|
||||
u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq);
|
||||
|
||||
|
@ -202,7 +202,7 @@ static void eq_update_ci(struct hinic_eq *eq)
|
|||
|
||||
val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) |
|
||||
HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) |
|
||||
HINIC_EQ_CI_SET(EQ_ARMED, INT_ARMED);
|
||||
HINIC_EQ_CI_SET(arm_state, INT_ARMED);
|
||||
|
||||
val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM);
|
||||
|
||||
|
@ -235,6 +235,8 @@ static void aeq_irq_handler(struct hinic_eq *eq)
|
|||
if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped)
|
||||
break;
|
||||
|
||||
dma_rmb();
|
||||
|
||||
event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
|
||||
if (event >= HINIC_MAX_AEQ_EVENTS) {
|
||||
dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event);
|
||||
|
@ -347,7 +349,7 @@ static void eq_irq_handler(void *data)
|
|||
else if (eq->type == HINIC_CEQ)
|
||||
ceq_irq_handler(eq);
|
||||
|
||||
eq_update_ci(eq);
|
||||
eq_update_ci(eq, EQ_ARMED);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -702,7 +704,7 @@ static int init_eq(struct hinic_eq *eq, struct hinic_hwif *hwif,
|
|||
}
|
||||
|
||||
set_eq_ctrls(eq);
|
||||
eq_update_ci(eq);
|
||||
eq_update_ci(eq, EQ_ARMED);
|
||||
|
||||
err = alloc_eq_pages(eq);
|
||||
if (err) {
|
||||
|
@ -752,18 +754,28 @@ err_req_irq:
|
|||
**/
|
||||
static void remove_eq(struct hinic_eq *eq)
|
||||
{
|
||||
struct msix_entry *entry = &eq->msix_entry;
|
||||
|
||||
free_irq(entry->vector, eq);
|
||||
hinic_set_msix_state(eq->hwif, eq->msix_entry.entry,
|
||||
HINIC_MSIX_DISABLE);
|
||||
free_irq(eq->msix_entry.vector, eq);
|
||||
|
||||
if (eq->type == HINIC_AEQ) {
|
||||
struct hinic_eq_work *aeq_work = &eq->aeq_work;
|
||||
|
||||
cancel_work_sync(&aeq_work->work);
|
||||
/* clear aeq_len to avoid hw access host memory */
|
||||
hinic_hwif_write_reg(eq->hwif,
|
||||
HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id), 0);
|
||||
} else if (eq->type == HINIC_CEQ) {
|
||||
tasklet_kill(&eq->ceq_tasklet);
|
||||
/* clear ceq_len to avoid hw access host memory */
|
||||
hinic_hwif_write_reg(eq->hwif,
|
||||
HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id), 0);
|
||||
}
|
||||
|
||||
/* update cons_idx to avoid invalid interrupt */
|
||||
eq->cons_idx = hinic_hwif_read_reg(eq->hwif, EQ_PROD_IDX_REG_ADDR(eq));
|
||||
eq_update_ci(eq, EQ_NOT_ARMED);
|
||||
|
||||
free_eq_pages(eq);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
#define MSG_NOT_RESP 0xFFFF
|
||||
|
||||
#define MGMT_MSG_TIMEOUT 1000
|
||||
#define MGMT_MSG_TIMEOUT 5000
|
||||
|
||||
#define mgmt_to_pfhwdev(pf_mgmt) \
|
||||
container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt)
|
||||
|
@ -267,7 +267,8 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt,
|
|||
goto unlock_sync_msg;
|
||||
}
|
||||
|
||||
if (!wait_for_completion_timeout(recv_done, MGMT_MSG_TIMEOUT)) {
|
||||
if (!wait_for_completion_timeout(recv_done,
|
||||
msecs_to_jiffies(MGMT_MSG_TIMEOUT))) {
|
||||
dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
|
||||
err = -ETIMEDOUT;
|
||||
goto unlock_sync_msg;
|
||||
|
|
|
@ -350,6 +350,9 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
|
|||
if (!rq_wqe)
|
||||
break;
|
||||
|
||||
/* make sure we read rx_done before packet length */
|
||||
dma_rmb();
|
||||
|
||||
cqe = rq->cqe[ci];
|
||||
status = be32_to_cpu(cqe->status);
|
||||
hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge);
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#define HW_CONS_IDX(sq) be16_to_cpu(*(u16 *)((sq)->hw_ci_addr))
|
||||
|
||||
#define MIN_SKB_LEN 17
|
||||
#define MIN_SKB_LEN 32
|
||||
|
||||
#define MAX_PAYLOAD_OFFSET 221
|
||||
#define TRANSPORT_OFFSET(l4_hdr, skb) ((u32)((l4_hdr) - (skb)->data))
|
||||
|
@ -622,6 +622,8 @@ static int free_tx_poll(struct napi_struct *napi, int budget)
|
|||
do {
|
||||
hw_ci = HW_CONS_IDX(sq) & wq->mask;
|
||||
|
||||
dma_rmb();
|
||||
|
||||
/* Reading a WQEBB to get real WQE size and consumer index. */
|
||||
sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci);
|
||||
if ((!sq_wqe) ||
|
||||
|
|
Loading…
Reference in New Issue