On 21/01/20(Tue) 12:31, Martin Pieuchot wrote:
> On 20/01/20(Mon) 16:42, Martin Pieuchot wrote:
> > Diff below is a refactoring of the actual em(4) code and defines that
> > will allows me to present a shorter diff to interrupt multiple CPUs and
> > make use of multiple queues.
> > 
> > It contains the following items:
> > 
> >   - Abstract the allocation/freeing of TX/RX ring into em_dma_malloc().
> >     This will ease the introduction of multiple rings.
> > 
> >   - Split the 82576 variant out of 82575.  The distinction is necessary
> >     when it comes to setting multiple queues.
> > 
> >   - Change multiple TX/RX related macro to take an index argument
> >     corresponding to a ring.  Currently only the index 0 and 1 are used.
> > 
> >   - Gather and print more stats counters
> > 
> >   - Switch to using a function, like FreeBSD, to translate 82542
> >     registers and get rid of a set of defines.
> > 
> > It has been tested one the models below, I'd like to be sure there isn't
> > any fallout with this part before continuing the effort.
> 
> New diff that works with 82576, previous breakage reported by Hrvoje
> Popovski.  So far the following models have been tested, I'm looking for
> more tests :o)

So far this has been tested on the following, I'm confident enough and
would like to move forward, ok?

        em2 at pci0 dev 4 function 0 "Intel 82540EM" rev 0x02: apic 9 int 14
        em1 at pci3 dev 1 function 0 "Intel 82545GM" rev 0x04: apic 4 int 0
        em0 at pci3 dev 1 function 0 "Intel 82546GB" rev 0x03: apic 3 int 0
        em3 at pci2 dev 0 function 0 "Intel 82571EB" rev 0x06: apic 0 int 16
        em0 at pci1 dev 0 function 0 "Intel 82572EI" rev 0x06: apic 0 int 16
        em2 at pci5 dev 0 function 0 "Intel 82573E" rev 0x03: msi
        em3 at pci6 dev 0 function 0 "Intel 82573L" rev 0x00: msi
        em0 at pci3 dev 0 function 0 "Intel 82574L" rev 0x00: msi
        em0 at pci0 dev 2 function 0 "Intel 82575GB" rev 0x02: msi
        em0 at pci1 dev 0 function 0 "Intel 82576" rev 0x01: msi
        em0 at pci0 dev 25 function 0 "Intel 82577LM" rev 0x06: msi
        em0 at pci0 dev 25 function 0 "Intel 82579LM" rev 0x04: msi
        em0 at pci1 dev 0 function 0 "Intel 82583V" rev 0x00: msi
        em0 at pci1 dev 0 function 0 "Intel I210" rev 0x03: msi
        em0 at pci1 dev 0 function 0 "Intel I211" rev 0x03: msi
        em0 at pci0 dev 25 function 0 "Intel I217-LM" rev 0x04: msi
        em0 at pci0 dev 25 function 0 "Intel I218-V" rev 0x03: msi
        em0 at pci0 dev 25 function 0 Intel I218-LM rev 0x04: msi
        em0 at pci0 dev 31 function 6 "Intel I219-V" rev 0x21: msi
        em0 at pci7 dev 0 function 0 "Intel I350" rev 0x01: msi


Index: pci/if_em.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em.c,v
retrieving revision 1.343
diff -u -p -r1.343 if_em.c
--- pci/if_em.c 20 Jan 2020 23:45:02 -0000      1.343
+++ pci/if_em.c 21 Jan 2020 11:27:14 -0000
@@ -260,6 +260,7 @@ void em_disable_aspm(struct em_softc *);
 void em_txeof(struct em_softc *);
 int  em_allocate_receive_structures(struct em_softc *);
 int  em_allocate_transmit_structures(struct em_softc *);
+int  em_allocate_desc_rings(struct em_softc *);
 int  em_rxfill(struct em_softc *);
 void em_rxrefill(void *);
 int  em_rxeof(struct em_softc *);
@@ -344,11 +345,6 @@ em_defer_attach(struct device *self)
 
                em_free_pci_resources(sc);
 
-               sc->sc_rx_desc_ring = NULL;
-               em_dma_free(sc, &sc->sc_rx_dma);
-               sc->sc_tx_desc_ring = NULL;
-               em_dma_free(sc, &sc->sc_tx_dma);
-
                return;
        }
        
