Date: Thu, 30 Jul 2026 00:35:46 +0000 From: Kevin Bowling <kbowling@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: fd594981c55b - main - igb: Address queue registers by hardware queue ID Message-ID: <6a6a9c62.3d42f.30bfbbd@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=fd594981c55b3a4e316e72265065566a54d40d38 commit fd594981c55b3a4e316e72265065566a54d40d38 Author: Kevin Bowling <kbowling@FreeBSD.org> AuthorDate: 2026-07-28 21:55:59 +0000 Commit: Kevin Bowling <kbowling@FreeBSD.org> CommitDate: 2026-07-30 00:34:21 +0000 igb: Address queue registers by hardware queue ID Use each ring's physical queue index for initialization, MSI-X routing, register dumps, sysctls, and debug output instead of assuming that its logical array index is also its hardware index. This is a no-op for the normal queue layout. A later SR-IOV change moves the PF ring to hardware queue num_vfs, so its hardware ID then differs from logical queue zero. Sponsored by: BBOX.io --- sys/dev/e1000/if_em.c | 161 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 106 insertions(+), 55 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index e447008eafff..49cc6f398b51 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -775,9 +775,12 @@ static int em_get_regs(SYSCTL_HANDLER_ARGS) struct sbuf *sb; u32 *regs_buff; int rc; + uint32_t rxqid, txqid; regs_buff = malloc(sizeof(u32) * IGB_REGS_LEN, M_DEVBUF, M_WAITOK); memset(regs_buff, 0, IGB_REGS_LEN * sizeof(u32)); + rxqid = sc->rx_queues[0].rxr.me; + txqid = sc->tx_queues[0].txr.me; rc = sysctl_wire_old_buffer(req, 0); MPASS(rc == 0); @@ -799,19 +802,19 @@ static int em_get_regs(SYSCTL_HANDLER_ARGS) regs_buff[2] = E1000_READ_REG(hw, E1000_CTRL_EXT); regs_buff[3] = E1000_READ_REG(hw, E1000_ICR); regs_buff[4] = E1000_READ_REG(hw, E1000_RCTL); - regs_buff[5] = E1000_READ_REG(hw, E1000_RDLEN(0)); - regs_buff[6] = E1000_READ_REG(hw, E1000_RDH(0)); - regs_buff[7] = E1000_READ_REG(hw, E1000_RDT(0)); - regs_buff[8] = E1000_READ_REG(hw, E1000_RXDCTL(0)); - regs_buff[9] = E1000_READ_REG(hw, E1000_RDBAL(0)); - regs_buff[10] = E1000_READ_REG(hw, E1000_RDBAH(0)); + regs_buff[5] = E1000_READ_REG(hw, E1000_RDLEN(rxqid)); + regs_buff[6] = E1000_READ_REG(hw, E1000_RDH(rxqid)); + regs_buff[7] = E1000_READ_REG(hw, E1000_RDT(rxqid)); + regs_buff[8] = E1000_READ_REG(hw, E1000_RXDCTL(rxqid)); + regs_buff[9] = E1000_READ_REG(hw, E1000_RDBAL(rxqid)); + regs_buff[10] = E1000_READ_REG(hw, E1000_RDBAH(rxqid)); regs_buff[11] = E1000_READ_REG(hw, E1000_TCTL); - regs_buff[12] = E1000_READ_REG(hw, E1000_TDBAL(0)); - regs_buff[13] = E1000_READ_REG(hw, E1000_TDBAH(0)); - regs_buff[14] = E1000_READ_REG(hw, E1000_TDLEN(0)); - regs_buff[15] = E1000_READ_REG(hw, E1000_TDH(0)); - regs_buff[16] = E1000_READ_REG(hw, E1000_TDT(0)); - regs_buff[17] = E1000_READ_REG(hw, E1000_TXDCTL(0)); + regs_buff[12] = E1000_READ_REG(hw, E1000_TDBAL(txqid)); + regs_buff[13] = E1000_READ_REG(hw, E1000_TDBAH(txqid)); + regs_buff[14] = E1000_READ_REG(hw, E1000_TDLEN(txqid)); + regs_buff[15] = E1000_READ_REG(hw, E1000_TDH(txqid)); + regs_buff[16] = E1000_READ_REG(hw, E1000_TDT(txqid)); + regs_buff[17] = E1000_READ_REG(hw, E1000_TXDCTL(txqid)); regs_buff[18] = E1000_READ_REG(hw, E1000_TDFH); regs_buff[19] = E1000_READ_REG(hw, E1000_TDFT); regs_buff[20] = E1000_READ_REG(hw, E1000_TDFHS); @@ -2615,10 +2618,13 @@ igb_configure_queues(struct e1000_softc *sc) case e1000_vfadapt_i350: /* RX entries */ for (int i = 0; i < sc->rx_num_queues; i++) { - u32 index = i >> 1; - ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + uint32_t index, qid; + rx_que = &sc->rx_queues[i]; - if (i & 1) { + qid = rx_que->rxr.me; + index = qid >> 1; + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + if (qid & 1) { ivar &= 0xFF00FFFF; ivar |= (rx_que->msix | E1000_IVAR_VALID) << 16; @@ -2630,10 +2636,13 @@ igb_configure_queues(struct e1000_softc *sc) } /* TX entries */ for (int i = 0; i < sc->tx_num_queues; i++) { - u32 index = i >> 1; - ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + uint32_t index, qid; + tx_que = &sc->tx_queues[i]; - if (i & 1) { + qid = tx_que->txr.me; + index = qid >> 1; + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + if (qid & 1) { ivar &= 0x00FFFFFF; ivar |= (tx_que->msix | E1000_IVAR_VALID) << 24; @@ -2654,10 +2663,13 @@ igb_configure_queues(struct e1000_softc *sc) case e1000_82576: /* RX entries */ for (int i = 0; i < sc->rx_num_queues; i++) { - u32 index = i & 0x7; /* Each IVAR has two entries */ - ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + uint32_t index, qid; + rx_que = &sc->rx_queues[i]; - if (i < 8) { + qid = rx_que->rxr.me; + index = qid & 0x7; /* Each IVAR has two entries */ + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + if (qid < 8) { ivar &= 0xFFFFFF00; ivar |= rx_que->msix | E1000_IVAR_VALID; } else { @@ -2670,10 +2682,13 @@ igb_configure_queues(struct e1000_softc *sc) } /* TX entries */ for (int i = 0; i < sc->tx_num_queues; i++) { - u32 index = i & 0x7; /* Each IVAR has two entries */ - ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + uint32_t index, qid; + tx_que = &sc->tx_queues[i]; - if (i < 8) { + qid = tx_que->txr.me; + index = qid & 0x7; /* Each IVAR has two entries */ + ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index); + if (qid < 8) { ivar &= 0xFFFF00FF; ivar |= (tx_que->msix | E1000_IVAR_VALID) << 8; @@ -3685,9 +3700,11 @@ em_initialize_transmit_unit(if_ctx_t ctx) for (int i = 0; i < sc->tx_num_queues; i++, txr++) { u64 bus_addr; caddr_t offp, endp; + uint32_t qid; que = &sc->tx_queues[i]; txr = &que->txr; + qid = txr->me; bus_addr = txr->tx_paddr; /* Clear checksum offload context. */ @@ -3696,17 +3713,17 @@ em_initialize_transmit_unit(if_ctx_t ctx) bzero(offp, endp - offp); /* Base and Len of TX Ring */ - E1000_WRITE_REG(hw, E1000_TDLEN(i), + E1000_WRITE_REG(hw, E1000_TDLEN(qid), scctx->isc_ntxd[0] * sizeof(struct e1000_tx_desc)); - E1000_WRITE_REG(hw, E1000_TDBAH(i), (u32)(bus_addr >> 32)); - E1000_WRITE_REG(hw, E1000_TDBAL(i), (u32)bus_addr); + E1000_WRITE_REG(hw, E1000_TDBAH(qid), (u32)(bus_addr >> 32)); + E1000_WRITE_REG(hw, E1000_TDBAL(qid), (u32)bus_addr); /* Init the HEAD/TAIL indices */ - E1000_WRITE_REG(hw, E1000_TDT(i), 0); - E1000_WRITE_REG(hw, E1000_TDH(i), 0); + E1000_WRITE_REG(hw, E1000_TDT(qid), 0); + E1000_WRITE_REG(hw, E1000_TDH(qid), 0); HW_DEBUGOUT2("Base = %x, Length = %x\n", - E1000_READ_REG(hw, E1000_TDBAL(i)), - E1000_READ_REG(hw, E1000_TDLEN(i))); + E1000_READ_REG(hw, E1000_TDBAL(qid)), + E1000_READ_REG(hw, E1000_TDLEN(qid))); txdctl = 0; /* clear txdctl */ txdctl |= 0x1f; /* PTHRESH */ @@ -3716,7 +3733,7 @@ em_initialize_transmit_unit(if_ctx_t ctx) txdctl |= E1000_TXDCTL_GRAN; txdctl |= 1 << 25; /* LWTHRESH */ - E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl); + E1000_WRITE_REG(hw, E1000_TXDCTL(qid), txdctl); } /* Set the default values for the Tx Inter Packet Gap timer */ @@ -3943,18 +3960,19 @@ em_initialize_receive_unit(if_ctx_t ctx) struct rx_ring *rxr = &que->rxr; /* Setup the Base and Length of the Rx Descriptor Ring */ u64 bus_addr = rxr->rx_paddr; + uint32_t qid = rxr->me; #if 0 u32 rdt = sc->rx_num_queues -1; /* default */ #endif - E1000_WRITE_REG(hw, E1000_RDLEN(i), + E1000_WRITE_REG(hw, E1000_RDLEN(qid), scctx->isc_nrxd[0] * sizeof(union e1000_rx_desc_extended)); - E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32)); - E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr); + E1000_WRITE_REG(hw, E1000_RDBAH(qid), (u32)(bus_addr >> 32)); + E1000_WRITE_REG(hw, E1000_RDBAL(qid), (u32)bus_addr); /* Setup the Head and Tail Descriptor Pointers */ - E1000_WRITE_REG(hw, E1000_RDH(i), 0); - E1000_WRITE_REG(hw, E1000_RDT(i), 0); + E1000_WRITE_REG(hw, E1000_RDH(qid), 0); + E1000_WRITE_REG(hw, E1000_RDT(qid), 0); } /* @@ -4014,6 +4032,7 @@ em_initialize_receive_unit(if_ctx_t ctx) struct rx_ring *rxr = &que->rxr; u64 bus_addr = rxr->rx_paddr; u32 rxdctl; + uint32_t qid = rxr->me; #ifdef notyet /* Configure for header split? -- ignore for now */ @@ -4022,22 +4041,22 @@ em_initialize_receive_unit(if_ctx_t ctx) srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; #endif - E1000_WRITE_REG(hw, E1000_RDLEN(i), + E1000_WRITE_REG(hw, E1000_RDLEN(qid), scctx->isc_nrxd[0] * sizeof(struct e1000_rx_desc)); - E1000_WRITE_REG(hw, E1000_RDBAH(i), + E1000_WRITE_REG(hw, E1000_RDBAH(qid), (uint32_t)(bus_addr >> 32)); - E1000_WRITE_REG(hw, E1000_RDBAL(i), + E1000_WRITE_REG(hw, E1000_RDBAL(qid), (uint32_t)bus_addr); - E1000_WRITE_REG(hw, E1000_SRRCTL(i), srrctl); + E1000_WRITE_REG(hw, E1000_SRRCTL(qid), srrctl); /* Enable this Queue */ - rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(i)); + rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(qid)); rxdctl |= E1000_RXDCTL_QUEUE_ENABLE; rxdctl &= 0xFFF00000; rxdctl |= IGB_RX_PTHRESH; rxdctl |= IGB_RX_HTHRESH << 8; rxdctl |= IGB_RX_WTHRESH << 16; - E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); + E1000_WRITE_REG(hw, E1000_RXDCTL(qid), rxdctl); } } else if (hw->mac.type >= e1000_pch2lan) { if (if_getmtu(ifp) > ETHERMTU) @@ -4977,6 +4996,38 @@ em_sysctl_reg_handler(SYSCTL_HANDLER_ARGS) return (sysctl_handle_int(oidp, &val, 0, req)); } +enum em_ring_register { + EM_RING_HEAD, + EM_RING_TAIL, +}; + +/* Queue register addresses can change when the PF enters IOV mode. */ +static int +em_sysctl_tx_ring_handler(SYSCTL_HANDLER_ARGS) +{ + struct tx_ring *txr; + u_int reg, val; + + txr = oidp->oid_arg1; + reg = oidp->oid_arg2 == EM_RING_HEAD ? E1000_TDH(txr->me) : + E1000_TDT(txr->me); + val = E1000_READ_REG(&txr->sc->hw, reg); + return (sysctl_handle_int(oidp, &val, 0, req)); +} + +static int +em_sysctl_rx_ring_handler(SYSCTL_HANDLER_ARGS) +{ + struct rx_ring *rxr; + u_int reg, val; + + rxr = oidp->oid_arg1; + reg = oidp->oid_arg2 == EM_RING_HEAD ? E1000_RDH(rxr->me) : + E1000_RDT(rxr->me); + val = E1000_READ_REG(&rxr->sc->hw, reg); + return (sysctl_handle_int(oidp, &val, 0, req)); +} + /* Per queue holdoff interrupt rate handler */ static int em_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS) @@ -5093,12 +5144,12 @@ em_add_hw_stats(struct e1000_softc *sc) "IU", "Interrupt Rate"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head", - CTLTYPE_UINT | CTLFLAG_RD, sc, - E1000_TDH(txr->me), em_sysctl_reg_handler, "IU", + CTLTYPE_UINT | CTLFLAG_RD, txr, EM_RING_HEAD, + em_sysctl_tx_ring_handler, "IU", "Transmit Descriptor Head"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_tail", - CTLTYPE_UINT | CTLFLAG_RD, sc, - E1000_TDT(txr->me), em_sysctl_reg_handler, "IU", + CTLTYPE_UINT | CTLFLAG_RD, txr, EM_RING_TAIL, + em_sysctl_tx_ring_handler, "IU", "Transmit Descriptor Tail"); SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "tx_irq", CTLFLAG_RD, &txr->tx_irq, @@ -5118,12 +5169,12 @@ em_add_hw_stats(struct e1000_softc *sc) "IU", "Interrupt Rate"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head", - CTLTYPE_UINT | CTLFLAG_RD, sc, - E1000_RDH(rxr->me), em_sysctl_reg_handler, "IU", + CTLTYPE_UINT | CTLFLAG_RD, rxr, EM_RING_HEAD, + em_sysctl_rx_ring_handler, "IU", "Receive Descriptor Head"); SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_tail", - CTLTYPE_UINT | CTLFLAG_RD, sc, - E1000_RDT(rxr->me), em_sysctl_reg_handler, "IU", + CTLTYPE_UINT | CTLFLAG_RD, rxr, EM_RING_TAIL, + em_sysctl_rx_ring_handler, "IU", "Receive Descriptor Tail"); SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "rx_irq", CTLFLAG_RD, &rxr->rx_irq, @@ -5814,15 +5865,15 @@ em_print_debug_info(struct e1000_softc *sc) for (int i = 0; i < sc->tx_num_queues; i++, txr++) { device_printf(dev, "TX Queue %d ------\n", i); device_printf(dev, "hw tdh = %d, hw tdt = %d\n", - E1000_READ_REG(&sc->hw, E1000_TDH(i)), - E1000_READ_REG(&sc->hw, E1000_TDT(i))); + E1000_READ_REG(&sc->hw, E1000_TDH(txr->me)), + E1000_READ_REG(&sc->hw, E1000_TDT(txr->me))); } for (int j=0; j < sc->rx_num_queues; j++, rxr++) { device_printf(dev, "RX Queue %d ------\n", j); device_printf(dev, "hw rdh = %d, hw rdt = %d\n", - E1000_READ_REG(&sc->hw, E1000_RDH(j)), - E1000_READ_REG(&sc->hw, E1000_RDT(j))); + E1000_READ_REG(&sc->hw, E1000_RDH(rxr->me)), + E1000_READ_REG(&sc->hw, E1000_RDT(rxr->me))); } }home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6a9c62.3d42f.30bfbbd>
