On Thu, Mar 25, 2021 at 05:21:38PM +0800, Kevin Lo wrote:
> Hi,
> 
> The diff below moves tx/rx descriptors into their own structs.
> This is a first step toward making rge work with multiple queues and 
> interrupts.
> Only one queue is currently used.
> 
> While here, update the RTL8125B microcode.

I can't really comment on the magic numbers, but the struct reorganisation
looks good to me, ok jmatthew@

> 
> Index: sys/dev/pci/if_rge.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_rge.c,v
> retrieving revision 1.12
> diff -u -p -u -p -r1.12 if_rge.c
> --- sys/dev/pci/if_rge.c      11 Feb 2021 16:22:06 -0000      1.12
> +++ sys/dev/pci/if_rge.c      25 Mar 2021 09:14:17 -0000
> @@ -61,7 +61,7 @@ int         rge_match(struct device *, void *, 
>  void         rge_attach(struct device *, struct device *, void *);
>  int          rge_activate(struct device *, int);
>  int          rge_intr(void *);
> -int          rge_encap(struct rge_softc *, struct mbuf *, int);
> +int          rge_encap(struct rge_queues *, struct mbuf *, int);
>  int          rge_ioctl(struct ifnet *, u_long, caddr_t);
>  void         rge_start(struct ifqueue *);
>  void         rge_watchdog(struct ifnet *);
> @@ -70,13 +70,13 @@ void              rge_stop(struct ifnet *);
>  int          rge_ifmedia_upd(struct ifnet *);
>  void         rge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
>  int          rge_allocmem(struct rge_softc *);
> -int          rge_newbuf(struct rge_softc *);
> -void         rge_discard_rxbuf(struct rge_softc *, int);
> -void         rge_rx_list_init(struct rge_softc *);
> -void         rge_tx_list_init(struct rge_softc *);
> -void         rge_fill_rx_ring(struct rge_softc *);
> -int          rge_rxeof(struct rge_softc *);
> -int          rge_txeof(struct rge_softc *);
> +int          rge_newbuf(struct rge_queues *);
> +void         rge_discard_rxbuf(struct rge_queues *, int);
> +void         rge_rx_list_init(struct rge_queues *);
> +void         rge_tx_list_init(struct rge_queues *);
> +void         rge_fill_rx_ring(struct rge_queues *);
> +int          rge_rxeof(struct rge_queues *);
> +int          rge_txeof(struct rge_queues *);
>  void         rge_reset(struct rge_softc *);
>  void         rge_iff(struct rge_softc *);
>  void         rge_set_phy_power(struct rge_softc *, int);
> @@ -159,6 +159,7 @@ rge_attach(struct device *parent, struct
>       pci_intr_handle_t ih;
>       const char *intrstr = NULL;
>       struct ifnet *ifp;
> +     struct rge_queues *q;
>       pcireg_t reg;
>       uint32_t hwrev;
>       uint8_t eaddr[ETHER_ADDR_LEN];
> @@ -184,6 +185,17 @@ rge_attach(struct device *parent, struct
>               }
>       }
>  
> +     q = malloc(sizeof(struct rge_queues), M_DEVBUF, M_NOWAIT | M_ZERO);
> +     if (q == NULL) {
> +             printf(": unable to allocate queue memory\n");
> +             return;
> +     }
> +     q->q_sc = sc;
> +     q->q_index = 0;
> +
> +     sc->sc_queues = q;
> +     sc->sc_nqueues = 1;
> +
>       /* 
>        * Allocate interrupt.
>        */
> @@ -323,9 +335,10 @@ int
>  rge_intr(void *arg)
>  {
>       struct rge_softc *sc = arg;
> +     struct rge_queues *q = sc->sc_queues;
>       struct ifnet *ifp = &sc->sc_arpcom.ac_if;
>       uint32_t status;
> -     int claimed = 0, rx, tx;
> +     int claimed = 0, rv;
>  
>       if (!(ifp->if_flags & IFF_RUNNING))
>               return (0);
> @@ -345,29 +358,21 @@ rge_intr(void *arg)
>       if (status & RGE_ISR_PCS_TIMEOUT)
>               claimed = 1;
>  
> -     rx = tx = 0;
> +     rv = 0;
>       if (status & sc->rge_intrs) {
> -             if (status &
> -                 (sc->rge_rx_ack | RGE_ISR_RX_ERR | RGE_ISR_RX_FIFO_OFLOW)) {
> -                     rx |= rge_rxeof(sc);
> -                     claimed = 1;
> -             }
> -
> -             if (status & (sc->rge_tx_ack | RGE_ISR_TX_ERR)) {
> -                     tx |= rge_txeof(sc);
> -                     claimed = 1;
> -             }
> +             rv |= rge_rxeof(q);
> +             rv |= rge_txeof(q);
>  
>               if (status & RGE_ISR_SYSTEM_ERR) {
>                       KERNEL_LOCK();
>                       rge_init(ifp);
>                       KERNEL_UNLOCK();
> -                     claimed = 1;
>               }
> +             claimed = 1;
>       }
>  
>       if (sc->rge_timerintr) {
> -             if ((tx | rx) == 0) {
> +             if (!rv) {
>                       /*
>                        * Nothing needs to be processed, fallback
>                        * to use TX/RX interrupts.
> @@ -379,11 +384,11 @@ rge_intr(void *arg)
>                        * race introduced by changing interrupt
>                        * masks.
>                        */
> -                     rge_rxeof(sc);
> -                     rge_txeof(sc);
> +                     rge_rxeof(q);
> +                     rge_txeof(q);
>               } else
>                       RGE_WRITE_4(sc, RGE_TIMERCNT, 1);
> -     } else if (tx | rx) {
> +     } else if (rv) {
>               /*
>                * Assume that using simulated interrupt moderation
>                * (hardware timer based) could reduce the interrupt
> @@ -398,8 +403,9 @@ rge_intr(void *arg)
>  }
>  
>  int
> -rge_encap(struct rge_softc *sc, struct mbuf *m, int idx)
> +rge_encap(struct rge_queues *q, struct mbuf *m, int idx)
>  {
> +     struct rge_softc *sc = q->q_sc;
>       struct rge_tx_desc *d = NULL;
>       struct rge_txq *txq;
>       bus_dmamap_t txmap;
> @@ -420,7 +426,7 @@ rge_encap(struct rge_softc *sc, struct m
>                       cflags |= RGE_TDEXTSTS_UDPCSUM;
>       }
>  
> -     txq = &sc->rge_ldata.rge_txq[idx];
> +     txq = &q->q_tx.rge_txq[idx];
>       txmap = txq->txq_dmamap;
>  
>       error = bus_dmamap_load_mbuf(sc->sc_dmat, txmap, m, BUS_DMA_NOWAIT);
> @@ -453,7 +459,7 @@ rge_encap(struct rge_softc *sc, struct m
>       cmdsts = RGE_TDCMDSTS_SOF;
>  
>       for (i = 0; i < txmap->dm_nsegs; i++) {
> -             d = &sc->rge_ldata.rge_tx_list[cur];
> +             d = &q->q_tx.rge_tx_list[cur];
>  
>               d->rge_extsts = htole32(cflags);
>               d->rge_addrlo = htole32(RGE_ADDR_LO(txmap->dm_segs[i].ds_addr));
> @@ -475,11 +481,11 @@ rge_encap(struct rge_softc *sc, struct m
>       d->rge_cmdsts |= htole32(RGE_TDCMDSTS_EOF);
>  
>       /* Transfer ownership of packet to the chip. */
> -     d = &sc->rge_ldata.rge_tx_list[idx];
> +     d = &q->q_tx.rge_tx_list[idx];
>  
>       d->rge_cmdsts |= htole32(RGE_TDCMDSTS_OWN);
>  
> -     bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
> +     bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map,
>           cur * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
>           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
>  
> @@ -529,7 +535,7 @@ rge_ioctl(struct ifnet *ifp, u_long cmd,
>               break;
>       case SIOCGIFRXR:
>               error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
> -                 NULL, RGE_JUMBO_FRAMELEN, &sc->rge_ldata.rge_rx_ring);
> +                 NULL, RGE_JUMBO_FRAMELEN, &sc->sc_queues->q_rx.rge_rx_ring);
>               break;
>       default:
>               error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
> @@ -550,6 +556,7 @@ rge_start(struct ifqueue *ifq)
>  {
>       struct ifnet *ifp = ifq->ifq_if;
>       struct rge_softc *sc = ifp->if_softc;
> +     struct rge_queues *q = sc->sc_queues;
>       struct mbuf *m;
>       int free, idx, used;
>       int queued = 0;
> @@ -560,8 +567,8 @@ rge_start(struct ifqueue *ifq)
>       }
>  
>       /* Calculate free space. */
> -     idx = sc->rge_ldata.rge_txq_prodidx;
> -     free = sc->rge_ldata.rge_txq_considx;
> +     idx = q->q_tx.rge_txq_prodidx;
> +     free = q->q_tx.rge_txq_considx;
>       if (free <= idx)
>               free += RGE_TX_LIST_CNT;
>       free -= idx;
> @@ -576,7 +583,7 @@ rge_start(struct ifqueue *ifq)
>               if (m == NULL)
>                       break;
>  
> -             used = rge_encap(sc, m, idx);
> +             used = rge_encap(q, m, idx);
>               if (used == 0) {
>                       m_freem(m);
>                       continue;
> @@ -603,7 +610,7 @@ rge_start(struct ifqueue *ifq)
>       /* Set a timeout in case the chip goes out to lunch. */
>       ifp->if_timer = 5;
>  
> -     sc->rge_ldata.rge_txq_prodidx = idx;
> +     q->q_tx.rge_txq_prodidx = idx;
>       ifq_serialize(ifq, &sc->sc_task);
>  }
>  
> @@ -622,6 +629,7 @@ int
>  rge_init(struct ifnet *ifp)
>  {
>       struct rge_softc *sc = ifp->if_softc;
> +     struct rge_queues *q = sc->sc_queues;
>       uint32_t val;
>       int i;
>  
> @@ -634,18 +642,18 @@ rge_init(struct ifnet *ifp)
>       RGE_WRITE_2(sc, RGE_RXMAXSIZE, RGE_JUMBO_FRAMELEN);
>  
>       /* Initialize RX and TX descriptors lists. */
> -     rge_rx_list_init(sc);
> -     rge_tx_list_init(sc);
> +     rge_rx_list_init(q);
> +     rge_tx_list_init(q);
>  
>       /* Load the addresses of the RX and TX lists into the chip. */
>       RGE_WRITE_4(sc, RGE_RXDESC_ADDR_LO,
> -         RGE_ADDR_LO(sc->rge_ldata.rge_rx_list_map->dm_segs[0].ds_addr));
> +         RGE_ADDR_LO(q->q_rx.rge_rx_list_map->dm_segs[0].ds_addr));
>       RGE_WRITE_4(sc, RGE_RXDESC_ADDR_HI,
> -         RGE_ADDR_HI(sc->rge_ldata.rge_rx_list_map->dm_segs[0].ds_addr));
> +         RGE_ADDR_HI(q->q_rx.rge_rx_list_map->dm_segs[0].ds_addr));
>       RGE_WRITE_4(sc, RGE_TXDESC_ADDR_LO,
> -         RGE_ADDR_LO(sc->rge_ldata.rge_tx_list_map->dm_segs[0].ds_addr));
> +         RGE_ADDR_LO(q->q_tx.rge_tx_list_map->dm_segs[0].ds_addr));
>       RGE_WRITE_4(sc, RGE_TXDESC_ADDR_HI,
> -         RGE_ADDR_HI(sc->rge_ldata.rge_tx_list_map->dm_segs[0].ds_addr));
> +         RGE_ADDR_HI(q->q_tx.rge_tx_list_map->dm_segs[0].ds_addr));
>  
>       RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
>  
> @@ -670,18 +678,17 @@ rge_init(struct ifnet *ifp)
>       pci_conf_write(sc->sc_pc, sc->sc_tag, 0x78, val | 0x00005000);
>  
>       RGE_WRITE_2(sc, 0x0382, 0x221b);
> -     RGE_WRITE_1(sc, 0x4500, 0);
> -     RGE_WRITE_2(sc, 0x4800, 0);
> +
> +     RGE_WRITE_1(sc, RGE_RSS_CTRL, 0);
> +
> +     val = RGE_READ_2(sc, RGE_RXQUEUE_CTRL) & ~0x001c;
> +     RGE_WRITE_2(sc, RGE_RXQUEUE_CTRL, val | (fls(sc->sc_nqueues) - 1) << 2);
> +
>       RGE_CLRBIT_1(sc, RGE_CFG1, RGE_CFG1_SPEED_DOWN);
>  
>       rge_write_mac_ocp(sc, 0xc140, 0xffff);
>       rge_write_mac_ocp(sc, 0xc142, 0xffff);
>  
> -     val = rge_read_mac_ocp(sc, 0xd3e2) & ~0x0fff;
> -     rge_write_mac_ocp(sc, 0xd3e2, val | 0x03a9);
> -
> -     RGE_MAC_CLRBIT(sc, 0xd3e4, 0x00ff);
> -     RGE_MAC_SETBIT(sc, 0xe860, 0x0080);
>       RGE_MAC_SETBIT(sc, 0xeb58, 0x0001);
>  
>       val = rge_read_mac_ocp(sc, 0xe614) & ~0x0700;
> @@ -690,14 +697,16 @@ rge_init(struct ifnet *ifp)
>       else
>               rge_write_mac_ocp(sc, 0xe614, val | 0x0200);
>  
> -     RGE_MAC_CLRBIT(sc, 0xe63e, 0x0c00);
> +     val = rge_read_mac_ocp(sc, 0xe63e) & ~0x0c00;
> +     rge_write_mac_ocp(sc, 0xe63e, val |
> +         ((fls(sc->sc_nqueues) - 1) & 0x03) << 10);
>  
> -     if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3) {
> -             val = rge_read_mac_ocp(sc, 0xe63e) & ~0x0030;
> -             rge_write_mac_ocp(sc, 0xe63e, val | 0x0020);
> -     } else
> -             RGE_MAC_CLRBIT(sc, 0xe63e, 0x0030);
> +     RGE_MAC_CLRBIT(sc, 0xe63e, 0x0030);
> +     if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3)
> +             RGE_MAC_SETBIT(sc, 0xe63e, 0x0020);
>  
> +     RGE_MAC_SETBIT(sc, 0xc0b4, 0x0001);
> +     RGE_MAC_CLRBIT(sc, 0xc0b4, 0x0001);
>       RGE_MAC_SETBIT(sc, 0xc0b4, 0x000c);
>  
>       val = rge_read_mac_ocp(sc, 0xeb6a) & ~0x00ff;
> @@ -724,19 +733,10 @@ rge_init(struct ifnet *ifp)
>       RGE_MAC_SETBIT(sc, 0xe052, 0x0068);
>       RGE_MAC_CLRBIT(sc, 0xe052, 0x0080);
>  
> -     val = rge_read_mac_ocp(sc, 0xc0ac) & ~0x0080;
> -     rge_write_mac_ocp(sc, 0xc0ac, val | 0x1f00);
> -
>       val = rge_read_mac_ocp(sc, 0xd430) & ~0x0fff;
>       rge_write_mac_ocp(sc, 0xd430, val | 0x047f);
>  
> -     val = rge_read_mac_ocp(sc, 0xe84c) & ~0x0040;
> -     if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3)
> -             rge_write_mac_ocp(sc, 0xe84c, 0x00c0);
> -     else
> -             rge_write_mac_ocp(sc, 0xe84c, 0x0080);
> -
> -     RGE_SETBIT_1(sc, RGE_DLLPR, RGE_DLLPR_PFM_EN);
> +     RGE_SETBIT_1(sc, RGE_DLLPR, RGE_DLLPR_PFM_EN | RGE_DLLPR_TX_10M_PS_EN);
>  
>       if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3)
>               RGE_SETBIT_1(sc, RGE_MCUCMD, 0x01);
> @@ -800,6 +800,7 @@ void
>  rge_stop(struct ifnet *ifp)
>  {
>       struct rge_softc *sc = ifp->if_softc;
> +     struct rge_queues *q = sc->sc_queues;
>       int i;
>  
>       timeout_del(&sc->sc_timeout);
> @@ -813,6 +814,7 @@ rge_stop(struct ifnet *ifp)
>           RGE_RXCFG_ERRPKT);
>  
>       RGE_WRITE_4(sc, RGE_IMR, 0);
> +     RGE_WRITE_4(sc, RGE_ISR, 0);
>  
>       /* Clear timer interrupts. */
>       RGE_WRITE_4(sc, RGE_TIMERINT0, 0);
> @@ -826,28 +828,28 @@ rge_stop(struct ifnet *ifp)
>       ifq_barrier(&ifp->if_snd);
>       ifq_clr_oactive(&ifp->if_snd);
>  
> -     if (sc->rge_head != NULL) {
> -             m_freem(sc->rge_head);
> -             sc->rge_head = sc->rge_tail = NULL;
> +     if (q->q_rx.rge_head != NULL) {
> +             m_freem(q->q_rx.rge_head);
> +             q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
>       }
>  
>       /* Free the TX list buffers. */
>       for (i = 0; i < RGE_TX_LIST_CNT; i++) {
> -             if (sc->rge_ldata.rge_txq[i].txq_mbuf != NULL) {
> +             if (q->q_tx.rge_txq[i].txq_mbuf != NULL) {
>                       bus_dmamap_unload(sc->sc_dmat,
> -                         sc->rge_ldata.rge_txq[i].txq_dmamap);
> -                     m_freem(sc->rge_ldata.rge_txq[i].txq_mbuf);
> -                     sc->rge_ldata.rge_txq[i].txq_mbuf = NULL;
> +                         q->q_tx.rge_txq[i].txq_dmamap);
> +                     m_freem(q->q_tx.rge_txq[i].txq_mbuf);
> +                     q->q_tx.rge_txq[i].txq_mbuf = NULL;
>               }
>       }
>  
>       /* Free the RX list buffers. */
>       for (i = 0; i < RGE_RX_LIST_CNT; i++) {
> -             if (sc->rge_ldata.rge_rxq[i].rxq_mbuf != NULL) {
> +             if (q->q_rx.rge_rxq[i].rxq_mbuf != NULL) {
>                       bus_dmamap_unload(sc->sc_dmat,
> -                         sc->rge_ldata.rge_rxq[i].rxq_dmamap);
> -                     m_freem(sc->rge_ldata.rge_rxq[i].rxq_mbuf);
> -                     sc->rge_ldata.rge_rxq[i].rxq_mbuf = NULL;
> +                         q->q_rx.rge_rxq[i].rxq_dmamap);
> +                     m_freem(q->q_rx.rge_rxq[i].rxq_mbuf);
> +                     q->q_rx.rge_rxq[i].rxq_mbuf = NULL;
>               }
>       }
>  }
> @@ -958,17 +960,18 @@ rge_ifmedia_sts(struct ifnet *ifp, struc
>  int
>  rge_allocmem(struct rge_softc *sc)
>  {
> +     struct rge_queues *q = sc->sc_queues;
>       int error, i;
>  
>       /* Allocate DMA'able memory for the TX ring. */
>       error = bus_dmamap_create(sc->sc_dmat, RGE_TX_LIST_SZ, 1,
> -         RGE_TX_LIST_SZ, 0, BUS_DMA_NOWAIT, &sc->rge_ldata.rge_tx_list_map);
> +         RGE_TX_LIST_SZ, 0, BUS_DMA_NOWAIT, &q->q_tx.rge_tx_list_map);
>       if (error) {
>               printf("%s: can't create TX list map\n", sc->sc_dev.dv_xname);
>               return (error);
>       }
>       error = bus_dmamem_alloc(sc->sc_dmat, RGE_TX_LIST_SZ, RGE_ALIGN, 0,
> -         &sc->rge_ldata.rge_tx_listseg, 1, &sc->rge_ldata.rge_tx_listnseg,
> +         &q->q_tx.rge_tx_listseg, 1, &q->q_tx.rge_tx_listnseg,
>           BUS_DMA_NOWAIT| BUS_DMA_ZERO);
>       if (error) {
>               printf("%s: can't alloc TX list\n", sc->sc_dev.dv_xname);
> @@ -976,33 +979,32 @@ rge_allocmem(struct rge_softc *sc)
>       }
>  
>       /* Load the map for the TX ring. */
> -     error = bus_dmamem_map(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
> -         sc->rge_ldata.rge_tx_listnseg, RGE_TX_LIST_SZ,
> -         (caddr_t *)&sc->rge_ldata.rge_tx_list,
> -         BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
> +     error = bus_dmamem_map(sc->sc_dmat, &q->q_tx.rge_tx_listseg,
> +         q->q_tx.rge_tx_listnseg, RGE_TX_LIST_SZ,
> +         (caddr_t *)&q->q_tx.rge_tx_list, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
>       if (error) {
>               printf("%s: can't map TX dma buffers\n", sc->sc_dev.dv_xname);
> -             bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
> -                 sc->rge_ldata.rge_tx_listnseg);
> +             bus_dmamem_free(sc->sc_dmat, &q->q_tx.rge_tx_listseg,
> +                 q->q_tx.rge_tx_listnseg);
>               return (error);
>       }
> -     error = bus_dmamap_load(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
> -         sc->rge_ldata.rge_tx_list, RGE_TX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
> +     error = bus_dmamap_load(sc->sc_dmat, q->q_tx.rge_tx_list_map,
> +         q->q_tx.rge_tx_list, RGE_TX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
>       if (error) {
>               printf("%s: can't load TX dma map\n", sc->sc_dev.dv_xname);
> -             bus_dmamap_destroy(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map);
> +             bus_dmamap_destroy(sc->sc_dmat, q->q_tx.rge_tx_list_map);
>               bus_dmamem_unmap(sc->sc_dmat,
> -                 (caddr_t)sc->rge_ldata.rge_tx_list, RGE_TX_LIST_SZ);
> -             bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
> -                 sc->rge_ldata.rge_tx_listnseg);
> +                 (caddr_t)q->q_tx.rge_tx_list, RGE_TX_LIST_SZ);
> +             bus_dmamem_free(sc->sc_dmat, &q->q_tx.rge_tx_listseg,
> +                 q->q_tx.rge_tx_listnseg);
>               return (error);
>       }
>  
>       /* Create DMA maps for TX buffers. */
>       for (i = 0; i < RGE_TX_LIST_CNT; i++) {
>               error = bus_dmamap_create(sc->sc_dmat, RGE_JUMBO_FRAMELEN,
> -                 RGE_TX_NSEGS, RGE_JUMBO_FRAMELEN, 0, 0,
> -                 &sc->rge_ldata.rge_txq[i].txq_dmamap);
> +                 RGE_TX_NSEGS, RGE_JUMBO_FRAMELEN, 0, BUS_DMA_NOWAIT,
> +                 &q->q_tx.rge_txq[i].txq_dmamap);
>               if (error) {
>                       printf("%s: can't create DMA map for TX\n",
>                           sc->sc_dev.dv_xname);
> @@ -1012,13 +1014,13 @@ rge_allocmem(struct rge_softc *sc)
>  
>       /* Allocate DMA'able memory for the RX ring. */
>       error = bus_dmamap_create(sc->sc_dmat, RGE_RX_LIST_SZ, 1,
> -         RGE_RX_LIST_SZ, 0, 0, &sc->rge_ldata.rge_rx_list_map);
> +         RGE_RX_LIST_SZ, 0, BUS_DMA_NOWAIT, &q->q_rx.rge_rx_list_map);
>       if (error) {
>               printf("%s: can't create RX list map\n", sc->sc_dev.dv_xname);
>               return (error);
>       }
>       error = bus_dmamem_alloc(sc->sc_dmat, RGE_RX_LIST_SZ, RGE_ALIGN, 0,
> -         &sc->rge_ldata.rge_rx_listseg, 1, &sc->rge_ldata.rge_rx_listnseg,
> +         &q->q_rx.rge_rx_listseg, 1, &q->q_rx.rge_rx_listnseg,
>           BUS_DMA_NOWAIT| BUS_DMA_ZERO);
>       if (error) {
>               printf("%s: can't alloc RX list\n", sc->sc_dev.dv_xname);
> @@ -1026,33 +1028,32 @@ rge_allocmem(struct rge_softc *sc)
>       }
>  
>       /* Load the map for the RX ring. */
> -     error = bus_dmamem_map(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
> -         sc->rge_ldata.rge_rx_listnseg, RGE_RX_LIST_SZ,
> -         (caddr_t *)&sc->rge_ldata.rge_rx_list,
> -         BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
> +     error = bus_dmamem_map(sc->sc_dmat, &q->q_rx.rge_rx_listseg,
> +         q->q_rx.rge_rx_listnseg, RGE_RX_LIST_SZ,
> +         (caddr_t *)&q->q_rx.rge_rx_list, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
>       if (error) {
>               printf("%s: can't map RX dma buffers\n", sc->sc_dev.dv_xname);
> -             bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
> -                 sc->rge_ldata.rge_rx_listnseg);
> +             bus_dmamem_free(sc->sc_dmat, &q->q_rx.rge_rx_listseg,
> +                 q->q_rx.rge_rx_listnseg);
>               return (error);
>       }
> -     error = bus_dmamap_load(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
> -         sc->rge_ldata.rge_rx_list, RGE_RX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
> +     error = bus_dmamap_load(sc->sc_dmat, q->q_rx.rge_rx_list_map,
> +         q->q_rx.rge_rx_list, RGE_RX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
>       if (error) {
>               printf("%s: can't load RX dma map\n", sc->sc_dev.dv_xname);
> -             bus_dmamap_destroy(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map);
> +             bus_dmamap_destroy(sc->sc_dmat, q->q_rx.rge_rx_list_map);
>               bus_dmamem_unmap(sc->sc_dmat,
> -                 (caddr_t)sc->rge_ldata.rge_rx_list, RGE_RX_LIST_SZ);
> -             bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
> -                 sc->rge_ldata.rge_rx_listnseg);
> +                 (caddr_t)q->q_rx.rge_rx_list, RGE_RX_LIST_SZ);
> +             bus_dmamem_free(sc->sc_dmat, &q->q_rx.rge_rx_listseg,
> +                 q->q_rx.rge_rx_listnseg);
>               return (error);
>       }
>  
>       /* Create DMA maps for RX buffers. */
>       for (i = 0; i < RGE_RX_LIST_CNT; i++) {
>               error = bus_dmamap_create(sc->sc_dmat, RGE_JUMBO_FRAMELEN, 1,
> -                 RGE_JUMBO_FRAMELEN, 0, 0,
> -                 &sc->rge_ldata.rge_rxq[i].rxq_dmamap);
> +                 RGE_JUMBO_FRAMELEN, 0, BUS_DMA_NOWAIT,
> +                 &q->q_rx.rge_rxq[i].rxq_dmamap);
>               if (error) {
>                       printf("%s: can't create DMA map for RX\n",
>                           sc->sc_dev.dv_xname);
> @@ -1067,8 +1068,9 @@ rge_allocmem(struct rge_softc *sc)
>   * Initialize the RX descriptor and attach an mbuf cluster.
>   */
>  int
> -rge_newbuf(struct rge_softc *sc)
> +rge_newbuf(struct rge_queues *q)
>  {
> +     struct rge_softc *sc = q->q_sc;
>       struct mbuf *m;
>       struct rge_rx_desc *r;
>       struct rge_rxq *rxq;
> @@ -1081,8 +1083,8 @@ rge_newbuf(struct rge_softc *sc)
>  
>       m->m_len = m->m_pkthdr.len = RGE_JUMBO_FRAMELEN;
>  
> -     idx = sc->rge_ldata.rge_rxq_prodidx;
> -     rxq = &sc->rge_ldata.rge_rxq[idx];
> +     idx = q->q_rx.rge_rxq_prodidx;
> +     rxq = &q->q_rx.rge_rxq[idx];
>       rxmap = rxq->rxq_dmamap;
>  
>       if (bus_dmamap_load_mbuf(sc->sc_dmat, rxmap, m, BUS_DMA_NOWAIT)) {
> @@ -1094,7 +1096,7 @@ rge_newbuf(struct rge_softc *sc)
>           BUS_DMASYNC_PREREAD);
>  
>       /* Map the segments into RX descriptors. */
> -     r = &sc->rge_ldata.rge_rx_list[idx];
> +     r = &q->q_rx.rge_rx_list[idx];
>  
>       if (RGE_OWN(r)) {
>               printf("%s: tried to map busy RX descriptor\n",
> @@ -1115,21 +1117,22 @@ rge_newbuf(struct rge_softc *sc)
>  
>       r->rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
>  
> -     bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
> +     bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
>           idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
>           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
>  
> -     sc->rge_ldata.rge_rxq_prodidx = RGE_NEXT_RX_DESC(idx);
> +     q->q_rx.rge_rxq_prodidx = RGE_NEXT_RX_DESC(idx);
>  
>       return (0);
>  }
>  
>  void
> -rge_discard_rxbuf(struct rge_softc *sc, int idx)
> +rge_discard_rxbuf(struct rge_queues *q, int idx)
>  {
> +     struct rge_softc *sc = q->q_sc;
>       struct rge_rx_desc *r;
>  
> -     r = &sc->rge_ldata.rge_rx_list[idx];
> +     r = &q->q_rx.rge_rx_list[idx];
>  
>       r->rge_cmdsts = htole32(RGE_JUMBO_FRAMELEN);
>       r->rge_extsts = 0;
> @@ -1137,73 +1140,75 @@ rge_discard_rxbuf(struct rge_softc *sc, 
>               r->rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
>       r->rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
>  
> -     bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
> +     bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
>           idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
>           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
>  }
>  
>  void
> -rge_rx_list_init(struct rge_softc *sc)
> +rge_rx_list_init(struct rge_queues *q)
>  {
> -     memset(sc->rge_ldata.rge_rx_list, 0, RGE_RX_LIST_SZ);
> +     memset(q->q_rx.rge_rx_list, 0, RGE_RX_LIST_SZ);
>  
> -     sc->rge_ldata.rge_rxq_prodidx = sc->rge_ldata.rge_rxq_considx = 0;
> -     sc->rge_head = sc->rge_tail = NULL;
> +     q->q_rx.rge_rxq_prodidx = q->q_rx.rge_rxq_considx = 0;
> +     q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
>  
> -     if_rxr_init(&sc->rge_ldata.rge_rx_ring, 2, RGE_RX_LIST_CNT - 1);
> -     rge_fill_rx_ring(sc);
> +     if_rxr_init(&q->q_rx.rge_rx_ring, 2, RGE_RX_LIST_CNT - 1);
> +     rge_fill_rx_ring(q);
>  }
>  
>  void
> -rge_fill_rx_ring(struct rge_softc *sc)
> +rge_fill_rx_ring(struct rge_queues *q)
>  {
> -     struct if_rxring *rxr = &sc->rge_ldata.rge_rx_ring;
> +     struct if_rxring *rxr = &q->q_rx.rge_rx_ring;
>       int slots;
>  
>       for (slots = if_rxr_get(rxr, RGE_RX_LIST_CNT); slots > 0; slots--) {
> -             if (rge_newbuf(sc) == ENOBUFS)
> +             if (rge_newbuf(q) == ENOBUFS)
>                       break;
>       }
>       if_rxr_put(rxr, slots);
>  }
>  
>  void
> -rge_tx_list_init(struct rge_softc *sc)
> +rge_tx_list_init(struct rge_queues *q)
>  {
> +     struct rge_softc *sc = q->q_sc;
>       int i;
>  
> -     memset(sc->rge_ldata.rge_tx_list, 0, RGE_TX_LIST_SZ);
> +     memset(q->q_tx.rge_tx_list, 0, RGE_TX_LIST_SZ);
>  
>       for (i = 0; i < RGE_TX_LIST_CNT; i++)
> -             sc->rge_ldata.rge_txq[i].txq_mbuf = NULL;
> +             q->q_tx.rge_txq[i].txq_mbuf = NULL;
>  
> -     bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map, 0,
> -         sc->rge_ldata.rge_tx_list_map->dm_mapsize,
> +     bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map, 0,
> +         q->q_tx.rge_tx_list_map->dm_mapsize,
>           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
>  
> -     sc->rge_ldata.rge_txq_prodidx = sc->rge_ldata.rge_txq_considx = 0;
> +     q->q_tx.rge_txq_prodidx = q->q_tx.rge_txq_considx = 0;
>  }
>  
>  int
> -rge_rxeof(struct rge_softc *sc)
> +rge_rxeof(struct rge_queues *q)
>  {
> +     struct rge_softc *sc = q->q_sc;
>       struct mbuf_list ml = MBUF_LIST_INITIALIZER();
>       struct mbuf *m;
>       struct ifnet *ifp = &sc->sc_arpcom.ac_if;
> -     struct if_rxring *rxr = &sc->rge_ldata.rge_rx_ring;
> +     struct if_rxring *rxr = &q->q_rx.rge_rx_ring;
>       struct rge_rx_desc *cur_rx;
>       struct rge_rxq *rxq;
>       uint32_t rxstat, extsts;
>       int i, total_len, rx = 0;
>  
> -     for (i = sc->rge_ldata.rge_rxq_considx; if_rxr_inuse(rxr) > 0;
> +     for (i = q->q_rx.rge_rxq_considx; if_rxr_inuse(rxr) > 0;
>           i = RGE_NEXT_RX_DESC(i)) {
>               /* Invalidate the descriptor memory. */
> -             bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
> +             bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
>                   i * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
>                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
>  
> -             cur_rx = &sc->rge_ldata.rge_rx_list[i];
> +             cur_rx = &q->q_rx.rge_rx_list[i];
>  
>               if (RGE_OWN(cur_rx))
>                       break;
> @@ -1212,7 +1217,7 @@ rge_rxeof(struct rge_softc *sc)
>               extsts = letoh32(cur_rx->rge_extsts);
>               
>               total_len = RGE_RXBYTES(cur_rx);
> -             rxq = &sc->rge_ldata.rge_rxq[i];
> +             rxq = &q->q_rx.rge_rxq[i];
>               m = rxq->rxq_mbuf;
>               rxq->rxq_mbuf = NULL;
>               if_rxr_put(rxr, 1);
> @@ -1225,7 +1230,7 @@ rge_rxeof(struct rge_softc *sc)
>  
>               if ((rxstat & (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) !=
>                   (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) {
> -                     rge_discard_rxbuf(sc, i);
> +                     rge_discard_rxbuf(q, i);
>                       continue;
>               }
>  
> @@ -1235,15 +1240,15 @@ rge_rxeof(struct rge_softc *sc)
>                        * If this is part of a multi-fragment packet,
>                        * discard all the pieces.
>                        */
> -                      if (sc->rge_head != NULL) {
> -                             m_freem(sc->rge_head);
> -                             sc->rge_head = sc->rge_tail = NULL;
> +                      if (q->q_rx.rge_head != NULL) {
> +                             m_freem(q->q_rx.rge_head);
> +                             q->q_rx.rge_head = q->q_rx.rge_head = NULL;
>                       }
> -                     rge_discard_rxbuf(sc, i);
> +                     rge_discard_rxbuf(q, i);
>                       continue;
>               }
>  
> -             if (sc->rge_head != NULL) {
> +             if (q->q_rx.rge_head != NULL) {
>                       m->m_len = total_len;
>                       /*
>                        * Special case: if there's 4 bytes or less
> @@ -1252,16 +1257,16 @@ rge_rxeof(struct rge_softc *sc)
>                        * care about anyway.
>                        */
>                       if (m->m_len <= ETHER_CRC_LEN) {
> -                             sc->rge_tail->m_len -=
> +                             q->q_rx.rge_tail->m_len -=
>                                   (ETHER_CRC_LEN - m->m_len);
>                               m_freem(m);
>                       } else {
>                               m->m_len -= ETHER_CRC_LEN;
>                               m->m_flags &= ~M_PKTHDR;
> -                             sc->rge_tail->m_next = m;
> +                             q->q_rx.rge_tail->m_next = m;
>                       }
> -                     m = sc->rge_head;
> -                     sc->rge_head = sc->rge_tail = NULL;
> +                     m = q->q_rx.rge_head;
> +                     q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
>                       m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
>               } else
>                       m->m_pkthdr.len = m->m_len =
> @@ -1295,36 +1300,35 @@ rge_rxeof(struct rge_softc *sc)
>       if (ifiq_input(&ifp->if_rcv, &ml))
>               if_rxr_livelocked(rxr);
>  
> -     sc->rge_ldata.rge_rxq_considx = i;
> -     rge_fill_rx_ring(sc);
> -
> -     if_input(ifp, &ml);
> +     q->q_rx.rge_rxq_considx = i;
> +     rge_fill_rx_ring(q);
>  
>       return (rx);
>  }
>  
>  int
> -rge_txeof(struct rge_softc *sc)
> +rge_txeof(struct rge_queues *q)
>  {
> +     struct rge_softc *sc = q->q_sc;
>       struct ifnet *ifp = &sc->sc_arpcom.ac_if;
>       struct rge_txq *txq;
>       uint32_t txstat;
>       int cons, idx, prod;
>       int free = 0;
>  
> -     prod = sc->rge_ldata.rge_txq_prodidx;
> -     cons = sc->rge_ldata.rge_txq_considx;
> +     prod = q->q_tx.rge_txq_prodidx;
> +     cons = q->q_tx.rge_txq_considx;
>  
>       while (prod != cons) {
> -             txq = &sc->rge_ldata.rge_txq[cons];
> +             txq = &q->q_tx.rge_txq[cons];
>               idx = txq->txq_descidx;
>  
> -             bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
> +             bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map,
>                   idx * sizeof(struct rge_tx_desc),
>                   sizeof(struct rge_tx_desc),
>                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
>  
> -             txstat = letoh32(sc->rge_ldata.rge_tx_list[idx].rge_cmdsts);
> +             txstat = letoh32(q->q_tx.rge_tx_list[idx].rge_cmdsts);
>  
>               if (txstat & RGE_TDCMDSTS_OWN) {
>                       free = 2;
> @@ -1342,7 +1346,7 @@ rge_txeof(struct rge_softc *sc)
>               if (txstat & RGE_TDCMDSTS_TXERR)
>                       ifp->if_oerrors++;
>  
> -             bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
> +             bus_dmamap_sync(sc->sc_dmat, q->q_tx.rge_tx_list_map,
>                   idx * sizeof(struct rge_tx_desc),
>                   sizeof(struct rge_tx_desc),
>                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
> @@ -1354,7 +1358,7 @@ rge_txeof(struct rge_softc *sc)
>       if (free == 0)
>               return (0);
>  
> -     sc->rge_ldata.rge_txq_considx = cons;
> +     q->q_tx.rge_txq_considx = cons;
>  
>       if (ifq_is_oactive(&ifp->if_snd))
>               ifq_restart(&ifp->if_snd);
> @@ -1900,11 +1904,6 @@ rge_phy_config_mac_cfg5(struct rge_softc
>               rge_write_ephy(sc, rtl8125_mac_cfg5_ephy[i].reg,
>                   rtl8125_mac_cfg5_ephy[i].val);
>  
> -     val = rge_read_ephy(sc, 0x0022) & ~0x0030;
> -     rge_write_ephy(sc, 0x0022, val | 0x0020);
> -     val = rge_read_ephy(sc, 0x0062) & ~0x0030;
> -     rge_write_ephy(sc, 0x0062, val | 0x0020);
> -
>       rge_phy_config_mcu(sc, RGE_MAC_CFG5_MCODE_VER);
>  
>       RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
> @@ -1932,6 +1931,9 @@ rge_phy_config_mac_cfg5(struct rge_softc
>       RGE_PHY_SETBIT(sc, 0xa4ca, 0x0040);
>       val = rge_read_phy_ocp(sc, 0xbf84) & ~0xe000;
>       rge_write_phy_ocp(sc, 0xbf84, val | 0xa000);
> +     rge_write_phy_ocp(sc, 0xa436, 0x8170);
> +     val = rge_read_phy_ocp(sc, 0xa438) & ~0x2700;
> +     rge_write_phy_ocp(sc, 0xa438, val | 0xd800);
>  }
>  
>  void
> @@ -2111,14 +2113,9 @@ rge_config_imtype(struct rge_softc *sc, 
>       switch (imtype) {
>       case RGE_IMTYPE_NONE:
>               sc->rge_intrs = RGE_INTRS;
> -             sc->rge_rx_ack = RGE_ISR_RX_OK | RGE_ISR_RX_DESC_UNAVAIL |
> -                 RGE_ISR_RX_FIFO_OFLOW;
> -             sc->rge_tx_ack = RGE_ISR_TX_OK;
>               break;
>       case RGE_IMTYPE_SIM:
>               sc->rge_intrs = RGE_INTRS_TIMER;
> -             sc->rge_rx_ack = RGE_ISR_PCS_TIMEOUT;
> -             sc->rge_tx_ack = RGE_ISR_PCS_TIMEOUT;
>               break;
>       default:
>               panic("%s: unknown imtype %d", sc->sc_dev.dv_xname, imtype);
> Index: sys/dev/pci/if_rgereg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_rgereg.h,v
> retrieving revision 1.6
> diff -u -p -u -p -r1.6 if_rgereg.h
> --- sys/dev/pci/if_rgereg.h   24 Dec 2020 01:00:00 -0000      1.6
> +++ sys/dev/pci/if_rgereg.h   25 Mar 2021 09:14:17 -0000
> @@ -65,6 +65,8 @@
>  #define RGE_PHYBASE          0x0a40
>  #define RGE_ADDR0            0x19e0
>  #define RGE_ADDR1            0x19e4
> +#define RGE_RSS_CTRL         0x4500
> +#define RGE_RXQUEUE_CTRL     0x4800
>  #define RGE_EEE_TXIDLE_TIMER 0x6048
>  
>  /* Flags for register RGE_CMD */
> @@ -251,30 +253,47 @@ struct rge_rxq {
>       bus_dmamap_t            rxq_dmamap;
>  };
>  
> -struct rge_list_data {
> +struct rge_tx {
>       struct rge_txq          rge_txq[RGE_TX_LIST_CNT];
>       int                     rge_txq_prodidx;
>       int                     rge_txq_considx;
> -     struct rge_rxq          rge_rxq[RGE_RX_LIST_CNT];
> -     int                     rge_rxq_prodidx;
> -     int                     rge_rxq_considx;
>  
>       bus_dma_segment_t       rge_tx_listseg;
>       int                     rge_tx_listnseg;
>       bus_dmamap_t            rge_tx_list_map;
>       struct rge_tx_desc      *rge_tx_list;
> +};
> +
> +struct rge_rx {
> +     struct rge_rxq          rge_rxq[RGE_RX_LIST_CNT];
> +     int                     rge_rxq_prodidx;
> +     int                     rge_rxq_considx;
> +
>       struct if_rxring        rge_rx_ring;
>       bus_dma_segment_t       rge_rx_listseg;
>       int                     rge_rx_listnseg;
>       bus_dmamap_t            rge_rx_list_map;
>       struct rge_rx_desc      *rge_rx_list;
> +
> +     struct mbuf             *rge_head;
> +     struct mbuf             *rge_tail;
> +};
> +
> +struct rge_queues {
> +     struct rge_softc        *q_sc;
> +     void                    *q_ihc;
> +     int                     q_index;
> +     char                    q_name[16];
> +     pci_intr_handle_t       q_ih;
> +     struct rge_tx           q_tx;
> +     struct rge_rx           q_rx;
>  };
>  
>  /* Microcode version */
>  #define RGE_MAC_CFG2_MCODE_VER       0x0b11
>  #define RGE_MAC_CFG3_MCODE_VER       0x0b33
>  #define RGE_MAC_CFG4_MCODE_VER       0x0b17
> -#define RGE_MAC_CFG5_MCODE_VER       0x0b36
> +#define RGE_MAC_CFG5_MCODE_VER       0x0b55
>  
>  enum rge_mac_type {
>       MAC_CFG_UNKNOWN = 1,
> @@ -304,14 +323,11 @@ struct rge_softc {
>       bus_dma_tag_t           sc_dmat;
>       pci_chipset_tag_t       sc_pc;
>       pcitag_t                sc_tag;
> -     bus_dma_segment_t       sc_rx_seg;
> -     bus_dmamap_t            sc_rx_dmamap;
>       struct ifmedia          sc_media;       /* media info */
>       enum rge_mac_type       rge_type;
> -     struct mbuf             *rge_head;
> -     struct mbuf             *rge_tail;
>  
> -     struct rge_list_data    rge_ldata;
> +     struct rge_queues       *sc_queues;
> +     unsigned int            sc_nqueues;
>  
>       struct task             sc_task;
>  
> @@ -322,8 +338,6 @@ struct rge_softc {
>  #define RGE_FLAG_MSI         0x00000001
>  
>       uint32_t                rge_intrs;
> -     uint32_t                rge_tx_ack;
> -     uint32_t                rge_rx_ack;
>       int                     rge_timerintr;
>  #define RGE_IMTYPE_NONE              0
>  #define RGE_IMTYPE_SIM               1
> @@ -522,8 +536,8 @@ static const struct {
>       { 0x0062, 0x0013 }, { 0x0063, 0xbb66 }, { 0x004b, 0xa909 },
>       { 0x0069, 0xff04 }, { 0x005b, 0x1ea0 }
>  }, rtl8125_mac_cfg5_ephy[] = {
> -     { 0x000b, 0xa908 }, { 0x001e, 0x20eb }, { 0x004b, 0xa908 },
> -     { 0x005e, 0x20eb }
> +     { 0x000b, 0xa908 }, { 0x0022, 0x0023 }, { 0x001e, 0x28eb },
> +     { 0x004b, 0xa908 }, { 0x0062, 0x0023 }, { 0x005e, 0x28eb }
>  };
>  
>  #define RTL8125_MAC_CFG2_MCU \
> @@ -4431,8 +4445,16 @@ static const struct {
>       { 0xa438, 0xd503 },     \
>       { 0xa438, 0x1800 },     \
>       { 0xa438, 0x0c94 },     \
> +     { 0xa438, 0xa802 },     \
> +     { 0xa438, 0xa301 },     \
> +     { 0xa438, 0xa801 },     \
> +     { 0xa438, 0xc004 },     \
> +     { 0xa438, 0xd710 },     \
> +     { 0xa438, 0x4000 },     \
> +     { 0xa438, 0x1800 },     \
> +     { 0xa438, 0x1e79 },     \
>       { 0xa436, 0xa026 },     \
> -     { 0xa438, 0xffff },     \
> +     { 0xa438, 0x1e78 },     \
>       { 0xa436, 0xa024 },     \
>       { 0xa438, 0x0c93 },     \
>       { 0xa436, 0xa022 },     \
> @@ -4448,7 +4470,7 @@ static const struct {
>       { 0xa436, 0xa000 },     \
>       { 0xa438, 0x0fc7 },     \
>       { 0xa436, 0xa008 },     \
> -     { 0xa438, 0x7f00 },     \
> +     { 0xa438, 0xff00 },     \
>       { 0xa436, 0xa016 },     \
>       { 0xa438, 0x0010 },     \
>       { 0xa436, 0xa012 },     \
> @@ -4957,6 +4979,308 @@ static const struct {
>       { 0xa436, 0xb838 },     \
>       { 0xa438, 0x000f },     \
>       { 0xb820, 0x0010 },     \
> +     { 0xa436, 0x846e },     \
> +     { 0xa438, 0xaf84 },     \
> +     { 0xa438, 0x86af },     \
> +     { 0xa438, 0x8690 },     \
> +     { 0xa438, 0xaf86 },     \
> +     { 0xa438, 0xa4af },     \
> +     { 0xa438, 0x86a4 },     \
> +     { 0xa438, 0xaf86 },     \
> +     { 0xa438, 0xa4af },     \
> +     { 0xa438, 0x86a4 },     \
> +     { 0xa438, 0xaf86 },     \
> +     { 0xa438, 0xa4af },     \
> +     { 0xa438, 0x86a4 },     \
> +     { 0xa438, 0xee82 },     \
> +     { 0xa438, 0x5f00 },     \
> +     { 0xa438, 0x0284 },     \
> +     { 0xa438, 0x90af },     \
> +     { 0xa438, 0x0441 },     \
> +     { 0xa438, 0xf8e0 },     \
> +     { 0xa438, 0x8ff3 },     \
> +     { 0xa438, 0xa000 },     \
> +     { 0xa438, 0x0502 },     \
> +     { 0xa438, 0x84a4 },     \
> +     { 0xa438, 0xae06 },     \
> +     { 0xa438, 0xa001 },     \
> +     { 0xa438, 0x0302 },     \
> +     { 0xa438, 0x84c8 },     \
> +     { 0xa438, 0xfc04 },     \
> +     { 0xa438, 0xf8f9 },     \
> +     { 0xa438, 0xef59 },     \
> +     { 0xa438, 0xe080 },     \
> +     { 0xa438, 0x15ad },     \
> +     { 0xa438, 0x2702 },     \
> +     { 0xa438, 0xae03 },     \
> +     { 0xa438, 0xaf84 },     \
> +     { 0xa438, 0xc3bf },     \
> +     { 0xa438, 0x53ca },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8ad },     \
> +     { 0xa438, 0x2807 },     \
> +     { 0xa438, 0x0285 },     \
> +     { 0xa438, 0x2cee },     \
> +     { 0xa438, 0x8ff3 },     \
> +     { 0xa438, 0x01ef },     \
> +     { 0xa438, 0x95fd },     \
> +     { 0xa438, 0xfc04 },     \
> +     { 0xa438, 0xf8f9 },     \
> +     { 0xa438, 0xfaef },     \
> +     { 0xa438, 0x69bf },     \
> +     { 0xa438, 0x53ca },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8ac },     \
> +     { 0xa438, 0x2822 },     \
> +     { 0xa438, 0xd480 },     \
> +     { 0xa438, 0x00bf },     \
> +     { 0xa438, 0x8684 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9bf },     \
> +     { 0xa438, 0x8687 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9bf },     \
> +     { 0xa438, 0x868a },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9bf },     \
> +     { 0xa438, 0x868d },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9ee },     \
> +     { 0xa438, 0x8ff3 },     \
> +     { 0xa438, 0x00af },     \
> +     { 0xa438, 0x8526 },     \
> +     { 0xa438, 0xe08f },     \
> +     { 0xa438, 0xf4e1 },     \
> +     { 0xa438, 0x8ff5 },     \
> +     { 0xa438, 0xe28f },     \
> +     { 0xa438, 0xf6e3 },     \
> +     { 0xa438, 0x8ff7 },     \
> +     { 0xa438, 0x1b45 },     \
> +     { 0xa438, 0xac27 },     \
> +     { 0xa438, 0x0eee },     \
> +     { 0xa438, 0x8ff4 },     \
> +     { 0xa438, 0x00ee },     \
> +     { 0xa438, 0x8ff5 },     \
> +     { 0xa438, 0x0002 },     \
> +     { 0xa438, 0x852c },     \
> +     { 0xa438, 0xaf85 },     \
> +     { 0xa438, 0x26e0 },     \
> +     { 0xa438, 0x8ff4 },     \
> +     { 0xa438, 0xe18f },     \
> +     { 0xa438, 0xf52c },     \
> +     { 0xa438, 0x0001 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xf4e5 },     \
> +     { 0xa438, 0x8ff5 },     \
> +     { 0xa438, 0xef96 },     \
> +     { 0xa438, 0xfefd },     \
> +     { 0xa438, 0xfc04 },     \
> +     { 0xa438, 0xf8f9 },     \
> +     { 0xa438, 0xef59 },     \
> +     { 0xa438, 0xbf53 },     \
> +     { 0xa438, 0x2202 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xa18b },     \
> +     { 0xa438, 0x02ae },     \
> +     { 0xa438, 0x03af },     \
> +     { 0xa438, 0x85da },     \
> +     { 0xa438, 0xbf57 },     \
> +     { 0xa438, 0x7202 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xf8e5 },     \
> +     { 0xa438, 0x8ff9 },     \
> +     { 0xa438, 0xbf57 },     \
> +     { 0xa438, 0x7502 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xfae5 },     \
> +     { 0xa438, 0x8ffb },     \
> +     { 0xa438, 0xbf57 },     \
> +     { 0xa438, 0x7802 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xfce5 },     \
> +     { 0xa438, 0x8ffd },     \
> +     { 0xa438, 0xbf57 },     \
> +     { 0xa438, 0x7b02 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xfee5 },     \
> +     { 0xa438, 0x8fff },     \
> +     { 0xa438, 0xbf57 },     \
> +     { 0xa438, 0x6c02 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xa102 },     \
> +     { 0xa438, 0x13ee },     \
> +     { 0xa438, 0x8ffc },     \
> +     { 0xa438, 0x80ee },     \
> +     { 0xa438, 0x8ffd },     \
> +     { 0xa438, 0x00ee },     \
> +     { 0xa438, 0x8ffe },     \
> +     { 0xa438, 0x80ee },     \
> +     { 0xa438, 0x8fff },     \
> +     { 0xa438, 0x00af },     \
> +     { 0xa438, 0x8599 },     \
> +     { 0xa438, 0xa101 },     \
> +     { 0xa438, 0x0cbf },     \
> +     { 0xa438, 0x534c },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8a1 },     \
> +     { 0xa438, 0x0303 },     \
> +     { 0xa438, 0xaf85 },     \
> +     { 0xa438, 0x77bf },     \
> +     { 0xa438, 0x5322 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8a1 },     \
> +     { 0xa438, 0x8b02 },     \
> +     { 0xa438, 0xae03 },     \
> +     { 0xa438, 0xaf86 },     \
> +     { 0xa438, 0x64e0 },     \
> +     { 0xa438, 0x8ff8 },     \
> +     { 0xa438, 0xe18f },     \
> +     { 0xa438, 0xf9bf },     \
> +     { 0xa438, 0x8684 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9e0 },     \
> +     { 0xa438, 0x8ffa },     \
> +     { 0xa438, 0xe18f },     \
> +     { 0xa438, 0xfbbf },     \
> +     { 0xa438, 0x8687 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9e0 },     \
> +     { 0xa438, 0x8ffc },     \
> +     { 0xa438, 0xe18f },     \
> +     { 0xa438, 0xfdbf },     \
> +     { 0xa438, 0x868a },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9e0 },     \
> +     { 0xa438, 0x8ffe },     \
> +     { 0xa438, 0xe18f },     \
> +     { 0xa438, 0xffbf },     \
> +     { 0xa438, 0x868d },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9af },     \
> +     { 0xa438, 0x867f },     \
> +     { 0xa438, 0xbf53 },     \
> +     { 0xa438, 0x2202 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xa144 },     \
> +     { 0xa438, 0x3cbf },     \
> +     { 0xa438, 0x547b },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8e4 },     \
> +     { 0xa438, 0x8ff8 },     \
> +     { 0xa438, 0xe58f },     \
> +     { 0xa438, 0xf9bf },     \
> +     { 0xa438, 0x547e },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8e4 },     \
> +     { 0xa438, 0x8ffa },     \
> +     { 0xa438, 0xe58f },     \
> +     { 0xa438, 0xfbbf },     \
> +     { 0xa438, 0x5481 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8e4 },     \
> +     { 0xa438, 0x8ffc },     \
> +     { 0xa438, 0xe58f },     \
> +     { 0xa438, 0xfdbf },     \
> +     { 0xa438, 0x5484 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8e4 },     \
> +     { 0xa438, 0x8ffe },     \
> +     { 0xa438, 0xe58f },     \
> +     { 0xa438, 0xffbf },     \
> +     { 0xa438, 0x5322 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8a1 },     \
> +     { 0xa438, 0x4448 },     \
> +     { 0xa438, 0xaf85 },     \
> +     { 0xa438, 0xa7bf },     \
> +     { 0xa438, 0x5322 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xc8a1 },     \
> +     { 0xa438, 0x313c },     \
> +     { 0xa438, 0xbf54 },     \
> +     { 0xa438, 0x7b02 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xf8e5 },     \
> +     { 0xa438, 0x8ff9 },     \
> +     { 0xa438, 0xbf54 },     \
> +     { 0xa438, 0x7e02 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xfae5 },     \
> +     { 0xa438, 0x8ffb },     \
> +     { 0xa438, 0xbf54 },     \
> +     { 0xa438, 0x8102 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xfce5 },     \
> +     { 0xa438, 0x8ffd },     \
> +     { 0xa438, 0xbf54 },     \
> +     { 0xa438, 0x8402 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xe48f },     \
> +     { 0xa438, 0xfee5 },     \
> +     { 0xa438, 0x8fff },     \
> +     { 0xa438, 0xbf53 },     \
> +     { 0xa438, 0x2202 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xa131 },     \
> +     { 0xa438, 0x03af },     \
> +     { 0xa438, 0x85a7 },     \
> +     { 0xa438, 0xd480 },     \
> +     { 0xa438, 0x00bf },     \
> +     { 0xa438, 0x8684 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9bf },     \
> +     { 0xa438, 0x8687 },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9bf },     \
> +     { 0xa438, 0x868a },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9bf },     \
> +     { 0xa438, 0x868d },     \
> +     { 0xa438, 0x0252 },     \
> +     { 0xa438, 0xa9ef },     \
> +     { 0xa438, 0x95fd },     \
> +     { 0xa438, 0xfc04 },     \
> +     { 0xa438, 0xf0d1 },     \
> +     { 0xa438, 0x2af0 },     \
> +     { 0xa438, 0xd12c },     \
> +     { 0xa438, 0xf0d1 },     \
> +     { 0xa438, 0x44f0 },     \
> +     { 0xa438, 0xd146 },     \
> +     { 0xa438, 0xbf86 },     \
> +     { 0xa438, 0xa102 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xbf86 },     \
> +     { 0xa438, 0xa102 },     \
> +     { 0xa438, 0x52c8 },     \
> +     { 0xa438, 0xd101 },     \
> +     { 0xa438, 0xaf06 },     \
> +     { 0xa438, 0xa570 },     \
> +     { 0xa438, 0xce42 },     \
> +     { 0xa436, 0xb818 },     \
> +     { 0xa438, 0x043d },     \
> +     { 0xa436, 0xb81a },     \
> +     { 0xa438, 0x06a3 },     \
> +     { 0xa436, 0xb81c },     \
> +     { 0xa438, 0xffff },     \
> +     { 0xa436, 0xb81e },     \
> +     { 0xa438, 0xffff },     \
> +     { 0xa436, 0xb850 },     \
> +     { 0xa438, 0xffff },     \
> +     { 0xa436, 0xb852 },     \
> +     { 0xa438, 0xffff },     \
> +     { 0xa436, 0xb878 },     \
> +     { 0xa438, 0xffff },     \
> +     { 0xa436, 0xb884 },     \
> +     { 0xa438, 0xffff },     \
> +     { 0xa436, 0xb832 },     \
> +     { 0xa438, 0x0003 },     \
>       { 0xa436, 0x0000 },     \
>       { 0xa438, 0x0000 },     \
>       { 0xa436, 0xb82e },     \
> @@ -4965,4 +5289,4 @@ static const struct {
>       { 0xa438, 0x0000 },     \
>       { 0xb820, 0x0000 },     \
>       { 0xa436, 0x801e },     \
> -     { 0xa438, 0x0016 }
> +     { 0xa438, 0x0019 }
> 

Reply via email to