summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/microsoft
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/microsoft')
-rw-r--r--drivers/net/ethernet/microsoft/mana/gdma_main.c1
-rw-r--r--drivers/net/ethernet/microsoft/mana/hw_channel.c6
-rw-r--r--drivers/net/ethernet/microsoft/mana/mana_en.c29
3 files changed, 26 insertions, 10 deletions
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index 37d2f108a839..786186c9a115 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -1934,6 +1934,7 @@ remove_irq:
mana_gd_remove_irqs(pdev);
free_workqueue:
destroy_workqueue(gc->service_wq);
+ gc->service_wq = NULL;
dev_err(&pdev->dev, "%s failed (error %d)\n", __func__, err);
return err;
}
diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
index ba3467f1e2ea..48a9acea4ab6 100644
--- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -814,9 +814,6 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
gc->max_num_cqs = 0;
}
- kfree(hwc->caller_ctx);
- hwc->caller_ctx = NULL;
-
if (hwc->txq)
mana_hwc_destroy_wq(hwc, hwc->txq);
@@ -826,6 +823,9 @@ void mana_hwc_destroy_channel(struct gdma_context *gc)
if (hwc->cq)
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
+ kfree(hwc->caller_ctx);
+ hwc->caller_ctx = NULL;
+
mana_gd_free_res_map(&hwc->inflight_msg_res);
hwc->num_inflight_msg = 0;
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 933e9d681ded..dca62fb9a3a9 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -1770,8 +1770,14 @@ static void mana_poll_tx_cq(struct mana_cq *cq)
ndev = txq->ndev;
apc = netdev_priv(ndev);
+ /* Limit CQEs polled to 4 wraparounds of the CQ to ensure the
+ * doorbell can be rung in time for the hardware's requirement
+ * of at least one doorbell ring every 8 wraparounds.
+ */
comp_read = mana_gd_poll_cq(cq->gdma_cq, completions,
- CQE_POLLING_BUFFER);
+ min((cq->gdma_cq->queue_size /
+ COMP_ENTRY_SIZE) * 4,
+ CQE_POLLING_BUFFER));
if (comp_read < 1)
return;
@@ -2156,7 +2162,14 @@ static void mana_poll_rx_cq(struct mana_cq *cq)
struct mana_rxq *rxq = cq->rxq;
int comp_read, i;
- comp_read = mana_gd_poll_cq(cq->gdma_cq, comp, CQE_POLLING_BUFFER);
+ /* Limit CQEs polled to 4 wraparounds of the CQ to ensure the
+ * doorbell can be rung in time for the hardware's requirement
+ * of at least one doorbell ring every 8 wraparounds.
+ */
+ comp_read = mana_gd_poll_cq(cq->gdma_cq, comp,
+ min((cq->gdma_cq->queue_size /
+ COMP_ENTRY_SIZE) * 4,
+ CQE_POLLING_BUFFER));
WARN_ON_ONCE(comp_read > CQE_POLLING_BUFFER);
rxq->xdp_flush = false;
@@ -2201,11 +2214,11 @@ static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
mana_gd_ring_cq(gdma_queue, SET_ARM_BIT);
cq->work_done_since_doorbell = 0;
napi_complete_done(&cq->napi, w);
- } else if (cq->work_done_since_doorbell >
- cq->gdma_cq->queue_size / COMP_ENTRY_SIZE * 4) {
+ } else if (cq->work_done_since_doorbell >=
+ (cq->gdma_cq->queue_size / COMP_ENTRY_SIZE) * 4) {
/* MANA hardware requires at least one doorbell ring every 8
* wraparounds of CQ even if there is no need to arm the CQ.
- * This driver rings the doorbell as soon as we have exceeded
+ * This driver rings the doorbell as soon as it has processed
* 4 wraparounds.
*/
mana_gd_ring_cq(gdma_queue, 0);
@@ -3412,6 +3425,7 @@ static int add_adev(struct gdma_dev *gd, const char *name)
struct auxiliary_device *adev;
struct mana_adev *madev;
int ret;
+ int id;
madev = kzalloc_obj(*madev);
if (!madev)
@@ -3421,7 +3435,8 @@ static int add_adev(struct gdma_dev *gd, const char *name)
ret = mana_adev_idx_alloc();
if (ret < 0)
goto idx_fail;
- adev->id = ret;
+ id = ret;
+ adev->id = id;
adev->name = name;
adev->dev.parent = gd->gdma_context->dev;
@@ -3447,7 +3462,7 @@ add_fail:
auxiliary_device_uninit(adev);
init_fail:
- mana_adev_idx_free(adev->id);
+ mana_adev_idx_free(id);
idx_fail:
kfree(madev);