Skip to content

Commit 4abe5a1

Browse files
committed
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 <[email protected]>
2 parents 07f8e4d + 7296695 commit 4abe5a1

File tree

6 files changed

+34
-60
lines changed

6 files changed

+34
-60
lines changed

drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,
389389

390390
spin_unlock_bh(&cmdq->cmdq_lock);
391391

392-
if (!wait_for_completion_timeout(&done, CMDQ_TIMEOUT)) {
392+
if (!wait_for_completion_timeout(&done,
393+
msecs_to_jiffies(CMDQ_TIMEOUT))) {
393394
spin_lock_bh(&cmdq->cmdq_lock);
394395

395396
if (cmdq->errcode[curr_prod_idx] == &errcode)
@@ -623,6 +624,8 @@ static int cmdq_cmd_ceq_handler(struct hinic_cmdq *cmdq, u16 ci,
623624
if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info)))
624625
return -EBUSY;
625626

627+
dma_rmb();
628+
626629
errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL);
627630

628631
cmdq_sync_cmd_handler(cmdq, ci, errcode);

drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -360,50 +360,6 @@ static int wait_for_db_state(struct hinic_hwdev *hwdev)
360360
return -EFAULT;
361361
}
362362

363-
static int wait_for_io_stopped(struct hinic_hwdev *hwdev)
364-
{
365-
struct hinic_cmd_io_status cmd_io_status;
366-
struct hinic_hwif *hwif = hwdev->hwif;
367-
struct pci_dev *pdev = hwif->pdev;
368-
struct hinic_pfhwdev *pfhwdev;
369-
unsigned long end;
370-
u16 out_size;
371-
int err;
372-
373-
if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
374-
dev_err(&pdev->dev, "Unsupported PCI Function type\n");
375-
return -EINVAL;
376-
}
377-
378-
pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
379-
380-
cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
381-
382-
end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT);
383-
do {
384-
err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
385-
HINIC_COMM_CMD_IO_STATUS_GET,
386-
&cmd_io_status, sizeof(cmd_io_status),
387-
&cmd_io_status, &out_size,
388-
HINIC_MGMT_MSG_SYNC);
389-
if ((err) || (out_size != sizeof(cmd_io_status))) {
390-
dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n",
391-
err);
392-
return err;
393-
}
394-
395-
if (cmd_io_status.status == IO_STOPPED) {
396-
dev_info(&pdev->dev, "IO stopped\n");
397-
return 0;
398-
}
399-
400-
msleep(20);
401-
} while (time_before(jiffies, end));
402-
403-
dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n");
404-
return -ETIMEDOUT;
405-
}
406-
407363
/**
408364
* clear_io_resource - set the IO resources as not active in the NIC
409365
* @hwdev: the NIC HW device
@@ -423,11 +379,8 @@ static int clear_io_resources(struct hinic_hwdev *hwdev)
423379
return -EINVAL;
424380
}
425381

426-
err = wait_for_io_stopped(hwdev);
427-
if (err) {
428-
dev_err(&pdev->dev, "IO has not stopped yet\n");
429-
return err;
430-
}
382+
/* sleep 100ms to wait for firmware stopping I/O */
383+
msleep(100);
431384

432385
cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
433386

drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ static u8 eq_cons_idx_checksum_set(u32 val)
188188
* eq_update_ci - update the HW cons idx of event queue
189189
* @eq: the event queue to update the cons idx for
190190
**/
191-
static void eq_update_ci(struct hinic_eq *eq)
191+
static void eq_update_ci(struct hinic_eq *eq, u32 arm_state)
192192
{
193193
u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq);
194194

@@ -202,7 +202,7 @@ static void eq_update_ci(struct hinic_eq *eq)
202202

203203
val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) |
204204
HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) |
205-
HINIC_EQ_CI_SET(EQ_ARMED, INT_ARMED);
205+
HINIC_EQ_CI_SET(arm_state, INT_ARMED);
206206

207207
val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM);
208208

@@ -235,6 +235,8 @@ static void aeq_irq_handler(struct hinic_eq *eq)
235235
if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped)
236236
break;
237237

