summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'openvz-sources/022.061/5105_linux-2.6.8.1-e100-3.4.8.patch')
-rw-r--r--openvz-sources/022.061/5105_linux-2.6.8.1-e100-3.4.8.patch953
1 files changed, 0 insertions, 953 deletions
diff --git a/openvz-sources/022.061/5105_linux-2.6.8.1-e100-3.4.8.patch b/openvz-sources/022.061/5105_linux-2.6.8.1-e100-3.4.8.patch
deleted file mode 100644
index 55c36c9..0000000
--- a/openvz-sources/022.061/5105_linux-2.6.8.1-e100-3.4.8.patch
+++ /dev/null
@@ -1,953 +0,0 @@
---- linux-2.6.8.1-t043-libata-update/drivers/net/e100.c 2005-09-26 13:32:56.000000000 +0400
-+++ rhel4u2/drivers/net/e100.c 2005-10-19 11:47:13.000000000 +0400
-@@ -87,9 +87,8 @@
- * cb_to_use is the next CB to use for queuing a command; cb_to_clean
- * is the next CB to check for completion; cb_to_send is the first
- * CB to start on in case of a previous failure to resume. CB clean
-- * up happens in interrupt context in response to a CU interrupt, or
-- * in dev->poll in the case where NAPI is enabled. cbs_avail keeps
-- * track of number of free CB resources available.
-+ * up happens in interrupt context in response to a CU interrupt.
-+ * cbs_avail keeps track of number of free CB resources available.
- *
- * Hardware padding of short packets to minimum packet size is
- * enabled. 82557 pads with 7Eh, while the later controllers pad
-@@ -112,9 +111,8 @@
- * replacement RFDs cannot be allocated, or the RU goes non-active,
- * the RU must be restarted. Frame arrival generates an interrupt,
- * and Rx indication and re-allocation happen in the same context,
-- * therefore no locking is required. If NAPI is enabled, this work
-- * happens in dev->poll. A software-generated interrupt is gen-
-- * erated from the watchdog to recover from a failed allocation
-+ * therefore no locking is required. A software-generated interrupt
-+ * is generated from the watchdog to recover from a failed allocation
- * senario where all Rx resources have been indicated and none re-
- * placed.
- *
-@@ -126,8 +124,6 @@
- * supported. Tx Scatter/Gather is not supported. Jumbo Frames is
- * not supported (hardware limitation).
- *
-- * NAPI support is enabled with CONFIG_E100_NAPI.
-- *
- * MagicPacket(tm) WoL support is enabled/disabled via ethtool.
- *
- * Thanks to JC (jchapman@katalix.com) for helping with
-@@ -156,11 +152,13 @@
- #include <linux/string.h>
- #include <asm/unaligned.h>
-
-+#include "e100_compat.h"
-
- #define DRV_NAME "e100"
--#define DRV_VERSION "3.0.18"
-+#define DRV_EXT "-NAPI"
-+#define DRV_VERSION "3.4.8-k2"DRV_EXT
- #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
--#define DRV_COPYRIGHT "Copyright(c) 1999-2004 Intel Corporation"
-+#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation"
- #define PFX DRV_NAME ": "
-
- #define E100_WATCHDOG_PERIOD (2 * HZ)
-@@ -169,6 +167,7 @@
- MODULE_DESCRIPTION(DRV_DESCRIPTION);
- MODULE_AUTHOR(DRV_COPYRIGHT);
- MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-
- static int debug = 3;
- module_param(debug, int, 0);
-@@ -201,6 +200,9 @@ static struct pci_device_id e100_id_tabl
- INTEL_8255X_ETHERNET_DEVICE(0x1053, 5),
- INTEL_8255X_ETHERNET_DEVICE(0x1054, 5),
- INTEL_8255X_ETHERNET_DEVICE(0x1055, 5),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1056, 5),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1057, 5),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
- INTEL_8255X_ETHERNET_DEVICE(0x1064, 6),
- INTEL_8255X_ETHERNET_DEVICE(0x1065, 6),
- INTEL_8255X_ETHERNET_DEVICE(0x1066, 6),
-@@ -209,12 +211,17 @@ static struct pci_device_id e100_id_tabl
- INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),
- INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),
- INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),
-- INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1091, 7),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1092, 7),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
-+ INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
- INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
- INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
- INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
- INTEL_8255X_ETHERNET_DEVICE(0x2459, 2),
- INTEL_8255X_ETHERNET_DEVICE(0x245D, 2),
-+ INTEL_8255X_ETHERNET_DEVICE(0x27DC, 7),
- { 0, }
- };
- MODULE_DEVICE_TABLE(pci, e100_id_table);
-@@ -242,6 +249,7 @@ enum phy {
- phy_nsc_tx = 0x5C002000,
- phy_82562_et = 0x033002A8,
- phy_82562_em = 0x032002A8,
-+ phy_82562_ek = 0x031002A8,
- phy_82562_eh = 0x017002A8,
- phy_unknown = 0xFFFFFFFF,
- };
-@@ -268,6 +276,12 @@ enum scb_status {
- rus_mask = 0x3C,
- };
-
-+enum ru_state {
-+ RU_SUSPENDED = 0,
-+ RU_RUNNING = 1,
-+ RU_UNINITIALIZED = -1,
-+};
-+
- enum scb_stat_ack {
- stat_ack_not_ours = 0x00,
- stat_ack_sw_gen = 0x04,
-@@ -330,11 +344,16 @@ enum eeprom_op {
- };
-
- enum eeprom_offsets {
-+ eeprom_cnfg_mdix = 0x03,
- eeprom_id = 0x0A,
- eeprom_config_asf = 0x0D,
- eeprom_smbus_addr = 0x90,
- };
-
-+enum eeprom_cnfg_mdix {
-+ eeprom_mdix_enabled = 0x0080,
-+};
-+
- enum eeprom_id {
- eeprom_id_wol = 0x0020,
- };
-@@ -350,10 +369,12 @@ enum cb_status {
- };
-
- enum cb_command {
-+ cb_nop = 0x0000,
- cb_iaaddr = 0x0001,
- cb_config = 0x0002,
- cb_multi = 0x0003,
- cb_tx = 0x0004,
-+ cb_ucode = 0x0005,
- cb_dump = 0x0006,
- cb_tx_sf = 0x0008,
- cb_cid = 0x1f00,
-@@ -428,12 +449,14 @@ struct multi {
- };
-
- /* Important: keep total struct u32-aligned */
-+#define UCODE_SIZE 134
- struct cb {
- u16 status;
- u16 command;
- u32 link;
- union {
- u8 iaaddr[ETH_ALEN];
-+ u32 ucode[UCODE_SIZE];
- struct config config;
- struct multi multi;
- struct {
-@@ -500,11 +523,11 @@ struct nic {
- struct rx *rx_to_use;
- struct rx *rx_to_clean;
- struct rfd blank_rfd;
-- int ru_running;
-+ enum ru_state ru_running;
-
- spinlock_t cb_lock ____cacheline_aligned;
- spinlock_t cmd_lock;
-- struct csr *csr;
-+ struct csr __iomem *csr;
- enum scb_cmd_lo cuc_cmd;
- unsigned int cbs_avail;
- struct cb *cbs;
-@@ -529,6 +552,7 @@ struct nic {
- struct timer_list watchdog;
- struct timer_list blink_timer;
- struct mii_if_info mii;
-+ struct work_struct tx_timeout_task;
- enum loopback loopback;
-
- struct mem *mem;
-@@ -548,6 +572,7 @@ struct nic {
- u32 rx_fc_pause;
- u32 rx_fc_unsupported;
- u32 rx_tco_frames;
-+ u32 rx_over_length_errors;
-
- u8 rev_id;
- u16 leds;
-@@ -565,13 +590,21 @@ static inline void e100_write_flush(stru
-
- static inline void e100_enable_irq(struct nic *nic)
- {
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&nic->cmd_lock, flags);
- writeb(irq_mask_none, &nic->csr->scb.cmd_hi);
-+ spin_unlock_irqrestore(&nic->cmd_lock, flags);
- e100_write_flush(nic);
- }
-
- static inline void e100_disable_irq(struct nic *nic)
- {
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&nic->cmd_lock, flags);
- writeb(irq_mask_all, &nic->csr->scb.cmd_hi);
-+ spin_unlock_irqrestore(&nic->cmd_lock, flags);
- e100_write_flush(nic);
- }
-
-@@ -586,16 +619,6 @@ static void e100_hw_reset(struct nic *ni
- writel(software_reset, &nic->csr->port);
- e100_write_flush(nic); udelay(20);
-
-- /* TCO workaround - 82559 and greater */
-- if(nic->mac >= mac_82559_D101M) {
-- /* Issue a redundant CU load base without setting
-- * general pointer, and without waiting for scb to
-- * clear. This gets us into post-driver. Finally,
-- * wait 20 msec for reset to take effect. */
-- writeb(cuc_load_base, &nic->csr->scb.cmd_lo);
-- mdelay(20);
-- }
--
- /* Mask off our interrupt line - it's unmasked after reset */
- e100_disable_irq(nic);
- }
-@@ -613,8 +636,7 @@ static int e100_self_test(struct nic *ni
- writel(selftest | dma_addr, &nic->csr->port);
- e100_write_flush(nic);
- /* Wait 10 msec for self-test to complete */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(HZ / 100 + 1);
-+ msleep(10);
-
- /* Interrupts are enabled after self-test */
- e100_disable_irq(nic);
-@@ -662,8 +684,7 @@ static void e100_eeprom_write(struct nic
- e100_write_flush(nic); udelay(4);
- }
- /* Wait 10 msec for cmd to complete */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(HZ / 100 + 1);
-+ msleep(10);
-
- /* Chip deselect */
- writeb(0, &nic->csr->eeprom_ctrl_lo);
-@@ -764,7 +785,7 @@ static int e100_eeprom_save(struct nic *
- return 0;
- }
-
--#define E100_WAIT_SCB_TIMEOUT 40
-+#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */
- static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
- {
- unsigned long flags;
-@@ -834,6 +855,10 @@ static inline int e100_exec_cb(struct ni
- * because the controller is too busy, so
- * let's just queue the command and try again
- * when another command is scheduled. */
-+ if(err == -ENOSPC) {
-+ //request a reset
-+ schedule_work(&nic->tx_timeout_task);
-+ }
- break;
- } else {
- nic->cuc_cmd = cuc_resume;
-@@ -878,7 +903,7 @@ static void mdio_write(struct net_device
-
- static void e100_get_defaults(struct nic *nic)
- {
-- struct param_range rfds = { .min = 64, .max = 256, .count = 64 };
-+ struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
- struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
-
- pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
-@@ -893,8 +918,9 @@ static void e100_get_defaults(struct nic
- /* Quadwords to DMA into FIFO before starting frame transmit */
- nic->tx_threshold = 0xE0;
-
-- nic->tx_command = cpu_to_le16(cb_tx | cb_i | cb_tx_sf |
-- ((nic->mac >= mac_82558_D101_A4) ? cb_cid : 0));
-+ /* no interrupt for every tx completion, delay = 256us if not 557*/
-+ nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
-+ ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
-
- /* Template for a freshly allocated RFD */
- nic->blank_rfd.command = cpu_to_le16(cb_el);
-@@ -958,7 +984,8 @@ static void e100_configure(struct nic *n
- if(nic->flags & multicast_all)
- config->multicast_all = 0x1; /* 1=accept, 0=no */
-
-- if(!(nic->flags & wol_magic))
-+ /* disable WoL when up */
-+ if(netif_running(nic->netdev) || !(nic->flags & wol_magic))
- config->magic_packet_disable = 0x1; /* 1=off, 0=on */
-
- if(nic->mac >= mac_82558_D101_A4) {
-@@ -980,6 +1007,27 @@ static void e100_configure(struct nic *n
- c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
- }
-
-+static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
-+{
-+ int i;
-+ static const u32 ucode[UCODE_SIZE] = {
-+ /* NFS packets are misinterpreted as TCO packets and
-+ * incorrectly routed to the BMC over SMBus. This
-+ * microcode patch checks the fragmented IP bit in the
-+ * NFS/UDP header to distinguish between NFS and TCO. */
-+ 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
-+ 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
-+ 0x00906EFD, 0x00900EFD, 0x00E00EF8,
-+ };
-+
-+ if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
-+ for(i = 0; i < UCODE_SIZE; i++)
-+ cb->u.ucode[i] = cpu_to_le32(ucode[i]);
-+ cb->command = cpu_to_le16(cb_ucode);
-+ } else
-+ cb->command = cpu_to_le16(cb_nop);
-+}
-+
- static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
- struct sk_buff *skb)
- {
-@@ -1045,7 +1093,9 @@ static int e100_phy_init(struct nic *nic
- mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
- }
-
-- if(nic->mac >= mac_82550_D102)
-+ if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
-+ (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
-+ (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)))
- /* enable/disable MDI/MDI-X auto-switching */
- mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
- nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
-@@ -1069,6 +1119,8 @@ static int e100_hw_init(struct nic *nic)
- return err;
- if((err = e100_exec_cmd(nic, ruc_load_base, 0)))
- return err;
-+ if((err = e100_exec_cb(nic, NULL, e100_load_ucode)))
-+ return err;
- if((err = e100_exec_cb(nic, NULL, e100_configure)))
- return err;
- if((err = e100_exec_cb(nic, NULL, e100_setup_iaaddr)))
-@@ -1143,9 +1195,11 @@ static void e100_update_stats(struct nic
- ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
- le32_to_cpu(s->tx_lost_crs);
- ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
-- ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors);
-+ ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
-+ nic->rx_over_length_errors;
- ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
- ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
-+ ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
- ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
- ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
- le32_to_cpu(s->rx_alignment_errors) +
-@@ -1170,7 +1224,9 @@ static void e100_update_stats(struct nic
- }
- }
-
-- e100_exec_cmd(nic, cuc_dump_reset, 0);
-+
-+ if(e100_exec_cmd(nic, cuc_dump_reset, 0))
-+ DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n");
- }
-
- static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex)
-@@ -1217,8 +1273,13 @@ static void e100_watchdog(unsigned long
- mii_check_link(&nic->mii);
-
- /* Software generated interrupt to recover from (rare) Rx
-- * allocation failure */
-- writeb(irq_sw_gen, &nic->csr->scb.cmd_hi);
-+ * allocation failure.
-+ * Unfortunately have to use a spinlock to not re-enable interrupts
-+ * accidentally, due to hardware that shares a register between the
-+ * interrupt mask bit and the SW Interrupt generation bit */
-+ spin_lock_irq(&nic->cmd_lock);
-+ writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
-+ spin_unlock_irq(&nic->cmd_lock);
- e100_write_flush(nic);
-
- e100_update_stats(nic);
-@@ -1241,12 +1302,15 @@ static inline void e100_xmit_prepare(str
- struct sk_buff *skb)
- {
- cb->command = nic->tx_command;
-+ /* interrupt every 16 packets regardless of delay */
-+ if((nic->cbs_avail & ~15) == nic->cbs_avail) cb->command |= cb_i;
- cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd);
- cb->u.tcb.tcb_byte_count = 0;
- cb->u.tcb.threshold = nic->tx_threshold;
- cb->u.tcb.tbd_count = 1;
- cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
- skb->data, skb->len, PCI_DMA_TODEVICE));
-+ // check for mapping failure?
- cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
- }
-
-@@ -1259,7 +1323,8 @@ static int e100_xmit_frame(struct sk_buf
- /* SW workaround for ICH[x] 10Mbps/half duplex Tx hang.
- Issue a NOP command followed by a 1us delay before
- issuing the Tx command. */
-- e100_exec_cmd(nic, cuc_nop, 0);
-+ if(e100_exec_cmd(nic, cuc_nop, 0))
-+ DPRINTK(TX_ERR, DEBUG, "exec cuc_nop failed\n");
- udelay(1);
- }
-
-@@ -1268,6 +1333,7 @@ static int e100_xmit_frame(struct sk_buf
- switch(err) {
- case -ENOSPC:
- /* We queued the skb, but now we're out of space. */
-+ DPRINTK(TX_ERR, DEBUG, "No space for CB\n");
- netif_stop_queue(netdev);
- break;
- case -ENOMEM:
-@@ -1376,30 +1442,41 @@ static int e100_alloc_cbs(struct nic *ni
- return 0;
- }
-
--static inline void e100_start_receiver(struct nic *nic)
-+static inline void e100_start_receiver(struct nic *nic, struct rx *rx)
- {
-+ if(!nic->rxs) return;
-+ if(RU_SUSPENDED != nic->ru_running) return;
-+
-+ /* handle init time starts */
-+ if(!rx) rx = nic->rxs;
-+
- /* (Re)start RU if suspended or idle and RFA is non-NULL */
-- if(!nic->ru_running && nic->rx_to_clean->skb) {
-- e100_exec_cmd(nic, ruc_start, nic->rx_to_clean->dma_addr);
-- nic->ru_running = 1;
-+ if(rx->skb) {
-+ e100_exec_cmd(nic, ruc_start, rx->dma_addr);
-+ nic->ru_running = RU_RUNNING;
- }
- }
-
- #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
- static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
- {
-- unsigned int rx_offset = 2; /* u32 align protocol headers */
--
-- if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + rx_offset)))
-+ if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + NET_IP_ALIGN)))
- return -ENOMEM;
-
- /* Align, init, and map the RFD. */
- rx->skb->dev = nic->netdev;
-- skb_reserve(rx->skb, rx_offset);
-+ skb_reserve(rx->skb, NET_IP_ALIGN);
- memcpy(rx->skb->data, &nic->blank_rfd, sizeof(struct rfd));
- rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
- RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
-
-+ if(pci_dma_mapping_error(rx->dma_addr)) {
-+ dev_kfree_skb_any(rx->skb);
-+ rx->skb = 0;
-+ rx->dma_addr = 0;
-+ return -ENOMEM;
-+ }
-+
- /* Link the RFD to end of RFA by linking previous RFD to
- * this one, and clearing EL bit of previous. */
- if(rx->prev->skb) {
-@@ -1434,7 +1511,7 @@ static inline int e100_rx_indicate(struc
-
- /* If data isn't ready, nothing to indicate */
- if(unlikely(!(rfd_status & cb_complete)))
-- return -EAGAIN;
-+ return -ENODATA;
-
- /* Get actual data size */
- actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
-@@ -1445,6 +1522,10 @@ static inline int e100_rx_indicate(struc
- pci_unmap_single(nic->pdev, rx->dma_addr,
- RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
-
-+ /* this allows for a fast restart without re-enabling interrupts */
-+ if(le16_to_cpu(rfd->command) & cb_el)
-+ nic->ru_running = RU_SUSPENDED;
-+
- /* Pull off the RFD and put the actual data (minus eth hdr) */
- skb_reserve(skb, sizeof(struct rfd));
- skb_put(skb, actual_size);
-@@ -1456,18 +1537,14 @@ static inline int e100_rx_indicate(struc
- dev_kfree_skb_any(skb);
- } else if(actual_size > nic->netdev->mtu + VLAN_ETH_HLEN) {
- /* Don't indicate oversized frames */
-- nic->net_stats.rx_over_errors++;
-+ nic->rx_over_length_errors++;
- nic->net_stats.rx_dropped++;
- dev_kfree_skb_any(skb);
- } else {
- nic->net_stats.rx_packets++;
- nic->net_stats.rx_bytes += actual_size;
- nic->netdev->last_rx = jiffies;
--#ifdef CONFIG_E100_NAPI
- netif_receive_skb(skb);
--#else
-- netif_rx(skb);
--#endif
- if(work_done)
- (*work_done)++;
- }
-@@ -1481,20 +1558,45 @@ static inline void e100_rx_clean(struct
- unsigned int work_to_do)
- {
- struct rx *rx;
-+ int restart_required = 0;
-+ struct rx *rx_to_start = NULL;
-+
-+ /* are we already rnr? then pay attention!!! this ensures that
-+ * the state machine progression never allows a start with a
-+ * partially cleaned list, avoiding a race between hardware
-+ * and rx_to_clean when in NAPI mode */
-+ if(RU_SUSPENDED == nic->ru_running)
-+ restart_required = 1;
-
- /* Indicate newly arrived packets */
- for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
-- if(e100_rx_indicate(nic, rx, work_done, work_to_do))
-+ int err = e100_rx_indicate(nic, rx, work_done, work_to_do);
-+ if(-EAGAIN == err) {
-+ /* hit quota so have more work to do, restart once
-+ * cleanup is complete */
-+ restart_required = 0;
-+ break;
-+ } else if(-ENODATA == err)
- break; /* No more to clean */
- }
-
-+ /* save our starting point as the place we'll restart the receiver */
-+ if(restart_required)
-+ rx_to_start = nic->rx_to_clean;
-+
- /* Alloc new skbs to refill list */
- for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
- if(unlikely(e100_rx_alloc_skb(nic, rx)))
- break; /* Better luck next time (see watchdog) */
- }
-
-- e100_start_receiver(nic);
-+ if(restart_required) {
-+ // ack the rnr?
-+ writeb(stat_ack_rnr, &nic->csr->scb.stat_ack);
-+ e100_start_receiver(nic, rx_to_start);
-+ if(work_done)
-+ (*work_done)++;
-+ }
- }
-
- static void e100_rx_clean_list(struct nic *nic)
-@@ -1502,6 +1604,8 @@ static void e100_rx_clean_list(struct ni
- struct rx *rx;
- unsigned int i, count = nic->params.rfds.count;
-
-+ nic->ru_running = RU_UNINITIALIZED;
-+
- if(nic->rxs) {
- for(rx = nic->rxs, i = 0; i < count; rx++, i++) {
- if(rx->skb) {
-@@ -1515,7 +1619,6 @@ static void e100_rx_clean_list(struct ni
- }
-
- nic->rx_to_use = nic->rx_to_clean = NULL;
-- nic->ru_running = 0;
- }
-
- static int e100_rx_alloc_list(struct nic *nic)
-@@ -1524,6 +1627,7 @@ static int e100_rx_alloc_list(struct nic
- unsigned int i, count = nic->params.rfds.count;
-
- nic->rx_to_use = nic->rx_to_clean = NULL;
-+ nic->ru_running = RU_UNINITIALIZED;
-
- if(!(nic->rxs = kmalloc(sizeof(struct rx) * count, GFP_ATOMIC)))
- return -ENOMEM;
-@@ -1539,6 +1643,7 @@ static int e100_rx_alloc_list(struct nic
- }
-
- nic->rx_to_use = nic->rx_to_clean = nic->rxs;
-+ nic->ru_running = RU_SUSPENDED;
-
- return 0;
- }
-@@ -1560,22 +1665,14 @@ static irqreturn_t e100_intr(int irq, vo
-
- /* We hit Receive No Resource (RNR); restart RU after cleaning */
- if(stat_ack & stat_ack_rnr)
-- nic->ru_running = 0;
-+ nic->ru_running = RU_SUSPENDED;
-
--#ifdef CONFIG_E100_NAPI
- e100_disable_irq(nic);
- netif_rx_schedule(netdev);
--#else
-- if(stat_ack & stat_ack_rx)
-- e100_rx_clean(nic, NULL, 0);
-- if(stat_ack & stat_ack_tx)
-- e100_tx_clean(nic);
--#endif
-
- return IRQ_HANDLED;
- }
-
--#ifdef CONFIG_E100_NAPI
- static int e100_poll(struct net_device *netdev, int *budget)
- {
- struct nic *nic = netdev_priv(netdev);
-@@ -1598,7 +1695,6 @@ static int e100_poll(struct net_device *
-
- return 1;
- }
--#endif
-
- #ifdef CONFIG_NET_POLL_CONTROLLER
- static void e100_netpoll(struct net_device *netdev)
-@@ -1606,6 +1702,7 @@ static void e100_netpoll(struct net_devi
- struct nic *nic = netdev_priv(netdev);
- e100_disable_irq(nic);
- e100_intr(nic->pdev->irq, netdev, NULL);
-+ e100_tx_clean(nic);
- e100_enable_irq(nic);
- }
- #endif
-@@ -1638,14 +1735,16 @@ static int e100_change_mtu(struct net_de
- return 0;
- }
-
-+#ifdef CONFIG_PM
- static int e100_asf(struct nic *nic)
- {
- /* ASF can be enabled from eeprom */
-- return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1055) &&
-+ return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) &&
- (nic->eeprom[eeprom_config_asf] & eeprom_asf) &&
- !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
- ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
- }
-+#endif
-
- static int e100_up(struct nic *nic)
- {
-@@ -1658,13 +1757,16 @@ static int e100_up(struct nic *nic)
- if((err = e100_hw_init(nic)))
- goto err_clean_cbs;
- e100_set_multicast_list(nic->netdev);
-- e100_start_receiver(nic);
-+ e100_start_receiver(nic, 0);
- mod_timer(&nic->watchdog, jiffies);
- if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
- nic->netdev->name, nic->netdev)))
- goto err_no_irq;
-- e100_enable_irq(nic);
- netif_wake_queue(nic->netdev);
-+ netif_poll_enable(nic->netdev);
-+ /* enable ints _after_ enabling poll, preventing a race between
-+ * disable ints+schedule */
-+ e100_enable_irq(nic);
- return 0;
-
- err_no_irq:
-@@ -1678,11 +1780,13 @@ err_rx_clean_list:
-
- static void e100_down(struct nic *nic)
- {
-+ /* wait here for poll to complete */
-+ netif_poll_disable(nic->netdev);
-+ netif_stop_queue(nic->netdev);
- e100_hw_reset(nic);
- free_irq(nic->pdev->irq, nic->netdev);
- del_timer_sync(&nic->watchdog);
- netif_carrier_off(nic->netdev);
-- netif_stop_queue(nic->netdev);
- e100_clean_cbs(nic);
- e100_rx_clean_list(nic);
- }
-@@ -1691,6 +1795,15 @@ static void e100_tx_timeout(struct net_d
- {
- struct nic *nic = netdev_priv(netdev);
-
-+ /* Reset outside of interrupt context, to avoid request_irq
-+ * in interrupt context */
-+ schedule_work(&nic->tx_timeout_task);
-+}
-+
-+static void e100_tx_timeout_task(struct net_device *netdev)
-+{
-+ struct nic *nic = netdev_priv(netdev);
-+
- DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
- readb(&nic->csr->scb.status));
- e100_down(netdev_priv(netdev));
-@@ -1724,7 +1837,7 @@ static int e100_loopback_test(struct nic
- mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
- BMCR_LOOPBACK);
-
-- e100_start_receiver(nic);
-+ e100_start_receiver(nic, 0);
-
- if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
- err = -ENOMEM;
-@@ -1734,12 +1847,11 @@ static int e100_loopback_test(struct nic
- memset(skb->data, 0xFF, ETH_DATA_LEN);
- e100_xmit_frame(skb, nic->netdev);
-
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(HZ / 100 + 1);
-+ msleep(10);
-
- if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd),
- skb->data, ETH_DATA_LEN))
-- err = -EAGAIN;
-+ err = -EAGAIN;
-
- err_loopback_none:
- mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0);
-@@ -1821,8 +1933,7 @@ static void e100_get_regs(struct net_dev
- mdio_read(netdev, nic->mii.phy_id, i);
- memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf));
- e100_exec_cb(nic, NULL, e100_dump);
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(HZ / 100 + 1);
-+ msleep(10);
- memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf,
- sizeof(nic->mem->dump_buf));
- }
-@@ -1846,7 +1957,6 @@ static int e100_set_wol(struct net_devic
- else
- nic->flags &= ~wol_magic;
-
-- pci_enable_wake(nic->pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
- e100_exec_cb(nic, NULL, e100_configure);
-
- return 0;
-@@ -1932,12 +2042,17 @@ static int e100_set_ringparam(struct net
- struct param_range *rfds = &nic->params.rfds;
- struct param_range *cbs = &nic->params.cbs;
-
-+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
-+ return -EINVAL;
-+
- if(netif_running(netdev))
- e100_down(nic);
- rfds->count = max(ring->rx_pending, rfds->min);
- rfds->count = min(rfds->count, rfds->max);
- cbs->count = max(ring->tx_pending, cbs->min);
- cbs->count = min(cbs->count, cbs->max);
-+ DPRINTK(DRV, INFO, "Ring Param settings: rx: %d, tx %d\n",
-+ rfds->count, cbs->count);
- if(netif_running(netdev))
- e100_up(nic);
-
-@@ -1961,18 +2076,27 @@ static int e100_diag_test_count(struct n
- static void e100_diag_test(struct net_device *netdev,
- struct ethtool_test *test, u64 *data)
- {
-+ struct ethtool_cmd cmd;
- struct nic *nic = netdev_priv(netdev);
-- int i;
-+ int i, err;
-
- memset(data, 0, E100_TEST_LEN * sizeof(u64));
- data[0] = !mii_link_ok(&nic->mii);
- data[1] = e100_eeprom_load(nic);
- if(test->flags & ETH_TEST_FL_OFFLINE) {
-+
-+ /* save speed, duplex & autoneg settings */
-+ err = mii_ethtool_gset(&nic->mii, &cmd);
-+
- if(netif_running(netdev))
- e100_down(nic);
- data[2] = e100_self_test(nic);
- data[3] = e100_loopback_test(nic, lb_mac);
- data[4] = e100_loopback_test(nic, lb_phy);
-+
-+ /* restore speed, duplex & autoneg settings */
-+ err = mii_ethtool_sset(&nic->mii, &cmd);
-+
- if(netif_running(netdev))
- e100_up(nic);
- }
-@@ -1987,8 +2111,7 @@ static int e100_phys_id(struct net_devic
- if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
- data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
- mod_timer(&nic->blink_timer, jiffies);
-- set_current_state(TASK_INTERRUPTIBLE);
-- schedule_timeout(data * HZ);
-+ msleep_interruptible(data * 1000);
- del_timer_sync(&nic->blink_timer);
- mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
-
-@@ -2135,13 +2258,12 @@ static int __devinit e100_probe(struct p
- SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
- netdev->tx_timeout = e100_tx_timeout;
- netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
--#ifdef CONFIG_E100_NAPI
- netdev->poll = e100_poll;
- netdev->weight = E100_NAPI_WEIGHT;
--#endif
- #ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = e100_netpoll;
- #endif
-+ strcpy(netdev->name, pci_name(pdev));
-
- nic = netdev_priv(netdev);
- nic->netdev = netdev;
-@@ -2166,8 +2288,6 @@ static int __devinit e100_probe(struct p
- goto err_out_disable_pdev;
- }
-
-- pci_set_master(pdev);
--
- if((err = pci_set_dma_mask(pdev, 0xFFFFFFFFULL))) {
- DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
- goto err_out_free_res;
-@@ -2188,9 +2308,19 @@ static int __devinit e100_probe(struct p
- else
- nic->flags &= ~ich;
-
-+ e100_get_defaults(nic);
-+
-+ /* locks must be initialized before calling hw_reset */
- spin_lock_init(&nic->cb_lock);
- spin_lock_init(&nic->cmd_lock);
-
-+ /* Reset the device before pci_set_master() in case device is in some
-+ * funky state and has an interrupt pending - hint: we don't have the
-+ * interrupt handler registered yet. */
-+ e100_hw_reset(nic);
-+
-+ pci_set_master(pdev);
-+
- init_timer(&nic->watchdog);
- nic->watchdog.function = e100_watchdog;
- nic->watchdog.data = (unsigned long)nic;
-@@ -2198,13 +2328,14 @@ static int __devinit e100_probe(struct p
- nic->blink_timer.function = e100_blink_led;
- nic->blink_timer.data = (unsigned long)nic;
-
-+ INIT_WORK(&nic->tx_timeout_task,
-+ (void (*)(void *))e100_tx_timeout_task, netdev);
-+
- if((err = e100_alloc(nic))) {
- DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n");
- goto err_out_iounmap;
- }
-
-- e100_get_defaults(nic);
-- e100_hw_reset(nic);
- e100_phy_init(nic);
-
- if((err = e100_eeprom_load(nic)))
-@@ -2223,8 +2354,10 @@ static int __devinit e100_probe(struct p
- (nic->eeprom[eeprom_id] & eeprom_id_wol))
- nic->flags |= wol_magic;
-
-- pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
-+ /* ack any pending wake events, disable PME */
-+ pci_enable_wake(pdev, 0, 0);
-
-+ strcpy(netdev->name, "eth%d");
- if((err = register_netdev(netdev))) {
- DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
- goto err_out_free;
-@@ -2282,7 +2415,7 @@ static int e100_suspend(struct pci_dev *
- pci_save_state(pdev, nic->pm_state);
- pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic)));
- pci_disable_device(pdev);
-- pci_set_power_state(pdev, state);
-+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
- }
-@@ -2292,9 +2425,12 @@ static int e100_resume(struct pci_dev *p
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct nic *nic = netdev_priv(netdev);
-
-- pci_set_power_state(pdev, 0);
-+ pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev, nic->pm_state);
-- e100_hw_init(nic);
-+ /* ack any pending wake events, disable PME */
-+ pci_enable_wake(pdev, 0, 0);
-+ if(e100_hw_init(nic))
-+ DPRINTK(HW, ERR, "e100_hw_init failed\n");
-
- netif_device_attach(netdev);
- if(netif_running(netdev))
-@@ -2304,6 +2440,21 @@ static int e100_resume(struct pci_dev *p
- }
- #endif
-
-+
-+static void e100_shutdown(struct device *dev)
-+{
-+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
-+ struct net_device *netdev = pci_get_drvdata(pdev);
-+ struct nic *nic = netdev_priv(netdev);
-+
-+#ifdef CONFIG_PM
-+ pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
-+#else
-+ pci_enable_wake(pdev, 0, nic->flags & (wol_magic));
-+#endif
-+}
-+
-+
- static struct pci_driver e100_driver = {
- .name = DRV_NAME,
- .id_table = e100_id_table,
-@@ -2313,6 +2464,11 @@ static struct pci_driver e100_driver = {
- .suspend = e100_suspend,
- .resume = e100_resume,
- #endif
-+
-+ .driver = {
-+ .shutdown = e100_shutdown,
-+ }
-+
- };
-
- static int __init e100_init_module(void)
-@@ -2321,7 +2477,7 @@ static int __init e100_init_module(void)
- printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
- printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT);
- }
-- return pci_module_init(&e100_driver);
-+ return pci_module_init(&e100_driver);
- }
-
- static void __exit e100_cleanup_module(void)
---- linux-2.6.8.1-t043-libata-update/drivers/net/e100_compat.h 1970-01-01 03:00:00.000000000 +0300
-+++ rhel4u2/drivers/net/e100_compat.h 2005-10-19 11:47:13.000000000 +0400
-@@ -0,0 +1,16 @@
-+#ifndef __E100_COMPAT_H__
-+#define __E100_COMPAT_H__
-+
-+typedef u32 pm_message_t;
-+
-+typedef int __bitwise pci_power_t;
-+
-+#define PCI_D0 ((pci_power_t __force) 0)
-+#define PCI_D1 ((pci_power_t __force) 1)
-+#define PCI_D2 ((pci_power_t __force) 2)
-+#define PCI_D3hot ((pci_power_t __force) 3)
-+#define PCI_D3cold ((pci_power_t __force) 4)
-+
-+#define pci_choose_state(pdev, state) (state)
-+
-+#endif /* __E100_COMPAT_H__ */