From ba268ba52502b803fef6b31978ffbd6c129dbf91 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Tue, 26 Feb 2013 20:28:49 +0800 Subject: [PATCH] bce: Move status index's location and cached status index into RX ring --- sys/dev/netif/bce/if_bce.c | 40 +++++++++++++++++++---------------- sys/dev/netif/bce/if_bcereg.h | 7 +++--- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/sys/dev/netif/bce/if_bce.c b/sys/dev/netif/bce/if_bce.c index d12094243b..8c4f60666e 100644 --- a/sys/dev/netif/bce/if_bce.c +++ b/sys/dev/netif/bce/if_bce.c @@ -399,7 +399,7 @@ static void bce_rx_intr(struct bce_rx_ring *, int, uint16_t); static void bce_phy_intr(struct bce_softc *); static void bce_disable_intr(struct bce_softc *); static void bce_enable_intr(struct bce_softc *); -static void bce_reenable_intr(struct bce_softc *); +static void bce_reenable_intr(struct bce_rx_ring *); static void bce_check_msi(void *); static void bce_stats_update(struct bce_softc *); @@ -2545,6 +2545,8 @@ bce_dma_alloc(struct bce_softc *sc) sc->rx_rings[i].rx_cid = RX_CID; sc->rx_rings[i].rx_hw_cons = &sc->status_block->status_rx_quick_consumer_index0; + sc->rx_rings[i].hw_status_idx = + &sc->status_block->status_idx; rc = bce_create_rx_ring(&sc->rx_rings[i]); if (rc != 0) { @@ -3697,7 +3699,6 @@ bce_blockinit(struct bce_softc *sc) sc->eaddr[3] + (sc->eaddr[4] << 8) + (sc->eaddr[5] << 16); REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val); - sc->last_status_idx = 0; sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE; /* Set up link change interrupt generation. */ @@ -4091,6 +4092,9 @@ bce_init_rx_chain(struct bce_rx_ring *rxr) rxr->free_rx_bd = USABLE_RX_BD(rxr); rxr->max_rx_bd = USABLE_RX_BD(rxr); + /* Clear cache status index */ + rxr->last_status_idx = 0; + /* Initialize the RX next pointer chain entries. */ for (i = 0; i < rxr->rx_pages; i++) { int j; @@ -4575,13 +4579,15 @@ bce_disable_intr(struct bce_softc *sc) static void bce_enable_intr(struct bce_softc *sc) { + struct bce_rx_ring *rxr = &sc->rx_rings[0]; /* XXX */ + lwkt_serialize_handler_enable(&sc->main_serialize); REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | - BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx); + BCE_PCICFG_INT_ACK_CMD_MASK_INT | rxr->last_status_idx); REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, - BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx); + BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | rxr->last_status_idx); REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW); @@ -4607,15 +4613,15 @@ bce_enable_intr(struct bce_softc *sc) /* Nothing. */ /****************************************************************************/ static void -bce_reenable_intr(struct bce_softc *sc) +bce_reenable_intr(struct bce_rx_ring *rxr) { - if (sc->bce_irq_type == PCI_INTR_TYPE_LEGACY) { - REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, + if (rxr->sc->bce_irq_type == PCI_INTR_TYPE_LEGACY) { + REG_WR(rxr->sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | - BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx); + BCE_PCICFG_INT_ACK_CMD_MASK_INT | rxr->last_status_idx); } - REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, - BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx); + REG_WR(rxr->sc, BCE_PCICFG_INT_ACK_CMD, + BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | rxr->last_status_idx); } @@ -5140,9 +5146,7 @@ bce_npoll_status(struct ifnet *ifp) static void bce_npoll_rx(struct ifnet *ifp, void *arg, int count) { - struct bce_softc *sc = ifp->if_softc; struct bce_rx_ring *rxr = arg; - struct status_block *sblk = sc->status_block; uint16_t hw_rx_cons; ASSERT_SERIALIZED(&rxr->rx_serialize); @@ -5151,7 +5155,7 @@ bce_npoll_rx(struct ifnet *ifp, void *arg, int count) * Save the status block index value for use when enabling * the interrupt. */ - sc->last_status_idx = sblk->status_idx; + rxr->last_status_idx = *rxr->hw_status_idx; /* Make sure status index is extracted before RX/TX cons */ cpu_lfence(); @@ -5275,7 +5279,7 @@ bce_intr(struct bce_softc *sc) * Save the status block index value for use during * the next interrupt. */ - sc->last_status_idx = sblk->status_idx; + rxr->last_status_idx = *rxr->hw_status_idx; /* Make sure status index is extracted before RX/TX cons */ cpu_lfence(); @@ -5330,7 +5334,7 @@ bce_intr(struct bce_softc *sc) lwkt_serialize_exit(&txr->tx_serialize); /* Re-enable interrupts. */ - bce_reenable_intr(sc); + bce_reenable_intr(rxr); } static void @@ -5346,7 +5350,7 @@ bce_intr_legacy(void *xsc) * read by the driver and we haven't asserted our interrupt * then there's nothing to do. */ - if (sblk->status_idx == sc->last_status_idx && + if (sblk->status_idx == sc->rx_rings[0].last_status_idx && (REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE)) return; @@ -5768,7 +5772,7 @@ bce_check_msi(void *xsc) (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) { if (sc->bce_check_rx_cons == rxr->rx_cons && sc->bce_check_tx_cons == txr->tx_cons && - sc->bce_check_status_idx == sc->last_status_idx) { + sc->bce_check_status_idx == rxr->last_status_idx) { uint32_t msi_ctrl; if (!sc->bce_msi_maylose) { @@ -5794,7 +5798,7 @@ bce_check_msi(void *xsc) sc->bce_msi_maylose = FALSE; sc->bce_check_rx_cons = rxr->rx_cons; sc->bce_check_tx_cons = txr->tx_cons; - sc->bce_check_status_idx = sc->last_status_idx; + sc->bce_check_status_idx = rxr->last_status_idx; done: callout_reset(&sc->bce_ckmsi_callout, BCE_MSI_CKINTVL, diff --git a/sys/dev/netif/bce/if_bcereg.h b/sys/dev/netif/bce/if_bcereg.h index 62610755c3..8d12088553 100644 --- a/sys/dev/netif/bce/if_bcereg.h +++ b/sys/dev/netif/bce/if_bcereg.h @@ -5758,6 +5758,10 @@ struct bce_tx_ring { struct bce_rx_ring { struct lwkt_serialize rx_serialize; struct bce_softc *sc; + + volatile uint16_t *hw_status_idx; + uint16_t last_status_idx; + uint32_t rx_cid; volatile uint16_t *rx_hw_cons; int rx_pages; @@ -5911,9 +5915,6 @@ struct bce_softc { struct status_block *status_block; /* virtual address */ bus_addr_t status_block_paddr; /* Physical address */ - /* Driver maintained status block values. */ - uint16_t last_status_idx; - /* H/W maintained statistics block. */ bus_dma_tag_t stats_tag; bus_dmamap_t stats_map; -- 2.41.0