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)

    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
    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 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: dev/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
--- dev/pci/if_em.c     20 Jan 2020 23:45:02 -0000      1.343
+++ dev/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: dev/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
--- dev/pci/if_em_hw.c  20 Jan 2020 23:45:02 -0000      1.105
+++ dev/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: dev/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
--- dev/pci/if_em_hw.h  20 Jan 2020 23:45:02 -0000      1.79
+++ dev/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: dev/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
--- dev/pci/if_em_osdep.h       18 Feb 2016 14:24:39 -0000      1.13
+++ dev/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