123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- From: Felix Fietkau <nbd@openwrt.org>
- Date: Sun, 12 Apr 2015 10:08:04 +0200
- Subject: [PATCH] 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: Felix Fietkau <nbd@openwrt.org>
- ---
- --- a/drivers/net/ethernet/broadcom/bgmac.c
- +++ b/drivers/net/ethernet/broadcom/bgmac.c
- @@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgma
- bgmac_phy_init(bgmac);
-
- netdev_reset_queue(bgmac->net_dev);
- -
- - bgmac->int_status = 0;
- }
-
- static void bgmac_chip_intrs_on(struct bgmac *bgmac)
- @@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int i
- if (!int_status)
- return IRQ_NONE;
-
- - /* Ack */
- - bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
- + int_status &= ~(BGMAC_IS_TX0 | BGMAC_IS_RX);
- + if (int_status)
- + bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", int_status);
-
- /* Disable new interrupts until handling existing ones */
- bgmac_chip_intrs_off(bgmac);
-
- - bgmac->int_status = int_status;
- -
- napi_schedule(&bgmac->napi);
-
- return IRQ_HANDLED;
- @@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int i
- static int bgmac_poll(struct napi_struct *napi, int weight)
- {
- struct bgmac *bgmac = container_of(napi, struct bgmac, napi);
- - struct bgmac_dma_ring *ring;
- int handled = 0;
-
- - if (bgmac->int_status & BGMAC_IS_TX0) {
- - ring = &bgmac->tx_ring[0];
- - bgmac_dma_tx_free(bgmac, ring);
- - bgmac->int_status &= ~BGMAC_IS_TX0;
- - }
- + /* Ack */
- + bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
-
- - if (bgmac->int_status & BGMAC_IS_RX) {
- - ring = &bgmac->rx_ring[0];
- - handled += bgmac_dma_rx_read(bgmac, ring, weight);
- - bgmac->int_status &= ~BGMAC_IS_RX;
- - }
- + bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]);
- + handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight);
-
- - if (bgmac->int_status) {
- - bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
- - bgmac->int_status = 0;
- - }
- + /* Poll again if more events arrived in the meantime */
- + if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX))
- + return handled;
-
- if (handled < weight) {
- napi_complete(napi);
- --- a/drivers/net/ethernet/broadcom/bgmac.h
- +++ b/drivers/net/ethernet/broadcom/bgmac.h
- @@ -452,7 +452,6 @@ struct bgmac {
-
- /* Int */
- u32 int_mask;
- - u32 int_status;
-
- /* Current MAC state */
- int mac_speed;
|