238+
dma_rmb();
239+
238240
event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
239241
if (event >= HINIC_MAX_AEQ_EVENTS) {
240242
dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event);
@@ -347,7 +349,7 @@ static void eq_irq_handler(void *data)
347349
else if (eq->type == HINIC_CEQ)
348350
ceq_irq_handler(eq);
349351

350-
eq_update_ci(eq);
352+
eq_update_ci(eq, EQ_ARMED);
351353
}
352354

353355
/**
@@ -702,7 +704,7 @@ static int init_eq(struct hinic_eq *eq, struct hinic_hwif *hwif,
702704
}
703705

704706
set_eq_ctrls(eq);
705-
eq_update_ci(eq);
707+
eq_update_ci(eq, EQ_ARMED);
706708

707709
err = alloc_eq_pages(eq);
708710
if (err) {
@@ -752,18 +754,28 @@ static int init_eq(struct hinic_eq *eq, struct hinic_hwif *hwif,
752754
**/
753755
static void remove_eq(struct hinic_eq *eq)
754756
{
755-
struct msix_entry *entry = &eq->msix_entry;
756-
757-
free_irq(entry->vector, eq);
757+
hinic_set_msix_state(eq->hwif, eq->msix_entry.entry,
758+
HINIC_MSIX_DISABLE);
759+
free_irq(eq->msix_entry.vector, eq);
758760

759761
if (eq->type == HINIC_AEQ) {
760762
struct hinic_eq_work *aeq_work = &eq->aeq_work;
761763

762764
cancel_work_sync(&aeq_work->work);
765+
/* clear aeq_len to avoid hw access host memory */
766+
hinic_hwif_write_reg(eq->hwif,
767+
HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id), 0);
763768
} else if (eq->type == HINIC_CEQ) {
764769
tasklet_kill(&eq->ceq_tasklet);
770+
/* clear ceq_len to avoid hw access host memory */
771+
hinic_hwif_write_reg(eq->hwif,
772+
HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id), 0);
765773
}
766774

775+
/* update cons_idx to avoid invalid interrupt */
776+
eq->cons_idx = hinic_hwif_read_reg(eq->hwif, EQ_PROD_IDX_REG_ADDR(eq));
777+
eq_update_ci(eq, EQ_NOT_ARMED);
778+
767779
free_eq_pages(eq);
768780
}
769781

drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
#define MSG_NOT_RESP 0xFFFF
4545

46-
#define MGMT_MSG_TIMEOUT 1000
46+
#define MGMT_MSG_TIMEOUT 5000
4747

4848
#define mgmt_to_pfhwdev(pf_mgmt) \
4949
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,
267267
goto unlock_sync_msg;
268268
}
269269

270-
if (!wait_for_completion_timeout(recv_done, MGMT_MSG_TIMEOUT)) {
270+
if (!wait_for_completion_timeout(recv_done,
271+
msecs_to_jiffies(MGMT_MSG_TIMEOUT))) {
271272
dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
272273
err = -ETIMEDOUT;
273274
goto unlock_sync_msg;

drivers/net/ethernet/huawei/hinic/hinic_rx.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
350350
if (!rq_wqe)
351351
break;
352352

353+
/* make sure we read rx_done before packet length */
354+
dma_rmb();
355+
353356
cqe = rq->cqe[ci];
354357
status = be32_to_cpu(cqe->status);
355358
hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge);

drivers/net/ethernet/huawei/hinic/hinic_tx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
#define HW_CONS_IDX(sq) be16_to_cpu(*(u16 *)((sq)->hw_ci_addr))
4747

48-
#define MIN_SKB_LEN 17
48+
#define MIN_SKB_LEN 32
4949

5050
#define MAX_PAYLOAD_OFFSET 221
5151
#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)
622622
do {
623623
hw_ci = HW_CONS_IDX(sq) & wq->mask;
624624

625+
dma_rmb();
626+
625627
/* Reading a WQEBB to get real WQE size and consumer index. */
626628
sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci);
627629
if ((!sq_wqe) ||

0 commit comments

Comments
 (0)