@@ -464,6 +460,7 @@ em_attach(struct device *parent, struct 
                case em_82572:
                case em_82574:
                case em_82575:
+               case em_82576:
                case em_82580:
                case em_i210:
                case em_i350:
@@ -494,23 +491,11 @@ em_attach(struct device *parent, struct 
        sc->hw.min_frame_size = 
            ETHER_MIN_LEN + ETHER_CRC_LEN;
 
-       /* Allocate Transmit Descriptor ring */
-       if (em_dma_malloc(sc, sc->sc_tx_slots * sizeof(struct em_tx_desc),
-           &sc->sc_tx_dma) != 0) {
-               printf("%s: Unable to allocate tx_desc memory\n", 
-                      DEVNAME(sc));
-               goto err_tx_desc;
-       }
-       sc->sc_tx_desc_ring = (struct em_tx_desc *)sc->sc_tx_dma.dma_vaddr;
-
-       /* Allocate Receive Descriptor ring */
-       if (em_dma_malloc(sc, sc->sc_rx_slots * sizeof(struct em_rx_desc),
-           &sc->sc_rx_dma) != 0) {
-               printf("%s: Unable to allocate rx_desc memory\n",
-                      DEVNAME(sc));
-               goto err_rx_desc;
+       if (em_allocate_desc_rings(sc) != 0) {
+               printf("%s: Unable to allocate descriptor ring memory\n",
+                   DEVNAME(sc));
+               goto err_pci;
        }
-       sc->sc_rx_desc_ring = (struct em_rx_desc *)sc->sc_rx_dma.dma_vaddr;
 
        /* Initialize the hardware */
        if ((defer = em_hardware_init(sc))) {
@@ -519,11 +504,12 @@ em_attach(struct device *parent, struct 
                else {
                        printf("%s: Unable to initialize the hardware\n",
                            DEVNAME(sc));
-                       goto err_hw_init;
+                       goto err_pci;
                }
        }
 
        if (sc->hw.mac_type == em_80003es2lan || sc->hw.mac_type == em_82575 ||
+           sc->hw.mac_type == em_82576 ||
            sc->hw.mac_type == em_82580 || sc->hw.mac_type == em_i210 ||
            sc->hw.mac_type == em_i350) {
                uint32_t reg = EM_READ_REG(&sc->hw, E1000_STATUS);
@@ -552,7 +538,7 @@ em_attach(struct device *parent, struct 
        if (em_read_mac_addr(&sc->hw) < 0) {
                printf("%s: EEPROM read error while reading mac address\n",
                       DEVNAME(sc));
-               goto err_mac_addr;
+               goto err_pci;
        }
 
        bcopy(sc->hw.mac_addr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
@@ -593,14 +579,6 @@ em_attach(struct device *parent, struct 
        INIT_DEBUGOUT("em_attach: end");
        return;
 
-err_mac_addr:
-err_hw_init:
-       sc->sc_rx_desc_ring = NULL;
-       em_dma_free(sc, &sc->sc_rx_dma);
-err_rx_desc:
-       sc->sc_tx_desc_ring = NULL;
-       em_dma_free(sc, &sc->sc_tx_dma);
-err_tx_desc:
 err_pci:
        em_free_pci_resources(sc);
 }
@@ -678,7 +656,7 @@ em_start(struct ifqueue *ifq)
                        if (sc->link_duplex == HALF_DUPLEX)
                                em_82547_move_tail_locked(sc);
                        else {
-                               E1000_WRITE_REG(&sc->hw, TDT,
+                               E1000_WRITE_REG(&sc->hw, TDT(0),
                                    sc->sc_tx_desc_head);
                                em_82547_update_fifo_head(sc, len);
                        }
@@ -697,7 +675,7 @@ em_start(struct ifqueue *ifq)
                 * available to transmit.
                 */
                if (post)
-                       E1000_WRITE_REG(&sc->hw, TDT, sc->sc_tx_desc_head);
+                       E1000_WRITE_REG(&sc->hw, TDT(0), sc->sc_tx_desc_head);
        }
 }
 
@@ -801,7 +779,7 @@ em_watchdog(struct ifnet *ifp)
        printf("%s: watchdog: head %u tail %u TDH %u TDT %u\n",
            DEVNAME(sc),
            sc->sc_tx_desc_head, sc->sc_tx_desc_tail,
-           E1000_READ_REG(&sc->hw, TDH), E1000_READ_REG(&sc->hw, TDT));
+           E1000_READ_REG(&sc->hw, TDH(0)), E1000_READ_REG(&sc->hw, TDT(0)));
 
        em_init(sc);
 
@@ -857,6 +835,7 @@ em_init(void *arg)
        case em_82571:
        case em_82572: /* Total Packet Buffer on these is 48k */
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_80003es2lan:
        case em_i350:
@@ -1185,6 +1164,7 @@ em_encap(struct em_softc *sc, struct mbu
        }
 
        if (sc->hw.mac_type >= em_82543 && sc->hw.mac_type != em_82575 &&
+           sc->hw.mac_type != em_82576 &&
            sc->hw.mac_type != em_82580 && sc->hw.mac_type != em_i210 &&
            sc->hw.mac_type != em_i350) {
                used += em_transmit_checksum_setup(sc, m, head,
@@ -1289,7 +1269,7 @@ em_82547_move_tail_locked(struct em_soft
        uint16_t length = 0;
        boolean_t eop = 0;
 
-       hw_tdt = E1000_READ_REG(&sc->hw, TDT);
+       hw_tdt = E1000_READ_REG(&sc->hw, TDT(0));
        sw_tdt = sc->sc_tx_desc_head;
 
        while (hw_tdt != sw_tdt) {
@@ -1305,7 +1285,7 @@ em_82547_move_tail_locked(struct em_soft
                                timeout_add(&sc->tx_fifo_timer_handle, 1);
                                break;
                        }
-                       E1000_WRITE_REG(&sc->hw, TDT, hw_tdt);
+                       E1000_WRITE_REG(&sc->hw, TDT(0), hw_tdt);
                        em_82547_update_fifo_head(sc, length);
                        length = 0;
                }
@@ -1360,8 +1340,8 @@ em_82547_tx_fifo_reset(struct em_softc *
 {
        uint32_t tctl;
 
-       if ((E1000_READ_REG(&sc->hw, TDT) ==
-            E1000_READ_REG(&sc->hw, TDH)) &&
+       if ((E1000_READ_REG(&sc->hw, TDT(0)) ==
+            E1000_READ_REG(&sc->hw, TDH(0))) &&
            (E1000_READ_REG(&sc->hw, TDFT) ==
             E1000_READ_REG(&sc->hw, TDFH)) &&
            (E1000_READ_REG(&sc->hw, TDFTS) ==
@@ -1494,6 +1474,7 @@ em_update_link_status(struct em_softc *s
                            ((sc->hw.mac_type == em_82571) ||
                            (sc->hw.mac_type == em_82572) ||
                            (sc->hw.mac_type == em_82575) ||
+                           (sc->hw.mac_type == em_82576) ||
                            (sc->hw.mac_type == em_82580))) {
                                int tarc0;
 
@@ -1774,6 +1755,15 @@ em_free_pci_resources(struct em_softc *s
                bus_space_unmap(sc->osdep.mem_bus_space_tag, 
sc->osdep.mem_bus_space_handle,
                                sc->osdep.em_memsize);
        sc->osdep.em_membase = 0;
+
+       if (sc->sc_rx_desc_ring != NULL) {
+               sc->sc_rx_desc_ring = NULL;
+               em_dma_free(sc, &sc->sc_rx_dma);
+       }
+       if (sc->sc_tx_desc_ring != NULL) {
+               sc->sc_tx_desc_ring = NULL;
+               em_dma_free(sc, &sc->sc_tx_dma);
+       }
 }
 
 /*********************************************************************
@@ -1826,6 +1816,7 @@ em_hardware_init(struct em_softc *sc)
             (sc->hw.mac_type == em_82571 ||
              sc->hw.mac_type == em_82572 ||
              sc->hw.mac_type == em_82575 ||
+             sc->hw.mac_type == em_82576 ||
              sc->hw.mac_type == em_82580 ||
              sc->hw.mac_type == em_i210 ||
              sc->hw.mac_type == em_i350 )) {
@@ -1911,11 +1902,13 @@ em_setup_interface(struct em_softc *sc)
 
 #if NVLAN > 0
        if (sc->hw.mac_type != em_82575 && sc->hw.mac_type != em_82580 &&
+           sc->hw.mac_type != em_82576 &&
            sc->hw.mac_type != em_i210 && sc->hw.mac_type != em_i350)
                ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
 #endif
 
        if (sc->hw.mac_type >= em_82543 && sc->hw.mac_type != em_82575 &&
+           sc->hw.mac_type != em_82576 &&
            sc->hw.mac_type != em_82580 && sc->hw.mac_type != em_i210 &&
            sc->hw.mac_type != em_i350)
                ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
@@ -1971,15 +1964,6 @@ em_detach(struct device *self, int flags
 
        em_free_pci_resources(sc);
 
-       if (sc->sc_rx_desc_ring != NULL) {
-               sc->sc_rx_desc_ring = NULL;
-               em_dma_free(sc, &sc->sc_rx_dma);
-       }
-       if (sc->sc_tx_desc_ring != NULL) {
-               sc->sc_tx_desc_ring = NULL;
-               em_dma_free(sc, &sc->sc_tx_dma);
-       }
-
        ether_ifdetach(ifp);
        if_detach(ifp);
 
@@ -2201,19 +2185,19 @@ em_initialize_transmit_unit(struct em_so
 
        /* Setup the Base and Length of the Tx Descriptor Ring */
        bus_addr = sc->sc_tx_dma.dma_map->dm_segs[0].ds_addr;
-       E1000_WRITE_REG(&sc->hw, TDLEN, 
+       E1000_WRITE_REG(&sc->hw, TDLEN(0),
                        sc->sc_tx_slots *
                        sizeof(struct em_tx_desc));
-       E1000_WRITE_REG(&sc->hw, TDBAH, (u_int32_t)(bus_addr >> 32));
-       E1000_WRITE_REG(&sc->hw, TDBAL, (u_int32_t)bus_addr);
+       E1000_WRITE_REG(&sc->hw, TDBAH(0), (u_int32_t)(bus_addr >> 32));
+       E1000_WRITE_REG(&sc->hw, TDBAL(0), (u_int32_t)bus_addr);
 
        /* Setup the HW Tx Head and Tail descriptor pointers */
-       E1000_WRITE_REG(&sc->hw, TDT, 0);
-       E1000_WRITE_REG(&sc->hw, TDH, 0);
+       E1000_WRITE_REG(&sc->hw, TDT(0), 0);
+       E1000_WRITE_REG(&sc->hw, TDH(0), 0);
 
        HW_DEBUGOUT2("Base = %x, Length = %x\n", 
-                    E1000_READ_REG(&sc->hw, TDBAL),
-                    E1000_READ_REG(&sc->hw, TDLEN));
+                    E1000_READ_REG(&sc->hw, TDBAL(0)),
+                    E1000_READ_REG(&sc->hw, TDLEN(0)));
 
        /* Set the default values for the Tx Inter Packet Gap timer */
        switch (sc->hw.mac_type) {
@@ -2247,11 +2231,12 @@ em_initialize_transmit_unit(struct em_so
        sc->sc_txd_cmd = E1000_TXD_CMD_IFCS;
 
        if (sc->hw.mac_type == em_82575 || sc->hw.mac_type == em_82580 ||
+           sc->hw.mac_type == em_82576 ||
            sc->hw.mac_type == em_i210 || sc->hw.mac_type == em_i350) {
                /* 82575/6 need to enable the TX queue and lack the IDE bit */
-               reg_tctl = E1000_READ_REG(&sc->hw, TXDCTL);
+               reg_tctl = E1000_READ_REG(&sc->hw, TXDCTL(0));
                reg_tctl |= E1000_TXDCTL_QUEUE_ENABLE;
-               E1000_WRITE_REG(&sc->hw, TXDCTL, reg_tctl);
+               E1000_WRITE_REG(&sc->hw, TXDCTL(0), reg_tctl);
        } else if (sc->tx_int_delay > 0)
                sc->sc_txd_cmd |= E1000_TXD_CMD_IDE;
 
@@ -2614,10 +2599,10 @@ em_initialize_receive_unit(struct em_sof
 
        /* Setup the Base and Length of the Rx Descriptor Ring */
        bus_addr = sc->sc_rx_dma.dma_map->dm_segs[0].ds_addr;
-       E1000_WRITE_REG(&sc->hw, RDLEN,
+       E1000_WRITE_REG(&sc->hw, RDLEN(0),
            sc->sc_rx_slots * sizeof(*sc->sc_rx_desc_ring));
-       E1000_WRITE_REG(&sc->hw, RDBAH, (u_int32_t)(bus_addr >> 32));
-       E1000_WRITE_REG(&sc->hw, RDBAL, (u_int32_t)bus_addr);
+       E1000_WRITE_REG(&sc->hw, RDBAH(0), (u_int32_t)(bus_addr >> 32));
+       E1000_WRITE_REG(&sc->hw, RDBAL(0), (u_int32_t)bus_addr);
 
        /* Setup the Receive Control Register */
        reg_rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
@@ -2669,20 +2654,21 @@ em_initialize_receive_unit(struct em_sof
                E1000_WRITE_REG(&sc->hw, RDTR, 0x20);
 
        if (sc->hw.mac_type == em_82575 || sc->hw.mac_type == em_82580 ||
+           sc->hw.mac_type == em_82576 ||
            sc->hw.mac_type == em_i210 || sc->hw.mac_type == em_i350) {
                /* 82575/6 need to enable the RX queue */
                uint32_t reg;
-               reg = E1000_READ_REG(&sc->hw, RXDCTL);
+               reg = E1000_READ_REG(&sc->hw, RXDCTL(0));
                reg |= E1000_RXDCTL_QUEUE_ENABLE;
-               E1000_WRITE_REG(&sc->hw, RXDCTL, reg);
+               E1000_WRITE_REG(&sc->hw, RXDCTL(0), reg);
        }
 
        /* Enable Receives */
        E1000_WRITE_REG(&sc->hw, RCTL, reg_rctl);
 
        /* Setup the HW Rx Head and Tail Descriptor Pointers */
-       E1000_WRITE_REG(&sc->hw, RDH, 0);
-       E1000_WRITE_REG(&sc->hw, RDT, sc->sc_rx_desc_head);
+       E1000_WRITE_REG(&sc->hw, RDH(0), 0);
+       E1000_WRITE_REG(&sc->hw, RDT(0), sc->sc_rx_desc_head);
 }
 
 /*********************************************************************
@@ -2770,7 +2756,7 @@ em_rxrefill(void *arg)
        struct em_softc *sc = arg;
 
        if (em_rxfill(sc))
-               E1000_WRITE_REG(&sc->hw, RDT, sc->sc_rx_desc_head);
+               E1000_WRITE_REG(&sc->hw, RDT(0), sc->sc_rx_desc_head);
        else if (if_rxr_inuse(&sc->sc_rx_ring) == 0)
                timeout_add(&sc->rx_refill, 1);
 }
@@ -3188,7 +3174,7 @@ em_flush_tx_ring(struct em_softc *sc)
        tctl = EM_READ_REG(&sc->hw, E1000_TCTL);
        EM_WRITE_REG(&sc->hw, E1000_TCTL, tctl | E1000_TCTL_EN);
 
-       KASSERT(EM_READ_REG(&sc->hw, E1000_TDT) == sc->sc_tx_desc_head);
+       KASSERT(EM_READ_REG(&sc->hw, E1000_TDT(0)) == sc->sc_tx_desc_head);
 
        txd = &sc->sc_tx_desc_ring[sc->sc_tx_desc_head];
        txd->buffer_addr = sc->sc_tx_dma.dma_map->dm_segs[0].ds_addr;
@@ -3202,7 +3188,7 @@ em_flush_tx_ring(struct em_softc *sc)
        if (++sc->sc_tx_desc_head == sc->sc_tx_slots)
                sc->sc_tx_desc_head = 0;
 
-       EM_WRITE_REG(&sc->hw, E1000_TDT, sc->sc_tx_desc_head);
+       EM_WRITE_REG(&sc->hw, E1000_TDT(0), sc->sc_tx_desc_head);
        bus_space_barrier(sc->osdep.mem_bus_space_tag, 
sc->osdep.mem_bus_space_handle,
            0, 0, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
        usec_delay(250);
@@ -3223,7 +3209,7 @@ em_flush_rx_ring(struct em_softc *sc)
        E1000_WRITE_FLUSH(&sc->hw);
        usec_delay(150);
 
-       rxdctl = EM_READ_REG(&sc->hw, E1000_RXDCTL);
+       rxdctl = EM_READ_REG(&sc->hw, E1000_RXDCTL(0));
        /* zero the lower 14 bits (prefetch and host thresholds) */
        rxdctl &= 0xffffc000;
        /*
@@ -3231,7 +3217,7 @@ em_flush_rx_ring(struct em_softc *sc)
         * and make sure the granularity is "descriptors" and not "cache lines"
         */
        rxdctl |= (0x1F | (1 << 8) | E1000_RXDCTL_THRESH_UNIT_DESC);
-       EM_WRITE_REG(&sc->hw, E1000_RXDCTL, rxdctl);
+       EM_WRITE_REG(&sc->hw, E1000_RXDCTL(0), rxdctl);
 
        /* momentarily enable the RX ring for the changes to take effect */
        EM_WRITE_REG(&sc->hw, E1000_RCTL, rctl | E1000_RCTL_EN);
@@ -3263,7 +3249,7 @@ em_flush_desc_rings(struct em_softc *sc)
        EM_WRITE_REG(&sc->hw, E1000_FEXTNVM11, fextnvm11);
 
        /* do nothing if we're not in faulty state, or if the queue is empty */
-       tdlen = EM_READ_REG(&sc->hw, E1000_TDLEN);
+       tdlen = EM_READ_REG(&sc->hw, E1000_TDLEN(0));
        hang_state = pci_conf_read(pa->pa_pc, pa->pa_tag, 
PCICFG_DESC_RING_STATUS);
        if (!(hang_state & FLUSH_DESC_REQUIRED) || !tdlen)
                return;
@@ -3359,6 +3345,15 @@ em_update_stats_counters(struct em_softc
        sc->stats.ptc1522 += E1000_READ_REG(&sc->hw, PTC1522);
        sc->stats.mptc += E1000_READ_REG(&sc->hw, MPTC);
        sc->stats.bptc += E1000_READ_REG(&sc->hw, BPTC);
+       sc->stats.sdpc += E1000_READ_REG(&sc->hw, SDPC);
+       sc->stats.mngpdc += E1000_READ_REG(&sc->hw, MGTPDC);
+       sc->stats.mngprc += E1000_READ_REG(&sc->hw, MGTPRC);
+       sc->stats.mngptc += E1000_READ_REG(&sc->hw, MGTPTC);
+       sc->stats.b2ospc += E1000_READ_REG(&sc->hw, B2OSPC);
+       sc->stats.o2bgptc += E1000_READ_REG(&sc->hw, O2BGPTC);
+       sc->stats.b2ogprc += E1000_READ_REG(&sc->hw, B2OGPRC);
+       sc->stats.o2bspc += E1000_READ_REG(&sc->hw, O2BSPC);
+       sc->stats.rpthc += E1000_READ_REG(&sc->hw, RPTHC);
 
        if (sc->hw.mac_type >= em_82543) {
                sc->stats.tncrs += 
@@ -3445,6 +3440,50 @@ em_print_hw_stats(struct em_softc *sc)
                (long long)sc->stats.gprc);
        printf("%s: Good Packets Xmtd = %lld\n", unit,
                (long long)sc->stats.gptc);
+       printf("%s: Switch Drop Packet Count = %lld\n", unit,
+           (long long)sc->stats.sdpc);
+       printf("%s: Management Packets Dropped Count  = %lld\n", unit,
+           (long long)sc->stats.mngptc);
+       printf("%s: Management Packets Received Count  = %lld\n", unit,
+           (long long)sc->stats.mngprc);
+       printf("%s: Management Packets Transmitted Count  = %lld\n", unit,
+           (long long)sc->stats.mngptc);
+       printf("%s: OS2BMC Packets Sent by MC Count  = %lld\n", unit,
+           (long long)sc->stats.b2ospc);
+       printf("%s: OS2BMC Packets Received by MC Count  = %lld\n", unit,
+           (long long)sc->stats.o2bgptc);
+       printf("%s: OS2BMC Packets Received by Host Count  = %lld\n", unit,
+           (long long)sc->stats.b2ogprc);
+       printf("%s: OS2BMC Packets Transmitted by Host Count  = %lld\n", unit,
+           (long long)sc->stats.o2bspc);
+       printf("%s: Multicast Packets Received Count  = %lld\n", unit,
+           (long long)sc->stats.mprc);
+       printf("%s: Rx Packets to Host Count = %lld\n", unit,
+           (long long)sc->stats.rpthc);
 }
 #endif
 #endif /* !SMALL_KERNEL */
+
+int
+em_allocate_desc_rings(struct em_softc *sc)
+{
+       /* Allocate Transmit Descriptor ring */
+       if (em_dma_malloc(sc, sc->sc_tx_slots * sizeof(struct em_tx_desc),
+           &sc->sc_tx_dma) != 0) {
+               printf("%s: Unable to allocate tx_desc memory\n", 
+                      DEVNAME(sc));
+               return (ENOMEM);
+       }
+       sc->sc_tx_desc_ring = (struct em_tx_desc *)sc->sc_tx_dma.dma_vaddr;
+
+       /* Allocate Receive Descriptor ring */
+       if (em_dma_malloc(sc, sc->sc_rx_slots * sizeof(struct em_rx_desc),
+           &sc->sc_rx_dma) != 0) {
+               printf("%s: Unable to allocate rx_desc memory\n",
+                      DEVNAME(sc));
+               return (ENOMEM);
+       }
+       sc->sc_rx_desc_ring = (struct em_rx_desc *)sc->sc_rx_dma.dma_vaddr;
+
+       return (0);
+}
Index: pci/if_em_hw.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.c,v
retrieving revision 1.105
diff -u -p -r1.105 if_em_hw.c
--- pci/if_em_hw.c      20 Jan 2020 23:45:02 -0000      1.105
+++ pci/if_em_hw.c      21 Jan 2020 10:28:22 -0000
@@ -511,6 +511,9 @@ em_set_mac_type(struct em_hw *hw)
        case E1000_DEV_ID_82575EB_PF:
        case E1000_DEV_ID_82575GB_QP:
        case E1000_DEV_ID_82575GB_QP_PM:
+               hw->mac_type = em_82575;
+               hw->initialize_hw_bits_disable = 1;
+               break;
        case E1000_DEV_ID_82576:
        case E1000_DEV_ID_82576_FIBER:
        case E1000_DEV_ID_82576_SERDES:
@@ -519,7 +522,7 @@ em_set_mac_type(struct em_hw *hw)
        case E1000_DEV_ID_82576_NS:
        case E1000_DEV_ID_82576_NS_SERDES:
        case E1000_DEV_ID_82576_SERDES_QUAD:
-               hw->mac_type = em_82575;
+               hw->mac_type = em_82576;
                hw->initialize_hw_bits_disable = 1;
                break;
        case E1000_DEV_ID_82580_COPPER:
@@ -685,6 +688,7 @@ em_set_mac_type(struct em_hw *hw)
                break;
        case em_80003es2lan:
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_i210:
        case em_i350:
@@ -725,6 +729,7 @@ em_set_media_type(struct em_hw *hw)
        }
 
        if (hw->mac_type == em_82575 || hw->mac_type == em_82580 ||
+           hw->mac_type == em_82576 ||
            hw->mac_type == em_i210 || hw->mac_type == em_i350) {
                hw->media_type = em_media_type_copper;
        
@@ -835,6 +840,7 @@ em_reset_hw(struct em_hw *hw)
 
         /* Set the completion timeout for 82575 chips */
         if (hw->mac_type == em_82575 || hw->mac_type == em_82580 ||
+           hw->mac_type == em_82576 ||
            hw->mac_type == em_i210 || hw->mac_type == em_i350) {
                 ret_val = em_set_pciex_completion_timeout(hw);
                 if (ret_val) {              
@@ -1123,13 +1129,13 @@ em_initialize_hardware_bits(struct em_hw
                reg_tarc0 &= ~0x78000000;       /* Clear bits 30, 29, 28, and
                                                 * 27 */
 
-               reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+               reg_txdctl = E1000_READ_REG(hw, TXDCTL(0));
                reg_txdctl |= E1000_TXDCTL_COUNT_DESC;  /* Set bit 22 */
-               E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
+               E1000_WRITE_REG(hw, TXDCTL(0), reg_txdctl);
 
-               reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+               reg_txdctl1 = E1000_READ_REG(hw, TXDCTL(1));
                reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC; /* Set bit 22 */
-               E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+               E1000_WRITE_REG(hw, TXDCTL(1), reg_txdctl1);
 
                switch (hw->mac_type) {
                case em_82571:
@@ -1620,10 +1626,10 @@ em_init_hw(struct em_hw *hw)
 
        /* Set the transmit descriptor write-back policy */
        if (hw->mac_type > em_82544) {
-               ctrl = E1000_READ_REG(hw, TXDCTL);
+               ctrl = E1000_READ_REG(hw, TXDCTL(0));
                ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | 
                    E1000_TXDCTL_FULL_TX_DESC_WB;
-               E1000_WRITE_REG(hw, TXDCTL, ctrl);
+               E1000_WRITE_REG(hw, TXDCTL(0), ctrl);
        }
        if ((hw->mac_type == em_82573) || (hw->mac_type == em_82574)) {
                em_enable_tx_pkt_filtering(hw);
@@ -1656,6 +1662,7 @@ em_init_hw(struct em_hw *hw)
        case em_82571:
        case em_82572:
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_i210:
        case em_i350:
@@ -1667,10 +1674,10 @@ em_init_hw(struct em_hw *hw)
        case em_pch_lpt:
        case em_pch_spt:
        case em_pch_cnp:
-               ctrl = E1000_READ_REG(hw, TXDCTL1);
+               ctrl = E1000_READ_REG(hw, TXDCTL(1));
                ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | 
                    E1000_TXDCTL_FULL_TX_DESC_WB;
-               E1000_WRITE_REG(hw, TXDCTL1, ctrl);
+               E1000_WRITE_REG(hw, TXDCTL(1), ctrl);
                break;
        }
 
@@ -4958,7 +4965,8 @@ em_read_phy_reg(struct em_hw *hw, uint32
                hw->mac_type == em_pch_cnp)
                return (em_access_phy_reg_hv(hw, reg_addr, phy_data, TRUE));
 
-       if (((hw->mac_type == em_80003es2lan) || (hw->mac_type == em_82575)) &&
+       if (((hw->mac_type == em_80003es2lan) || (hw->mac_type == em_82575) ||
+           (hw->mac_type == em_82576)) &&
            (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
                swfw = E1000_SWFW_PHY1_SM;
        } else {
@@ -5658,6 +5666,7 @@ em_match_gig_phy(struct em_hw *hw)
                        match = TRUE;
                break;
        case em_82575:
+       case em_82576:
                if (hw->phy_id == M88E1000_E_PHY_ID)
                        match = TRUE;
                if (hw->phy_id == IGP01E1000_I_PHY_ID)
@@ -5959,6 +5968,7 @@ em_init_eeprom_params(struct em_hw *hw)
        case em_82573:
        case em_82574:
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_i210:
        case em_i350:
@@ -7307,6 +7317,7 @@ em_read_mac_addr(struct em_hw *hw)
        case em_82546_rev_3:
        case em_82571:
        case em_82575:
+       case em_82576:
        case em_80003es2lan:
                if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
                        hw->perm_mac_addr[5] ^= 0x01;
@@ -8105,6 +8116,7 @@ em_get_bus_info(struct em_hw *hw)
        case em_82573:
        case em_82574:
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_80003es2lan:
        case em_i210:
@@ -9309,6 +9321,7 @@ em_get_auto_rd_done(struct em_hw *hw)
        case em_82573:
        case em_82574:
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_80003es2lan:
        case em_i210:
@@ -9369,6 +9382,7 @@ em_get_phy_cfg_done(struct em_hw *hw)
                break;
        case em_80003es2lan:
        case em_82575:
+       case em_82576:
        case em_82580:
        case em_i350:
                switch (hw->bus_func) {
@@ -11584,3 +11598,91 @@ out:
        return ret_val;
 }
 
+uint32_t
+em_translate_82542_register(uint32_t reg)
+{
+       /*
+        * Some of the 82542 registers are located at different
+        * offsets than they are in newer adapters.
+        * Despite the difference in location, the registers
+        * function in the same manner.
+        */
+       switch (reg) {
+       case E1000_RA:
+               reg = 0x00040;
+               break;
+       case E1000_RDTR:
+               reg = 0x00108;
+               break;
+       case E1000_RDBAL(0):
+               reg = 0x00110;
+               break;
+       case E1000_RDBAH(0):
+               reg = 0x00114;
+               break;
+       case E1000_RDLEN(0):
+               reg = 0x00118;
+               break;
+       case E1000_RDH(0):
+               reg = 0x00120;
+               break;
+       case E1000_RDT(0):
+               reg = 0x00128;
+               break;
+       case E1000_RDBAL(1):
+               reg = 0x00138;
+               break;
+       case E1000_RDBAH(1):
+               reg = 0x0013C;
+               break;
+       case E1000_RDLEN(1):
+               reg = 0x00140;
+               break;
+       case E1000_RDH(1):
+               reg = 0x00148;
+               break;
+       case E1000_RDT(1):
+               reg = 0x00150;
+               break;
+       case E1000_FCRTH:
+               reg = 0x00160;
+               break;
+       case E1000_FCRTL:
+               reg = 0x00168;
+               break;
+       case E1000_MTA:
+               reg = 0x00200;
+               break;
+       case E1000_TDBAL(0):
+               reg = 0x00420;
+               break;
+       case E1000_TDBAH(0):
+               reg = 0x00424;
+               break;
+       case E1000_TDLEN(0):
+               reg = 0x00428;
+               break;
+       case E1000_TDH(0):
+               reg = 0x00430;
+               break;
+       case E1000_TDT(0):
+               reg = 0x00438;
+               break;
+       case E1000_TIDV:
+               reg = 0x00440;
+               break;
+       case E1000_VFTA:
+               reg = 0x00600;
+               break;
+       case E1000_TDFH:
+               reg = 0x08010;
+               break;
+       case E1000_TDFT:
+               reg = 0x08018;
+               break;
+       default:
+               break;
+       }
+
+       return (reg);
+}
Index: pci/if_em_hw.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v
retrieving revision 1.79
diff -u -p -r1.79 if_em_hw.h
--- pci/if_em_hw.h      20 Jan 2020 23:45:02 -0000      1.79
+++ pci/if_em_hw.h      21 Jan 2020 10:28:22 -0000
@@ -70,6 +70,7 @@ typedef enum {
     em_82573,
     em_82574,
     em_82575,
+    em_82576,
     em_82580,
     em_i350,
     em_i210,
@@ -447,6 +448,7 @@ int32_t em_read_pcie_cap_reg(struct em_h
 /* Port I/O is only supported on 82544 and newer */
 int32_t em_disable_pciex_master(struct em_hw *hw);
 int32_t em_check_phy_reset_block(struct em_hw *hw);
+uint32_t em_translate_82542_register(uint32_t);
 
 #ifndef E1000_READ_REG_IO
 #define E1000_READ_REG_IO(a, reg) \
@@ -1043,12 +1045,20 @@ struct em_ffvt_entry {
 #define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
 #define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
 #define E1000_RCTL     0x00100  /* RX Control - RW */
+#define E1000_GPIE     0x01514  /* General Purpose Interrupt Enable - RW */
+#define E1000_EICS     0x01520  /* Ext. Interrupt Cause Set - W0 */
+#define E1000_EIMS     0x01524  /* Ext. Interrupt Mask Set/Read - RW */
+#define E1000_EIMC     0x01528  /* Ext. Interrupt Mask Clear - WO */
+#define E1000_EIAC     0x0152C  /* Ext. Interrupt Auto Clear - RW */
+#define E1000_EIAM     0x01530  /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_EICR     0x01580  /* Ext. Interrupt Cause Read - R/clr */
+#define E1000_EITR(_n)  (0x01680 + (0x4 * (_n)))
+#define E1000_IVAR0    0x01700  /* Interrupt Vector Allocation (array) - RW */
+#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
 #define E1000_RDTR1    0x02820  /* RX Delay Timer (1) - RW */
 #define E1000_RDBAL1   0x02900  /* RX Descriptor Base Address Low (1) - RW */
 #define E1000_RDBAH1   0x02904  /* RX Descriptor Base Address High (1) - RW */
 #define E1000_RDLEN1   0x02908  /* RX Descriptor Length (1) - RW */
-#define E1000_RDH1     0x02910  /* RX Descriptor Head (1) - RW */
-#define E1000_RDT1     0x02918  /* RX Descriptor Tail (1) - RW */
 #define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
 #define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
 #define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
@@ -1079,20 +1089,31 @@ struct em_ffvt_entry {
 #define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
 #define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
 #define E1000_PSRCTL   0x02170  /* Packet Split Receive Control - RW */
-#define E1000_RDBAL    0x02800  /* RX Descriptor Base Address Low - RW */
-#define E1000_RDBAH    0x02804  /* RX Descriptor Base Address High - RW */
-#define E1000_RDLEN    0x02808  /* RX Descriptor Length - RW */
-#define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
-#define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
+/* RX Descriptor Base Address Low - RW */
+#define E1000_RDBAL(_n)        ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) :        
\
+    (0x0C000 + ((_n) * 0x40)))
+/* RX Descriptor Base Address High - RW */
+#define E1000_RDBAH(_n)        ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) :        
\
+    (0x0C004 + ((_n) * 0x40)))
+/* RX Descriptor Length - RW */
+#define E1000_RDLEN(_n)        ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) :        
\
+    (0x0C008 + ((_n) * 0x40)))
+/* Split and Replication Receive CTRL - RW */
+#define E1000_SRRCTL(_n)       ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : \
+    (0x0C00C + ((_n) * 0x40)))
+/* RX Descriptor Head - RW */
+#define E1000_RDH(_n)  ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) :        \
+    (0x0C010 + ((_n) * 0x40)))
+/* RX Descriptor Tail - RW */
+#define E1000_RDT(_n)  ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) :        \
+    (0x0C018 + ((_n) * 0x40)))
 #define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
 #define E1000_RDBAL0   E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
 #define E1000_RDBAH0   E1000_RDBAH /* RX Desc Base Address High (0) - RW */
 #define E1000_RDLEN0   E1000_RDLEN /* RX Desc Length (0) - RW */
-#define E1000_RDH0     E1000_RDH   /* RX Desc Head (0) - RW */
-#define E1000_RDT0     E1000_RDT   /* RX Desc Tail (0) - RW */
 #define E1000_RDTR0    E1000_RDTR  /* RX Delay Timer (0) - RW */
-#define E1000_RXDCTL   0x02828  /* RX Descriptor Control queue 0 - RW */
-#define E1000_RXDCTL1  0x02928  /* RX Descriptor Control queue 1 - RW */
+#define E1000_RXDCTL(_n)       ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : \
+    (0x0C028 + ((_n) * 0x40)))
 #define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
 #define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
 #define E1000_RAID     0x02C08  /* Receive Ack Interrupt Delay - RW */
@@ -1103,13 +1124,24 @@ struct em_ffvt_entry {
 #define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
 #define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
 #define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
-#define E1000_TDBAL    0x03800  /* TX Descriptor Base Address Low - RW */
-#define E1000_TDBAH    0x03804  /* TX Descriptor Base Address High - RW */
-#define E1000_TDLEN    0x03808  /* TX Descriptor Length - RW */
-#define E1000_TDH      0x03810  /* TX Descriptor Head - RW */
-#define E1000_TDT      0x03818  /* TX Descriptor Tail - RW */
+/* TX Descriptor Base Address Low - RW */
+#define E1000_TDBAL(_n)        ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) :        
\
+    (0x0E000 + ((_n) * 0x40)))
+/* TX Descriptor Base Address High - RW */
+#define E1000_TDBAH(_n)        ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) :        
\
+    (0x0E004 + ((_n) * 0x40)))
+/* TX Descriptor Length - RW */
+#define E1000_TDLEN(_n)        ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) :        
\
+    (0x0E008 + ((_n) * 0x40)))
+/* TX Descriptor Head - RW */
+#define E1000_TDH(_n)  ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) :        \
+    (0x0E010 + ((_n) * 0x40)))
+/* TX Descriptor Tail - RW */
+#define E1000_TDT(_n)  ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) :        \
+    (0x0E018 + ((_n) * 0x40)))
 #define E1000_TIDV     0x03820  /* TX Interrupt Delay Value - RW */
-#define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
+#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) :      \
+    (0x0E028 + ((_n) * 0x40)))
 #define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
 #define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
 #define E1000_TARC0    0x03840  /* TX Arbitration Count (0) */
@@ -1118,7 +1150,6 @@ struct em_ffvt_entry {
 #define E1000_TDLEN1   0x03908  /* TX Desc Length (1) - RW */
 #define E1000_TDH1     0x03910  /* TX Desc Head (1) - RW */
 #define E1000_TDT1     0x03918  /* TX Desc Tail (1) - RW */
-#define E1000_TXDCTL1  0x03928  /* TX Descriptor Control (1) - RW */
 #define E1000_TARC1    0x03940  /* TX Arbitration Count (1) */
 #define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
 #define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
@@ -1179,6 +1210,7 @@ struct em_ffvt_entry {
 #define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
 #define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
 #define E1000_IAC      0x04100  /* Interrupt Assertion Count */
+#define E1000_RPTHC    0x04104 /* CONFLICT Rx Packets to Host Count */
 #define E1000_ICRXPTC  0x04104  /* Interrupt Cause Rx Packet Timer Expire 
Count */
 #define E1000_ICRXATC  0x04108  /* Interrupt Cause Rx Absolute Timer Expire 
Count */
 #define E1000_ICTXPTC  0x0410C  /* Interrupt Cause Tx Packet Timer Expire 
Count */
@@ -1187,6 +1219,7 @@ struct em_ffvt_entry {
 #define E1000_ICTXQMTC 0x0411C  /* Interrupt Cause Tx Queue Minimum Threshold 
Count */
 #define E1000_ICRXDMTC 0x04120  /* Interrupt Cause Rx Descriptor Minimum 
Threshold Count */
 #define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
+#define E1000_SDPC     0x041A4   /* Switch Drop Packet Count */
 #define E1000_PCS_CFG0 0x04200  /* PCS Configuration 0 - RW */
 #define E1000_PCS_LCTL 0x04208  /* PCS Link Control - RW */
 #define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
@@ -1231,11 +1264,34 @@ struct em_ffvt_entry {
 /* RSS registers */
 #define E1000_CPUVEC    0x02C10 /* CPU Vector Register - RW */
 #define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
-#define E1000_RETA      0x05C00 /* Redirection Table - RW Array */
-#define E1000_RSSRK     0x05C80 /* RSS Random Key - RW Array */
+#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))/* Redirection Table - RW Array */
+#define E1000_RSSRK(_i)        (0x05C80 + ((_i) * 4))/* RSS Random Key - RW 
Array */
 #define E1000_RSSIM     0x05864 /* RSS Interrupt Mask */
 #define E1000_RSSIR     0x05868 /* RSS Interrupt Request */
 
+/* BMC2OS Registers */
+#define E1000_B2OSPC    0x8FE0
+#define E1000_B2OGPRC   0x4158
+#define E1000_O2BGPTC   0x8FE4
+#define E1000_O2BSPC    0x415C
+
+/* Per Queue Packets Count */
+#define E1000_PQGPRC(_i) (0x010010 + ((_i) * 0x100))
+#define E1000_PQGPTC(_i) (0x010014 + ((_i) * 0x100))
+
+/* Phy Power Management (i210 8.27.2 pag 542) */
+#define        E1000_PHPM      0x0E14
+#define        E1000_PHPM_SPD_EN       (1 << 0)
+#define        E1000_PHPM_D0LPLU       (1 << 1)
+#define        E1000_PHPM_LPLU         (1 << 2)
+#define        E1000_PHPM_DIS_1000_ND0 (1 << 3)
+#define        E1000_PHPM_LINK_ED      (1 << 4)
+#define        E1000_PHPM_GOLINK_DISC  (1 << 5)
+#define        E1000_PHPM_DIS_1000     (1 << 6)
+#define        E1000_PHPM_SPD_B2B_EN   (1 << 7)
+#define        E1000_PHPM_RST_COMPL    (1 << 8)
+#define        E1000_PHPM_DIS_100_ND0  (1 << 9)
+
 /* Energy Efficient Ethernet "EEE" registers */
 #define E1000_IPCNFG    0x0E38 /* Internal PHY Configuration */
 #define E1000_LTRC      0x01A0 /* Latency Tolerance Reporting Control */
@@ -1244,236 +1300,6 @@ struct em_ffvt_entry {
 #define E1000_TLPIC     0x4148 /* EEE Tx LPI Count - TLPIC */
 #define E1000_RLPIC     0x414C /* EEE Rx LPI Count - RLPIC */
 
-/* Register Set (82542)
- *
- * Some of the 82542 registers are located at different offsets than they are
- * in more current versions of the 8254x. Despite the difference in location,
- * the registers function in the same manner.
- */
-#define E1000_82542_CTRL     E1000_CTRL
-#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
-#define E1000_82542_STATUS   E1000_STATUS
-#define E1000_82542_EECD     E1000_EECD
-#define E1000_82542_EERD     E1000_EERD
-#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
-#define E1000_82542_FLA      E1000_FLA
-#define E1000_82542_MDIC     E1000_MDIC
-#define E1000_82542_SCTL     E1000_SCTL
-#define E1000_82542_FEXTNVM  E1000_FEXTNVM
-#define E1000_82542_FEXTNVM3 E1000_FEXTNVM3
-#define E1000_82542_FEXTNVM4 E1000_FEXTNVM4
-#define E1000_82542_FEXTNVM6 E1000_FEXTNVM6
-#define E1000_82542_FEXTNVM7 E1000_FEXTNVM7
-#define E1000_82542_FCAL     E1000_FCAL
-#define E1000_82542_FCAH     E1000_FCAH
-#define E1000_82542_FCT      E1000_FCT
-#define E1000_82542_CONNSW   E1000_CONNSW
-#define E1000_82542_VET      E1000_VET
-#define E1000_82542_RA       0x00040
-#define E1000_82542_ICR      E1000_ICR
-#define E1000_82542_ITR      E1000_ITR
-#define E1000_82542_ICS      E1000_ICS
-#define E1000_82542_IMS      E1000_IMS
-#define E1000_82542_IMC      E1000_IMC
-#define E1000_82542_RCTL     E1000_RCTL
-#define E1000_82542_RDTR     0x00108
-#define E1000_82542_RDBAL    0x00110
-#define E1000_82542_RDBAH    0x00114
-#define E1000_82542_RDLEN    0x00118
-#define E1000_82542_RDH      0x00120
-#define E1000_82542_RDT      0x00128
-#define E1000_82542_RDTR0    E1000_82542_RDTR
-#define E1000_82542_RDBAL0   E1000_82542_RDBAL
-#define E1000_82542_RDBAH0   E1000_82542_RDBAH
-#define E1000_82542_RDLEN0   E1000_82542_RDLEN
-#define E1000_82542_RDH0     E1000_82542_RDH
-#define E1000_82542_RDT0     E1000_82542_RDT
-#define E1000_82542_SRRCTL(_n) (0x280C + ((_n) << 8)) /* Split and Replication
-                                                       * RX Control - RW */
-#define E1000_82542_DCA_RXCTRL(_n) (0x02814 + ((_n) << 8))
-#define E1000_82542_RDBAH3   0x02B04 /* RX Desc Base High Queue 3 - RW */
-#define E1000_82542_RDBAL3   0x02B00 /* RX Desc Low Queue 3 - RW */
-#define E1000_82542_RDLEN3   0x02B08 /* RX Desc Length Queue 3 - RW */
-#define E1000_82542_RDH3     0x02B10 /* RX Desc Head Queue 3 - RW */
-#define E1000_82542_RDT3     0x02B18 /* RX Desc Tail Queue 3 - RW */
-#define E1000_82542_RDBAL2   0x02A00 /* RX Desc Base Low Queue 2 - RW */
-#define E1000_82542_RDBAH2   0x02A04 /* RX Desc Base High Queue 2 - RW */
-#define E1000_82542_RDLEN2   0x02A08 /* RX Desc Length Queue 2 - RW */
-#define E1000_82542_RDH2     0x02A10 /* RX Desc Head Queue 2 - RW */
-#define E1000_82542_RDT2     0x02A18 /* RX Desc Tail Queue 2 - RW */
-#define E1000_82542_RDTR1    0x00130
-#define E1000_82542_RDBAL1   0x00138
-#define E1000_82542_RDBAH1   0x0013C
-#define E1000_82542_RDLEN1   0x00140
-#define E1000_82542_RDH1     0x00148
-#define E1000_82542_RDT1     0x00150
-#define E1000_82542_FCRTH    0x00160
-#define E1000_82542_FCRTL    0x00168
-#define E1000_82542_FCTTV    E1000_FCTTV
-#define E1000_82542_TXCW     E1000_TXCW
-#define E1000_82542_RXCW     E1000_RXCW
-#define E1000_82542_MTA      0x00200
-#define E1000_82542_TCTL     E1000_TCTL
-#define E1000_82542_TCTL_EXT E1000_TCTL_EXT
-#define E1000_82542_TIPG     E1000_TIPG
-#define E1000_82542_TDBAL    0x00420
-#define E1000_82542_TDBAH    0x00424
-#define E1000_82542_TDLEN    0x00428
-#define E1000_82542_TDH      0x00430
-#define E1000_82542_TDT      0x00438
-#define E1000_82542_TIDV     0x00440
-#define E1000_82542_TBT      E1000_TBT
-#define E1000_82542_AIT      E1000_AIT
-#define E1000_82542_VFTA     0x00600
-#define E1000_82542_LEDCTL   E1000_LEDCTL
-#define E1000_82542_PBA      E1000_PBA
-#define E1000_82542_PBS      E1000_PBS
-#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-#define E1000_82542_EEARBC   E1000_EEARBC
-#define E1000_82542_FLASHT   E1000_FLASHT
-#define E1000_82542_EEWR     E1000_EEWR
-#define E1000_82542_FLSWCTL  E1000_FLSWCTL
-#define E1000_82542_FLSWDATA E1000_FLSWDATA
-#define E1000_82542_FLSWCNT  E1000_FLSWCNT
-#define E1000_82542_FLOP     E1000_FLOP
-#define E1000_82542_EXTCNF_CTRL  E1000_EXTCNF_CTRL
-#define E1000_82542_EXTCNF_SIZE  E1000_EXTCNF_SIZE
-#define E1000_82542_PHY_CTRL E1000_PHY_CTRL
-#define E1000_82542_ERT      E1000_ERT
-#define E1000_82542_RXDCTL   E1000_RXDCTL
-#define E1000_82542_RXDCTL1  E1000_RXDCTL1
-#define E1000_82542_RADV     E1000_RADV
-#define E1000_82542_RSRPD    E1000_RSRPD
-#define E1000_82542_TXDMAC   E1000_TXDMAC
-#define E1000_82542_KABGTXD  E1000_KABGTXD
-#define E1000_82542_TDFHS    E1000_TDFHS
-#define E1000_82542_TDFTS    E1000_TDFTS
-#define E1000_82542_TDFPC    E1000_TDFPC
-#define E1000_82542_TXDCTL   E1000_TXDCTL
-#define E1000_82542_TADV     E1000_TADV
-#define E1000_82542_TSPMT    E1000_TSPMT
-#define E1000_82542_CRCERRS  E1000_CRCERRS
-#define E1000_82542_ALGNERRC E1000_ALGNERRC
-#define E1000_82542_SYMERRS  E1000_SYMERRS
-#define E1000_82542_RXERRC   E1000_RXERRC
-#define E1000_82542_MPC      E1000_MPC
-#define E1000_82542_SCC      E1000_SCC
-#define E1000_82542_ECOL     E1000_ECOL
-#define E1000_82542_MCC      E1000_MCC
-#define E1000_82542_LATECOL  E1000_LATECOL
-#define E1000_82542_COLC     E1000_COLC
-#define E1000_82542_DC       E1000_DC
-#define E1000_82542_TNCRS    E1000_TNCRS
-#define E1000_82542_SEC      E1000_SEC
-#define E1000_82542_CEXTERR  E1000_CEXTERR
-#define E1000_82542_RLEC     E1000_RLEC
-#define E1000_82542_XONRXC   E1000_XONRXC
-#define E1000_82542_XONTXC   E1000_XONTXC
-#define E1000_82542_XOFFRXC  E1000_XOFFRXC
-#define E1000_82542_XOFFTXC  E1000_XOFFTXC
-#define E1000_82542_FCRUC    E1000_FCRUC
-#define E1000_82542_PRC64    E1000_PRC64
-#define E1000_82542_PRC127   E1000_PRC127
-#define E1000_82542_PRC255   E1000_PRC255
-#define E1000_82542_PRC511   E1000_PRC511
-#define E1000_82542_PRC1023  E1000_PRC1023
-#define E1000_82542_PRC1522  E1000_PRC1522
-#define E1000_82542_GPRC     E1000_GPRC
-#define E1000_82542_BPRC     E1000_BPRC
-#define E1000_82542_MPRC     E1000_MPRC
-#define E1000_82542_GPTC     E1000_GPTC
-#define E1000_82542_GORCL    E1000_GORCL
-#define E1000_82542_GORCH    E1000_GORCH
-#define E1000_82542_GOTCL    E1000_GOTCL
-#define E1000_82542_GOTCH    E1000_GOTCH
-#define E1000_82542_RNBC     E1000_RNBC
-#define E1000_82542_RUC      E1000_RUC
-#define E1000_82542_RFC      E1000_RFC
-#define E1000_82542_ROC      E1000_ROC
-#define E1000_82542_RJC      E1000_RJC
-#define E1000_82542_MGTPRC   E1000_MGTPRC
-#define E1000_82542_MGTPDC   E1000_MGTPDC
-#define E1000_82542_MGTPTC   E1000_MGTPTC
-#define E1000_82542_TORL     E1000_TORL
-#define E1000_82542_TORH     E1000_TORH
-#define E1000_82542_TOTL     E1000_TOTL
-#define E1000_82542_TOTH     E1000_TOTH
-#define E1000_82542_TPR      E1000_TPR
-#define E1000_82542_TPT      E1000_TPT
-#define E1000_82542_PTC64    E1000_PTC64
-#define E1000_82542_PTC127   E1000_PTC127
-#define E1000_82542_PTC255   E1000_PTC255
-#define E1000_82542_PTC511   E1000_PTC511
-#define E1000_82542_PTC1023  E1000_PTC1023
-#define E1000_82542_PTC1522  E1000_PTC1522
-#define E1000_82542_MPTC     E1000_MPTC
-#define E1000_82542_BPTC     E1000_BPTC
-#define E1000_82542_TSCTC    E1000_TSCTC
-#define E1000_82542_TSCTFC   E1000_TSCTFC
-#define E1000_82542_RXCSUM   E1000_RXCSUM
-#define E1000_82542_WUC      E1000_WUC
-#define E1000_82542_WUFC     E1000_WUFC
-#define E1000_82542_WUS      E1000_WUS
-#define E1000_82542_MANC     E1000_MANC
-#define E1000_82542_IPAV     E1000_IPAV
-#define E1000_82542_IP4AT    E1000_IP4AT
-#define E1000_82542_IP6AT    E1000_IP6AT
-#define E1000_82542_WUPL     E1000_WUPL
-#define E1000_82542_WUPM     E1000_WUPM
-#define E1000_82542_FFLT     E1000_FFLT
-#define E1000_82542_FCRTV_PCH E1000_FCRTV_PCH
-#define E1000_82542_TDFH     0x08010
-#define E1000_82542_TDFT     0x08018
-#define E1000_82542_FFMT     E1000_FFMT
-#define E1000_82542_FFVT     E1000_FFVT
-#define E1000_82542_CRC_OFFSET E1000_CRC_OFFSET
-#define E1000_82542_HOST_IF  E1000_HOST_IF
-#define E1000_82542_IAM         E1000_IAM
-#define E1000_82542_EEMNGCTL    E1000_EEMNGCTL
-#define E1000_82542_PSRCTL      E1000_PSRCTL
-#define E1000_82542_RAID        E1000_RAID
-#define E1000_82542_TARC0       E1000_TARC0
-#define E1000_82542_TDBAL1      E1000_TDBAL1
-#define E1000_82542_TDBAH1      E1000_TDBAH1
-#define E1000_82542_TDLEN1      E1000_TDLEN1
-#define E1000_82542_TDH1        E1000_TDH1
-#define E1000_82542_TDT1        E1000_TDT1
-#define E1000_82542_TXDCTL1     E1000_TXDCTL1
-#define E1000_82542_TARC1       E1000_TARC1
-#define E1000_82542_RFCTL       E1000_RFCTL
-#define E1000_82542_GCR         E1000_GCR
-#define E1000_82542_GSCL_1      E1000_GSCL_1
-#define E1000_82542_GSCL_2      E1000_GSCL_2
-#define E1000_82542_GSCL_3      E1000_GSCL_3
-#define E1000_82542_GSCL_4      E1000_GSCL_4
-#define E1000_82542_FACTPS      E1000_FACTPS
-#define E1000_82542_SWSM        E1000_SWSM
-#define E1000_82542_H2ME        E1000_H2ME
-#define E1000_82542_FWSM        E1000_FWSM
-#define E1000_82542_FFLT_DBG    E1000_FFLT_DBG
-#define E1000_82542_IAC         E1000_IAC
-#define E1000_82542_ICRXPTC     E1000_ICRXPTC
-#define E1000_82542_ICRXATC     E1000_ICRXATC
-#define E1000_82542_ICTXPTC     E1000_ICTXPTC
-#define E1000_82542_ICTXATC     E1000_ICTXATC
-#define E1000_82542_ICTXQEC     E1000_ICTXQEC
-#define E1000_82542_ICTXQMTC    E1000_ICTXQMTC
-#define E1000_82542_ICRXDMTC    E1000_ICRXDMTC
-#define E1000_82542_ICRXOC      E1000_ICRXOC
-#define E1000_82542_HICR        E1000_HICR
-#define E1000_82542_PCS_CFG0   E1000_PCS_CFG0
-#define E1000_82542_PCS_LCTL   E1000_PCS_LCTL
-#define E1000_82542_PCS_LSTAT  E1000_PCS_LSTAT
-
-#define E1000_82542_CPUVEC      E1000_CPUVEC
-#define E1000_82542_MRQC        E1000_MRQC
-#define E1000_82542_RETA        E1000_RETA
-#define E1000_82542_RSSRK       E1000_RSSRK
-#define E1000_82542_RSSIM       E1000_RSSIM
-#define E1000_82542_RSSIR       E1000_RSSIR
-#define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA
-#define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC
-
 #define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK    0x0C000000
 #define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC  0x08000000
 
@@ -1553,6 +1379,15 @@ struct em_hw_stats {
     uint64_t ictxqmtc;
     uint64_t icrxdmtc;
     uint64_t icrxoc;
+    uint64_t sdpc;
+    uint64_t mngpdc;
+    uint64_t mngptc;
+    uint64_t mngprc;
+    uint64_t b2ospc;
+    uint64_t o2bgptc;
+    uint64_t b2ogprc;
+    uint64_t o2bspc;
+    uint64_t rpthc;
 };
 
 /* Structure containing variables used by the shared code (em_hw.c) */
@@ -2273,6 +2108,10 @@ struct em_hw {
 #define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
 #define E1000_WUC_APMPME     0x00000008 /* Assert PME on APM Wakeup */
 #define E1000_WUC_SPM        0x80000000 /* Enable SPM */
+/* Flexible Host Filter Table */
+#define E1000_FHFT(_n)       (0x09000 + ((_n) * 0x100))
+/* Ext Flexible Host Filter Table */
+#define E1000_FHFT_EXT(_n)  (0x09A00 + ((_n) * 0x100))
 
 /* Wake Up Filter Control */
 #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
@@ -2491,6 +2330,42 @@ struct em_host_command_info {
 #define E1000_FACTPS_LAN_FUNC_SEL                   0x40000000
 #define E1000_FACTPS_PM_STATE_CHANGED               0x80000000
 
+/* IVAR0 bit definitions */
+#define E1000_IVAR_VALID       0x80
+
+/* GPIE bit definitions */
+#define E1000_GPIE_NSICR       0x00000001
+#define E1000_GPIE_MSIX_MODE   0x00000010
+#define E1000_GPIE_EIAME       0x40000000
+#define E1000_GPIE_PBA         0x80000000
+
+/* MRQC bit definitions */
+#define E1000_MRQC_ENABLE_RSS_4Q               0x00000002
+#define E1000_MRQC_ENABLE_VMDQ                 0x00000003
+#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q          0x00000005
+#define E1000_MRQC_RSS_FIELD_IPV4_UDP          0x00400000
+#define E1000_MRQC_RSS_FIELD_IPV6_UDP          0x00800000
+#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX       0x01000000
+#define E1000_MRQC_ENABLE_RSS_8Q               0x00000002
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT            10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_MASK         0x00000F00
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                2  /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_LEGACY           0x00000000
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF       0x02000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT                0x04000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION  0x06000000
+#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
+#define E1000_SRRCTL_DESCTYPE_MASK             0x0E000000
+#define E1000_SRRCTL_TIMESTAMP                 0x40000000
+#define E1000_SRRCTL_DROP_EN                   0x80000000
+
+/* WUFC bit definitions */
+#define E1000_WUFC_FLX(_n)                     (1 << (16 + _n))
+#define E1000_WUFC_FLEX_HQ                     (1 << 14)
+
 /* PCI-Ex Config Space */
 #define PCI_EX_LINK_STATUS           0x12
 #define PCI_EX_LINK_WIDTH_MASK       0x3F0
@@ -3481,6 +3356,7 @@ struct em_host_command_info {
 #define GG82563_E_PHY_ID     0x01410CA0
 #define BME1000_E_PHY_ID     0x01410CB0
 #define BME1000_E_PHY_ID_R2  0x01410CB1
+#define I347AT4_E_PHY_ID     0x01410DC0
 #define M88E1543_E_PHY_ID    0x01410EA0
 #define I82577_E_PHY_ID      0x01540050
 #define I82578_E_PHY_ID      0x004DD040
Index: pci/if_em_osdep.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_em_osdep.h,v
retrieving revision 1.13
diff -u -p -r1.13 if_em_osdep.h
--- pci/if_em_osdep.h   18 Feb 2016 14:24:39 -0000      1.13
+++ pci/if_em_osdep.h   17 Jan 2020 13:33:59 -0000
@@ -96,20 +96,21 @@ struct em_osdep
                           offset, value)
 
 /* Convert a register name to its offset in the adapter's memory space */
-#define E1000_REG_OFFSET(hw, reg) \
-       ((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg)
+#define E1000_REG_TR(hw, reg)                                          \
+       ((hw)->mac_type >= em_82543 ?                                   \
+            reg : em_translate_82542_register(reg))
 
 /* Register READ/WRITE macros */
 
 #define E1000_READ_REG(hw, reg) \
        bus_space_read_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
                         ((struct em_osdep *)(hw)->back)->mem_bus_space_handle, 
\
-                         ((hw)->mac_type >= em_82543 ? E1000_##reg : 
E1000_82542_##reg))
+                         E1000_REG_TR(hw, E1000_##reg))
 
 #define E1000_WRITE_REG(hw, reg, value) \
        bus_space_write_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
                          ((struct em_osdep 
*)(hw)->back)->mem_bus_space_handle, \
-                          ((hw)->mac_type >= em_82543 ? E1000_##reg : 
E1000_82542_##reg), \
+                          E1000_REG_TR(hw, E1000_##reg), \
                           value)
 
 #define EM_READ_REG(hw, reg) \
@@ -122,18 +123,26 @@ struct em_osdep
                          ((struct em_osdep 
*)(hw)->back)->mem_bus_space_handle, \
                           reg, value)
 
+#define EM_READ_REG_ARRAY(hw, reg, index)                              \
+       bus_space_read_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
+           ((struct em_osdep *)(hw)->back)->mem_bus_space_handle,      \
+           reg + ((index) << 2))
+
+#define EM_WRITE_REG_ARRAY(hw, reg, index, value)                      \
+       bus_space_write_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
+           ((struct em_osdep *)(hw)->back)->mem_bus_space_handle,      \
+           reg + ((index) << 2), value)
 
 #define E1000_READ_REG_ARRAY(hw, reg, index) \
        bus_space_read_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
                         ((struct em_osdep *)(hw)->back)->mem_bus_space_handle, 
\
-                         ((hw)->mac_type >= em_82543 ? E1000_##reg : 
E1000_82542_##reg) \
-                         + ((index) << 2))
+                          E1000_REG_TR(hw, E1000_##reg) + ((index) << 2))
 
 #define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \
        bus_space_write_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
                          ((struct em_osdep 
*)(hw)->back)->mem_bus_space_handle, \
-                          ((hw)->mac_type >= em_82543 ? E1000_##reg : 
E1000_82542_##reg) \
-                          + ((index) << 2), value)
+                          E1000_REG_TR(hw, E1000_##reg) + ((index) << 2), \
+                          value)
 
 #define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
 #define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
@@ -141,14 +150,14 @@ struct em_osdep
 #define E1000_WRITE_REG_ARRAY_BYTE(hw, reg, index, value) \
        bus_space_write_1(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
                          ((struct em_osdep 
*)(hw)->back)->mem_bus_space_handle, \
-                          ((hw)->mac_type >= em_82543 ? E1000_##reg : 
E1000_82542_##reg \
-                          + index), value)
+                          E1000_REG_TR(hw, E1000_##reg) + index, \
+                          value)
 
 #define E1000_WRITE_REG_ARRAY_WORD(hw, reg, index, value) \
        bus_space_write_2(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
                          ((struct em_osdep 
*)(hw)->back)->mem_bus_space_handle, \
-                          ((hw)->mac_type >= em_82543 ? E1000_##reg : 
E1000_82542_##reg \
-                          + (index << 1)), value)
+                          E1000_REG_TR(hw, E1000_##reg) + (index << 1), \
+                          value)
 
 #define E1000_READ_ICH_FLASH_REG(hw, reg) \
        bus_space_read_4(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \

Reply via email to