Commit eb64e292 authored by Felix Fietkau's avatar Felix Fietkau Committed by David S. Miller

bgmac: leave interrupts disabled as long as there is work to do

Always poll rx and tx during NAPI poll instead of relying on the status
of the first interrupt. This prevents bgmac_poll from leaving unfinished
work around until the next IRQ.
In my tests this makes bridging/routing throughput under heavy load more
stable and ensures that no new IRQs arrive as long as bgmac_poll uses up
the entire budget.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b38c83dd
...@@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgmac *bgmac) ...@@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgmac *bgmac)
bgmac_phy_init(bgmac); bgmac_phy_init(bgmac);
netdev_reset_queue(bgmac->net_dev); netdev_reset_queue(bgmac->net_dev);
bgmac->int_status = 0;
} }
static void bgmac_chip_intrs_on(struct bgmac *bgmac) static void bgmac_chip_intrs_on(struct bgmac *bgmac)
...@@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int irq, void *dev_id) ...@@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
if (!int_status) if (!int_status)
return IRQ_NONE; return IRQ_NONE;
/* Ack */ int_status &= ~(BGMAC_IS_TX0 | BGMAC_IS_RX);
bgmac_write(bgmac, BGMAC_INT_STATUS, int_status); if (int_status)
bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", int_status);
/* Disable new interrupts until handling existing ones */ /* Disable new interrupts until handling existing ones */
bgmac_chip_intrs_off(bgmac); bgmac_chip_intrs_off(bgmac);
bgmac->int_status = int_status;
napi_schedule(&bgmac->napi); napi_schedule(&bgmac->napi);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int irq, void *dev_id) ...@@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
static int bgmac_poll(struct napi_struct *napi, int weight) static int bgmac_poll(struct napi_struct *napi, int weight)
{ {
struct bgmac *bgmac = container_of(napi, struct bgmac, napi); struct bgmac *bgmac = container_of(napi, struct bgmac, napi);
struct bgmac_dma_ring *ring;
int handled = 0; int handled = 0;
if (bgmac->int_status & BGMAC_IS_TX0) { /* Ack */
ring = &bgmac->tx_ring[0]; bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
bgmac_dma_tx_free(bgmac, ring);
bgmac->int_status &= ~BGMAC_IS_TX0;
}
if (bgmac->int_status & BGMAC_IS_RX) { bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]);
ring = &bgmac->rx_ring[0]; handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight);
handled += bgmac_dma_rx_read(bgmac, ring, weight);
bgmac->int_status &= ~BGMAC_IS_RX;
}
if (bgmac->int_status) { /* Poll again if more events arrived in the meantime */
bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status); if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX))
bgmac->int_status = 0; return handled;
}
if (handled < weight) { if (handled < weight) {
napi_complete(napi); napi_complete(napi);
......
...@@ -452,7 +452,6 @@ struct bgmac { ...@@ -452,7 +452,6 @@ struct bgmac {
/* Int */ /* Int */
u32 int_mask; u32 int_mask;
u32 int_status;
/* Current MAC state */ /* Current MAC state */
int mac_speed; int mac_speed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment