On Thu, Jan 30, 2020 at 09:15:35AM +0100, Martin Pieuchot wrote:
> 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.
> > > 

I see in the diff where this is being done, but is the multi-queue part not
in this diff? Just looks like you separated things, and left it at that?

> > >   - 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

You can add this to the "works as intended" list (t490):

em0 at pci0 dev 31 function 6 "Intel I219-LM" rev 0x30: msi

Diff reads ok to me. So ok mlarkin@ if you are still looking for oks and didn't
commit it already.

-ml

>       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