summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-11-24 01:44:49 +0000
committerglebius <glebius@FreeBSD.org>2005-11-24 01:44:49 +0000
commitf9340d98845e83aca6b2febdfa5a1ca70a412a2e (patch)
tree3dc3f02bad40bf51991675a7a8989304e121d368 /sys/dev
parent0dcc27d29ef2ba8b1858011048d970e62fb0701b (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/em/if_em.c208
-rw-r--r--sys/dev/em/if_em_hw.c355
-rw-r--r--sys/dev/em/if_em_hw.h104
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 */
OpenPOWER on IntegriCloud