Skip to content

Commit c3b744f

Browse files
RajuRangojukuba-moo
authored andcommitted
amd-xgbe: refactor the dma IRQ handling code path
Refactor the DMA interrupt bottom-half handling to improve the readability, maintainability, without changing the intended behavior. Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com> Link: https://patch.msgid.link/20251129175016.3034185-2-Raju.Rangoju@amd.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent aee0f01 commit c3b744f

1 file changed

Lines changed: 40 additions & 20 deletions

File tree

drivers/net/ethernet/amd/xgbe/xgbe-drv.c

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,11 @@ static irqreturn_t xgbe_ecc_isr(int irq, void *data)
367367
static void xgbe_isr_bh_work(struct work_struct *work)
368368
{
369369
struct xgbe_prv_data *pdata = from_work(pdata, work, dev_bh_work);
370+
unsigned int mac_isr, mac_tssr, mac_mdioisr;
370371
struct xgbe_hw_if *hw_if = &pdata->hw_if;
371-
struct xgbe_channel *channel;
372+
bool per_ch_irq, ti, ri, rbu, fbe;
372373
unsigned int dma_isr, dma_ch_isr;
373-
unsigned int mac_isr, mac_tssr, mac_mdioisr;
374+
struct xgbe_channel *channel;
374375
unsigned int i;
375376

376377
/* The DMA interrupt status register also reports MAC and MTL
@@ -384,43 +385,62 @@ static void xgbe_isr_bh_work(struct work_struct *work)
384385
netif_dbg(pdata, intr, pdata->netdev, "DMA_ISR=%#010x\n", dma_isr);
385386

386387
for (i = 0; i < pdata->channel_count; i++) {
388+
bool schedule_napi = false;
389+
struct napi_struct *napi;
390+
387391
if (!(dma_isr & (1 << i)))
388392
continue;
389393

390394
channel = pdata->channel[i];
391395

392396
dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
397+
398+
/* Precompute flags once */
399+
ti = !!XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI);
400+
ri = !!XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI);
401+
rbu = !!XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RBU);
402+
fbe = !!XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE);
403+
393404
netif_dbg(pdata, intr, pdata->netdev, "DMA_CH%u_ISR=%#010x\n",
394405
i, dma_ch_isr);
395406

396-
/* The TI or RI interrupt bits may still be set even if using
397-
* per channel DMA interrupts. Check to be sure those are not
398-
* enabled before using the private data napi structure.
407+
per_ch_irq = pdata->per_channel_irq;
408+
409+
/*
410+
* Decide which NAPI to use and whether to schedule:
411+
* - When not using per-channel IRQs: schedule on global NAPI
412+
* if TI or RI are set.
399413
*/
400-
if (!pdata->per_channel_irq &&
401-
(XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI) ||
402-
XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI))) {
403-
if (napi_schedule_prep(&pdata->napi)) {
404-
/* Disable Tx and Rx interrupts */
405-
xgbe_disable_rx_tx_ints(pdata);
406-
407-
/* Turn on polling */
408-
__napi_schedule(&pdata->napi);
409-
}
414+
if (!per_ch_irq && (ti || ri))
415+
schedule_napi = true;
416+
417+
napi = per_ch_irq ? &channel->napi : &pdata->napi;
418+
419+
if (schedule_napi && napi_schedule_prep(napi)) {
420+
/* Disable interrupts appropriately before polling */
421+
xgbe_disable_rx_tx_ints(pdata);
422+
423+
/* Turn on polling */
424+
__napi_schedule(napi);
410425
} else {
411-
/* Don't clear Rx/Tx status if doing per channel DMA
412-
* interrupts, these will be cleared by the ISR for
413-
* per channel DMA interrupts.
426+
/*
427+
* Don't clear Rx/Tx status if doing per-channel DMA
428+
* interrupts; those bits will be serviced/cleared by
429+
* the per-channel ISR/NAPI. In non-per-channel mode
430+
* when we're not scheduling NAPI here, ensure we don't
431+
* accidentally clear TI/RI in HW: zero them in the
432+
* local copy so that the eventual write-back does not
433+
* clear TI/RI.
414434
*/
415435
XGMAC_SET_BITS(dma_ch_isr, DMA_CH_SR, TI, 0);
416436
XGMAC_SET_BITS(dma_ch_isr, DMA_CH_SR, RI, 0);
417437
}
418438

419-
if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RBU))
439+
if (rbu)
420440
pdata->ext_stats.rx_buffer_unavailable++;
421441

422442
/* Restart the device on a Fatal Bus Error */
423-
if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE))
443+
if (fbe)
424444
schedule_work(&pdata->restart_work);
425445

426446
/* Clear interrupt signals */

0 commit comments

Comments
 (0)