and then shift and mask the interesting bits out.

this works on an overdrive 1000, where i discovered that arm64 appears
to have a single instruction for shift/mask.

maybe too much churn to be worth it?

Index: if_msk.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_msk.c,v
retrieving revision 1.137
diff -u -p -r1.137 if_msk.c
--- if_msk.c    5 Jan 2022 03:53:26 -0000       1.137
+++ if_msk.c    6 Jan 2022 00:38:18 -0000
@@ -120,6 +120,53 @@
 #include <dev/pci/if_skreg.h>
 #include <dev/pci/if_mskvar.h>
 
+#define MSK_STATUS_OWN_SHIFT           63
+#define MSK_STATUS_OWN_MASK            0x1
+#define MSK_STATUS_OPCODE_SHIFT                56
+#define MSK_STATUS_OPCODE_MASK         0x7f
+
+#define MSK_STATUS_OWN(_d) \
+    (((_d) >> MSK_STATUS_OWN_SHIFT) & MSK_STATUS_OWN_MASK)
+#define MSK_STATUS_OPCODE(_d) \
+    (((_d) >> MSK_STATUS_OPCODE_SHIFT) & MSK_STATUS_OPCODE_MASK)
+
+#define MSK_STATUS_OPCODE_RXSTAT       0x60
+#define MSK_STATUS_OPCODE_RXTIMESTAMP  0x61
+#define MSK_STATUS_OPCODE_RXVLAN       0x62
+#define MSK_STATUS_OPCODE_RXCKSUM      0x64
+#define MSK_STATUS_OPCODE_RXCKSUMVLAN  \
+    (MSK_STATUS_OPCODE_RXVLAN | MSK_STATUS_OPCODE_RXCKSUM)
+#define MSK_STATUS_OPCODE_RXTIMEVLAN   \
+    (MSK_STATUS_OPCODE_RXVLAN | MSK_STATUS_OPCODE_RXTIMESTAMP)
+#define MSK_STATUS_OPCODE_RSS_HASH     0x65
+#define MSK_STATUS_OPCODE_TXIDX                0x68
+#define MSK_STATUS_OPCODE_MACSEC       0x6c
+#define MSK_STATUS_OPCODE_PUTIDX       0x70
+
+#define MSK_STATUS_RXSTAT_PORT_SHIFT   48
+#define MSK_STATUS_RXSTAT_PORT_MASK    0x1
+#define MSK_STATUS_RXSTAT_LEN_SHIFT    32
+#define MSK_STATUS_RXSTAT_LEN_MASK     0xffff
+#define MSK_STATUS_RXSTAT_STATUS_SHIFT 0
+#define MSK_STATUS_RXSTAT_STATUS_MASK  0xffffffff
+
+#define MSK_STATUS_RXSTAT_PORT(_d) \
+    (((_d) >> MSK_STATUS_RXSTAT_PORT_SHIFT) & MSK_STATUS_RXSTAT_PORT_MASK)
+#define MSK_STATUS_RXSTAT_LEN(_d) \
+    (((_d) >> MSK_STATUS_RXSTAT_LEN_SHIFT) & MSK_STATUS_RXSTAT_LEN_MASK)
+#define MSK_STATUS_RXSTAT_STATUS(_d) \
+    (((_d) >> MSK_STATUS_RXSTAT_STATUS_SHIFT) & MSK_STATUS_RXSTAT_STATUS_MASK)
+
+#define MSK_STATUS_TXIDX_PORTA_SHIFT   0
+#define MSK_STATUS_TXIDX_PORTA_MASK    0xfff
+#define MSK_STATUS_TXIDX_PORTB_SHIFT   24
+#define MSK_STATUS_TXIDX_PORTB_MASK    0xfff
+
+#define MSK_STATUS_TXIDX_PORTA(_d) \
+    (((_d) >> MSK_STATUS_TXIDX_PORTA_SHIFT) & MSK_STATUS_TXIDX_PORTA_MASK)
+#define MSK_STATUS_TXIDX_PORTB(_d) \
+    (((_d) >> MSK_STATUS_TXIDX_PORTB_SHIFT) & MSK_STATUS_TXIDX_PORTB_MASK)
+
 int mskc_probe(struct device *, void *, void *);
 void mskc_attach(struct device *, struct device *self, void *aux);
 int mskc_detach(struct device *, int);
