patch-2.4.23 linux-2.4.23/drivers/net/e1000/e1000_main.c
Next file: linux-2.4.23/drivers/net/e1000/e1000_osdep.h
Previous file: linux-2.4.23/drivers/net/e1000/e1000_hw.h
Back to the patch index
Back to the overall index
- Lines: 672
- Date:
2003-11-28 10:26:20.000000000 -0800
- Orig file:
linux-2.4.22/drivers/net/e1000/e1000_main.c
- Orig date:
2003-08-25 04:44:42.000000000 -0700
diff -urN linux-2.4.22/drivers/net/e1000/e1000_main.c linux-2.4.23/drivers/net/e1000/e1000_main.c
@@ -30,27 +30,41 @@
/* Change Log
*
- * 5.1.13 5/28/03
- * o Bug fix: request_irq() failure resulted in freeing resources twice!
- * [Don Fry (brazilnut@us.ibm.com)]
- * o Bug fix: fix VLAN support on ppc64 [Mark Rakes (mrakes@vivato.net)]
- * o Bug fix: missing Tx cleanup opportunities during interrupt handling.
- * o Bug fix: alloc_etherdev failure didn't cleanup regions in probe.
- * o Cleanup: s/int/unsigned int/ for descriptor ring indexes.
+ * 5.2.20 9/30/03
+ * o Bug fix: SERDES devices might be connected to a back-plane
+ * switch that doesn't support auto-neg, so add the capability
+ * to force 1000/Full.
+ * o Bug fix: Flow control settings for hi/lo watermark didn't
+ * consider changes in the Rx FIFO size, which could occur with
+ * Jumbo Frames or with the reduced FIFO in 82547.
+ * o Better propagation of error codes. [Janice Girouard
+ * (janiceg@us.ibm.com)].
+ * o Bug fix: hang under heavy Tx stress when running out of Tx
+ * descriptors; wasn't clearing context descriptor when backing
+ * out of send because of no-resource condition.
+ *
+ * 5.2.16 8/8/03
+ * o Added support for new controllers: 82545GM, 82546GB, 82541/7_B1
+ * o Bug fix: reset h/w before first EEPROM read because we don't know
+ * who may have been messing with the device before we got there.
+ * [Dave Johnson (ddj -a-t- cascv.brown.edu)]
+ * o Bug fix: read the correct work from EEPROM to detect programmed
+ * WoL settings.
+ * o Bug fix: TSO would hang if space left in FIFO was being miscalculated
+ * when mss dropped without a correspoding drop in the DMA buffer size.
+ * o ASF for Fiber nics isn't supported.
+ * o Bug fix: Workaround added for potential hang with 82544 running in
+ * PCI-X if send buffer terminates within an evenly-aligned dword.
+ * o Feature: Add support for ethtool flow control setting.
+ * o Feature: Add support for ethtool TSO setting.
+ * o Feature: Increase default Tx Descriptor count to 1024 for >= 82544.
*
- * 5.1.11 5/6/03
- * o Feature: Added support for 82546EB (Quad-port) hardware.
- * o Feature: Added support for Diagnostics through Ethtool.
- * o Cleanup: Removed /proc support.
- * o Cleanup: Removed proprietary IDIAG interface.
- * o Bug fix: TSO bug fixes.
- *
- * 5.0.42 3/5/03
+ * 5.1.13 5/28/03
*/
char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "5.1.13-k1";
+char e1000_driver_version[] = "5.2.20-k1";
char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
@@ -61,7 +75,7 @@
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask, private data (not used) }
*/
-static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
+static struct pci_device_id e1000_pci_tbl[] = {
{0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -71,15 +85,28 @@
{0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
/* required last entry */
{0,}
};
@@ -120,7 +147,7 @@
static void e1000_update_stats(struct e1000_adapter *adapter);
static inline void e1000_irq_disable(struct e1000_adapter *adapter);
static inline void e1000_irq_enable(struct e1000_adapter *adapter);
-static void e1000_intr(int irq, void *data, struct pt_regs *regs);
+static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
#ifdef CONFIG_E1000_NAPI
static int e1000_clean(struct net_device *netdev, int *budget);
@@ -228,6 +255,7 @@
e1000_up(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ int err;
/* hardware has been reset, we need to reload some things */
@@ -240,9 +268,10 @@
e1000_configure_rx(adapter);
e1000_alloc_rx_buffers(adapter);
- if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
- netdev->name, netdev))
- return -1;
+ if((err = request_irq(netdev->irq, &e1000_intr,
+ SA_SHIRQ | SA_SAMPLE_RANDOM,
+ netdev->name, netdev)))
+ return err;
mod_timer(&adapter->watchdog_timer, jiffies);
e1000_irq_enable(adapter);
@@ -296,7 +325,13 @@
}
E1000_WRITE_REG(&adapter->hw, PBA, pba);
+ /* flow control settings */
+ adapter->hw.fc_high_water = pba - E1000_FC_HIGH_DIFF;
+ adapter->hw.fc_low_water = pba - E1000_FC_LOW_DIFF;
+ adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
+ adapter->hw.fc_send_xon = 1;
adapter->hw.fc = adapter->hw.original_fc;
+
e1000_reset_hw(&adapter->hw);
if(adapter->hw.mac_type >= e1000_82544)
E1000_WRITE_REG(&adapter->hw, WUC, 0);
@@ -328,29 +363,32 @@
int mmio_len;
int pci_using_dac;
int i;
+ int err;
uint16_t eeprom_data;
- if((i = pci_enable_device(pdev)))
- return i;
+ if((err = pci_enable_device(pdev)))
+ return err;
- if(!(i = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) {
+ if(!(err = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) {
pci_using_dac = 1;
} else {
- if((i = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) {
+ if((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) {
E1000_ERR("No usable DMA configuration, aborting\n");
- return i;
+ return err;
}
pci_using_dac = 0;
}
- if((i = pci_request_regions(pdev, e1000_driver_name)))
- return i;
+ if((err = pci_request_regions(pdev, e1000_driver_name)))
+ return err;
pci_set_master(pdev);
netdev = alloc_etherdev(sizeof(struct e1000_adapter));
- if(!netdev)
+ if(!netdev) {
+ err = -ENOMEM;
goto err_alloc_etherdev;
+ }
SET_MODULE_OWNER(netdev);
@@ -364,8 +402,10 @@
mmio_len = pci_resource_len(pdev, BAR_0);
adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
- if(!adapter->hw.hw_addr)
+ if(!adapter->hw.hw_addr) {
+ err = -EIO;
goto err_ioremap;
+ }
for(i = BAR_1; i <= BAR_5; i++) {
if(pci_resource_len(pdev, i) == 0)
@@ -403,7 +443,7 @@
/* setup the private structure */
- if(e1000_sw_init(adapter))
+ if((err = e1000_sw_init(adapter)))
goto err_sw_init;
if(adapter->hw.mac_type >= e1000_82543) {
@@ -425,10 +465,16 @@
if(pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
+ /* before reading the EEPROM, reset the controller to
+ * put the device in a known good starting state */
+
+ e1000_reset_hw(&adapter->hw);
+
/* make sure the EEPROM is good */
if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
+ err = -EIO;
goto err_eeprom;
}
@@ -437,8 +483,10 @@
e1000_read_mac_addr(&adapter->hw);
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->dev_addr))
+ if(!is_valid_ether_addr(netdev->dev_addr)) {
+ err = -EIO;
goto err_eeprom;
+ }
e1000_read_part_num(&adapter->hw, &(adapter->part_num));
@@ -475,12 +523,28 @@
* enable the ACPI Magic Packet filter
*/
- e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data);
- if((adapter->hw.mac_type >= e1000_82544) &&
- (eeprom_data & E1000_EEPROM_APME))
+ switch(adapter->hw.mac_type) {
+ case e1000_82542_rev2_0:
+ case e1000_82542_rev2_1:
+ case e1000_82543:
+ break;
+ case e1000_82546:
+ case e1000_82546_rev_3:
+ if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
+ && (adapter->hw.media_type == e1000_media_type_copper)) {
+ e1000_read_eeprom(&adapter->hw,
+ EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
+ break;
+ }
+ /* Fall Through */
+ default:
+ e1000_read_eeprom(&adapter->hw,
+ EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+ break;
+ }
+ if(eeprom_data & E1000_EEPROM_APME)
adapter->wol |= E1000_WUFC_MAG;
-
/* reset the hardware with the new settings */
e1000_reset(adapter);
@@ -492,10 +556,10 @@
err_eeprom:
iounmap(adapter->hw.hw_addr);
err_ioremap:
- kfree(netdev);
+ free_netdev(netdev);
err_alloc_etherdev:
pci_release_regions(pdev);
- return -ENOMEM;
+ return err;
}
/**
@@ -515,7 +579,8 @@
struct e1000_adapter *adapter = netdev->priv;
uint32_t manc;
- if(adapter->hw.mac_type >= e1000_82540) {
+ if(adapter->hw.mac_type >= e1000_82540 &&
+ adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if(manc & E1000_MANC_SMBUS_EN) {
manc |= E1000_MANC_ARP_EN;
@@ -530,7 +595,7 @@
iounmap(adapter->hw.hw_addr);
pci_release_regions(pdev);
- kfree(netdev);
+ free_netdev(netdev);
}
/**
@@ -569,35 +634,20 @@
if (e1000_set_mac_type(hw)) {
E1000_ERR("Unknown MAC Type\n");
- return -1;
+ return -EIO;
}
/* initialize eeprom parameters */
e1000_init_eeprom_params(hw);
- /* flow control settings */
-
- hw->fc_high_water = E1000_FC_HIGH_THRESH;
- hw->fc_low_water = E1000_FC_LOW_THRESH;
- hw->fc_pause_time = E1000_FC_PAUSE_TIME;
- hw->fc_send_xon = 1;
-
- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547))
+ if((hw->mac_type == e1000_82541) ||
+ (hw->mac_type == e1000_82547) ||
+ (hw->mac_type == e1000_82541_rev_2) ||
+ (hw->mac_type == e1000_82547_rev_2))
hw->phy_init_script = 1;
- /* Media type - copper or fiber */
-
- if(hw->mac_type >= e1000_82543) {
- uint32_t status = E1000_READ_REG(hw, STATUS);
-
- if(status & E1000_STATUS_TBIMODE)
- hw->media_type = e1000_media_type_fiber;
- else
- hw->media_type = e1000_media_type_copper;
- } else {
- hw->media_type = e1000_media_type_fiber;
- }
+ e1000_set_media_type(hw);
if(hw->mac_type < e1000_82543)
hw->report_tx_early = 0;
@@ -613,6 +663,7 @@
if(hw->media_type == e1000_media_type_copper) {
hw->mdix = AUTO_ALL_MODES;
hw->disable_polarity_correction = FALSE;
+ hw->master_slave = E1000_MASTER_SLAVE;
}
atomic_set(&adapter->irq_sem, 1);
@@ -638,18 +689,19 @@
e1000_open(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
+ int err;
/* allocate transmit descriptors */
- if(e1000_setup_tx_resources(adapter))
+ if((err = e1000_setup_tx_resources(adapter)))
goto err_setup_tx;
/* allocate receive descriptors */
- if(e1000_setup_rx_resources(adapter))
+ if((err = e1000_setup_rx_resources(adapter)))
goto err_setup_rx;
- if(e1000_up(adapter))
+ if((err = e1000_up(adapter)))
goto err_up;
return 0;
@@ -661,7 +713,7 @@
err_setup_tx:
e1000_reset(adapter);
- return -EBUSY;
+ return err;
}
/**
@@ -762,7 +814,8 @@
tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
break;
default:
- if(adapter->hw.media_type == e1000_media_type_fiber)
+ if(adapter->hw.media_type == e1000_media_type_fiber ||
+ adapter->hw.media_type == e1000_media_type_internal_serdes)
tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
else
tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
@@ -797,6 +850,12 @@
adapter->txd_cmd |= E1000_TXD_CMD_RS;
else
adapter->txd_cmd |= E1000_TXD_CMD_RPS;
+
+ /* Cache if we're 82544 running in PCI-X because we'll
+ * need this to apply a workaround later in the send path. */
+ if(adapter->hw.mac_type == e1000_82544 &&
+ adapter->hw.bus_type == e1000_bus_type_pcix)
+ adapter->pcix_82544 = 1;
}
/**
@@ -1488,28 +1547,48 @@
unsigned int first)
{
struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+ struct e1000_tx_desc *tx_desc;
struct e1000_buffer *buffer_info;
- int len = skb->len;
+ unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
unsigned int offset = 0, size, count = 0, i;
-
#ifdef NETIF_F_TSO
- unsigned int tso = skb_shinfo(skb)->tso_size;
+ unsigned int mss;
#endif
- unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
+ unsigned int nr_frags;
unsigned int f;
+
+#ifdef NETIF_F_TSO
+ mss = skb_shinfo(skb)->tso_size;
+ /* The controller does a simple calculation to
+ * make sure there is enough room in the FIFO before
+ * initiating the DMA for each buffer. The calc is:
+ * 4 = ceil(buffer len/mss). To make sure we don't
+ * overrun the FIFO, adjust the max buffer len if mss
+ * drops. */
+ if(mss)
+ max_per_txd = min(mss << 2, max_per_txd);
+#endif
+ nr_frags = skb_shinfo(skb)->nr_frags;
len -= skb->data_len;
i = tx_ring->next_to_use;
while(len) {
buffer_info = &tx_ring->buffer_info[i];
- size = min(len, E1000_MAX_DATA_PER_TXD);
+ size = min(len, max_per_txd);
#ifdef NETIF_F_TSO
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
- if(tso && !nr_frags && size == len && size > 4)
+ if(mss && !nr_frags && size == len && size > 8)
size -= 4;
#endif
+ /* Workaround for potential 82544 hang in PCI-X. Avoid
+ * terminating buffers within evenly-aligned dwords. */
+ if(adapter->pcix_82544 &&
+ !((unsigned long)(skb->data + offset + size - 1) & 4) &&
+ size > 4)
+ size -= 4;
+
buffer_info->length = size;
buffer_info->dma =
pci_map_single(adapter->pdev,
@@ -1529,22 +1608,30 @@
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = 0;
+ offset = frag->page_offset;
while(len) {
buffer_info = &tx_ring->buffer_info[i];
- size = min(len, E1000_MAX_DATA_PER_TXD);
+ size = min(len, max_per_txd);
#ifdef NETIF_F_TSO
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
- if(tso && f == (nr_frags-1) && size == len && size > 4)
+ if(mss && f == (nr_frags-1) && size == len && size > 8)
size -= 4;
#endif
+ /* Workaround for potential 82544 hang in PCI-X.
+ * Avoid terminating buffers within evenly-aligned
+ * dwords. */
+ if(adapter->pcix_82544 &&
+ !((unsigned long)(frag->page+offset+size-1) & 4) &&
+ size > 4)
+ size -= 4;
+
buffer_info->length = size;
buffer_info->dma =
pci_map_page(adapter->pdev,
frag->page,
- frag->page_offset + offset,
+ offset,
size,
PCI_DMA_TODEVICE);
buffer_info->time_stamp = jiffies;
@@ -1555,6 +1642,46 @@
if(++i == tx_ring->count) i = 0;
}
}
+
+ if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2) {
+
+ /* There aren't enough descriptors available to queue up
+ * this send (need: count + 1 context desc + 1 desc gap
+ * to keep tail from touching head), so undo the mapping
+ * and abort the send. We could have done the check before
+ * we mapped the skb, but because of all the workarounds
+ * (above), it's too difficult to predict how many we're
+ * going to need.*/
+ i = adapter->tx_ring.next_to_use;
+
+ if(i == first) {
+ /* Cleanup after e1000_tx_[csum|tso] scribbling
+ * on descriptors. */
+ tx_desc = E1000_TX_DESC(*tx_ring, first);
+ tx_desc->buffer_addr = 0;
+ tx_desc->lower.data = 0;
+ tx_desc->upper.data = 0;
+ }
+
+ while(count--) {
+ buffer_info = &tx_ring->buffer_info[i];
+
+ if(buffer_info->dma) {
+ pci_unmap_page(adapter->pdev,
+ buffer_info->dma,
+ buffer_info->length,
+ PCI_DMA_TODEVICE);
+ buffer_info->dma = 0;
+ }
+
+ if(++i == tx_ring->count) i = 0;
+ }
+
+ adapter->tx_ring.next_to_use = first;
+
+ return 0;
+ }
+
i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -1649,29 +1776,19 @@
return 0;
}
-/* Tx Descriptors needed, worst case */
-#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
- (((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
-#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
- MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
-
static int
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev->priv;
unsigned int first;
unsigned int tx_flags = 0;
+ int count;
if(skb->len <= 0) {
dev_kfree_skb_any(skb);
return 0;
}
- if(E1000_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED) {
- netif_stop_queue(netdev);
- return 1;
- }
-
if(adapter->hw.mac_type == e1000_82547) {
if(e1000_82547_fifo_workaround(adapter, skb)) {
netif_stop_queue(netdev);
@@ -1692,7 +1809,12 @@
else if(e1000_tx_csum(adapter, skb))
tx_flags |= E1000_TX_FLAGS_CSUM;
- e1000_tx_queue(adapter, e1000_tx_map(adapter, skb, first), tx_flags);
+ if((count = e1000_tx_map(adapter, skb, first)))
+ e1000_tx_queue(adapter, count, tx_flags);
+ else {
+ netif_stop_queue(netdev);
+ return 1;
+ }
netdev->trans_start = jiffies;
@@ -1965,7 +2087,7 @@
* @pt_regs: CPU registers structure
**/
-static void
+static irqreturn_t
e1000_intr(int irq, void *data, struct pt_regs *regs)
{
struct net_device *netdev = data;
@@ -1976,7 +2098,7 @@
#endif
if(!icr)
- return; /* Not our interrupt */
+ return IRQ_NONE; /* Not our interrupt */
if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
adapter->hw.get_link_status = 1;
@@ -2000,6 +2122,8 @@
!e1000_clean_tx_irq(adapter))
break;
#endif
+
+ return IRQ_HANDLED;
}
#ifdef CONFIG_E1000_NAPI
@@ -2229,7 +2353,7 @@
/**
* e1000_alloc_rx_buffers - Replace used receive buffers
- * @data: address of board private structure
+ * @adapter: address of board private structure
**/
static void
@@ -2385,7 +2509,7 @@
uint16_t mii_reg;
uint16_t spddplx;
- if(adapter->hw.media_type == e1000_media_type_fiber)
+ if(adapter->hw.media_type != e1000_media_type_copper)
return -EOPNOTSUPP;
switch (cmd) {
@@ -2657,7 +2781,7 @@
case SYS_DOWN:
case SYS_HALT:
case SYS_POWER_OFF:
- pci_for_each_dev(pdev) {
+ while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
if(pci_dev_driver(pdev) == &e1000_driver)
e1000_suspend(pdev, 3);
}
@@ -2704,7 +2828,8 @@
E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
}
- if(adapter->hw.media_type == e1000_media_type_fiber) {
+ if(adapter->hw.media_type == e1000_media_type_fiber ||
+ adapter->hw.media_type == e1000_media_type_internal_serdes) {
/* keep the laser running in D3 */
ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
@@ -2724,7 +2849,8 @@
pci_save_state(pdev, adapter->pci_state);
- if(adapter->hw.mac_type >= e1000_82540) {
+ if(adapter->hw.mac_type >= e1000_82540 &&
+ adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
if(manc & E1000_MANC_SMBUS_EN) {
manc |= E1000_MANC_ARP_EN;
@@ -2762,7 +2888,8 @@
netif_device_attach(netdev);
- if(adapter->hw.mac_type >= e1000_82540) {
+ if(adapter->hw.mac_type >= e1000_82540 &&
+ adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
manc &= ~(E1000_MANC_ARP_EN);
E1000_WRITE_REG(&adapter->hw, MANC, manc);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)