Re: rge(4): move tx/rx descriptors into their own structs

2021-03-29 Thread Jonathan Matthew
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 -  1.12
> +++ sys/dev/pci/if_rge.c  25 Mar 2021 09:14:17 -
> @@ -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_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(4): move tx/rx descriptors into their own structs

2021-03-25 Thread Kevin Lo
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.

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.c11 Feb 2021 16:22:06 -  1.12
+++ sys/dev/pci/if_rge.c25 Mar 2021 09:14:17 -
@@ -61,7 +61,7 @@ int   rge_match(struct device *, void *, 
 void   rge_attach(struct device *, struct device *, void *);
 intrge_activate(struct device *, int);
 intrge_intr(void *);
-intrge_encap(struct rge_softc *, struct mbuf *, int);
+intrge_encap(struct rge_queues *, struct mbuf *, int);
 intrge_ioctl(struct ifnet *, u_long, caddr_t);
 void   rge_start(struct ifqueue *);
 void   rge_watchdog(struct ifnet *);
@@ -70,13 +70,13 @@ voidrge_stop(struct ifnet *);
 intrge_ifmedia_upd(struct ifnet *);
 void   rge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 intrge_allocmem(struct rge_softc *);
-intrge_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 *);
-intrge_rxeof(struct rge_softc *);
-intrge_txeof(struct rge_softc *);
+intrge_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 *);
+intrge_rxeof(struct rge_queues *);
+intrge_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_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