@@ -624,6 +671,7 @@ mskc_reset(struct sk_softc *sc)
 {
        u_int32_t imtimer_ticks, reg1;
        int reg;
+       unsigned int i;
 
        DPRINTFN(2, ("mskc_reset\n"));
 
@@ -758,8 +806,8 @@ mskc_reset(struct sk_softc *sc)
        }
 
        /* Reset status ring. */
-       bzero(sc->sk_status_ring,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
+       for (i = 0; i < MSK_STATUS_RING_CNT; i++)
+               sc->sk_status_ring[i] = htole64(0);
        sc->sk_status_idx = 0;
 
        sk_win_write_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_RESET);
@@ -1138,8 +1186,8 @@ mskc_attach(struct device *parent, struc
        sc->sk_pc = pc;
 
        if (bus_dmamem_alloc(sc->sc_dmatag,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
+           MSK_STATUS_RING_CNT * sizeof(uint64_t),
+           MSK_STATUS_RING_CNT * sizeof(uint64_t),
            0, &sc->sk_status_seg, 1, &sc->sk_status_nseg,
            BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
                printf(": can't alloc status buffers\n");
@@ -1148,27 +1196,27 @@ mskc_attach(struct device *parent, struc
 
        if (bus_dmamem_map(sc->sc_dmatag,
            &sc->sk_status_seg, sc->sk_status_nseg,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
+           MSK_STATUS_RING_CNT * sizeof(uint64_t),
            &kva, BUS_DMA_NOWAIT)) {
-               printf(": can't map dma buffers (%lu bytes)\n",
-                   (ulong)(MSK_STATUS_RING_CNT * sizeof(struct 
msk_status_desc)));
+               printf(": can't map dma buffers (%zu bytes)\n",
+                   MSK_STATUS_RING_CNT * sizeof(uint64_t));
                goto fail_3;
        }
        if (bus_dmamap_create(sc->sc_dmatag,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 1,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), 0,
+           MSK_STATUS_RING_CNT * sizeof(uint64_t), 1,
+           MSK_STATUS_RING_CNT * sizeof(uint64_t), 0,
            BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
            &sc->sk_status_map)) {
                printf(": can't create dma map\n");
                goto fail_4;
        }
        if (bus_dmamap_load(sc->sc_dmatag, sc->sk_status_map, kva,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
+           MSK_STATUS_RING_CNT * sizeof(uint64_t),
            NULL, BUS_DMA_NOWAIT)) {
                printf(": can't load dma map\n");
                goto fail_5;
        }
-       sc->sk_status_ring = (struct msk_status_desc *)kva;
+       sc->sk_status_ring = (uint64_t *)kva;
 
        /* Reset the adapter. */
        mskc_reset(sc);
@@ -1364,7 +1412,7 @@ mskc_attach(struct device *parent, struc
 
 fail_4:
        bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring,
-           MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
+           MSK_STATUS_RING_CNT * sizeof(uint64_t));
 fail_3:
        bus_dmamem_free(sc->sc_dmatag,
            &sc->sk_status_seg, sc->sk_status_nseg);
@@ -1395,7 +1443,7 @@ mskc_detach(struct device *self, int fla
        if (sc->sk_status_nseg > 0) {
                bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
                bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sk_status_ring,
-                   MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
+                   MSK_STATUS_RING_CNT * sizeof(uint64_t));
                bus_dmamem_free(sc->sc_dmatag,
                    &sc->sk_status_seg, sc->sk_status_nseg);
        }
@@ -1749,7 +1797,6 @@ int
 msk_intr(void *xsc)
 {
        struct sk_softc         *sc = xsc;
-       struct sk_if_softc      *sc_if;
        struct sk_if_softc      *sc_if0 = sc->sk_if[SK_PORT_A];
        struct sk_if_softc      *sc_if1 = sc->sk_if[SK_PORT_B];
        struct mbuf_list        ml[2] = {
@@ -1758,8 +1805,9 @@ msk_intr(void *xsc)
                                };
        struct ifnet            *ifp0 = NULL, *ifp1 = NULL;
        int                     claimed = 0;
-       u_int32_t               status, sk_status;
-       struct msk_status_desc  *cur_st;
+       u_int32_t               status;
+       uint64_t                *ring = sc->sk_status_ring;
+       uint64_t                desc;
 
        status = CSR_READ_4(sc, SK_Y2_ISSR2);
        if (status == 0xffffffff)
@@ -1788,42 +1836,40 @@ msk_intr(void *xsc)
 
        MSK_CDSTSYNC(sc, sc->sk_status_idx,
            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-       cur_st = &sc->sk_status_ring[sc->sk_status_idx];
 
-       while (cur_st->sk_opcode & SK_Y2_STOPC_OWN) {
-               cur_st->sk_opcode &= ~SK_Y2_STOPC_OWN;
-               switch (cur_st->sk_opcode) {
-               case SK_Y2_STOPC_RXSTAT:
-                       sc_if = sc->sk_if[cur_st->sk_link & 0x01];
-                       msk_rxeof(sc_if, &ml[cur_st->sk_link & 0x01],
-                           lemtoh16(&cur_st->sk_len),
-                           lemtoh32(&cur_st->sk_status));
+       while (MSK_STATUS_OWN(desc = lemtoh64(&ring[sc->sk_status_idx]))) {
+               unsigned int opcode, port;
+
+               ring[sc->sk_status_idx] = htole64(0); /* clear ownership */
+
+               opcode = MSK_STATUS_OPCODE(desc);
+               switch (opcode) {
+               case MSK_STATUS_OPCODE_RXSTAT:
+                       port = MSK_STATUS_RXSTAT_PORT(desc);
+                       msk_rxeof(sc->sk_if[port], &ml[port],
+                           MSK_STATUS_RXSTAT_LEN(desc),
+                           MSK_STATUS_RXSTAT_STATUS(desc));
                        break;
                case SK_Y2_STOPC_TXSTAT:
-                       sk_status = lemtoh32(&cur_st->sk_status);
-                       if (sc_if0)
-                               msk_txeof(sc_if0, sk_status & 0xfff);
+                       if (sc_if0) {
+                               msk_txeof(sc_if0,
+                                   MSK_STATUS_TXIDX_PORTA(desc));
+                       }
                        if (sc_if1) {
-                               /*
-                                * this would be easier as a 64bit
-                                * load of the whole status descriptor,
-                                * a shift, and a mask.
-                                */
-                               unsigned int prod = (sk_status >> 24) & 0xff;
-                               prod |= (lemtoh16(&cur_st->sk_len) & 0xf) << 8;
-                               msk_txeof(sc_if1, prod);
+                               msk_txeof(sc_if1,
+                                   MSK_STATUS_TXIDX_PORTB(desc));
                        }
                        break;
                default:
-                       printf("opcode=0x%x\n", cur_st->sk_opcode);
+                       printf("opcode=0x%x\n", opcode);
                        break;
                }
-               SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT);
 
-               MSK_CDSTSYNC(sc, sc->sk_status_idx,
-                   BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
-               cur_st = &sc->sk_status_ring[sc->sk_status_idx];
+               SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT);
        }
+
+       MSK_CDSTSYNC(sc, sc->sk_status_idx,
+           BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 
        if (status & SK_Y2_IMR_BMU) {
                CSR_WRITE_4(sc, SK_STAT_BMU_CSR, SK_STAT_BMU_IRQ_CLEAR);

Reply via email to