summaryrefslogtreecommitdiffstats
path: root/sys/dev/em/if_em.c
diff options
context:
space:
mode:
authorpdeuskar <pdeuskar@FreeBSD.org>2002-07-16 16:55:03 +0000
committerpdeuskar <pdeuskar@FreeBSD.org>2002-07-16 16:55:03 +0000
commit7995d306bcdcaa2681090cfcaed794f15a85c77d (patch)
tree284e4f4e8951c0bd2650ac202095af1ba0c16b3f /sys/dev/em/if_em.c
parent4410d83dcc36f0f5f77a472d9371eb764d2e3d62 (diff)
downloadFreeBSD-src-7995d306bcdcaa2681090cfcaed794f15a85c77d.zip
FreeBSD-src-7995d306bcdcaa2681090cfcaed794f15a85c77d.tar.gz
- Use IO mode to reset the controller (82544 and beyond)
- Read the Mac address only once during attach. (This fixes the failover issue observed using the bonding driver) MFC after: 3 days
Diffstat (limited to 'sys/dev/em/if_em.c')
-rw-r--r--sys/dev/em/if_em.c127
1 files changed, 96 insertions, 31 deletions
diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c
index e91abd6..f28143a 100644
--- a/sys/dev/em/if_em.c
+++ b/sys/dev/em/if_em.c
@@ -53,7 +53,7 @@ struct adapter *em_adapter_list = NULL;
* Driver version
*********************************************************************/
-char em_driver_version[] = "1.3.8";
+char em_driver_version[] = "1.3.14";
/*********************************************************************
@@ -128,20 +128,20 @@ static int em_allocate_receive_structures(struct adapter *);
static int em_allocate_transmit_structures(struct adapter *);
static void em_process_receive_interrupts(struct adapter *);
static void em_receive_checksum(struct adapter *,
- struct em_rx_desc * rx_desc,
- struct mbuf *);
+ struct em_rx_desc * rx_desc,
+ struct mbuf *);
static void em_transmit_checksum_setup(struct adapter *,
- struct mbuf *,
- struct em_tx_buffer *,
- u_int32_t *,
- u_int32_t *);
+ struct mbuf *,
+ struct em_tx_buffer *,
+ u_int32_t *,
+ u_int32_t *);
static void em_set_promisc(struct adapter *);
static void em_disable_promisc(struct adapter *);
static void em_set_multi(struct adapter *);
static void em_print_hw_stats(struct adapter *);
static void em_print_link_status(struct adapter *);
static int em_get_buf(struct em_rx_buffer *, struct adapter *,
- struct mbuf *);
+ struct mbuf *);
static void em_enable_vlans(struct adapter *adapter);
/*********************************************************************
@@ -267,7 +267,6 @@ em_attach(device_t dev)
adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
adapter->hw.tbi_compatibility_en = TRUE;
adapter->rx_buffer_len = EM_RXBUFFER_2048;
- adapter->rx_checksum = EM_ENABLE_RXCSUM_OFFLOAD;
adapter->hw.fc_high_water = FC_DEFAULT_HI_THRESH;
adapter->hw.fc_low_water = FC_DEFAULT_LO_THRESH;
@@ -339,6 +338,16 @@ em_attach(device_t dev)
return(EIO);
}
+ /* Copy the permanent MAC address out of the EEPROM */
+ if (em_read_mac_addr(&adapter->hw) < 0) {
+ printf("em%d: EEPROM read error while reading mac address\n",
+ adapter->unit);
+ return(EIO);
+ }
+
+ memcpy(adapter->interface_data.ac_enaddr, adapter->hw.mac_addr,
+ ETH_LENGTH_OF_ADDRESS);
+
/* Setup OS specific network interface */
em_setup_interface(dev, adapter);
@@ -1051,7 +1060,11 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
ifmr->ifm_active |= IFM_100_TX;
break;
case 1000:
+#if __FreeBSD_version < 500000
+ ifmr->ifm_active |= IFM_1000_TX;
+#else
ifmr->ifm_active |= IFM_1000_T;
+#endif
break;
}
if (adapter->link_duplex == FULL_DUPLEX)
@@ -1087,7 +1100,11 @@ em_media_change(struct ifnet *ifp)
adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
break;
case IFM_1000_SX:
+#if __FreeBSD_version < 500000
+ case IFM_1000_TX:
+#else
case IFM_1000_T:
+#endif
adapter->hw.autoneg = DO_AUTO_NEG;
adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
break;
@@ -1183,26 +1200,53 @@ em_identify_hardware(struct adapter * adapter)
static int
em_allocate_pci_resources(struct adapter * adapter)
{
- int resource_id = EM_MMBA;
+ int i, val, rid;
device_t dev = adapter->dev;
+ rid = EM_MMBA;
adapter->res_memory = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &resource_id, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_ACTIVE);
if (!(adapter->res_memory)) {
printf("em%d: Unable to allocate bus resource: memory\n",
adapter->unit);
return(ENXIO);
}
- adapter->osdep.bus_space_tag =
+ adapter->osdep.mem_bus_space_tag =
rman_get_bustag(adapter->res_memory);
- adapter->osdep.bus_space_handle =
+ adapter->osdep.mem_bus_space_handle =
rman_get_bushandle(adapter->res_memory);
- adapter->hw.hw_addr = (uint8_t *)&adapter->osdep.bus_space_handle;
+ adapter->hw.hw_addr = (uint8_t *)&adapter->osdep.mem_bus_space_handle;
+
- resource_id = 0x0;
+ if (adapter->hw.mac_type > em_82543) {
+ /* Figure our where our IO BAR is ? */
+ rid = EM_MMBA;
+ for (i = 0; i < 5; i++) {
+ val = pci_read_config(dev, rid, 4);
+ if (val & 0x00000001) {
+ adapter->io_rid = rid;
+ break;
+ }
+ rid += 4;
+ }
+
+ adapter->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
+ &adapter->io_rid, 0, ~0, 1,
+ RF_ACTIVE);
+ if (!(adapter->res_ioport)) {
+ printf("em%d: Unable to allocate bus resource: ioport\n",
+ adapter->unit);
+ return(ENXIO);
+ }
+
+ adapter->hw.io_base =
+ rman_get_start(adapter->res_ioport);
+ }
+
+ rid = 0x0;
adapter->res_interrupt = bus_alloc_resource(dev, SYS_RES_IRQ,
- &resource_id, 0, ~0, 1,
+ &rid, 0, ~0, 1,
RF_SHAREABLE | RF_ACTIVE);
if (!(adapter->res_interrupt)) {
printf("em%d: Unable to allocate bus resource: interrupt\n",
@@ -1237,6 +1281,11 @@ em_free_pci_resources(struct adapter * adapter)
bus_release_resource(dev, SYS_RES_MEMORY, EM_MMBA,
adapter->res_memory);
}
+
+ if (adapter->res_ioport != NULL) {
+ bus_release_resource(dev, SYS_RES_IOPORT, adapter->io_rid,
+ adapter->res_ioport);
+ }
return;
}
@@ -1260,16 +1309,6 @@ em_hardware_init(struct adapter * adapter)
adapter->unit);
return(EIO);
}
- /* Copy the permanent MAC address and part number out of the EEPROM */
- if (em_read_mac_addr(&adapter->hw) < 0) {
- printf("em%d: EEPROM read error while reading mac address\n",
- adapter->unit);
- return(EIO);
- }
-
- memcpy(adapter->interface_data.ac_enaddr, adapter->hw.mac_addr,
- ETH_LENGTH_OF_ADDRESS);
-
if (em_read_part_num(&adapter->hw, &(adapter->part_num)) < 0) {
printf("em%d: EEPROM read error while reading part number\n",
@@ -1351,9 +1390,15 @@ em_setup_interface(device_t dev, struct adapter * adapter)
0, NULL);
ifmedia_add(&adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
0, NULL);
+#if __FreeBSD_version < 500000
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_TX | IFM_FDX,
+ 0, NULL);
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_TX, 0, NULL);
+#else
ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX,
0, NULL);
ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL);
+#endif
}
ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
@@ -1799,8 +1844,9 @@ em_initialize_receive_unit(struct adapter * adapter)
switch (adapter->rx_buffer_len) {
+ default:
case EM_RXBUFFER_2048:
- reg_rctl |= E1000_RCTL_SZ_2048 | E1000_RCTL_LPE;
+ reg_rctl |= E1000_RCTL_SZ_2048;
break;
case EM_RXBUFFER_4096:
reg_rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
@@ -1811,10 +1857,11 @@ em_initialize_receive_unit(struct adapter * adapter)
case EM_RXBUFFER_16384:
reg_rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
break;
- default:
- reg_rctl |= E1000_RCTL_SZ_2048;
}
+ if (ifp->if_mtu > ETHERMTU)
+ reg_rctl |= E1000_RCTL_LPE;
+
/* Enable 82543 Receive Checksum Offload for TCP and UDP */
if ((adapter->hw.mac_type >= em_82543) &&
(ifp->if_capenable & IFCAP_RXCSUM)) {
@@ -2091,14 +2138,32 @@ em_disable_intr(struct adapter *adapter)
return;
}
-void em_write_pci_cfg(struct em_hw *adapter,
+void em_write_pci_cfg(struct em_hw *hw,
uint32_t reg,
uint16_t *value)
{
- pci_write_config(((struct em_osdep *)adapter->back)->dev, reg,
+ pci_write_config(((struct em_osdep *)hw->back)->dev, reg,
*value, 2);
}
+void em_read_pci_cfg(struct em_hw *hw, uint32_t reg,
+ uint16_t *value)
+{
+ *value = pci_read_config(((struct em_osdep *)hw->back)->dev,
+ reg, 2);
+ return;
+}
+
+uint32_t em_io_read(struct em_hw *hw, uint32_t port)
+{
+ return(inl(port));
+}
+
+void em_io_write(struct em_hw *hw, uint32_t port, uint32_t value)
+{
+ outl(port, value);
+ return;
+}
/**********************************************************************
*
OpenPOWER on IntegriCloud