rpms/kernel/FC-3 jwltest-b44-bounce-bufs.patch, NONE, 1.1.12.1 jwltest-bonding-2_6_12-rc2.patch, NONE, 1.1.6.1 jwltest-bonding-sysfs.patch, NONE, 1.1.6.1 jwltest-e1000-update-5_7_6-k2.patch, NONE, 1.1.10.1 jwltest-e1000-watchdog.patch, NONE, 1.1.10.1 jwltest-e1000-workqueue-flush.patch, NONE, 1.1.10.1 jwltest-ipw2100-1_1_0.patch, NONE, 1.1.8.1 kernel-2.6.spec, 1.813, 1.813.2.1 linux-2.6.9-module_version.patch, 1.6, 1.6.10.1
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Mon Apr 25 18:36:22 UTC 2005
Author: linville
Update of /cvs/dist/rpms/kernel/FC-3
In directory cvs.devel.redhat.com:/tmp/cvs-serv23213
Modified Files:
Tag: private-linville-fc3-jwltest-7-branch
kernel-2.6.spec linux-2.6.9-module_version.patch
Added Files:
Tag: private-linville-fc3-jwltest-7-branch
jwltest-b44-bounce-bufs.patch jwltest-bonding-2_6_12-rc2.patch
jwltest-bonding-sysfs.patch
jwltest-e1000-update-5_7_6-k2.patch
jwltest-e1000-watchdog.patch
jwltest-e1000-workqueue-flush.patch
jwltest-ipw2100-1_1_0.patch
Log Message:
jwltest-b44-bounce-bufs.patch:
b44.c | 36 +++++++++++++++++++++---------------
b44.h | 3 +--
2 files changed, 22 insertions(+), 17 deletions(-)
--- NEW FILE jwltest-b44-bounce-bufs.patch ---
--- linux-2.6.11/drivers/net/b44.h.orig 2005-03-09 16:44:40.753866914 -0500
+++ linux-2.6.11/drivers/net/b44.h 2005-03-09 16:44:50.197605243 -0500
@@ -397,7 +397,6 @@ struct b44 {
struct ring_info *rx_buffers;
struct ring_info *tx_buffers;
- unsigned char *tx_bufs;
u32 dma_offset;
u32 flags;
@@ -429,7 +428,7 @@ struct b44 {
struct pci_dev *pdev;
struct net_device *dev;
- dma_addr_t rx_ring_dma, tx_ring_dma,tx_bufs_dma;
+ dma_addr_t rx_ring_dma, tx_ring_dma;
u32 rx_pending;
u32 tx_pending;
--- linux-2.6.11/drivers/net/b44.c.orig 2005-03-09 16:44:40.755866647 -0500
+++ linux-2.6.11/drivers/net/b44.c 2005-03-09 16:44:50.199604976 -0500
@@ -908,6 +908,7 @@ static void b44_tx_timeout(struct net_de
static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
+ struct sk_buff *bounce_skb;
dma_addr_t mapping;
u32 len, entry, ctrl;
@@ -923,15 +924,31 @@ static int b44_start_xmit(struct sk_buff
return 1;
}
- entry = bp->tx_prod;
mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
if(mapping+len > B44_DMA_MASK) {
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
- pci_unmap_single(bp->pdev, mapping, len,PCI_DMA_TODEVICE);
- memcpy(bp->tx_bufs+entry*TX_PKT_BUF_SZ,skb->data,skb->len);
- mapping = pci_map_single(bp->pdev, bp->tx_bufs+entry*TX_PKT_BUF_SZ, len, PCI_DMA_TODEVICE);
+ pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
+
+ bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
+ GFP_ATOMIC|GFP_DMA);
+ if (!bounce_skb)
+ return NETDEV_TX_BUSY;
+
+ mapping = pci_map_single(bp->pdev, bounce_skb->data,
+ len, PCI_DMA_TODEVICE);
+ if(mapping+len > B44_DMA_MASK) {
+ pci_unmap_single(bp->pdev, mapping,
+ len, PCI_DMA_TODEVICE);
+ dev_kfree_skb_any(bounce_skb);
+ return NETDEV_TX_BUSY;
+ }
+
+ memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ skb = bounce_skb;
}
+ entry = bp->tx_prod;
bp->tx_buffers[entry].skb = skb;
pci_unmap_addr_set(&bp->tx_buffers[entry], mapping, mapping);
@@ -1078,11 +1095,6 @@ static void b44_free_consistent(struct b
bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
}
- if (bp->tx_bufs) {
- pci_free_consistent(bp->pdev, B44_TX_RING_SIZE * TX_PKT_BUF_SZ,
- bp->tx_bufs, bp->tx_bufs_dma);
- bp->tx_bufs = NULL;
- }
}
/*
@@ -1105,12 +1117,6 @@ static int b44_alloc_consistent(struct b
goto out_err;
memset(bp->tx_buffers, 0, size);
- size = B44_TX_RING_SIZE * TX_PKT_BUF_SZ;
- bp->tx_bufs = pci_alloc_consistent(bp->pdev, size, &bp->tx_bufs_dma);
- if (!bp->tx_bufs)
- goto out_err;
- memset(bp->tx_bufs, 0, size);
-
size = DMA_TABLE_BYTES;
bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
if (!bp->rx_ring)
jwltest-bonding-2_6_12-rc2.patch:
bond_3ad.c | 2 +-
bond_3ad.h | 1 -
bond_alb.c | 16 +++++++++-------
bond_main.c | 54 ++++++++++++++++++++----------------------------------
bonding.h | 1 +
bonding_compat.h | 7 +++++++
6 files changed, 38 insertions(+), 43 deletions(-)
--- NEW FILE jwltest-bonding-2_6_12-rc2.patch ---
--- linux-2.6.11/drivers/net/bonding/bond_3ad.h.orig 2005-04-08 10:48:26.717400547 -0400
+++ linux-2.6.11/drivers/net/bonding/bond_3ad.h 2005-04-08 10:48:44.236065061 -0400
@@ -290,7 +290,6 @@ void bond_3ad_initialize(struct bonding
int bond_3ad_bind_slave(struct slave *slave);
void bond_3ad_unbind_slave(struct slave *slave);
void bond_3ad_state_machine_handler(struct bonding *bond);
-void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length);
void bond_3ad_adapter_speed_changed(struct slave *slave);
void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
--- linux-2.6.11/drivers/net/bonding/bonding.h.orig 2005-04-08 10:48:26.724399614 -0400
+++ linux-2.6.11/drivers/net/bonding/bonding.h 2005-04-08 11:05:22.161032308 -0400
@@ -33,6 +33,7 @@
#include <linux/timer.h>
#include <linux/proc_fs.h>
#include <linux/if_bonding.h>
+#include "bonding_compat.h"
#include "bond_3ad.h"
#include "bond_alb.h"
--- linux-2.6.11/drivers/net/bonding/bonding_compat.h.orig 2005-04-08 11:03:31.727754295 -0400
+++ linux-2.6.11/drivers/net/bonding/bonding_compat.h 2005-04-08 11:05:02.030715962 -0400
@@ -0,0 +1,7 @@
+#ifndef __BONDING_COMPAT_H__
+#define __BONDING_COMPAT_H__
+
+#define dev_set_mac_address(dev, sa) \
+ (dev)->set_mac_address((dev), (sa))
+
+#endif /* __BONDING_COMPAT_H__ */
--- linux-2.6.11/drivers/net/bonding/bond_3ad.c.orig 2005-04-08 10:48:26.715400814 -0400
+++ linux-2.6.11/drivers/net/bonding/bond_3ad.c 2005-04-08 10:48:44.231065728 -0400
@@ -2175,7 +2175,7 @@ out:
* received frames (loopback). Since only the payload is given to this
* function, it check for loopback.
*/
-void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
+static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
{
struct port *port;
--- linux-2.6.11/drivers/net/bonding/bond_main.c.orig 2005-04-08 10:48:26.726399348 -0400
+++ linux-2.6.11/drivers/net/bonding/bond_main.c 2005-04-08 10:48:44.257062262 -0400
@@ -793,29 +793,20 @@ struct vlan_entry *bond_next_vlan(struct
* @skb: hw accel VLAN tagged skb to transmit
* @slave_dev: slave that is supposed to xmit this skbuff
*
- * When the bond gets an skb to tarnsmit that is
+ * When the bond gets an skb to transmit that is
* already hardware accelerated VLAN tagged, and it
* needs to relay this skb to a slave that is not
* hw accel capable, the skb needs to be "unaccelerated",
* i.e. strip the hwaccel tag and re-insert it as part
* of the payload.
- *
- * Assumption - once a VLAN device is created over the bond device, all
- * packets are going to be hardware accelerated VLAN tagged since the IP
- * binding is done over the VLAN device
*/
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev)
{
unsigned short vlan_id;
- int res;
if (!list_empty(&bond->vlan_list) &&
- !(slave_dev->features & NETIF_F_HW_VLAN_TX)) {
- res = vlan_get_tag(skb, &vlan_id);
- if (res) {
- return -EINVAL;
- }
-
+ !(slave_dev->features & NETIF_F_HW_VLAN_TX) &&
+ vlan_get_tag(skb, &vlan_id) == 0) {
skb->dev = slave_dev;
skb = vlan_put_tag(skb, vlan_id);
if (!skb) {
@@ -1719,7 +1710,7 @@ static int bond_enslave(struct net_devic
*/
memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
addr.sa_family = slave_dev->type;
- res = slave_dev->set_mac_address(slave_dev, &addr);
+ res = dev_set_mac_address(slave_dev, &addr);
if (res) {
dprintk("Error %d calling set_mac_address\n", res);
goto err_free;
@@ -1849,8 +1840,8 @@ static int bond_enslave(struct net_devic
if (bond_update_speed_duplex(new_slave) &&
(new_slave->link != BOND_LINK_DOWN)) {
printk(KERN_WARNING DRV_NAME
- ": Warning: failed to get speed/duplex from %s, speed "
- "forced to 100Mbps, duplex forced to Full.\n",
+ ": Warning: failed to get speed and duplex from %s, "
+ "assumed to be 100Mb/sec and Full.\n",
new_slave->dev->name);
if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1991,7 +1982,7 @@ err_close:
err_restore_mac:
memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
- slave_dev->set_mac_address(slave_dev, &addr);
+ dev_set_mac_address(slave_dev, &addr);
err_free:
kfree(new_slave);
@@ -2171,7 +2162,7 @@ static int bond_release(struct net_devic
/* restore original ("permanent") mac address */
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
- slave_dev->set_mac_address(slave_dev, &addr);
+ dev_set_mac_address(slave_dev, &addr);
}
/* restore the original state of the
@@ -2262,7 +2253,7 @@ static int bond_release_all(struct net_d
/* restore original ("permanent") mac address*/
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
- slave_dev->set_mac_address(slave_dev, &addr);
+ dev_set_mac_address(slave_dev, &addr);
}
/* restore the original state of the IFF_NOARP flag that might have
@@ -3898,12 +3889,7 @@ static int bond_change_mtu(struct net_de
bond_for_each_slave(bond, slave, i) {
dprintk("s %p s->p %p c_m %p\n", slave,
slave->prev, slave->dev->change_mtu);
- if (slave->dev->change_mtu) {
- res = slave->dev->change_mtu(slave->dev, new_mtu);
- } else {
- slave->dev->mtu = new_mtu;
- res = 0;
- }
+ res = dev_set_mtu(slave->dev, new_mtu);
if (res) {
/* If we failed to set the slave's mtu to the new value
@@ -3929,14 +3915,10 @@ unwind:
bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
int tmp_res;
- if (slave->dev->change_mtu) {
- tmp_res = slave->dev->change_mtu(slave->dev, bond_dev->mtu);
- if (tmp_res) {
- dprintk("unwind err %d dev %s\n", tmp_res,
- slave->dev->name);
- }
- } else {
- slave->dev->mtu = bond_dev->mtu;
+ tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu);
+ if (tmp_res) {
+ dprintk("unwind err %d dev %s\n", tmp_res,
+ slave->dev->name);
}
}
@@ -3988,7 +3970,7 @@ static int bond_set_mac_address(struct n
goto unwind;
}
- res = slave->dev->set_mac_address(slave->dev, addr);
+ res = dev_set_mac_address(slave->dev, addr);
if (res) {
/* TODO: consider downing the slave
* and retry ?
@@ -4014,7 +3996,7 @@ unwind:
bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
int tmp_res;
- tmp_res = slave->dev->set_mac_address(slave->dev, &tmp_sa);
+ tmp_res = dev_set_mac_address(slave->dev, &tmp_sa);
if (tmp_res) {
dprintk("unwind err %d dev %s\n", tmp_res,
slave->dev->name);
@@ -4306,6 +4288,10 @@ static int __init bond_init(struct net_d
*/
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
+ /* don't acquire bond device's xmit_lock when
+ * transmitting */
+ bond_dev->features |= NETIF_F_LLTX;
+
/* By default, we declare the bond to be fully
* VLAN hardware accelerated capable. Special
* care is taken in the various xmit functions
--- linux-2.6.11/drivers/net/bonding/bond_alb.c.orig 2005-04-08 10:48:26.719400281 -0400
+++ linux-2.6.11/drivers/net/bonding/bond_alb.c 2005-04-08 10:48:44.241064395 -0400
@@ -54,6 +54,7 @@
#include <linux/if_ether.h>
#include <linux/if_bonding.h>
#include <linux/if_vlan.h>
+#include <linux/in.h>
#include <net/ipx.h>
#include <net/arp.h>
#include <asm/byteorder.h>
@@ -275,7 +276,7 @@ static struct slave *tlb_get_least_loade
}
/* Caller must hold bond lock for read */
-struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
+static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct tlb_client_info *hash_table;
@@ -627,7 +628,7 @@ static void rlb_req_update_subnet_client
}
/* Caller must hold both bond and ptr locks for read */
-struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
+static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
@@ -954,9 +955,9 @@ static int alb_set_slave_mac_addr(struct
/* each slave will receive packets destined to a different mac */
memcpy(s_addr.sa_data, addr, dev->addr_len);
s_addr.sa_family = dev->type;
- if (dev->set_mac_address(dev, &s_addr)) {
+ if (dev_set_mac_address(dev, &s_addr)) {
printk(KERN_ERR DRV_NAME
- ": Error: dev->set_mac_address of dev %s failed! ALB "
+ ": Error: dev_set_mac_address of dev %s failed! ALB "
"mode requires that the base driver support setting "
"the hw address also when the network device's "
"interface is open\n",
@@ -1209,7 +1210,7 @@ static int alb_set_mac_address(struct bo
/* save net_device's current hw address */
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
- res = slave->dev->set_mac_address(slave->dev, addr);
+ res = dev_set_mac_address(slave->dev, addr);
/* restore net_device's hw address */
memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
@@ -1229,7 +1230,7 @@ unwind:
stop_at = slave;
bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
- slave->dev->set_mac_address(slave->dev, &sa);
+ dev_set_mac_address(slave->dev, &sa);
memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
}
@@ -1300,7 +1301,8 @@ int bond_alb_xmit(struct sk_buff *skb, s
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
- (skb->nh.iph->daddr == ip_bcast)) {
+ (skb->nh.iph->daddr == ip_bcast) ||
+ (skb->nh.iph->protocol == IPPROTO_IGMP)) {
do_tx_balance = 0;
break;
}
jwltest-bonding-sysfs.patch:
Makefile | 2
bond_3ad.c | 74 ++-
bond_alb.c | 61 +-
bond_main.c | 408 +++++++++++------
bond_sysfs.c | 1348 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bonding.h | 35 +
6 files changed, 1733 insertions(+), 195 deletions(-)
--- NEW FILE jwltest-bonding-sysfs.patch ---
--- linux-2.6.11/drivers/net/bonding/bonding.h.orig 2005-04-13 20:24:00.556480998 -0400
+++ linux-2.6.11/drivers/net/bonding/bonding.h 2005-04-13 20:20:13.113828694 -0400
@@ -33,12 +33,13 @@
#include <linux/timer.h>
#include <linux/proc_fs.h>
#include <linux/if_bonding.h>
+#include <linux/kobject.h>
#include "bonding_compat.h"
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "2.6.1"
-#define DRV_RELDATE "October 29, 2004"
+#define DRV_VERSION "3.1.6"
+#define DRV_RELDATE "April 8, 2005"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@@ -148,13 +149,18 @@ struct bond_params {
u32 arp_targets[BOND_MAX_ARP_TARGETS];
};
+struct bond_parm_tbl {
+ char *modename;
+ int mode;
+};
+
struct vlan_entry {
struct list_head vlan_list;
unsigned short vlan_id;
};
struct slave {
- struct net_device *dev; /* first - usefull for panic debug */
+ struct net_device *dev; /* first - useful for panic debug */
struct slave *next;
struct slave *prev;
s16 delay;
@@ -180,7 +186,7 @@ struct slave {
* beforehand.
*/
struct bonding {
- struct net_device *dev; /* first - usefull for panic debug */
+ struct net_device *dev; /* first - useful for panic debug */
struct slave *first_slave;
struct slave *curr_active_slave;
struct slave *current_arp_slave;
@@ -204,6 +210,7 @@ struct bonding {
struct bond_params params;
struct list_head vlan_list;
struct vlan_group *vlgrp;
+ u32 my_ip;
};
/**
@@ -248,6 +255,26 @@ extern inline void bond_set_slave_active
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_deinit(struct net_device *bond_dev);
+int bond_create_sysfs(void);
+void bond_destroy_sysfs(void);
+void bond_destroy_sysfs_entry(struct bonding *bond);
+int bond_create_sysfs_entry(struct bonding *bond);
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
+int bond_check_abi_ver(void);
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, struct slave **vassal);
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
+void bond_mii_monitor(struct net_device *bond_dev);
+void bond_loadbalance_arp_mon(struct net_device *bond_dev);
+void bond_activebackup_arp_mon(struct net_device *bond_dev);
+void bond_set_mode_ops(struct net_device *bond_dev, int mode);
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+const char *bond_mode_name(int mode);
+void bond_select_active_slave(struct bonding *bond);
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
#endif /* _LINUX_BONDING_H */
--- linux-2.6.11/drivers/net/bonding/bond_sysfs.c.orig 2005-04-13 20:24:00.566479664 -0400
+++ linux-2.6.11/drivers/net/bonding/bond_sysfs.c 2005-04-13 20:17:54.578314141 -0400
@@ -0,0 +1,1348 @@
+
+/*
+ * Copyright(c) 2004 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ *
+ * Changes:
+ *
+ * 2004/12/12 - Mitch Williams <mitch.a.williams at intel dot com>
+ * - Initial creation of sysfs interface.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/in.h>
+#include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/inet.h>
+#include <linux/rtnetlink.h>
+
+/* #define BONDING_DEBUG 1 */
+#include "bonding.h"
+#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv))
+
+/*---------------------------- Declarations -------------------------------*/
+
+/* Macros for real simple parsing of text. */
+#define eat_nonalnum(str,whence,max) \
+ while (whence < max) {if (!isalnum(str[whence])) whence++; else break;};
+#define find_next_nonalpha(str,whence,max) \
+ while (whence < max) {if (isalnum(str[whence])) whence++; else break;};
+
+extern struct list_head bond_dev_list;
+extern struct bond_params bonding_defaults;
+extern struct bond_parm_tbl bond_mode_tbl[];
+extern struct bond_parm_tbl bond_lacp_tbl[];
+
+static struct class *netdev_class;
+/*--------------------------- Data Structures -----------------------------*/
+
+/* Bonding sysfs lock. Why can't we just use the subsytem lock?
+ * Because kobject_register tries to acquire the subsystem lock. If
+ * we already hold the lock (which we would if the user was creating
+ * a new bond through the sysfs interface), we deadlock.
+ */
+
+struct rw_semaphore bonding_rwsem;
+
+
+
+
+/*------------------------------ Functions --------------------------------*/
+
+/*
+ * "show" function for the bond_masters attribute.
+ * The class parameter is ignored.
+ */
+static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
+{
+ int res = 0;
+ struct bonding *bond;
+
+ down_read(&(bonding_rwsem));
+
+ list_for_each_entry(bond, &bond_dev_list, bond_list) {
+ res += sprintf(buffer + res, "%s ",
+ bond->dev->name);
+ if (res > (PAGE_SIZE - IFNAMSIZ)) {
+ dprintk("eek! too many bonds!\n");
+ break;
+ }
+ }
+ res += sprintf(buffer + res, "\n");
+ res++;
+ up_read(&(bonding_rwsem));
+ return res;
+}
+
+/*
+ * "store" function for the bond_masters attribute. This is what
+ * creates and deletes entire bonds.
+ *
+ * The class parameter is ignored.
+ *
+ * This function uses the eat_nonalnum and eat_alnum macros, define
+ * above. Why not use sscanf()? Scanf can get strings, but can't filter
[...2347 lines suppressed...]
+err:
+ rtnl_lock();
bond_free_all();
-
+ bond_destroy_sysfs();
rtnl_unlock();
-
+out:
return res;
+
}
static void __exit bonding_exit(void)
{
unregister_netdevice_notifier(&bond_netdev_notifier);
-
rtnl_lock();
bond_free_all();
+ bond_destroy_sysfs();
rtnl_unlock();
}
--- linux-2.6.11/drivers/net/bonding/Makefile.orig 2005-04-13 20:24:00.543482733 -0400
+++ linux-2.6.11/drivers/net/bonding/Makefile 2005-04-13 20:17:54.579314007 -0400
@@ -4,5 +4,5 @@
obj-$(CONFIG_BONDING) += bonding.o
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
--- linux-2.6.11/drivers/net/bonding/bond_alb.c.orig 2005-04-13 20:24:00.561480331 -0400
+++ linux-2.6.11/drivers/net/bonding/bond_alb.c 2005-04-13 20:19:01.222421416 -0400
@@ -198,20 +198,21 @@ static int tlb_initialize(struct bonding
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
+ struct tlb_client_info *new_hashtbl;
int i;
spin_lock_init(&(bond_info->tx_hashtbl_lock));
- _lock_tx_hashtbl(bond);
-
- bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
- if (!bond_info->tx_hashtbl) {
+ new_hashtbl = kmalloc(size, GFP_KERNEL);
+ if (!new_hashtbl) {
printk(KERN_ERR DRV_NAME
- ": Error: %s: Failed to allocate TLB hash table\n",
+ ": %s: Error: Failed to allocate TLB hash table\n",
bond->dev->name);
- _unlock_tx_hashtbl(bond);
return -1;
}
+ _lock_tx_hashtbl(bond);
+
+ bond_info->tx_hashtbl = new_hashtbl;
memset(bond_info->tx_hashtbl, 0, size);
@@ -514,7 +515,8 @@ static void rlb_update_client(struct rlb
client_info->mac_dst);
if (!skb) {
printk(KERN_ERR DRV_NAME
- ": Error: failed to create an ARP packet\n");
+ ": %s: Error: failed to create an ARP packet\n",
+ client_info->slave->dev->master->name);
continue;
}
@@ -524,7 +526,8 @@ static void rlb_update_client(struct rlb
skb = vlan_put_tag(skb, client_info->vlan_id);
if (!skb) {
printk(KERN_ERR DRV_NAME
- ": Error: failed to insert VLAN tag\n");
+ ": %s: Error: failed to insert VLAN tag\n",
+ client_info->slave->dev->master->name);
continue;
}
}
@@ -607,8 +610,9 @@ static void rlb_req_update_subnet_client
if (!client_info->slave) {
printk(KERN_ERR DRV_NAME
- ": Error: found a client with no channel in "
- "the client's hash table\n");
+ ": %s: Error: found a client with no channel in "
+ "the client's hash table\n",
+ bond->dev->name);
continue;
}
/*update all clients using this src_ip, that are not assigned
@@ -798,21 +802,22 @@ static int rlb_initialize(struct bonding
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
+ struct rlb_client_info *new_hashtbl;
int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
int i;
spin_lock_init(&(bond_info->rx_hashtbl_lock));
- _lock_rx_hashtbl(bond);
-
- bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
- if (!bond_info->rx_hashtbl) {
+ new_hashtbl = kmalloc(size, GFP_KERNEL);
+ if (!new_hashtbl) {
printk(KERN_ERR DRV_NAME
- ": Error: %s: Failed to allocate RLB hash table\n",
+ ": %s: Error: Failed to allocate RLB hash table\n",
bond->dev->name);
- _unlock_rx_hashtbl(bond);
return -1;
}
+ _lock_rx_hashtbl(bond);
+
+ bond_info->rx_hashtbl = new_hashtbl;
bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
@@ -928,7 +933,8 @@ static void alb_send_learning_packets(st
skb = vlan_put_tag(skb, vlan->vlan_id);
if (!skb) {
printk(KERN_ERR DRV_NAME
- ": Error: failed to insert VLAN tag\n");
+ ": %s: Error: failed to insert VLAN tag\n",
+ bond->dev->name);
continue;
}
}
@@ -957,11 +963,11 @@ static int alb_set_slave_mac_addr(struct
s_addr.sa_family = dev->type;
if (dev_set_mac_address(dev, &s_addr)) {
printk(KERN_ERR DRV_NAME
- ": Error: dev_set_mac_address of dev %s failed! ALB "
+ ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
"mode requires that the base driver support setting "
"the hw address also when the network device's "
"interface is open\n",
- dev->name);
+ dev->master->name, dev->name);
return -EOPNOTSUPP;
}
return 0;
@@ -1111,9 +1117,9 @@ static int alb_handle_addr_collision_on_
* of the new slave
*/
printk(KERN_ERR DRV_NAME
- ": Error: the hw address of slave %s is not "
+ ": %s: Error: the hw address of slave %s is not "
"unique - cannot enslave it!",
- slave->dev->name);
+ bond->dev->name, slave->dev->name);
return -EINVAL;
}
@@ -1159,16 +1165,16 @@ static int alb_handle_addr_collision_on_
bond->alb_info.rlb_enabled);
printk(KERN_WARNING DRV_NAME
- ": Warning: the hw address of slave %s is in use by "
+ ": %s: Warning: the hw address of slave %s is in use by "
"the bond; giving it the hw address of %s\n",
- slave->dev->name, free_mac_slave->dev->name);
+ bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
} else if (has_bond_addr) {
printk(KERN_ERR DRV_NAME
- ": Error: the hw address of slave %s is in use by the "
+ ": %s: Error: the hw address of slave %s is in use by the "
"bond; couldn't find a slave with a free hw address to "
"give it (this should not have happened)\n",
- slave->dev->name);
+ bond->dev->name, slave->dev->name);
return -EFAULT;
}
@@ -1256,8 +1262,11 @@ int bond_alb_initialize(struct bonding *
tlb_deinitialize(bond);
return res;
}
+ } else {
+ bond->alb_info.rlb_enabled = 0;
}
+
return 0;
}
@@ -1415,7 +1424,7 @@ void bond_alb_monitor(struct bonding *bo
read_lock(&bond->curr_slave_lock);
bond_for_each_slave(bond, slave, i) {
- alb_send_learning_packets(slave,slave->dev->dev_addr);
+ alb_send_learning_packets(slave, slave->dev->dev_addr);
}
read_unlock(&bond->curr_slave_lock);
jwltest-e1000-update-5_7_6-k2.patch:
e1000.h | 3
e1000_ethtool.c | 11 +-
e1000_hw.c | 86 +++++++++--------
e1000_hw.h | 11 +-
e1000_main.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++------
5 files changed, 309 insertions(+), 77 deletions(-)
--- NEW FILE jwltest-e1000-update-5_7_6-k2.patch ---
--- linux-2.6.11/drivers/net/e1000/e1000_hw.c.orig 2005-03-18 15:21:34.767630045 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_hw.c 2005-03-18 15:22:07.541256468 -0500
@@ -1572,7 +1572,8 @@ e1000_phy_force_speed_duplex(struct e100
if(mii_status_reg & MII_SR_LINK_STATUS) break;
msec_delay(100);
}
- if((i == 0) && (hw->phy_type == e1000_phy_m88)) {
+ if((i == 0) &&
+ (hw->phy_type == e1000_phy_m88)) {
/* We didn't get link. Reset the DSP and wait again for link. */
ret_val = e1000_phy_reset_dsp(hw);
if(ret_val) {
@@ -2503,7 +2504,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
}
}
- ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+ ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
phy_data);
return ret_val;
@@ -2609,7 +2610,7 @@ e1000_write_phy_reg(struct e1000_hw *hw,
}
}
- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+ ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
phy_data);
return ret_val;
@@ -2955,8 +2956,7 @@ e1000_phy_m88_get_info(struct e1000_hw *
/* Check polarity status */
ret_val = e1000_check_polarity(hw, &polarity);
if(ret_val)
- return ret_val;
-
+ return ret_val;
phy_info->cable_polarity = polarity;
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
@@ -2966,9 +2966,9 @@ e1000_phy_m88_get_info(struct e1000_hw *
phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
M88E1000_PSSR_MDIX_SHIFT;
- if(phy_data & M88E1000_PSSR_1000MBS) {
- /* Cable Length Estimation and Local/Remote Receiver Informatoion
- * are only valid at 1000 Mbps
+ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
+ /* Cable Length Estimation and Local/Remote Receiver Information
+ * are only valid at 1000 Mbps.
*/
phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT);
@@ -4639,41 +4639,44 @@ e1000_get_bus_info(struct e1000_hw *hw)
{
uint32_t status;
- if(hw->mac_type < e1000_82543) {
+ switch (hw->mac_type) {
+ case e1000_82542_rev2_0:
+ case e1000_82542_rev2_1:
hw->bus_type = e1000_bus_type_unknown;
hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown;
- return;
- }
-
- status = E1000_READ_REG(hw, STATUS);
- hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
- e1000_bus_type_pcix : e1000_bus_type_pci;
+ break;
+ default:
+ status = E1000_READ_REG(hw, STATUS);
+ hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
+ e1000_bus_type_pcix : e1000_bus_type_pci;
- if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
- hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
- e1000_bus_speed_66 : e1000_bus_speed_120;
- } else if(hw->bus_type == e1000_bus_type_pci) {
- hw->bus_speed = (status & E1000_STATUS_PCI66) ?
- e1000_bus_speed_66 : e1000_bus_speed_33;
- } else {
- switch (status & E1000_STATUS_PCIX_SPEED) {
- case E1000_STATUS_PCIX_SPEED_66:
- hw->bus_speed = e1000_bus_speed_66;
- break;
- case E1000_STATUS_PCIX_SPEED_100:
- hw->bus_speed = e1000_bus_speed_100;
- break;
- case E1000_STATUS_PCIX_SPEED_133:
- hw->bus_speed = e1000_bus_speed_133;
- break;
- default:
- hw->bus_speed = e1000_bus_speed_reserved;
- break;
+ if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
+ hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
+ e1000_bus_speed_66 : e1000_bus_speed_120;
+ } else if(hw->bus_type == e1000_bus_type_pci) {
+ hw->bus_speed = (status & E1000_STATUS_PCI66) ?
+ e1000_bus_speed_66 : e1000_bus_speed_33;
+ } else {
+ switch (status & E1000_STATUS_PCIX_SPEED) {
+ case E1000_STATUS_PCIX_SPEED_66:
+ hw->bus_speed = e1000_bus_speed_66;
+ break;
+ case E1000_STATUS_PCIX_SPEED_100:
+ hw->bus_speed = e1000_bus_speed_100;
+ break;
+ case E1000_STATUS_PCIX_SPEED_133:
+ hw->bus_speed = e1000_bus_speed_133;
+ break;
+ default:
+ hw->bus_speed = e1000_bus_speed_reserved;
+ break;
+ }
}
+ hw->bus_width = (status & E1000_STATUS_BUS64) ?
+ e1000_bus_width_64 : e1000_bus_width_32;
+ break;
}
- hw->bus_width = (status & E1000_STATUS_BUS64) ?
- e1000_bus_width_64 : e1000_bus_width_32;
}
/******************************************************************************
* Reads a value from one of the devices registers using port I/O (as opposed
@@ -4738,6 +4741,7 @@ e1000_get_cable_length(struct e1000_hw *
uint16_t agc_value = 0;
uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
uint16_t i, phy_data;
+ uint16_t cable_length;
DEBUGFUNC("e1000_get_cable_length");
@@ -4749,10 +4753,11 @@ e1000_get_cable_length(struct e1000_hw *
&phy_data);
if(ret_val)
return ret_val;
+ cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+ M88E1000_PSSR_CABLE_LENGTH_SHIFT;
/* Convert the enum value to ranged values */
- switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT) {
+ switch (cable_length) {
case e1000_cable_length_50:
*min_length = 0;
*max_length = e1000_igp_cable_length_50;
@@ -4919,8 +4924,7 @@ e1000_check_downshift(struct e1000_hw *h
return ret_val;
hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
- }
- else if(hw->phy_type == e1000_phy_m88) {
+ } else if(hw->phy_type == e1000_phy_m88) {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
&phy_data);
if(ret_val)
--- linux-2.6.11/drivers/net/e1000/e1000_hw.h.orig 2005-03-18 15:21:34.770629645 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_hw.h 2005-03-18 15:22:07.549255401 -0500
@@ -369,6 +369,7 @@ int32_t e1000_set_d3_lplu_state(struct e
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82547EI 0x1019
+
#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6
@@ -1734,6 +1735,9 @@ struct e1000_hw {
#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 */
@@ -1794,8 +1798,7 @@ struct e1000_hw {
#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 */
@@ -2098,7 +2101,11 @@ struct e1000_hw {
#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080
#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500
+
/* Bit definitions for valid PHY IDs. */
+/* I = Integrated
+ * E = External
+ */
#define M88E1000_E_PHY_ID 0x01410C50
#define M88E1000_I_PHY_ID 0x01410C30
#define M88E1011_I_PHY_ID 0x01410C20
--- linux-2.6.11/drivers/net/e1000/e1000.h.orig 2005-03-18 15:21:34.764630445 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000.h 2005-03-18 15:22:07.532257669 -0500
@@ -138,6 +138,7 @@ struct e1000_adapter;
#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define AUTO_ALL_MODES 0
+#define E1000_EEPROM_82544_APM 0x0004
#define E1000_EEPROM_APME 0x0400
#ifndef E1000_MASTER_SLAVE
@@ -209,6 +210,7 @@ struct e1000_adapter {
/* TX */
struct e1000_desc_ring tx_ring;
+ struct e1000_buffer previous_buffer_info;
spinlock_t tx_lock;
uint32_t txd_cmd;
uint32_t tx_int_delay;
@@ -222,6 +224,7 @@ struct e1000_adapter {
uint32_t tx_fifo_size;
atomic_t tx_fifo_stall;
boolean_t pcix_82544;
+ boolean_t detect_tx_hung;
/* RX */
struct e1000_desc_ring rx_ring;
--- linux-2.6.11/drivers/net/e1000/e1000_ethtool.c.orig 2005-03-18 15:21:34.762630712 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_ethtool.c 2005-03-18 15:22:07.526258470 -0500
@@ -1310,7 +1310,7 @@ e1000_run_loopback_test(struct e1000_ada
struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
- int i;
+ int i, ret_val;
E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
@@ -1330,11 +1330,12 @@ e1000_run_loopback_test(struct e1000_ada
rxdr->buffer_info[i].length,
PCI_DMA_FROMDEVICE);
- if (!e1000_check_lbtest_frame(rxdr->buffer_info[i++].skb, 1024))
- return 0;
- } while (i < 64);
+ ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb,
+ 1024);
+ i++;
+ } while (ret_val != 0 && i < 64);
- return 13;
+ return ret_val;
}
static int
--- linux-2.6.11/drivers/net/e1000/e1000_main.c.orig 2005-03-18 15:21:34.773629245 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_main.c 2005-03-18 15:22:07.557254333 -0500
@@ -35,6 +35,14 @@
* - More errlogging support from Jon Mason <jonmason at us.ibm.com>
* - Fix TSO issues on PPC64 machines -- Jon Mason <jonmason at us.ibm.com>
*
+ * 5.7.1 12/16/04
+ * - Resurrect 82547EI/GI related fix in e1000_intr to avoid deadlocks. This
+ * fix was removed as it caused system instability. The suspected cause of
+ * this is the called to e1000_irq_disable in e1000_intr. Inlined the
+ * required piece of e1000_irq_disable into e1000_intr - Anton Blanchard
+ * 5.7.0 12/10/04
+ * - include fix to the condition that determines when to quit NAPI - Robert Olsson
+ * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down
* 5.6.5 11/01/04
* - Enabling NETIF_F_SG without checksum offload is illegal -
John Mason <jdmason at us.ibm.com>
@@ -57,7 +65,7 @@ char e1000_driver_string[] = "Intel(R) P
#else
#define DRIVERNAPI "-NAPI"
#endif
-char e1000_driver_version[] = "5.6.10.1-k2"DRIVERNAPI;
+char e1000_driver_version[] = "5.7.6-k2"DRIVERNAPI;
char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
@@ -81,6 +89,7 @@ static struct pci_device_id e1000_pci_tb
INTEL_E1000_ETHERNET_DEVICE(0x1011),
INTEL_E1000_ETHERNET_DEVICE(0x1012),
INTEL_E1000_ETHERNET_DEVICE(0x1013),
+ INTEL_E1000_ETHERNET_DEVICE(0x1014),
INTEL_E1000_ETHERNET_DEVICE(0x1015),
INTEL_E1000_ETHERNET_DEVICE(0x1016),
INTEL_E1000_ETHERNET_DEVICE(0x1017),
@@ -308,6 +317,9 @@ e1000_up(struct e1000_adapter *adapter)
mod_timer(&adapter->watchdog_timer, jiffies);
e1000_irq_enable(adapter);
+#ifdef CONFIG_E1000_NAPI
+ netif_poll_enable(netdev);
+#endif
return 0;
}
@@ -321,6 +333,10 @@ e1000_down(struct e1000_adapter *adapter
del_timer_sync(&adapter->tx_fifo_stall_timer);
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
+
+#ifdef CONFIG_E1000_NAPI
+ netif_poll_disable(netdev);
+#endif
adapter->link_speed = 0;
adapter->link_duplex = 0;
netif_carrier_off(netdev);
@@ -414,6 +430,7 @@ e1000_probe(struct pci_dev *pdev,
int i;
int err;
uint16_t eeprom_data;
+ uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
if((err = pci_enable_device(pdev)))
return err;
@@ -510,9 +527,6 @@ e1000_probe(struct pci_dev *pdev,
}
#ifdef NETIF_F_TSO
- /* Disbaled for now until root-cause is found for
- * hangs reported against non-IA archs. TSO can be
- * enabled using ethtool -K eth<x> tso on */
if((adapter->hw.mac_type >= e1000_82544) &&
(adapter->hw.mac_type != e1000_82547))
netdev->features |= NETIF_F_TSO;
@@ -584,6 +598,11 @@ e1000_probe(struct pci_dev *pdev,
case e1000_82542_rev2_1:
case e1000_82543:
break;
+ case e1000_82544:
+ e1000_read_eeprom(&adapter->hw,
+ EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
+ eeprom_apme_mask = E1000_EEPROM_82544_APM;
+ break;
case e1000_82546:
case e1000_82546_rev_3:
if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
@@ -598,7 +617,7 @@ e1000_probe(struct pci_dev *pdev,
EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
break;
}
- if(eeprom_data & E1000_EEPROM_APME)
+ if(eeprom_data & eeprom_apme_mask)
adapter->wol |= E1000_WUFC_MAG;
/* reset the hardware with the new settings */
@@ -807,6 +826,31 @@ e1000_close(struct net_device *netdev)
}
/**
+ * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
+ * @adapter: address of board private structure
+ * @begin: address of beginning of memory
+ * @end: address of end of memory
+ **/
+static inline boolean_t
+e1000_check_64k_bound(struct e1000_adapter *adapter,
+ void *start, unsigned long len)
+{
+ unsigned long begin = (unsigned long) start;
+ unsigned long end = begin + len;
+
+ /* first rev 82545 and 82546 need to not allow any memory
+ * write location to cross a 64k boundary due to errata 23 */
+ if (adapter->hw.mac_type == e1000_82545 ||
+ adapter->hw.mac_type == e1000_82546 ) {
+
+ /* check buffer doesn't cross 64kB */
+ return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE;
+ }
+
+ return TRUE;
+}
+
+/**
* e1000_setup_tx_resources - allocate Tx resources (Descriptors)
* @adapter: board private structure
*
@@ -824,7 +868,7 @@ e1000_setup_tx_resources(struct e1000_ad
txdr->buffer_info = vmalloc(size);
if(!txdr->buffer_info) {
DPRINTK(PROBE, ERR,
- "Unble to Allocate Memory for the Transmit descriptor ring\n");
+ "Unable to Allocate Memory for the Transmit descriptor ring\n");
return -ENOMEM;
}
memset(txdr->buffer_info, 0, size);
@@ -836,11 +880,42 @@ e1000_setup_tx_resources(struct e1000_ad
txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
if(!txdr->desc) {
+setup_tx_desc_die:
DPRINTK(PROBE, ERR,
- "Unble to Allocate Memory for the Transmit descriptor ring\n");
+ "Unable to Allocate Memory for the Transmit descriptor ring\n");
vfree(txdr->buffer_info);
return -ENOMEM;
}
+
+ /* fix for errata 23, cant cross 64kB boundary */
+ if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
+ void *olddesc = txdr->desc;
+ dma_addr_t olddma = txdr->dma;
+ DPRINTK(TX_ERR,ERR,"txdr align check failed: %u bytes at %p\n",
+ txdr->size, txdr->desc);
+ /* try again, without freeing the previous */
+ txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
+ /* failed allocation, critial failure */
+ if(!txdr->desc) {
+ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+ goto setup_tx_desc_die;
+ }
+
+ if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
+ /* give up */
+ pci_free_consistent(pdev, txdr->size,
+ txdr->desc, txdr->dma);
+ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+ DPRINTK(PROBE, ERR,
+ "Unable to Allocate aligned Memory for the Transmit"
+ " descriptor ring\n");
+ vfree(txdr->buffer_info);
+ return -ENOMEM;
+ } else {
+ /* free old, move on with the new one since its okay */
+ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+ }
+ }
memset(txdr->desc, 0, txdr->size);
txdr->next_to_use = 0;
@@ -945,7 +1020,7 @@ e1000_setup_rx_resources(struct e1000_ad
rxdr->buffer_info = vmalloc(size);
if(!rxdr->buffer_info) {
DPRINTK(PROBE, ERR,
- "Unble to Allocate Memory for the Recieve descriptor ring\n");
+ "Unable to Allocate Memory for the Recieve descriptor ring\n");
return -ENOMEM;
}
memset(rxdr->buffer_info, 0, size);
@@ -958,11 +1033,43 @@ e1000_setup_rx_resources(struct e1000_ad
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
if(!rxdr->desc) {
+setup_rx_desc_die:
DPRINTK(PROBE, ERR,
"Unble to Allocate Memory for the Recieve descriptor ring\n");
vfree(rxdr->buffer_info);
return -ENOMEM;
}
+
+ /* fix for errata 23, cant cross 64kB boundary */
+ if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
+ void *olddesc = rxdr->desc;
+ dma_addr_t olddma = rxdr->dma;
+ DPRINTK(RX_ERR,ERR,
+ "rxdr align check failed: %u bytes at %p\n",
+ rxdr->size, rxdr->desc);
+ /* try again, without freeing the previous */
+ rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+ /* failed allocation, critial failure */
+ if(!rxdr->desc) {
+ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+ goto setup_rx_desc_die;
+ }
+
+ if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
+ /* give up */
+ pci_free_consistent(pdev, rxdr->size,
+ rxdr->desc, rxdr->dma);
+ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+ DPRINTK(PROBE, ERR,
+ "Unable to Allocate aligned Memory for the"
+ " Receive descriptor ring\n");
+ vfree(rxdr->buffer_info);
+ return -ENOMEM;
+ } else {
+ /* free old, move on with the new one since its okay */
+ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+ }
+ }
memset(rxdr->desc, 0, rxdr->size);
rxdr->next_to_clean = 0;
@@ -1096,6 +1203,7 @@ e1000_unmap_and_free_tx_resource(struct
struct e1000_buffer *buffer_info)
{
struct pci_dev *pdev = adapter->pdev;
+
if(buffer_info->dma) {
pci_unmap_page(pdev,
buffer_info->dma,
@@ -1124,6 +1232,11 @@ e1000_clean_tx_ring(struct e1000_adapter
/* Free all the Tx ring sk_buffs */
+ if (likely(adapter->previous_buffer_info.skb != NULL)) {
+ e1000_unmap_and_free_tx_resource(adapter,
+ &adapter->previous_buffer_info);
+ }
+
for(i = 0; i < tx_ring->count; i++) {
buffer_info = &tx_ring->buffer_info[i];
e1000_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1425,7 +1538,6 @@ e1000_watchdog(unsigned long data)
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
struct net_device *netdev = adapter->netdev;
struct e1000_desc_ring *txdr = &adapter->tx_ring;
- unsigned int i;
uint32_t link;
e1000_check_for_link(&adapter->hw);
@@ -1505,12 +1617,8 @@ e1000_watchdog(unsigned long data)
/* Cause software interrupt to ensure rx ring is cleaned */
E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
- /* Early detection of hung controller */
- i = txdr->next_to_clean;
- if(txdr->buffer_info[i].dma &&
- time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
- !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
- netif_stop_queue(netdev);
+ /* Force detection of hung controller every watchdog period*/
+ adapter->detect_tx_hung = TRUE;
/* Reset the timer */
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1522,7 +1630,7 @@ e1000_watchdog(unsigned long data)
#define E1000_TX_FLAGS_VLAN_MASK 0xffff0000
#define E1000_TX_FLAGS_VLAN_SHIFT 16
-static inline boolean_t
+static inline int
e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
{
#ifdef NETIF_F_TSO
@@ -1531,8 +1639,19 @@ e1000_tso(struct e1000_adapter *adapter,
uint32_t cmd_length = 0;
uint16_t ipcse, tucse, mss;
uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
+#if 0 /* Not in RHEL4 (see below)... */
+ int err;
+#endif
if(skb_shinfo(skb)->tso_size) {
+#if 0 /* Not in RHEL4... */
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (err)
+ return err;
+ }
+#endif
+
hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
mss = skb_shinfo(skb)->tso_size;
skb->nh.iph->tot_len = 0;
@@ -1569,11 +1688,11 @@ e1000_tso(struct e1000_adapter *adapter,
if(++i == adapter->tx_ring.count) i = 0;
adapter->tx_ring.next_to_use = i;
- return TRUE;
+ return 1;
}
#endif
- return FALSE;
+ return 0;
}
static inline boolean_t
@@ -1798,6 +1917,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
unsigned int nr_frags = 0;
unsigned int mss = 0;
int count = 0;
+ int tso;
unsigned int f;
len -= skb->data_len;
@@ -1869,7 +1989,13 @@ e1000_xmit_frame(struct sk_buff *skb, st
first = adapter->tx_ring.next_to_use;
- if(likely(e1000_tso(adapter, skb)))
+ tso = e1000_tso(adapter, skb);
+ if (tso < 0) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (likely(tso))
tx_flags |= E1000_TX_FLAGS_TSO;
else if(likely(e1000_tx_csum(adapter, skb)))
tx_flags |= E1000_TX_FLAGS_CSUM;
@@ -2151,10 +2277,28 @@ e1000_intr(int irq, void *data, struct p
__netif_rx_schedule(netdev);
}
#else
+ /* Writing IMC and IMS is needed for 82547.
+ Due to Hub Link bus being occupied, an interrupt
+ de-assertion message is not able to be sent.
+ When an interrupt assertion message is generated later,
+ two messages are re-ordered and sent out.
+ That causes APIC to think 82547 is in de-assertion
+ state, while 82547 is in assertion state, resulting
+ in dead lock. Writing IMC forces 82547 into
+ de-assertion state.
+ */
+ if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2){
+ atomic_inc(&adapter->irq_sem);
+ E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+ }
+
for(i = 0; i < E1000_MAX_INTR; i++)
if(unlikely(!e1000_clean_rx_irq(adapter) &
!e1000_clean_tx_irq(adapter)))
break;
+
+ if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
+ e1000_irq_enable(adapter);
#endif
return IRQ_HANDLED;
@@ -2174,24 +2318,21 @@ e1000_clean(struct net_device *netdev, i
int tx_cleaned;
int work_done = 0;
- if (!netif_carrier_ok(netdev))
- goto quit_polling;
-
tx_cleaned = e1000_clean_tx_irq(adapter);
e1000_clean_rx_irq(adapter, &work_done, work_to_do);
*budget -= work_done;
netdev->quota -= work_done;
- /* if no Rx and Tx cleanup work was done, exit the polling mode */
- if(!tx_cleaned || (work_done < work_to_do) ||
+ /* if no Tx and not enough Rx work done, exit the polling mode */
+ if((!tx_cleaned && (work_done < work_to_do)) ||
!netif_running(netdev)) {
-quit_polling: netif_rx_complete(netdev);
+ netif_rx_complete(netdev);
e1000_irq_enable(adapter);
return 0;
}
- return (work_done >= work_to_do);
+ return 1;
}
#endif
@@ -2215,11 +2356,34 @@ e1000_clean_tx_irq(struct e1000_adapter
eop_desc = E1000_TX_DESC(*tx_ring, eop);
while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+ /* pre-mature writeback of Tx descriptors */
+ /* clear (free buffers and unmap pci_mapping) */
+ /* previous_buffer_info */
+ if (likely(adapter->previous_buffer_info.skb != NULL)) {
+ e1000_unmap_and_free_tx_resource(adapter,
+ &adapter->previous_buffer_info);
+ }
+
for(cleaned = FALSE; !cleaned; ) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
+ cleaned = (i == eop);
+
+ /* pre-mature writeback of Tx descriptors */
+ /* save the cleaning of the this for the */
+ /* next iteration */
+ if (cleaned) {
+ memcpy(&adapter->previous_buffer_info,
+ buffer_info,
+ sizeof(struct e1000_buffer));
+ memset(buffer_info,
+ 0,
+ sizeof(struct e1000_buffer));
+ } else {
+ e1000_unmap_and_free_tx_resource(adapter,
+ buffer_info);
+ }
- e1000_unmap_and_free_tx_resource(adapter, buffer_info);
tx_desc->buffer_addr = 0;
tx_desc->lower.data = 0;
tx_desc->upper.data = 0;
@@ -2241,6 +2405,16 @@ e1000_clean_tx_irq(struct e1000_adapter
netif_wake_queue(netdev);
spin_unlock(&adapter->tx_lock);
+
+ if(adapter->detect_tx_hung) {
+ /* detect a transmit hang in hardware, this serializes the
+ * check with the clearing of time_stamp and movement of i */
+ adapter->detect_tx_hung = FALSE;
+ if(tx_ring->buffer_info[i].dma &&
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) &&
+ !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
+ netif_stop_queue(netdev);
+ }
return cleaned;
}
@@ -2407,19 +2581,43 @@ e1000_alloc_rx_buffers(struct e1000_adap
struct e1000_rx_desc *rx_desc;
struct e1000_buffer *buffer_info;
struct sk_buff *skb;
- unsigned int i;
+ unsigned int i, bufsz;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
while(!buffer_info->skb) {
- skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
+ bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
+ skb = dev_alloc_skb(bufsz);
if(unlikely(!skb)) {
/* Better luck next round */
break;
}
+ /* fix for errata 23, cant cross 64kB boundary */
+ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
+ struct sk_buff *oldskb = skb;
+ DPRINTK(RX_ERR,ERR,
+ "skb align check failed: %u bytes at %p\n",
+ bufsz, skb->data);
+ /* try again, without freeing the previous */
+ skb = dev_alloc_skb(bufsz);
+ if (!skb) {
+ dev_kfree_skb(oldskb);
+ break;
+ }
+ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
+ /* give up */
+ dev_kfree_skb(skb);
+ dev_kfree_skb(oldskb);
+ break; /* while !buffer_info->skb */
+ } else {
+ /* move on with the new one */
+ dev_kfree_skb(oldskb);
+ }
+ }
+
/* Make buffer alignment 2 beyond a 16 byte boundary
* this will result in a 16 byte aligned IP header after
* the 14 byte MAC header is removed
@@ -2435,6 +2633,25 @@ e1000_alloc_rx_buffers(struct e1000_adap
adapter->rx_buffer_len,
PCI_DMA_FROMDEVICE);
+ /* fix for errata 23, cant cross 64kB boundary */
+ if(!e1000_check_64k_bound(adapter,
+ (void *)(unsigned long)buffer_info->dma,
+ adapter->rx_buffer_len)) {
+ DPRINTK(RX_ERR,ERR,
+ "dma align check failed: %u bytes at %ld\n",
+ adapter->rx_buffer_len, (unsigned long)buffer_info->dma);
+
+ dev_kfree_skb(skb);
+ buffer_info->skb = NULL;
+
+ pci_unmap_single(pdev,
+ buffer_info->dma,
+ adapter->rx_buffer_len,
+ PCI_DMA_FROMDEVICE);
+
+ break; /* while !buffer_info->skb */
+ }
+
rx_desc = E1000_RX_DESC(*rx_ring, i);
rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
jwltest-e1000-watchdog.patch:
e1000.h | 1 +
e1000_main.c | 15 +++++++++++++--
2 files changed, 14 insertions(+), 2 deletions(-)
--- NEW FILE jwltest-e1000-watchdog.patch ---
--- linux-2.6.11/drivers/net/e1000/e1000.h.orig 2005-03-18 15:25:19.291666832 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000.h 2005-03-18 15:26:23.723067936 -0500
@@ -203,6 +203,7 @@ struct e1000_adapter {
spinlock_t stats_lock;
atomic_t irq_sem;
struct work_struct tx_timeout_task;
+ struct work_struct watchdog_task;
uint8_t fc_autoneg;
struct timer_list blink_timer;
--- linux-2.6.11/drivers/net/e1000/e1000_main.c.orig 2005-03-18 15:25:19.381654822 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_main.c 2005-03-18 15:26:23.728067269 -0500
@@ -143,6 +143,7 @@ static void e1000_clean_rx_ring(struct e
static void e1000_set_multi(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data);
+static void e1000_watchdog_task(struct e1000_adapter *adapter);
static void e1000_82547_tx_fifo_stall(unsigned long data);
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
@@ -576,6 +577,9 @@ e1000_probe(struct pci_dev *pdev,
adapter->watchdog_timer.function = &e1000_watchdog;
adapter->watchdog_timer.data = (unsigned long) adapter;
+ INIT_WORK(&adapter->watchdog_task,
+ (void (*)(void *))e1000_watchdog_task, adapter);
+
init_timer(&adapter->phy_info_timer);
adapter->phy_info_timer.function = &e1000_update_phy_info;
adapter->phy_info_timer.data = (unsigned long) adapter;
@@ -1531,13 +1535,20 @@ e1000_82547_tx_fifo_stall(unsigned long
/**
* e1000_watchdog - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
+ * @data: pointer to adapter cast into an unsigned long
**/
-
static void
e1000_watchdog(unsigned long data)
{
struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+
+ /* Do the rest outside of interrupt context */
+ schedule_work(&adapter->watchdog_task);
+}
+
+static void
+e1000_watchdog_task(struct e1000_adapter *adapter)
+{
struct net_device *netdev = adapter->netdev;
struct e1000_desc_ring *txdr = &adapter->tx_ring;
uint32_t link;
jwltest-e1000-workqueue-flush.patch:
e1000_main.c | 2 ++
1 files changed, 2 insertions(+)
--- NEW FILE jwltest-e1000-workqueue-flush.patch ---
--- linux-2.6.11/drivers/net/e1000/e1000_main.c.orig 2005-03-18 15:28:40.346833843 -0500
+++ linux-2.6.11/drivers/net/e1000/e1000_main.c 2005-03-18 15:29:22.822164850 -0500
@@ -666,6 +666,8 @@ e1000_remove(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev->priv;
uint32_t manc;
+ flush_scheduled_work();
+
if(adapter->hw.mac_type >= e1000_82540 &&
adapter->hw.media_type == e1000_media_type_copper) {
manc = E1000_READ_REG(&adapter->hw, MANC);
jwltest-ipw2100-1_1_0.patch:
Documentation/networking/README.ipw2100 | 162
drivers/net/wireless/Kconfig | 55
drivers/net/wireless/Makefile | 4
drivers/net/wireless/ipw2100.c | 8649 ++++++++++++++++++++++++++++++
drivers/net/wireless/ipw2100.h | 1278 ++++
drivers/net/wireless/ipw2100/LICENSE | 339 -
drivers/net/wireless/ipw2100/Makefile | 15
drivers/net/wireless/ipw2100/ipw2100.c | 8972 --------------------------------
drivers/net/wireless/ipw2100/ipw2100.h | 1287 ----
9 files changed, 10064 insertions(+), 10697 deletions(-)
--- NEW FILE jwltest-ipw2100-1_1_0.patch ---
--- /dev/null 2004-02-23 16:02:56.000000000 -0500
+++ linux-2.6.9/drivers/net/wireless/ipw2100.h 2005-03-24 13:25:56.222518588 -0500
@@ -0,0 +1,1278 @@
+/******************************************************************************
+
+ Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc., 59
+ Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ The full GNU General Public License is included in this distribution in the
+ file called LICENSE.
+
+ Contact Information:
+ James P. Ketrenos <ipw2100-admin at linux.intel.com>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+******************************************************************************/
+#ifndef _IPW2100_H
+#define _IPW2100_H
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <asm/io.h>
+#include <linux/socket.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/version.h>
+#include <net/iw_handler.h> // new driver API
+
+#include <ieee80211.h>
+
+#include <linux/workqueue.h>
+
+#ifndef IRQ_NONE
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+#endif
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_INVALID 0x10
+#define IW_QUAL_LEVEL_INVALID 0x20
+#define IW_QUAL_NOISE_INVALID 0x40
+#endif
+
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
+#define pci_dma_sync_single_for_cpu pci_dma_sync_single
+#define pci_dma_sync_single_for_device pci_dma_sync_single
+#endif
+
+#ifndef HAVE_FREE_NETDEV
+#define free_netdev(x) kfree(x)
+#endif
+
+
+
+struct ipw2100_priv;
+struct ipw2100_tx_packet;
+struct ipw2100_rx_packet;
+
+#ifdef CONFIG_IPW_DEBUG
+enum { IPW_DEBUG_ENABLED = 1 };
+extern u32 ipw2100_debug_level;
+#define IPW_DEBUG(level, message...) \
+do { \
+ if (ipw2100_debug_level & (level)) { \
+ printk(KERN_DEBUG "ipw2100: %c %s ", \
+ in_interrupt() ? 'I' : 'U', __FUNCTION__); \
+ printk(message); \
+ } \
+} while (0)
+#else
+enum { IPW_DEBUG_ENABLED = 0 };
+#define IPW_DEBUG(level, message...) do {} while (0)
+#endif /* CONFIG_IPW_DEBUG */
+
+#define IPW_DL_UNINIT 0x80000000
+#define IPW_DL_NONE 0x00000000
+#define IPW_DL_ALL 0x7FFFFFFF
+
+/*
+ * To use the debug system;
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IPW_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry. xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IPW2100_xxxx_DEBUG() macro definition for your
+ * classification, or use IPW_DEBUG(IPW_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ipw2100/debug_level
+ *
+ * you simply need to add your entry to the ipw2100_debug_levels array.
+ *
+ * If you do not see debug_level in /proc/net/ipw2100 then you do not have
+ * CONFIG_IPW_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IPW_DL_ERROR (1<<0)
+#define IPW_DL_WARNING (1<<1)
+#define IPW_DL_INFO (1<<2)
+#define IPW_DL_WX (1<<3)
+#define IPW_DL_HC (1<<5)
+#define IPW_DL_STATE (1<<6)
+
+#define IPW_DL_NOTIF (1<<10)
+#define IPW_DL_SCAN (1<<11)
+#define IPW_DL_ASSOC (1<<12)
+#define IPW_DL_DROP (1<<13)
+
+#define IPW_DL_IOCTL (1<<14)
+#define IPW_DL_RF_KILL (1<<17)
+
+
+#define IPW_DL_MANAGE (1<<15)
+#define IPW_DL_FW (1<<16)
+
+#define IPW_DL_FRAG (1<<21)
+#define IPW_DL_WEP (1<<22)
+#define IPW_DL_TX (1<<23)
+#define IPW_DL_RX (1<<24)
+#define IPW_DL_ISR (1<<25)
+#define IPW_DL_IO (1<<26)
+#define IPW_DL_TRACE (1<<28)
+
+#define IPW_DEBUG_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
+#define IPW_DEBUG_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
+#define IPW_DEBUG_INFO(f...) IPW_DEBUG(IPW_DL_INFO, ## f)
+#define IPW_DEBUG_WX(f...) IPW_DEBUG(IPW_DL_WX, ## f)
+#define IPW_DEBUG_SCAN(f...) IPW_DEBUG(IPW_DL_SCAN, ## f)
+#define IPW_DEBUG_NOTIF(f...) IPW_DEBUG(IPW_DL_NOTIF, ## f)
+#define IPW_DEBUG_TRACE(f...) IPW_DEBUG(IPW_DL_TRACE, ## f)
+#define IPW_DEBUG_RX(f...) IPW_DEBUG(IPW_DL_RX, ## f)
+#define IPW_DEBUG_TX(f...) IPW_DEBUG(IPW_DL_TX, ## f)
+#define IPW_DEBUG_ISR(f...) IPW_DEBUG(IPW_DL_ISR, ## f)
+#define IPW_DEBUG_MANAGEMENT(f...) IPW_DEBUG(IPW_DL_MANAGE, ## f)
+#define IPW_DEBUG_WEP(f...) IPW_DEBUG(IPW_DL_WEP, ## f)
+#define IPW_DEBUG_HC(f...) IPW_DEBUG(IPW_DL_HC, ## f)
+#define IPW_DEBUG_FRAG(f...) IPW_DEBUG(IPW_DL_FRAG, ## f)
+#define IPW_DEBUG_FW(f...) IPW_DEBUG(IPW_DL_FW, ## f)
+#define IPW_DEBUG_RF_KILL(f...) IPW_DEBUG(IPW_DL_RF_KILL, ## f)
+#define IPW_DEBUG_DROP(f...) IPW_DEBUG(IPW_DL_DROP, ## f)
+#define IPW_DEBUG_IO(f...) IPW_DEBUG(IPW_DL_IO, ## f)
+#define IPW_DEBUG_IOCTL(f...) IPW_DEBUG(IPW_DL_IOCTL, ## f)
+#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
+#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
+
+
+#define VERIFY(f) \
+{ \
+ int status = 0; \
+ status = f; \
+ if(status) \
+ return status; \
+}
+
+enum {
+ IPW_HW_STATE_DISABLED = 1,
+ IPW_HW_STATE_ENABLED = 0
+};
+
+struct ssid_context {
+ char ssid[IW_ESSID_MAX_SIZE + 1];
+ int ssid_len;
+ unsigned char bssid[ETH_ALEN];
+ int port_type;
+ int channel;
+
+};
+
+extern const char *port_type_str[];
+extern const char *band_str[];
+
+#define NUMBER_OF_BD_PER_COMMAND_PACKET 1
[...20511 lines suppressed...]
+- 802.1x (tested with XSupplicant 1.0.1)
+
+Enabled (but not supported) features:
- Monitor/RFMon mode
-- transmit power control
-- long/short preamble support
-- power states support (ACPI)
+- WPA/WPA2
-TODO
------------- ----- ----- ---- --- -- -
-- Fix bugs... The biggies:
- C3 corruption
- Fragmentation
+The distinction between officially supported and enabled is a reflection
+on the amount of validation and interoperability testing that has been
+performed on a given feature.
-Command Line Parameters
------------- ----- ----- ---- --- -- -
+===========================
+2. Command Line Parameters
+---------------------------
If the driver is built as a module, the following optional parameters are used
by entering them on the command line with the modprobe command using this
@@ -34,54 +61,82 @@ syntax:
modprobe ipw2100 [<option>=<VAL1><,VAL2>...]
-For example, to set the interface name for driver, entering:
-
- modprobe ipw2100 if_name=wlan%d
+For example, to disable the radio on driver loading, enter:
-results in the ipw2100 driver defaulting to the wlan prefix, with the system
-assigning a unique number in place of %d. The default interface name is eth%d.
+ modprobe ipw2100 disable=1
The ipw2100 driver supports the following module parameters:
Name Value Example:
debug 0x0-0xffffffff debug=1024
-if_name string if_name=wlan%d
mode 0,1,2 mode=1 /* AdHoc */
channel int channel=3 /* Only valid in AdHoc or Monitor */
associate boolean associate=0 /* Do NOT auto associate */
disable boolean disable=1 /* Do not power the HW */
-Radio Kill Switch
------------- ----- ----- ---- --- -- -
-Most laptops provide the ability for the user to physically disable the radio.
-Some vendors have implemented this as a physical switch that requires no
-software to turn the radio off and on. On other laptops, however, the switch
-is controlled through a button being pressed and a software driver then making
-calls to turn the radio off and on. This is referred to as a "software based
-RF kill switch"
+===========================
+3. Sysfs Helper Files
+---------------------------
-To determine if you have such a switch, you can check the contents of:
+There are several ways to control the behavior of the driver. Many of the
+general capabilities are exposed through the Wireless Tools (iwconfig). There
+are a few capabilities that are exposed through entries in the Linux Sysfs.
- /sys/bus/pci/drivers/ipw2100/*/rf_kill
-A value of:
+----- Driver Level ------
+For the driver level files, look in /sys/bus/pci/drivers/ipw2100/
+
+ debug_level
- Radio is {en,dis}abled by RF switch
+ This controls the same global as the 'debug' module parameter. For
+ information on the various debugging levels available, run the 'dvals'
+ script found in the driver source directory.
-means that you have an RF switch and the radio is in the state
-described.
+ NOTE: 'debug_level' is only enabled if CONFIG_IPW2100_DEBUG is turn
+ on.
-A value of:
+----- Device Level ------
+For the device level files look in
+
+ /sys/bus/pci/drivers/ipw2100/{PCI-ID}/
- Your hardware does not have an RF switch
+For example:
+ /sys/bus/pci/drivers/ipw2100/0000:02:01.0
-is self explanatory. In this case you should not need to worry about
-enabling the radio.
+For the device level files, see /sys/bus/pci/drivers/ipw2100:
+ rf_kill
+ read -
+ 0 = RF kill not enabled (radio on)
+ 1 = SW based RF kill active (radio off)
+ 2 = HW based RF kill active (radio off)
+ 3 = Both HW and SW RF kill active (radio off)
+ write -
+ 0 = If SW based RF kill active, turn the radio back on
+ 1 = If radio is on, activate SW based RF kill
+
+ NOTE: If you enable the SW based RF kill and then toggle the HW
+ based RF kill from ON -> OFF -> ON, the radio will NOT come back on
+
+
+===========================
+4. Radio Kill Switch
+---------------------------
+Most laptops provide the ability for the user to physically disable the radio.
+Some vendors have implemented this as a physical switch that requires no
+software to turn the radio off and on. On other laptops, however, the switch
+is controlled through a button being pressed and a software driver then making
+calls to turn the radio off and on. This is referred to as a "software based
+RF kill switch"
-Dynamic Firmware
------------- ----- ----- ---- --- -- -
+See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
+on your system.
+
+
+===========================
+5. Dynamic Firmware
+---------------------------
As the firmware is licensed under a restricted use license, it can not be
included within the kernel sources. To enable the IPW2100 you will need a
firmware image to load into the wireless NIC's processors.
@@ -91,8 +146,9 @@ You can obtain these images from <http:/
See INSTALL for instructions on installing the firmware.
-Power Management
------------- ----- ----- ---- --- -- -
+===========================
+6. Power Management
+---------------------------
The IPW2100 supports the configuration of the Power Save Protocol
through a private wireless extension interface. The IPW2100 supports
the following different modes:
@@ -144,22 +200,33 @@ xxxx/yyyy will be replaced with 'off' --
level if `iwconfig eth1 power on` is invoked.
-Support
------------- ----- ----- ---- --- -- -
+===========================
+7. Support
+---------------------------
-For general information and support, go to:
+For general development information and support,
+go to:
http://ipw2100.sf.net/
-License
------------- ----- ----- ---- --- -- -
+The ipw2100 1.1.0 driver and firmware can be downloaded from:
+
+ http://support.intel.com
+
+For installation support on the ipw2100 1.1.0 driver on Linux kernels
+2.6.8 or greater, email support is available from:
+
+ http://supportmail.intel.com
+
+===========================
+8. License
+---------------------------
- Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+ Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
+ under the terms of the GNU General Public License (version 2) as
+ published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -173,7 +240,7 @@ License
The full GNU General Public License is included in this distribution in the
file called LICENSE.
- Contact Information:
+ License Contact Information:
James P. Ketrenos <ipw2100-admin at linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/kernel-2.6.spec,v
retrieving revision 1.813
retrieving revision 1.813.2.1
diff -u -r1.813 -r1.813.2.1
--- kernel-2.6.spec 21 Apr 2005 06:18:41 -0000 1.813
+++ kernel-2.6.spec 25 Apr 2005 18:36:20 -0000 1.813.2.1
@@ -21,7 +21,8 @@
%define sublevel 11
%define kversion 2.6.%{sublevel}
%define rpmversion 2.6.%{sublevel}
-%define rhbsys %([ -r /etc/beehive-root -o -n "%{?__beehive_build}" ] && echo || echo .`whoami`)
+#%define rhbsys %([ -r /etc/beehive-root -o -n "%{?__beehive_build}" ] && echo || echo .`whoami`)
+%define rhbsys .jwltest.7
%if %{FC3}
%define release %(R="$Revision$"; RR="${R##: }"; echo ${RR%%?})_FC3%{rhbsys}
%endif
@@ -283,6 +284,12 @@
# NIC driver updates
Patch1351: linux-2.6.9-net-tr-irqlock-fix.patch
Patch1362: linux-2.6.9-net-airo-nullptr.patch
+Patch1363: jwltest-b44-bounce-bufs.patch
+Patch1364: jwltest-e1000-update-5_7_6-k2.patch
+Patch1365: jwltest-e1000-watchdog.patch
+Patch1366: jwltest-e1000-workqueue-flush.patch
+Patch1367: jwltest-bonding-2_6_12-rc2.patch
+Patch1368: jwltest-bonding-sysfs.patch
# USB bits
Patch1400: linux-2.6.10-usb-use_both_schemes.patch
@@ -319,6 +326,7 @@
Patch3020: linux-2.6.9-ipw2100.patch
Patch3021: linux-2.6.9-ipw2200.patch
Patch3022: linux-2.6.9-ieee80211.patch
+Patch3023: jwltest-ipw2100-1_1_0.patch
#
# 10000 to 20000 is for stuff that has to come last due to the
@@ -562,6 +570,18 @@
%patch1351 -p1
# NULL out ptrs in airo after kfree'ing them.
%patch1362 -p1
+# Improve B44 bounce buffer allocation
+%patch1363 -p1
+# E1000 update to 5.7.6-k2
+%patch1364 -p1
+# E1000 move body of watchdog to workqueue
+%patch1365 -p1
+# E1000 flush workqueues at remove
+%patch1366 -p1
+# Bonding backport from 2.6.12-rc2
+%patch1367 -p1
+# Bonding sysfs support
+%patch1368 -p1
# USB Bits.
# Enable both old and new style USB initialisation.
@@ -621,6 +641,7 @@
%patch3020 -p1
%patch3021 -p1
%patch3022 -p1
+%patch3023 -p1 -E
#
# Patches 5000 to 6000 are reserved for new drivers that are about to
linux-2.6.9-module_version.patch:
linux-2.6.10/drivers/scsi/gdth.c | 1 +
linux-2.6.9/drivers/block/DAC960.c | 1 +
linux-2.6.9/drivers/block/cciss.c | 1 +
linux-2.6.9/drivers/block/cpqarray.c | 1 +
linux-2.6.9/drivers/message/fusion/mptbase.c | 1 +
linux-2.6.9/drivers/net/b44.c | 1 +
linux-2.6.9/drivers/net/e1000/e1000_main.c | 4 +++-
linux-2.6.9/drivers/net/ixgb/ixgb_main.c | 4 +++-
linux-2.6.9/drivers/net/ns83820.c | 1 +
linux-2.6.9/drivers/net/tg3.c | 1 +
linux-2.6.9/drivers/scsi/3w-9xxx.c | 9 +++++----
linux-2.6.9/drivers/scsi/ahci.c | 1 +
12 files changed, 20 insertions(+), 6 deletions(-)
Index: linux-2.6.9-module_version.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/FC-3/linux-2.6.9-module_version.patch,v
retrieving revision 1.6
retrieving revision 1.6.10.1
diff -u -r1.6 -r1.6.10.1
--- linux-2.6.9-module_version.patch 10 Mar 2005 00:26:59 -0000 1.6
+++ linux-2.6.9-module_version.patch 25 Apr 2005 18:36:20 -0000 1.6.10.1
@@ -26,8 +26,8 @@
#else
#define DRIVERNAPI "-NAPI"
#endif
--char e1000_driver_version[] = "5.6.10.1-k2"DRIVERNAPI;
-+#define DRV_VERSION "5.6.10.1-k2"DRIVERNAPI;
+-char e1000_driver_version[] = "5.7.6-k2"DRIVERNAPI;
++#define DRV_VERSION "5.7.6-k2"DRIVERNAPI;
+char e1000_driver_version[] = DRV_VERSION;
char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
More information about the fedora-cvs-commits
mailing list