summaryrefslogtreecommitdiffstats
path: root/sys/dev/em/if_em.c
diff options
context:
space:
mode:
authorpdeuskar <pdeuskar@FreeBSD.org>2004-09-01 23:22:41 +0000
committerpdeuskar <pdeuskar@FreeBSD.org>2004-09-01 23:22:41 +0000
commitf42123243465f139c6618ed6352cef11b2d561a0 (patch)
treea56b0eef358761b21773943572e581d42e91725e /sys/dev/em/if_em.c
parent433dcaa41e11d40f456fd88dda1ad03bbac9fda1 (diff)
downloadFreeBSD-src-f42123243465f139c6618ed6352cef11b2d561a0.zip
FreeBSD-src-f42123243465f139c6618ed6352cef11b2d561a0.tar.gz
Added support for Intel PRO/1000 GT Desktop Adapter(Device ID 8086 107C)
Removed support for Intel 82541ER Added fix for 82547 which corrects an issue with Jumbo frames larger than 10k. Added fix for vlan tagged frames not being properly bridged. Corrected TBI workaround. Corrected incorrect LED operation issues Submitted by: tackerman (Tony Ackerman) MFC after: 2 weeks
Diffstat (limited to 'sys/dev/em/if_em.c')
-rw-r--r--sys/dev/em/if_em.c78
1 files changed, 60 insertions, 18 deletions
diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c
index 28aafa4..3a0659c 100644
--- a/sys/dev/em/if_em.c
+++ b/sys/dev/em/if_em.c
@@ -51,7 +51,7 @@ struct adapter *em_adapter_list = NULL;
* Driver version
*********************************************************************/
-char em_driver_version[] = "1.7.25";
+char em_driver_version[] = "1.7.35";
/*********************************************************************
@@ -80,7 +80,6 @@ static em_vendor_info_t em_vendor_info_array[] =
{ 0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0},
- { 0x8086, 0x1014, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0},
@@ -99,6 +98,7 @@ static em_vendor_info_t em_vendor_info_array[] =
{ 0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, 0x107C, PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */
{ 0, 0, 0, 0, 0}
};
@@ -742,7 +742,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
em_init(adapter);
break;
default:
- IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)\n", (int)command);
+ IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)", (int)command);
error = EINVAL;
}
@@ -797,6 +797,7 @@ em_init_locked(struct adapter * adapter)
{
struct ifnet *ifp;
+ uint32_t pba;
ifp = &adapter->interface_data.ac_if;
INIT_DEBUGOUT("em_init: begin");
@@ -805,6 +806,36 @@ em_init_locked(struct adapter * adapter)
em_stop(adapter);
+ /* 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) {
+ pba = E1000_PBA_22K; /* 22K for Rx, 18K 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;
+ }
+ INIT_DEBUGOUT1("em_init: pba=%dK",pba);
+ E1000_WRITE_REG(&adapter->hw, PBA, pba);
+
/* Get the latest mac address, User can use a LAA */
bcopy(adapter->interface_data.ac_enaddr, adapter->hw.mac_addr,
ETHER_ADDR_LEN);
@@ -1138,10 +1169,6 @@ em_tx_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, int e
bcopy(seg, q->segs, nsegs * sizeof(seg[0]));
}
-#define EM_FIFO_HDR 0x10
-#define EM_82547_PKT_THRESH 0x3e0
-#define EM_82547_TX_FIFO_SIZE 0x2800
-#define EM_82547_TX_FIFO_BEGIN 0xf00
/*********************************************************************
*
* This routine maps the mbufs to tx descriptors.
@@ -1356,7 +1383,7 @@ em_82547_move_tail_locked(struct adapter *adapter)
if(eop) {
if (em_82547_fifo_workaround(adapter, length)) {
- adapter->tx_fifo_wrk++;
+ adapter->tx_fifo_wrk_cnt++;
callout_reset(&adapter->tx_fifo_timer, 1,
em_82547_move_tail, adapter);
break;
@@ -1387,7 +1414,7 @@ em_82547_fifo_workaround(struct adapter *adapter, int len)
fifo_pkt_len = EM_ROUNDUP(len + EM_FIFO_HDR, EM_FIFO_HDR);
if (adapter->link_duplex == HALF_DUPLEX) {
- fifo_space = EM_82547_TX_FIFO_SIZE - adapter->tx_fifo_head;
+ fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
if (fifo_pkt_len >= (EM_82547_PKT_THRESH + fifo_space)) {
if (em_82547_tx_fifo_reset(adapter)) {
@@ -1409,8 +1436,8 @@ em_82547_update_fifo_head(struct adapter *adapter, int len)
/* tx_fifo_head is always 16 byte aligned */
adapter->tx_fifo_head += fifo_pkt_len;
- if (adapter->tx_fifo_head >= EM_82547_TX_FIFO_SIZE) {
- adapter->tx_fifo_head -= EM_82547_TX_FIFO_SIZE;
+ if (adapter->tx_fifo_head >= adapter->tx_fifo_size) {
+ adapter->tx_fifo_head -= adapter->tx_fifo_size;
}
return;
@@ -1435,17 +1462,17 @@ em_82547_tx_fifo_reset(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, TCTL, tctl & ~E1000_TCTL_EN);
/* Reset FIFO pointers */
- E1000_WRITE_REG(&adapter->hw, TDFT, EM_82547_TX_FIFO_BEGIN);
- E1000_WRITE_REG(&adapter->hw, TDFH, EM_82547_TX_FIFO_BEGIN);
- E1000_WRITE_REG(&adapter->hw, TDFTS, EM_82547_TX_FIFO_BEGIN);
- E1000_WRITE_REG(&adapter->hw, TDFHS, EM_82547_TX_FIFO_BEGIN);
+ E1000_WRITE_REG(&adapter->hw, TDFT, adapter->tx_head_addr);
+ E1000_WRITE_REG(&adapter->hw, TDFH, adapter->tx_head_addr);
+ E1000_WRITE_REG(&adapter->hw, TDFTS, adapter->tx_head_addr);
+ E1000_WRITE_REG(&adapter->hw, TDFHS, adapter->tx_head_addr);
/* Re-enable TX unit */
E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
E1000_WRITE_FLUSH(&adapter->hw);
adapter->tx_fifo_head = 0;
- adapter->tx_fifo_reset++;
+ adapter->tx_fifo_reset_cnt++;
return(TRUE);
}
@@ -1459,13 +1486,23 @@ em_set_promisc(struct adapter * adapter)
{
u_int32_t reg_rctl;
+ u_int32_t ctrl;
struct ifnet *ifp = &adapter->interface_data.ac_if;
reg_rctl = E1000_READ_REG(&adapter->hw, RCTL);
+ ctrl = E1000_READ_REG(&adapter->hw, CTRL);
if (ifp->if_flags & IFF_PROMISC) {
reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
+
+ /* Disable VLAN stripping in promiscous mode
+ * This enables bridging of vlan tagged frames to occur
+ * and also allows vlan tags to be seen in tcpdump
+ */
+ ctrl &= ~E1000_CTRL_VME;
+ E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+
} else if (ifp->if_flags & IFF_ALLMULTI) {
reg_rctl |= E1000_RCTL_MPE;
reg_rctl &= ~E1000_RCTL_UPE;
@@ -1486,6 +1523,7 @@ em_disable_promisc(struct adapter * adapter)
reg_rctl &= (~E1000_RCTL_MPE);
E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl);
+ em_enable_vlans(adapter);
return;
}
@@ -3169,6 +3207,10 @@ em_print_debug_info(struct adapter *adapter)
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));
@@ -3183,8 +3225,8 @@ em_print_debug_info(struct adapter *adapter)
adapter->clean_tx_interrupts);
#endif
printf("em%d: fifo workaround = %lld, fifo_reset = %lld\n", unit,
- (long long)adapter->tx_fifo_wrk,
- (long long)adapter->tx_fifo_reset);
+ (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));
OpenPOWER on IntegriCloud