diff options
author | glebius <glebius@FreeBSD.org> | 2005-11-24 01:44:49 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-11-24 01:44:49 +0000 |
commit | f9340d98845e83aca6b2febdfa5a1ca70a412a2e (patch) | |
tree | 3dc3f02bad40bf51991675a7a8989304e121d368 | |
parent | 0dcc27d29ef2ba8b1858011048d970e62fb0701b (diff) | |
download | FreeBSD-src-f9340d98845e83aca6b2febdfa5a1ca70a412a2e.zip FreeBSD-src-f9340d98845e83aca6b2febdfa5a1ca70a412a2e.tar.gz |
Merge in new driver version from Intel - 3.2.18.
The most important change is support for adapters based on
82571 and 82572 chips.
Tested on: 82547EI on i386
Tested on: 82540EM on sparc64
-rw-r--r-- | sys/dev/em/if_em.c | 208 | ||||
-rw-r--r-- | sys/dev/em/if_em_hw.c | 355 | ||||
-rw-r--r-- | sys/dev/em/if_em_hw.h | 104 |
3 files changed, 497 insertions, 170 deletions
diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index cf2a2ac..bc049cf 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -48,7 +48,7 @@ int em_display_debug_stats = 0; * Driver version *********************************************************************/ -char em_driver_version[] = "2.1.7"; +char em_driver_version[] = "Version - 3.2.18"; /********************************************************************* @@ -107,8 +107,17 @@ static em_vendor_info_t em_vendor_info_array[] = { 0x8086, E1000_DEV_ID_82547EI_MOBILE, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82547GI, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82571EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82571EB_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82571EB_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, + + { 0x8086, E1000_DEV_ID_82572EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82572EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82572EI_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82573E, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82573E_IAMT, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82573L, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ { 0, 0, 0, 0, 0} @@ -281,7 +290,7 @@ em_probe(device_t dev) ((pci_subdevice_id == ent->subdevice_id) || (ent->subdevice_id == PCI_ANY_ID))) { - sprintf(adapter_name, "%s, Version - %s", + sprintf(adapter_name, "%s %s", em_strings[ent->index], em_driver_version); device_set_desc_copy(dev, adapter_name); @@ -392,16 +401,6 @@ em_attach(device_t dev) adapter->hw.tbi_compatibility_en = TRUE; adapter->rx_buffer_len = EM_RXBUFFER_2048; - /* - * These parameters control the automatic generation(Tx) and - * response(Rx) to Ethernet PAUSE frames. - */ - adapter->hw.fc_high_water = FC_DEFAULT_HI_THRESH; - adapter->hw.fc_low_water = FC_DEFAULT_LO_THRESH; - adapter->hw.fc_pause_time = FC_DEFAULT_TX_TIMER; - adapter->hw.fc_send_xon = TRUE; - adapter->hw.fc = em_fc_full; - adapter->hw.phy_init_script = 1; adapter->hw.phy_reset_disable = FALSE; @@ -674,9 +673,9 @@ em_start(struct ifnet *ifp) static int em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { - int mask, reinit, error = 0; struct ifreq *ifr = (struct ifreq *) data; struct adapter * adapter = ifp->if_softc; + int error = 0; if (adapter->in_detach) return(error); @@ -687,9 +686,9 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ether_ioctl(ifp, command, data); break; case SIOCSIFMTU: - IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); + { #ifndef __NO_STRICT_ALIGNMENT - if (ifr->ifr_mtu > ETHERMTU) { + if (ifr->ifr_mtu > ETHERMTU) /* * XXX * Due to the limitation of DMA engine, it needs fix-up @@ -697,21 +696,38 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) * jumbo frame until we have better solutions. */ error = EINVAL; - } else -#endif - if (ifr->ifr_mtu > MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN || \ - /* 82573 does not support jumbo frames */ - (adapter->hw.mac_type == em_82573 && ifr->ifr_mtu > ETHERMTU) ) { +#else + int max_frame_size; + + IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); + + switch (adapter->hw.mac_type) { + case em_82571: + case em_82572: + max_frame_size = 10500; + break; + case em_82573: + /* 82573 does not support jumbo frames. */ + max_frame_size = ETHER_MAX_LEN; + break; + default: + max_frame_size = MAX_JUMBO_FRAME_SIZE; + } + if (ifr->ifr_mtu > max_frame_size - ETHER_HDR_LEN - + ETHER_CRC_LEN) { error = EINVAL; - } else { - EM_LOCK(adapter); - ifp->if_mtu = ifr->ifr_mtu; - adapter->hw.max_frame_size = - ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - em_init_locked(adapter); - EM_UNLOCK(adapter); + break; } + + EM_LOCK(adapter); + ifp->if_mtu = ifr->ifr_mtu; + adapter->hw.max_frame_size = + ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; + em_init_locked(adapter); + EM_UNLOCK(adapter); +#endif break; + } case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)"); EM_LOCK(adapter); @@ -752,6 +768,9 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = ifmedia_ioctl(ifp, ifr, &adapter->media, command); break; case SIOCSIFCAP: + { + int mask, reinit; + IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)"); reinit = 0; mask = ifr->ifr_reqcap ^ ifp->if_capenable; @@ -786,6 +805,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) em_init(adapter); break; + } default: IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)", (int)command); error = EINVAL; @@ -852,33 +872,38 @@ em_init_locked(struct adapter * adapter) em_stop(adapter); - /* Packet Buffer Allocation (PBA) + /* + * Packet Buffer Allocation (PBA) * Writing PBA sets the receive portion of the buffer * the remainder is used for the transmit buffer. - * - * Devices before the 82547 had a Packet Buffer of 64K. - * Default allocation: PBA=48K for Rx, leaving 16K for Tx. - * After the 82547 the buffer was reduced to 40K. - * Default allocation: PBA=30K for Rx, leaving 10K for Tx. - * Note: default does not leave enough room for Jumbo Frame >10k. */ - if(adapter->hw.mac_type < em_82547) { - /* Total FIFO is 64K */ - if(adapter->rx_buffer_len > EM_RXBUFFER_8192) - pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ - else - pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ - } else { - /* Total FIFO is 40K */ - if(adapter->hw.max_frame_size > EM_RXBUFFER_8192) { + switch (adapter->hw.mac_type) { + case em_82547: + case em_82547_rev_2: /* 82547: Total Packet Buffer is 40K */ + if (adapter->hw.max_frame_size > EM_RXBUFFER_8192) pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */ - } else { - pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */ - } + else + pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */ adapter->tx_fifo_head = 0; adapter->tx_head_addr = pba << EM_TX_HEAD_ADDR_SHIFT; adapter->tx_fifo_size = (E1000_PBA_40K - pba) << EM_PBA_BYTES_SHIFT; + break; + case em_82571: /* 82571: Total Packet Buffer is 48K */ + case em_82572: /* 82572: Total Packet Buffer is 48K */ + pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */ + break; + case em_82573: /* 82573: Total Packet Buffer is 32K */ + /* Jumbo frames not supported */ + pba = E1000_PBA_12K; /* 12K for Rx, 20K for Tx */ + break; + default: + /* Devices before 82547 had a Packet Buffer of 64K. */ + if(adapter->hw.max_frame_size > EM_RXBUFFER_8192) + pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ + else + pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ } + INIT_DEBUGOUT1("em_init: pba=%dK",pba); E1000_WRITE_REG(&adapter->hw, PBA, pba); @@ -1878,6 +1903,8 @@ em_free_pci_resources(struct adapter * adapter) static int em_hardware_init(struct adapter * adapter) { + uint16_t rx_buffer_size; + INIT_DEBUGOUT("em_hardware_init: begin"); /* Issue a global reset */ em_reset_hw(&adapter->hw); @@ -1898,6 +1925,28 @@ em_hardware_init(struct adapter * adapter) return(EIO); } + /* + * These parameters control the automatic generation (Tx) and + * response (Rx) to Ethernet PAUSE frames. + * - High water mark should allow for at least two frames to be + * received after sending an XOFF. + * - Low water mark works best when it is very near the high water mark. + * This allows the receiver to restart by sending XON when it has drained + * a bit. Here we use an arbitary value of 1500 which will restart after + * one full frame is pulled from the buffer. There could be several smaller + * frames in the buffer and if so they will not trigger the XON until their + * total number reduces the buffer by 1500. + * - The pause time is fairly large at 1000 x 512ns = 512 usec. + */ + rx_buffer_size = ((E1000_READ_REG(&adapter->hw, PBA) & 0xffff) << 10 ); + + adapter->hw.fc_high_water = rx_buffer_size - + roundup2(adapter->hw.max_frame_size, 1024); + adapter->hw.fc_low_water = adapter->hw.fc_high_water - 1500; + adapter->hw.fc_pause_time = 0x1000; + adapter->hw.fc_send_xon = TRUE; + adapter->hw.fc = em_fc_full; + if (em_init_hw(&adapter->hw) < 0) { printf("em%d: Hardware Initialization Failed", adapter->unit); @@ -2292,7 +2341,7 @@ em_initialize_transmit_unit(struct adapter * adapter) /* Program the Transmit Control Register */ reg_tctl = E1000_TCTL_PSP | E1000_TCTL_EN | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); - if (adapter->hw.mac_type >= em_82573) + if (adapter->hw.mac_type >= em_82571) reg_tctl |= E1000_TCTL_MULR; if (adapter->link_duplex == 1) { reg_tctl |= E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT; @@ -3272,40 +3321,45 @@ em_update_stats_counters(struct adapter *adapter) static void em_print_debug_info(struct adapter *adapter) { - int unit = adapter->unit; + int unit = adapter->unit; uint8_t *hw_addr = adapter->hw.hw_addr; printf("em%d: Adapter hardware address = %p \n", unit, hw_addr); - printf("em%d:CTRL = 0x%x\n", unit, - E1000_READ_REG(&adapter->hw, CTRL)); - printf("em%d:RCTL = 0x%x PS=(0x8402)\n", unit, - E1000_READ_REG(&adapter->hw, RCTL)); - printf("em%d:tx_int_delay = %d, tx_abs_int_delay = %d\n", unit, - E1000_READ_REG(&adapter->hw, TIDV), - E1000_READ_REG(&adapter->hw, TADV)); - printf("em%d:rx_int_delay = %d, rx_abs_int_delay = %d\n", unit, - E1000_READ_REG(&adapter->hw, RDTR), - E1000_READ_REG(&adapter->hw, RADV)); - printf("em%d: fifo workaround = %lld, fifo_reset = %lld\n", unit, - (long long)adapter->tx_fifo_wrk_cnt, - (long long)adapter->tx_fifo_reset_cnt); - printf("em%d: hw tdh = %d, hw tdt = %d\n", unit, - E1000_READ_REG(&adapter->hw, TDH), - E1000_READ_REG(&adapter->hw, TDT)); - printf("em%d: Num Tx descriptors avail = %d\n", unit, - adapter->num_tx_desc_avail); - printf("em%d: Tx Descriptors not avail1 = %ld\n", unit, - adapter->no_tx_desc_avail1); - printf("em%d: Tx Descriptors not avail2 = %ld\n", unit, - adapter->no_tx_desc_avail2); - printf("em%d: Std mbuf failed = %ld\n", unit, - adapter->mbuf_alloc_failed); - printf("em%d: Std mbuf cluster failed = %ld\n", unit, - adapter->mbuf_cluster_failed); - printf("em%d: Driver dropped packets = %ld\n", unit, - adapter->dropped_pkts); + printf("em%d: CTRL = 0x%x RCTL = 0x%x \n", unit, + E1000_READ_REG(&adapter->hw, CTRL), + E1000_READ_REG(&adapter->hw, RCTL)); + printf("em%d: Packet buffer = Tx=%dk Rx=%dk \n", unit, + ((E1000_READ_REG(&adapter->hw, PBA) & 0xffff0000) >> 16),\ + (E1000_READ_REG(&adapter->hw, PBA) & 0xffff) ); + printf("em%d: Flow control watermarks high = %d low = %d\n", unit, + adapter->hw.fc_high_water, + adapter->hw.fc_low_water); + printf("em%d: tx_int_delay = %d, tx_abs_int_delay = %d\n", unit, + E1000_READ_REG(&adapter->hw, TIDV), + E1000_READ_REG(&adapter->hw, TADV)); + printf("em%d: rx_int_delay = %d, rx_abs_int_delay = %d\n", unit, + E1000_READ_REG(&adapter->hw, RDTR), + E1000_READ_REG(&adapter->hw, RADV)); + printf("em%d: fifo workaround = %lld, fifo_reset_count = %lld\n", + unit, (long long)adapter->tx_fifo_wrk_cnt, + (long long)adapter->tx_fifo_reset_cnt); + printf("em%d: hw tdh = %d, hw tdt = %d\n", unit, + E1000_READ_REG(&adapter->hw, TDH), + E1000_READ_REG(&adapter->hw, TDT)); + printf("em%d: Num Tx descriptors avail = %d\n", unit, + adapter->num_tx_desc_avail); + printf("em%d: Tx Descriptors not avail1 = %ld\n", unit, + adapter->no_tx_desc_avail1); + printf("em%d: Tx Descriptors not avail2 = %ld\n", unit, + adapter->no_tx_desc_avail2); + printf("em%d: Std mbuf failed = %ld\n", unit, + adapter->mbuf_alloc_failed); + printf("em%d: Std mbuf cluster failed = %ld\n", unit, + adapter->mbuf_cluster_failed); + printf("em%d: Driver dropped packets = %ld\n", unit, + adapter->dropped_pkts); - return; + return; } static void diff --git a/sys/dev/em/if_em_hw.c b/sys/dev/em/if_em_hw.c index 8795f6d..179a2ee 100644 --- a/sys/dev/em/if_em_hw.c +++ b/sys/dev/em/if_em_hw.c @@ -91,15 +91,14 @@ uint16_t em_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = static const uint16_t em_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] = - { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, - 22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58, - 32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74, - 43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90, - 57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108, - 73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124, - 91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128, - 108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}; - + { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, + 0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, + 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, + 21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, + 40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, + 60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, + 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124, + 104, 109, 114, 118, 121, 124}; /****************************************************************************** * Set the phy type member in the hw struct. @@ -315,8 +314,19 @@ em_set_mac_type(struct em_hw *hw) case E1000_DEV_ID_82547GI: hw->mac_type = em_82547_rev_2; break; + case E1000_DEV_ID_82571EB_COPPER: + case E1000_DEV_ID_82571EB_FIBER: + case E1000_DEV_ID_82571EB_SERDES: + hw->mac_type = em_82571; + break; + case E1000_DEV_ID_82572EI_COPPER: + case E1000_DEV_ID_82572EI_FIBER: + case E1000_DEV_ID_82572EI_SERDES: + hw->mac_type = em_82572; + break; case E1000_DEV_ID_82573E: case E1000_DEV_ID_82573E_IAMT: + case E1000_DEV_ID_82573L: hw->mac_type = em_82573; break; default: @@ -325,6 +335,8 @@ em_set_mac_type(struct em_hw *hw) } switch(hw->mac_type) { + case em_82571: + case em_82572: case em_82573: hw->eeprom_semaphore_present = TRUE; /* fall through */ @@ -333,9 +345,8 @@ em_set_mac_type(struct em_hw *hw) case em_82541_rev_2: case em_82547_rev_2: hw->asf_firmware_present = TRUE; - break; default: - break; + break; } return E1000_SUCCESS; @@ -361,21 +372,31 @@ em_set_media_type(struct em_hw *hw) switch (hw->device_id) { case E1000_DEV_ID_82545GM_SERDES: case E1000_DEV_ID_82546GB_SERDES: + case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82572EI_SERDES: hw->media_type = em_media_type_internal_serdes; break; default: - if(hw->mac_type >= em_82543) { - status = E1000_READ_REG(hw, STATUS); - if(status & E1000_STATUS_TBIMODE) { - hw->media_type = em_media_type_fiber; - /* tbi_compatibility not valid on fiber */ - hw->tbi_compatibility_en = FALSE; - } else { - hw->media_type = em_media_type_copper; - } - } else { - /* This is an 82542 (fiber only) */ - hw->media_type = em_media_type_fiber; + switch (hw->mac_type) { + case em_82542_rev2_0: + case em_82542_rev2_1: + hw->media_type = em_media_type_fiber; + break; + case em_82573: + /* + * The STATUS_TBIMODE bit is reserved or reused for + * this device. + */ + hw->media_type = em_media_type_copper; + break; + default: + status = E1000_READ_REG(hw, STATUS); + if (status & E1000_STATUS_TBIMODE) { + hw->media_type = em_media_type_fiber; + /* tbi_compatibility not valid on fiber */ + hw->tbi_compatibility_en = FALSE; + } else + hw->media_type = em_media_type_copper; } } } @@ -519,19 +540,23 @@ em_reset_hw(struct em_hw *hw) /* Wait for EEPROM reload */ msec_delay(20); break; - case em_82573: - usec_delay(10); - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_EE_RST; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_FLUSH(hw); - /* fall through */ - ret_val = em_get_auto_rd_done(hw); - if(ret_val) - /* We don't want to continue accessing MAC registers. */ - return ret_val; - break; - default: + case em_82573: + if (em_is_onboard_nvm_eeprom(hw) == FALSE) { + usec_delay(10); + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_EE_RST; + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); + E1000_WRITE_FLUSH(hw); + } + /* fall through */ + case em_82571: + case em_82572: + ret_val = em_get_auto_rd_done(hw); + if(ret_val) + /* We don't want to continue accessing MAC registers. */ + return ret_val; + break; + default: /* Wait for EEPROM reload (it happens automatically) */ msec_delay(5); break; @@ -683,12 +708,14 @@ em_init_hw(struct em_hw *hw) if(hw->mac_type > em_82544) { ctrl = E1000_READ_REG(hw, TXDCTL); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; - switch (hw->mac_type) { - default: - break; + switch (hw->mac_type) { + case em_82571: + case em_82572: + ctrl |= (1 << 22); case em_82573: - ctrl |= E1000_TXDCTL_COUNT_DESC; - break; + ctrl |= E1000_TXDCTL_COUNT_DESC; + default: + break; } E1000_WRITE_REG(hw, TXDCTL, ctrl); } @@ -697,6 +724,23 @@ em_init_hw(struct em_hw *hw) em_enable_tx_pkt_filtering(hw); } + switch (hw->mac_type) { + case em_82571: + case em_82572: + ctrl = E1000_READ_REG(hw, TXDCTL1); + ctrl &= ~E1000_TXDCTL_WTHRESH; + ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB; + ctrl |= (1 << 22); + E1000_WRITE_REG(hw, TXDCTL1, ctrl); + default: + break; + } + + if (hw->mac_type == em_82573) { + uint32_t gcr = E1000_READ_REG(hw, GCR); + gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; + E1000_WRITE_REG(hw, GCR, gcr); + } /* Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link @@ -768,6 +812,11 @@ em_setup_link(struct em_hw *hw) DEBUGFUNC("em_setup_link"); + /* In the case of the phy reset being blocked, we already have a link. + * We do not have to set it up again. */ + if (em_check_phy_reset_block(hw)) + return E1000_SUCCESS; + /* Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or @@ -776,19 +825,27 @@ em_setup_link(struct em_hw *hw) * control setting, then the variable hw->fc will * be initialized based on a value in the EEPROM. */ - if(em_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } - - if(hw->fc == em_fc_default) { - if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) - hw->fc = em_fc_none; - else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == - EEPROM_WORD0F_ASM_DIR) - hw->fc = em_fc_tx_pause; - else - hw->fc = em_fc_full; + if (hw->fc == em_fc_default) { + switch (hw->mac_type) { + case em_82573: + hw->fc = em_fc_full; + break; + default: + ret_val = em_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, + 1, &eeprom_data); + if (ret_val) { + DEBUGOUT("EEPROM Read Error\n"); + return -E1000_ERR_EEPROM; + } + + if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) + hw->fc = em_fc_none; + else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == + EEPROM_WORD0F_ASM_DIR) + hw->fc = em_fc_tx_pause; + else + hw->fc = em_fc_full; + } } /* We want to save off the original Flow Control configuration just @@ -881,6 +938,14 @@ em_setup_fiber_serdes_link(struct em_hw *hw) DEBUGFUNC("em_setup_fiber_serdes_link"); + /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists + * until explicitly turned off or a power cycle is performed. A read to + * the register does not indicate its status. Therefore, we ensure + * loopback mode is disabled during initialization. + */ + if (hw->mac_type == em_82571 || hw->mac_type == em_82572) + E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK); + /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be * set when the optics detect a signal. On older adapters, it will be * cleared when there is a signal. This applies to fiber media only. @@ -2884,15 +2949,22 @@ em_phy_hw_reset(struct em_hw *hw) DEBUGOUT("Resetting Phy...\n"); if(hw->mac_type > em_82543) { - /* Read the device control register and assert the E1000_CTRL_PHY_RST - * bit. Then, take it out of reset. - */ - ctrl = E1000_READ_REG(hw, CTRL); - E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); - E1000_WRITE_FLUSH(hw); - msec_delay(10); - E1000_WRITE_REG(hw, CTRL, ctrl); - E1000_WRITE_FLUSH(hw); + /* + * Read the device control register and assert the E1000_CTRL_PHY_RST + * bit. Then, take it out of reset. + * For pre-em_82571 hardware, we delay for 10ms between the assert + * and deassert. For em_82571 hardware and later, we instead delay + * for 10ms after the deassertion. + */ + ctrl = E1000_READ_REG(hw, CTRL); + E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); + E1000_WRITE_FLUSH(hw); + if (hw->mac_type < em_82571) + msec_delay(10); + E1000_WRITE_REG(hw, CTRL, ctrl); + E1000_WRITE_FLUSH(hw); + if (hw->mac_type >= em_82571) + msec_delay(10); } else { /* Read the Extended Device Control Register, assert the PHY_RESET_DIR * bit to put the PHY into reset. Then, take it out of reset. @@ -2946,6 +3018,8 @@ em_phy_reset(struct em_hw *hw) switch (hw->mac_type) { case em_82541_rev_2: + case em_82571: + case em_82572: ret_val = em_phy_hw_reset(hw); if(ret_val) return ret_val; @@ -2984,6 +3058,15 @@ em_detect_gig_phy(struct em_hw *hw) DEBUGFUNC("em_detect_gig_phy"); + /* The 82571 firmware may still be configuring the PHY. In this + * case, we cannot access the PHY until the configuration is done. So + * we explicitly set the PHY values. */ + if(hw->mac_type == em_82571 || hw->mac_type == em_82572) { + hw->phy_id = IGP01E1000_I_PHY_ID; + hw->phy_type = em_phy_igp_2; + return E1000_SUCCESS; + } + /* Read the PHY ID Registers to identify which PHY is onboard. */ ret_val = em_read_phy_reg(hw, PHY_ID1, &phy_id_high); if(ret_val) @@ -3337,6 +3420,21 @@ em_init_eeprom_params(struct em_hw *hw) eeprom->use_eerd = FALSE; eeprom->use_eewr = FALSE; break; + case em_82571: + case em_82572: + eeprom->type = em_eeprom_spi; + eeprom->opcode_bits = 8; + eeprom->delay_usec = 1; + if (eecd & E1000_EECD_ADDR_BITS) { + eeprom->page_size = 32; + eeprom->address_bits = 16; + } else { + eeprom->page_size = 8; + eeprom->address_bits = 8; + } + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; + break; case em_82573: eeprom->type = em_eeprom_spi; eeprom->opcode_bits = 8; @@ -3561,6 +3659,7 @@ em_acquire_eeprom(struct em_hw *hw) eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); DEBUGOUT("Could not acquire EEPROM grant\n"); + em_put_hw_eeprom_semaphore(hw); return -E1000_ERR_EEPROM; } } @@ -4067,7 +4166,7 @@ em_write_eeprom(struct em_hw *hw, return -E1000_ERR_EEPROM; } - /* 82573 reads only through eerd */ + /* 82573 writes only through eewr */ if(eeprom->use_eewr == TRUE) return em_write_eeprom_eewr(hw, offset, words, data); @@ -4356,9 +4455,15 @@ em_read_mac_addr(struct em_hw * hw) hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF); hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8); } - if(((hw->mac_type == em_82546) || (hw->mac_type == em_82546_rev_3)) && - (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) - hw->perm_mac_addr[5] ^= 0x01; + switch (hw->mac_type) { + case em_82546: + case em_82546_rev_3: + case em_82571: + if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) + hw->perm_mac_addr[5] ^= 0x01; + default: + break; + } for(i = 0; i < NODE_ADDRESS_SIZE; i++) hw->mac_addr[i] = hw->perm_mac_addr[i]; @@ -4388,6 +4493,12 @@ em_init_rx_addrs(struct em_hw *hw) em_rar_set(hw, hw->mac_addr, 0); rar_num = E1000_RAR_ENTRIES; + + /* Reserve a spot for the Locally Administered Address to work around + * an 82571 issue in which a reset on one port will reload the MAC on + * the other port. */ + if ((hw->mac_type == em_82571) && (hw->laa_is_present == TRUE)) + rar_num -= 1; /* Zero out the other 15 receive addresses. */ DEBUGOUT("Clearing RAR[1-15]\n"); for(i = 1; i < rar_num; i++) { @@ -4430,6 +4541,12 @@ em_mc_addr_list_update(struct em_hw *hw, /* Clear RAR[1-15] */ DEBUGOUT(" Clearing RAR[1-15]\n"); num_rar_entry = E1000_RAR_ENTRIES; + /* Reserve a spot for the Locally Administered Address to work around + * an 82571 issue in which a reset on one port will reload the MAC on + * the other port. */ + if ((hw->mac_type == em_82571) && (hw->laa_is_present == TRUE)) + num_rar_entry -= 1; + for(i = rar_used_count; i < num_rar_entry; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); @@ -5154,9 +5271,15 @@ em_get_bus_info(struct em_hw *hw) hw->bus_speed = em_bus_speed_unknown; hw->bus_width = em_bus_width_unknown; break; + case em_82572: case em_82573: hw->bus_type = em_bus_type_pci_express; hw->bus_speed = em_bus_speed_2500; + hw->bus_width = em_bus_width_pciex_1; + break; + case em_82571: + hw->bus_type = em_bus_type_pci_express; + hw->bus_speed = em_bus_speed_2500; hw->bus_width = em_bus_width_pciex_4; break; default: @@ -5253,6 +5376,7 @@ em_get_cable_length(struct em_hw *hw, int32_t ret_val; uint16_t agc_value = 0; uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE; + uint16_t max_agc = 0; uint16_t i, phy_data; uint16_t cable_length; @@ -5341,6 +5465,51 @@ em_get_cable_length(struct em_hw *hw, IGP01E1000_AGC_RANGE) : 0; *max_length = em_igp_cable_length_table[agc_value] + IGP01E1000_AGC_RANGE; + } else if (hw->phy_type == em_phy_igp_2) { + uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = + {IGP02E1000_PHY_AGC_A, + IGP02E1000_PHY_AGC_B, + IGP02E1000_PHY_AGC_C, + IGP02E1000_PHY_AGC_D}; + + /* Read the AGC registers for all channels */ + for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { + ret_val = em_read_phy_reg(hw, agc_reg_array[i], + &phy_data); + if (ret_val) + return ret_val; + + /* + * Getting bits 15:9, which represent the combination + * of course and fine gain values. The result is a + * number that can be put into the lookup table to + * obtain the approximate cable length. + */ + cur_agc = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & + IGP02E1000_AGC_LENGTH_MASK; + + /* Remove min & max AGC values from calculation. */ + if (em_igp_2_cable_length_table[min_agc] > + em_igp_2_cable_length_table[cur_agc]) + min_agc = cur_agc; + if (em_igp_2_cable_length_table[max_agc] < + em_igp_2_cable_length_table[cur_agc]) + max_agc = cur_agc; + + agc_value += em_igp_2_cable_length_table[cur_agc]; + } + + agc_value -= (em_igp_2_cable_length_table[min_agc] + + em_igp_2_cable_length_table[max_agc]); + agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2); + + /* + * Calculate cable length with the error range + * of +/- 10 meters. + */ + *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ? + (agc_value - IGP02E1000_AGC_RANGE) : 0; + *max_length = agc_value + IGP02E1000_AGC_RANGE; } return E1000_SUCCESS; @@ -6465,10 +6634,9 @@ em_get_auto_rd_done(struct em_hw *hw) DEBUGFUNC("em_get_auto_rd_done"); switch (hw->mac_type) { - default: - msec_delay(5); - break; case em_82573: + case em_82571: + case em_82572: while(timeout) { if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; else msec_delay(1); @@ -6480,8 +6648,16 @@ em_get_auto_rd_done(struct em_hw *hw) return -E1000_ERR_RESET; } break; + default: + msec_delay(5); } + /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high. + * Need to wait for PHY configuration completion before accessing NVM + * and PHY. */ + if (hw->mac_type == em_82573) + msec_delay(25); + return E1000_SUCCESS; } @@ -6497,12 +6673,32 @@ em_get_auto_rd_done(struct em_hw *hw) int32_t em_get_phy_cfg_done(struct em_hw *hw) { - DEBUGFUNC("em_get_phy_cfg_done"); - - /* Simply wait for 10ms */ - msec_delay(10); - - return E1000_SUCCESS; + int32_t timeout = PHY_CFG_TIMEOUT; + uint32_t cfg_mask = E1000_EEPROM_CFG_DONE; + + DEBUGFUNC("em_get_phy_cfg_done"); + + switch (hw->mac_type) { + case em_82571: + case em_82572: + while (timeout) { + if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) + break; + else + msec_delay(1); + timeout--; + } + + if (!timeout) { + DEBUGOUT("MNG configuration cycle has not completed.\n"); + return -E1000_ERR_RESET; + } + break; + default: + msec_delay(10); + } + + return E1000_SUCCESS; } /*************************************************************************** @@ -6572,8 +6768,7 @@ em_put_hw_eeprom_semaphore(struct em_hw *hw) return; swsm = E1000_READ_REG(hw, SWSM); - /* Release both semaphores. */ - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + swsm &= ~(E1000_SWSM_SWESMBI); E1000_WRITE_REG(hw, SWSM, swsm); } @@ -6592,7 +6787,7 @@ int32_t em_check_phy_reset_block(struct em_hw *hw) { uint32_t manc = 0; - if(hw->mac_type > em_82547_rev_2) + if (hw->mac_type > em_82547_rev_2) manc = E1000_READ_REG(hw, MANC); return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? E1000_BLK_PHY_RESET : E1000_SUCCESS; @@ -6609,6 +6804,8 @@ em_arc_subsystem_valid(struct em_hw *hw) * if this is the case. We read FWSM to determine the manageability mode. */ switch (hw->mac_type) { + case em_82571: + case em_82572: case em_82573: fwsm = E1000_READ_REG(hw, FWSM); if((fwsm & E1000_FWSM_MODE_MASK) != 0) diff --git a/sys/dev/em/if_em_hw.h b/sys/dev/em/if_em_hw.h index 34b7304..d23d2b6 100644 --- a/sys/dev/em/if_em_hw.h +++ b/sys/dev/em/if_em_hw.h @@ -63,6 +63,8 @@ typedef enum { em_82541_rev_2, em_82547, em_82547_rev_2, + em_82571, + em_82572, em_82573, em_num_macs } em_mac_type; @@ -72,6 +74,7 @@ typedef enum { em_eeprom_spi, em_eeprom_microwire, em_eeprom_flash, + em_eeprom_none, /* No NVM support */ em_num_eeprom_types } em_eeprom_type; @@ -126,6 +129,7 @@ typedef enum { em_bus_width_32, em_bus_width_64, em_bus_width_pciex_1, + em_bus_width_pciex_2, em_bus_width_pciex_4, em_bus_width_reserved } em_bus_width; @@ -152,6 +156,7 @@ typedef enum { em_igp_cable_length_90 = 90, em_igp_cable_length_100 = 100, em_igp_cable_length_110 = 110, + em_igp_cable_length_115 = 115, em_igp_cable_length_120 = 120, em_igp_cable_length_130 = 130, em_igp_cable_length_140 = 140, @@ -492,8 +497,15 @@ uint8_t em_arc_subsystem_valid(struct em_hw *hw); #define E1000_DEV_ID_82546GB_PCIE 0x108A #define E1000_DEV_ID_82547EI 0x1019 #define E1000_DEV_ID_82547EI_MOBILE 0x101A +#define E1000_DEV_ID_82571EB_COPPER 0x105E +#define E1000_DEV_ID_82571EB_FIBER 0x105F +#define E1000_DEV_ID_82571EB_SERDES 0x1060 +#define E1000_DEV_ID_82572EI_COPPER 0x107D +#define E1000_DEV_ID_82572EI_FIBER 0x107E +#define E1000_DEV_ID_82572EI_SERDES 0x107F #define E1000_DEV_ID_82573E 0x108B #define E1000_DEV_ID_82573E_IAMT 0x108C +#define E1000_DEV_ID_82573L 0x109A #define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 @@ -854,6 +866,7 @@ struct em_ffvt_entry { #define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX #define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX #define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX +#define E1000_DISABLE_SERDES_LOOPBACK 0x0400 /* Register Set. (82543, 82544) * @@ -875,6 +888,7 @@ struct em_ffvt_entry { #define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ #define E1000_FLA 0x0001C /* Flash Access - RW */ #define E1000_MDIC 0x00020 /* MDI Control - RW */ +#define E1000_SCTL 0x00024 /* SerDes Control - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ #define E1000_FCT 0x00030 /* Flow Control Type - RW */ @@ -886,6 +900,12 @@ 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_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 */ @@ -917,6 +937,12 @@ struct em_ffvt_entry { #define E1000_RDH 0x02810 /* RX Descriptor Head - RW */ #define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */ #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 - RW */ #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ @@ -1002,15 +1028,15 @@ struct em_ffvt_entry { #define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ #define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ #define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ -#define E1000_IAC 0x4100 /* Interrupt Assertion Count */ -#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */ -#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */ -#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */ -#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */ -#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */ -#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */ -#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */ -#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */ +#define E1000_IAC 0x04100 /* Interrupt Assertion 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 */ +#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */ +#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */ +#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_RXCSUM 0x05000 /* RX Checksum Control - RW */ #define E1000_RFCTL 0x05008 /* Receive Filter Control*/ #define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ @@ -1040,6 +1066,14 @@ struct em_ffvt_entry { #define E1000_FWSM 0x05B54 /* FW Semaphore */ #define E1000_FFLT_DBG 0x05F04 /* Debug Register */ #define E1000_HICR 0x08F00 /* Host Inteface Control */ + +/* 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_RSSIM 0x05864 /* RSS Interrupt Mask */ +#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ /* Register Set (82542) * * Some of the 82542 registers are located at different offsets than they are @@ -1054,6 +1088,7 @@ struct em_ffvt_entry { #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_FCAL E1000_FCAL #define E1000_82542_FCAH E1000_FCAH #define E1000_82542_FCT E1000_FCT @@ -1071,6 +1106,18 @@ struct em_ffvt_entry { #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_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 @@ -1219,6 +1266,13 @@ struct em_ffvt_entry { #define E1000_82542_ICRXOC E1000_ICRXOC #define E1000_82542_HICR E1000_HICR +#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 + /* Statistics counters collected by the MAC */ struct em_hw_stats { uint64_t crcerrs; @@ -1358,6 +1412,7 @@ struct em_hw { boolean_t serdes_link_down; boolean_t tbi_compatibility_en; boolean_t tbi_compatibility_on; + boolean_t laa_is_present; boolean_t phy_reset_disable; boolean_t fc_send_xon; boolean_t fc_strict_ieee; @@ -1396,6 +1451,7 @@ struct em_hw { #define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ #define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */ #define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ @@ -1468,6 +1524,7 @@ struct em_hw { #define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ #define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ +#define E1000_EECD_SECVAL_SHIFT 22 #define E1000_STM_OPCODE 0xDB00 #define E1000_HICR_FW_RESET 0xC0 @@ -1513,6 +1570,8 @@ struct em_hw { #define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 #define E1000_CTRL_EXT_WR_WMARK_384 0x02000000 #define E1000_CTRL_EXT_WR_WMARK_448 0x03000000 +#define E1000_CTRL_EXT_CANC 0x04000000 /* Interrupt delay cancellation */ +#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ @@ -1546,6 +1605,7 @@ struct em_hw { #define E1000_LEDCTL_LED2_BLINK 0x00800000 #define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 #define E1000_LEDCTL_LED3_MODE_SHIFT 24 +#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000 #define E1000_LEDCTL_LED3_IVRT 0x40000000 #define E1000_LEDCTL_LED3_BLINK 0x80000000 @@ -1806,6 +1866,16 @@ struct em_hw { #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ +/* Multiple Receive Queue Control */ +#define E1000_MRQC_ENABLE_MASK 0x00000003 +#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001 +#define E1000_MRQC_ENABLE_RSS_INT 0x00000004 +#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000 +#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 +#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00040000 +#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000 +#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000 /* Definitions for power management and wakeup registers */ /* Wake Up Control */ @@ -1949,7 +2019,7 @@ struct em_host_command_info { #define E1000_MDALIGN 4096 -#define E1000_GCR_BEM32 0x00400000 +#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 /* Function Active and Power State to MNG */ #define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 #define E1000_FACTPS_LAN0_VALID 0x00000004 @@ -2002,6 +2072,7 @@ struct em_host_command_info { /* EEPROM Word Offsets */ #define EEPROM_COMPAT 0x0003 #define EEPROM_ID_LED_SETTINGS 0x0004 +#define EEPROM_VERSION 0x0005 #define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */ #define EEPROM_PHY_CLASS_WORD 0x0007 #define EEPROM_INIT_CONTROL1_REG 0x000A @@ -2012,6 +2083,8 @@ struct em_host_command_info { #define EEPROM_FLASH_VERSION 0x0032 #define EEPROM_CHECKSUM_REG 0x003F +#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */ + /* Word definitions for ID LED Settings */ #define ID_LED_RESERVED_0000 0x0000 #define ID_LED_RESERVED_FFFF 0xFFFF @@ -2130,6 +2203,8 @@ struct em_host_command_info { #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 #define E1000_PBA_30K 0x001E +#define E1000_PBA_32K 0x0020 +#define E1000_PBA_38K 0x0026 #define E1000_PBA_40K 0x0028 #define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */ @@ -2261,6 +2336,9 @@ struct em_host_command_info { #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ #define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ +#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */ + /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ #define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */ @@ -2330,8 +2408,6 @@ struct em_host_command_info { #define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 -#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ -#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/ /* PHY Control Register */ #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ #define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ @@ -2612,11 +2688,11 @@ struct em_host_command_info { /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */ #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128 -#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128 +#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113 /* The precision error of the cable length is +/- 10 meters */ #define IGP01E1000_AGC_RANGE 10 -#define IGP02E1000_AGC_RANGE 10 +#define IGP02E1000_AGC_RANGE 15 /* IGP01E1000 PCS Initialization register */ /* bits 3:6 in the PCS registers stores the channels polarity */ |