aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-18 14:06:44 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-18 14:06:44 -0800
commit8b2d1833a29e9dc8bccad348396ad08666379d77 (patch)
treea7bb3bb922bb744934cc0d0bcce043ad8129ab0e /drivers
parentc9daa2722a3f1967e3e9750fd4cb6a7352a3cd63 (diff)
parentba596a01886b236c8171fc28d53842da0128224e (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (31 commits) Replace cpmac fix dl2k: the rest dl2k: MSCR, MSSR, ESR, PHY_SCR fixes dl2k: BMSR fixes dl2k: ANAR, ANLPAR fixes dl2k: BMCR_t fixes 3c574, 3c515 bitfields abuse sbni endian fixes wan/lmc bitfields fixes dscc4 endian fixes S2io: Fixed synchronization between scheduling of napi with card reset and close atl1: fix frame length bug Documentation: add a guideline for hard_start_xmit method Revert "sky2: remove check for PCI wakeup setting from BIOS" e1000e Kconfig: remove ref to nonexistant docs bonding: Don't hold lock when calling rtnl_unlock bonding: fix lock ordering for rtnl and bonding_rwsem bonding: Fix up parameter parsing bonding: release slaves when master removed via sysfs bonding: fix locking during alb failover and slave removal ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/3c515.c60
-rw-r--r--drivers/net/Kconfig3
-rw-r--r--drivers/net/atl1/atl1_main.c8
-rw-r--r--drivers/net/bonding/bond_alb.c23
-rw-r--r--drivers/net/bonding/bond_main.c64
-rw-r--r--drivers/net/bonding/bond_sysfs.c66
-rw-r--r--drivers/net/bonding/bonding.h4
-rw-r--r--drivers/net/cpmac.c2
-rw-r--r--drivers/net/dl2k.c215
-rw-r--r--drivers/net/dl2k.h157
-rw-r--r--drivers/net/ipg.c36
-rw-r--r--drivers/net/pcmcia/3c574_cs.c31
-rw-r--r--drivers/net/s2io.c17
-rw-r--r--drivers/net/sky2.c24
-rw-r--r--drivers/net/wan/dscc4.c94
-rw-r--r--drivers/net/wan/lmc/lmc_media.c12
-rw-r--r--drivers/net/wan/sbni.h12
-rw-r--r--drivers/net/wireless/b43/rfkill.c11
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c6
-rw-r--r--drivers/net/wireless/ipw2200.c2
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c11
23 files changed, 383 insertions, 481 deletions
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 275e7510eba..684bab78101 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -243,14 +243,16 @@ enum eeprom_offset {
enum Window3 { /* Window 3: MAC/config bits. */
Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
};
-union wn3_config {
- int i;
- struct w3_config_fields {
- unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
- int pad8:8;
- unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
- int pad24:7;
- } u;
+enum wn3_config {
+ Ram_size = 7,
+ Ram_width = 8,
+ Ram_speed = 0x30,
+ Rom_size = 0xc0,
+ Ram_split_shift = 16,
+ Ram_split = 3 << Ram_split_shift,
+ Xcvr_shift = 20,
+ Xcvr = 7 << Xcvr_shift,
+ Autoselect = 0x1000000,
};
enum Window4 {
@@ -614,7 +616,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
/* Read the station address from the EEPROM. */
EL3WINDOW(0);
for (i = 0; i < 0x18; i++) {
- short *phys_addr = (short *) dev->dev_addr;
+ __be16 *phys_addr = (__be16 *) dev->dev_addr;
int timer;
outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
/* Pause for at least 162 us. for the read to take place. */
@@ -646,22 +648,22 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
{
char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
- union wn3_config config;
+ __u32 config;
EL3WINDOW(3);
vp->available_media = inw(ioaddr + Wn3_Options);
- config.i = inl(ioaddr + Wn3_Config);
+ config = inl(ioaddr + Wn3_Config);
if (corkscrew_debug > 1)
printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
- config.i, inw(ioaddr + Wn3_Options));
+ config, inw(ioaddr + Wn3_Options));
printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
- 8 << config.u.ram_size,
- config.u.ram_width ? "word" : "byte",
- ram_split[config.u.ram_split],
- config.u.autoselect ? "autoselect/" : "",
- media_tbl[config.u.xcvr].name);
- dev->if_port = config.u.xcvr;
- vp->default_media = config.u.xcvr;
- vp->autoselect = config.u.autoselect;
+ 8 << config & Ram_size,
+ config & Ram_width ? "word" : "byte",
+ ram_split[(config & Ram_split) >> Ram_split_shift],
+ config & Autoselect ? "autoselect/" : "",
+ media_tbl[(config & Xcvr) >> Xcvr_shift].name);
+ vp->default_media = (config & Xcvr) >> Xcvr_shift;
+ vp->autoselect = config & Autoselect ? 1 : 0;
+ dev->if_port = vp->default_media;
}
if (vp->media_override != 7) {
printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
@@ -694,14 +696,14 @@ static int corkscrew_open(struct net_device *dev)
{
int ioaddr = dev->base_addr;
struct corkscrew_private *vp = netdev_priv(dev);
- union wn3_config config;
+ __u32 config;
int i;
/* Before initializing select the active media port. */
EL3WINDOW(3);
if (vp->full_duplex)
outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */
- config.i = inl(ioaddr + Wn3_Config);
+ config = inl(ioaddr + Wn3_Config);
if (vp->media_override != 7) {
if (corkscrew_debug > 1)
@@ -727,12 +729,12 @@ static int corkscrew_open(struct net_device *dev)
} else
dev->if_port = vp->default_media;
- config.u.xcvr = dev->if_port;
- outl(config.i, ioaddr + Wn3_Config);
+ config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
+ outl(config, ioaddr + Wn3_Config);
if (corkscrew_debug > 1) {
printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
- dev->name, config.i);
+ dev->name, config);
}
outw(TxReset, ioaddr + EL3_CMD);
@@ -901,7 +903,7 @@ static void corkscrew_timer(unsigned long data)
ok = 1;
}
if (!ok) {
- union wn3_config config;
+ __u32 config;
do {
dev->if_port =
@@ -928,9 +930,9 @@ static void corkscrew_timer(unsigned long data)
ioaddr + Wn4_Media);
EL3WINDOW(3);
- config.i = inl(ioaddr + Wn3_Config);
- config.u.xcvr = dev->if_port;
- outl(config.i, ioaddr + Wn3_Config);
+ config = inl(ioaddr + Wn3_Config);
+ config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
+ outl(config, ioaddr + Wn3_Config);
outw(dev->if_port == 3 ? StartCoax : StopCoax,
ioaddr + EL3_CMD);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 114771a2a13..9ae3166e316 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1976,9 +1976,6 @@ config E1000E
<http://support.intel.com>
- More specific information on configuring the driver is in
- <file:Documentation/networking/e1000e.txt>.
-
To compile this driver as a module, choose M here. The module
will be called e1000e.
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 35b0a7dd4ef..9200ee59d85 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -120,7 +120,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
struct atl1_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+ hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
adapter->wol = 0;
@@ -688,7 +688,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
int old_mtu = netdev->mtu;
- int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
@@ -853,8 +853,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
/* set Interrupt Clear Timer */
iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER);
- /* set MTU, 4 : VLAN */
- iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU);
+ /* set max frame size hw will accept */
+ iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU);
/* jumbo size & rrd retirement timer */
value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 25b8dbf6cfd..b57bc9467db 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -979,7 +979,7 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
/*
* Send learning packets after MAC address swap.
*
- * Called with RTNL and bond->lock held for read.
+ * Called with RTNL and no other locks
*/
static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
struct slave *slave2)
@@ -987,6 +987,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
struct slave *disabled_slave = NULL;
+ ASSERT_RTNL();
+
/* fasten the change in the switch */
if (SLAVE_IS_OK(slave1)) {
alb_send_learning_packets(slave1, slave1->dev->dev_addr);
@@ -1031,7 +1033,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
* a slave that has @slave's permanet address as its current address.
* We'll make sure that that slave no longer uses @slave's permanent address.
*
- * Caller must hold bond lock
+ * Caller must hold RTNL and no other locks
*/
static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
{
@@ -1542,7 +1544,12 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
return 0;
}
-/* Caller must hold bond lock for write */
+/*
+ * Remove slave from tlb and rlb hash tables, and fix up MAC addresses
+ * if necessary.
+ *
+ * Caller must hold RTNL and no other locks
+ */
void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
{
if (bond->slave_cnt > 1) {
@@ -1601,9 +1608,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
struct slave *swap_slave;
int i;
- if (new_slave)
- ASSERT_RTNL();
-
if (bond->curr_active_slave == new_slave) {
return;
}
@@ -1649,6 +1653,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
+ ASSERT_RTNL();
+
/* curr_active_slave must be set before calling alb_swap_mac_addr */
if (swap_slave) {
/* swap mac address */
@@ -1659,12 +1665,11 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
bond->alb_info.rlb_enabled);
}
- read_lock(&bond->lock);
-
if (swap_slave) {
alb_fasten_mac_swap(bond, swap_slave, new_slave);
+ read_lock(&bond->lock);
} else {
- /* fasten bond mac on new current slave */
+ read_lock(&bond->lock);
alb_send_learning_packets(new_slave, bond->dev->dev_addr);
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b0b26036266..49a198206e3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1746,7 +1746,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
* has been cleared (if our_slave == old_current),
* but before a new active slave is selected.
*/
+ write_unlock_bh(&bond->lock);
bond_alb_deinit_slave(bond, slave);
+ write_lock_bh(&bond->lock);
}
if (oldcurrent == slave) {
@@ -1905,6 +1907,12 @@ static int bond_release_all(struct net_device *bond_dev)
slave_dev = slave->dev;
bond_detach_slave(bond, slave);
+ /* now that the slave is detached, unlock and perform
+ * all the undo steps that should not be called from
+ * within a lock.
+ */
+ write_unlock_bh(&bond->lock);
+
if ((bond->params.mode == BOND_MODE_TLB) ||
(bond->params.mode == BOND_MODE_ALB)) {
/* must be called only after the slave
@@ -1915,12 +1923,6 @@ static int bond_release_all(struct net_device *bond_dev)
bond_compute_features(bond);
- /* now that the slave is detached, unlock and perform
- * all the undo steps that should not be called from
- * within a lock.
- */
- write_unlock_bh(&bond->lock);
-
bond_destroy_slave_symlinks(bond_dev, slave_dev);
bond_del_vlans_from_slave(bond, slave_dev);
@@ -2384,7 +2386,9 @@ void bond_mii_monitor(struct work_struct *work)
rtnl_lock();
read_lock(&bond->lock);
__bond_mii_monitor(bond, 1);
- rtnl_unlock();
+ read_unlock(&bond->lock);
+ rtnl_unlock(); /* might sleep, hold no other locks */
+ read_lock(&bond->lock);
}
delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
@@ -3399,9 +3403,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
case NETDEV_CHANGENAME:
return bond_event_changename(event_bond);
case NETDEV_UNREGISTER:
- /*
- * TODO: remove a bond from the list?
- */
+ bond_release_all(event_bond->dev);
break;
default:
break;
@@ -4540,18 +4542,27 @@ static void bond_free_all(void)
/*
* Convert string input module parms. Accept either the
- * number of the mode or its string name.
+ * number of the mode or its string name. A bit complicated because
+ * some mode names are substrings of other names, and calls from sysfs
+ * may have whitespace in the name (trailing newlines, for example).
*/
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
{
- int i;
+ int mode = -1, i, rv;
+ char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
+
+ rv = sscanf(buf, "%d", &mode);
+ if (!rv) {
+ rv = sscanf(buf, "%20s", modestr);
+ if (!rv)
+ return -1;
+ }
for (i = 0; tbl[i].modename; i++) {
- if ((isdigit(*mode_arg) &&
- tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
- (strcmp(mode_arg, tbl[i].modename) == 0)) {
+ if (mode == tbl[i].mode)
+ return tbl[i].mode;
+ if (strcmp(modestr, tbl[i].modename) == 0)
return tbl[i].mode;
- }
}
return -1;
@@ -4865,9 +4876,22 @@ static struct lock_class_key bonding_netdev_xmit_lock_key;
int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
{
struct net_device *bond_dev;
+ struct bonding *bond, *nxt;
int res;
rtnl_lock();
+ down_write(&bonding_rwsem);
+
+ /* Check to see if the bond already exists. */
+ list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+ if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
+ printk(KERN_ERR DRV_NAME
+ ": cannot add bond %s; it already exists\n",
+ name);
+ res = -EPERM;
+ goto out_rtnl;
+ }
+
bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
ether_setup);
if (!bond_dev) {
@@ -4906,10 +4930,12 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
netif_carrier_off(bond_dev);
+ up_write(&bonding_rwsem);
rtnl_unlock(); /* allows sysfs registration of net device */
res = bond_create_sysfs_entry(bond_dev->priv);
if (res < 0) {
rtnl_lock();
+ down_write(&bonding_rwsem);
goto out_bond;
}
@@ -4920,6 +4946,7 @@ out_bond:
out_netdev:
free_netdev(bond_dev);
out_rtnl:
+ up_write(&bonding_rwsem);
rtnl_unlock();
return res;
}
@@ -4940,6 +4967,9 @@ static int __init bonding_init(void)
#ifdef CONFIG_PROC_FS
bond_create_proc_dir();
#endif
+
+ init_rwsem(&bonding_rwsem);
+
for (i = 0; i < max_bonds; i++) {
res = bond_create(NULL, &bonding_defaults, NULL);
if (res)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 11b76b35241..90a1f31e8e6 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -109,11 +109,10 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
{
char command[IFNAMSIZ + 1] = {0, };
char *ifname;
- int res = count;
+ int rv, res = count;
struct bonding *bond;
struct bonding *nxt;
- down_write(&(bonding_rwsem));
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
if ((strlen(command) <= 1) ||
@@ -121,39 +120,28 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
goto err_no_cmd;
if (command[0] == '+') {
-
- /* Check to see if the bond already exists. */
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
- if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
- printk(KERN_ERR DRV_NAME
- ": cannot add bond %s; it already exists\n",
- ifname);
- res = -EPERM;
- goto out;
- }
-
printk(KERN_INFO DRV_NAME
": %s is being created...\n", ifname);
- if (bond_create(ifname, &bonding_defaults, &bond)) {
- printk(KERN_INFO DRV_NAME
- ": %s interface already exists. Bond creation failed.\n",
- ifname);
- res = -EPERM;
+ rv = bond_create(ifname, &bonding_defaults, &bond);
+ if (rv) {
+ printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
+ res = rv;
}
goto out;
}
if (command[0] == '-') {
+ rtnl_lock();
+ down_write(&bonding_rwsem);
+
list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
- rtnl_lock();
/* check the ref count on the bond's kobject.
* If it's > expected, then there's a file open,
* and we have to fail.
*/
if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
> expected_refcount){
- rtnl_unlock();
printk(KERN_INFO DRV_NAME
": Unable remove bond %s due to open references.\n",
ifname);
@@ -164,6 +152,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
": %s is being deleted...\n",
bond->dev->name);
bond_destroy(bond);
+ up_write(&bonding_rwsem);
rtnl_unlock();
goto out;
}
@@ -171,6 +160,8 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
printk(KERN_ERR DRV_NAME
": unable to delete non-existent bond %s\n", ifname);
res = -ENODEV;
+ up_write(&bonding_rwsem);
+ rtnl_unlock();
goto out;
}
@@ -183,7 +174,6 @@ err_no_cmd:
* get called forever, which is bad.
*/
out:
- up_write(&(bonding_rwsem));
return res;
}
/* class attribute for bond_masters file. This ends up in /sys/class/net */
@@ -271,6 +261,9 @@ static ssize_t bonding_store_slaves(struct device *d,
/* Note: We can't hold bond->lock here, as bond_create grabs it. */
+ rtnl_lock();
+ down_write(&(bonding_rwsem));
+
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
if ((strlen(command) <= 1) ||
@@ -336,12 +329,10 @@ static ssize_t bonding_store_slaves(struct device *d,
dev->mtu = bond->dev->mtu;
}
}
- rtnl_lock();
res = bond_enslave(bond->dev, dev);
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
slave->original_mtu = original_mtu;
- rtnl_unlock();
if (res) {
ret = res;
}
@@ -359,12 +350,10 @@ static ssize_t bonding_store_slaves(struct device *d,
if (dev) {
printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
bond->dev->name, dev->name);
- rtnl_lock();
if (bond->setup_by_slave)
res = bond_release_and_destroy(bond->dev, dev);
else
res = bond_release(bond->dev, dev);
- rtnl_unlock();
if (res) {
ret = res;
goto out;
@@ -389,6 +378,8 @@ err_no_cmd:
ret = -EPERM;
out:
+ up_write(&(bonding_rwsem));
+ rtnl_unlock();
return ret;
}
@@ -423,7 +414,7 @@ static ssize_t bonding_store_mode(struct device *d,
goto out;
}
- new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+ new_value = bond_parse_parm(buf, bond_mode_tbl);
if (new_value < 0) {
printk(KERN_ERR DRV_NAME
": %s: Ignoring invalid mode value %.*s.\n",
@@ -478,7 +469,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
goto out;
}
- new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+ new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
if (new_value < 0) {
printk(KERN_ERR DRV_NAME
": %s: Ignoring invalid xmit hash policy value %.*s.\n",
@@ -518,7 +509,7 @@ static ssize_t bonding_store_arp_validate(struct device *d,
int new_value;
struct bonding *bond = to_bond(d);
- new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
+ new_value = bond_parse_parm(buf, arp_validate_tbl);
if (new_value < 0) {
printk(KERN_ERR DRV_NAME
": %s: Ignoring invalid arp_validate value %s\n",
@@ -941,7 +932,7 @@ static ssize_t bonding_store_lacp(struct device *d,
goto out;
}
- new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+ new_value = bond_parse_parm(buf, bond_lacp_tbl);
if ((new_value == 1) || (new_value == 0)) {
bond->params.lacp_fast = new_value;
@@ -1075,7 +1066,10 @@ static ssize_t bonding_store_primary(struct device *d,
struct slave *slave;
struct bonding *bond = to_bond(d);
- write_lock_bh(&bond->lock);
+ rtnl_lock();
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
+
if (!USES_PRIMARY(bond->params.mode)) {
printk(KERN_INFO DRV_NAME
": %s: Unable to set primary slave; %s is in mode %d\n",
@@ -1109,8 +1103,8 @@ static ssize_t bonding_store_primary(struct device *d,
}
}
out:
- write_unlock_bh(&bond->lock);
-
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
rtnl_unlock();
return count;
@@ -1190,7 +1184,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
struct bonding *bond = to_bond(d);
rtnl_lock();
- write_lock_bh(&bond->lock);
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
if (!USES_PRIMARY(bond->params.mode)) {
printk(KERN_INFO DRV_NAME
@@ -1247,7 +1242,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
}
}
out:
- write_unlock_bh(&bond->lock);
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
rtnl_unlock();
return count;
@@ -1418,8 +1414,6 @@ int bond_create_sysfs(void)
int ret = 0;
struct bonding *firstbond;
- init_rwsem(&bonding_rwsem);
-
/* get the netdev class pointer */
firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
if (!firstbond)
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index e1e4734e23c..6d83be49899 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -141,6 +141,8 @@ struct bond_parm_tbl {
int mode;
};
+#define BOND_MAX_MODENAME_LEN 20
+
struct vlan_entry {
struct list_head vlan_list;
__be32 vlan_ip;
@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *);
void bond_loadbalance_arp_mon(struct work_struct *);
void bond_activebackup_arp_mon(struct work_struct *);
void bond_set_mode_ops(struct bonding *bond, int mode);
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
void bond_register_arp(struct bonding *);
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 6fd95a2c8ce..6e12d48351b 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -459,7 +459,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
len = max(skb->len, ETH_ZLEN);
- queue = skb->queue_mapping;
+ queue = skb_get_queue_mapping(skb);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(dev, queue);
#else
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index 47cce9cad30..e233d04a213 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -1316,9 +1316,10 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
i,
(u32) (np->tx_ring_dma + i * sizeof (*desc)),
- (u32) desc->next_desc,
- (u32) desc->status, (u32) (desc->fraginfo >> 32),
- (u32) desc->fraginfo);
+ (u32)le64_to_cpu(desc->next_desc),
+ (u32)le64_to_cpu(desc->status),
+ (u32)(le64_to_cpu(desc->fraginfo) >> 32),
+ (u32)le64_to_cpu(desc->fraginfo));
printk ("\n");
}
printk ("\n");
@@ -1435,7 +1436,7 @@ mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data)
static int
mii_wait_link (struct net_device *dev, int wait)
{
- BMSR_t bmsr;
+ __u16 bmsr;
int phy_addr;
struct netdev_private *np;
@@ -1443,8 +1444,8 @@ mii_wait_link (struct net_device *dev, int wait)
phy_addr = np->phy_addr;
do {
- bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
- if (bmsr.bits.link_status)
+ bmsr = mii_read (dev, phy_addr, MII_BMSR);
+ if (bmsr & MII_BMSR_LINK_STATUS)
return 0;
mdelay (1);
} while (--wait > 0);
@@ -1453,70 +1454,72 @@ mii_wait_link (struct net_device *dev, int wait)
static int
mii_get_media (struct net_device *dev)
{
- ANAR_t negotiate;
- BMSR_t bmsr;
- BMCR_t bmcr;
- MSCR_t mscr;
- MSSR_t mssr;
+ __u16 negotiate;
+ __u16 bmsr;
+ __u16 mscr;
+ __u16 mssr;
int phy_addr;
struct netdev_private *np;
np = netdev_priv(dev);
phy_addr = np->phy_addr;
- bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
+ bmsr = mii_read (dev, phy_addr, MII_BMSR);
if (np->an_enable) {
- if (!bmsr.bits.an_complete) {
+ if (!(bmsr & MII_BMSR_AN_COMPLETE)) {
/* Auto-Negotiation not completed */
return -1;
}
- negotiate.image = mii_read (dev, phy_addr, MII_ANAR) &
+ negotiate = mii_read (dev, phy_addr, MII_ANAR) &
mii_read (dev, phy_addr, MII_ANLPAR);
- mscr.image = mii_read (dev, phy_addr, MII_MSCR);
- mssr.image = mii_read (dev, phy_addr, MII_MSSR);
- if (mscr.bits.media_1000BT_FD & mssr.bits.lp_1000BT_FD) {
+ mscr = mii_read (dev, phy_addr, MII_MSCR);
+ mssr = mii_read (dev, phy_addr, MII_MSSR);
+ if (mscr & MII_MSCR_1000BT_FD && mssr & MII_MSSR_LP_1000BT_FD) {
np->speed = 1000;
np->full_duplex = 1;
printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
- } else if (mscr.bits.media_1000BT_HD & mssr.bits.lp_1000BT_HD) {
+ } else if (mscr & MII_MSCR_1000BT_HD && mssr & MII_MSSR_LP_1000BT_HD) {
np->speed = 1000;
np->full_duplex = 0;
printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n");
- } else if (negotiate.bits.media_100BX_FD) {
+ } else if (negotiate & MII_ANAR_100BX_FD) {
np->speed = 100;
np->full_duplex = 1;
printk (KERN_INFO "Auto 100 Mbps, Full duplex\n");
- } else if (negotiate.bits.media_100BX_HD) {
+ } else if (negotiate & MII_ANAR_100BX_HD) {
np->speed = 100;
np->full_duplex = 0;
printk (KERN_INFO "Auto 100 Mbps, Half duplex\n");
- } else if (negotiate.bits.media_10BT_FD) {
+ } else if (negotiate & MII_ANAR_10BT_FD) {
np->speed = 10;
np->full_duplex = 1;
printk (KERN_INFO "Auto 10 Mbps, Full duplex\n");
- } else if (negotiate.bits.media_10BT_HD) {
+ } else if (negotiate & MII_ANAR_10BT_HD) {
np->speed = 10;
np->full_duplex = 0;
printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");
}
- if (negotiate.bits.pause) {
+ if (negotiate & MII_ANAR_PAUSE) {
np->tx_flow &= 1;
np->rx_flow &= 1;
- } else if (negotiate.bits.asymmetric) {
+ } else if (negotiate & MII_ANAR_ASYMMETRIC) {
np->tx_flow = 0;
np->rx_flow &= 1;
}
/* else tx_flow, rx_flow = user select */
} else {
- bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
- if (bmcr.bits.speed100 == 1 && bmcr.bits.speed1000 == 0) {
+ __u16 bmcr = mii_read (dev, phy_addr, MII_BMCR);
+ switch (bmcr & (MII_BMCR_SPEED_100 | MII_BMCR_SPEED_1000)) {
+ case MII_BMCR_SPEED_1000:
+ printk (KERN_INFO "Operating at 1000 Mbps, ");
+ break;
+ case MII_BMCR_SPEED_100:
printk (KERN_INFO "Operating at 100 Mbps, ");
- } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) {
+ break;
+ case 0:
printk (KERN_INFO "Operating at 10 Mbps, ");
- } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) {
- printk (KERN_INFO "Operating at 1000 Mbps, ");
}
- if (bmcr.bits.duplex_mode) {
+ if (bmcr & MII_BMCR_DUPLEX_MODE) {
printk ("Full duplex\n");
} else {
printk ("Half duplex\n");
@@ -1537,10 +1540,10 @@ mii_get_media (struct net_device *dev)
static int
mii_set_media (struct net_device *dev)
{
- PHY_SCR_t pscr;
- BMCR_t bmcr;
- BMSR_t bmsr;
- ANAR_t anar;
+ __u16 pscr;
+ __u16 bmcr;
+ __u16 bmsr;
+ __u16 anar;
int phy_addr;
struct netdev_private *np;
np = netdev_priv(dev);
@@ -1549,76 +1552,77 @@ mii_set_media (struct net_device *dev)
/* Does user set speed? */
if (np->an_enable) {
/* Advertise capabilities */
- bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
- anar.image = mii_read (dev, phy_addr, MII_ANAR);
- anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD;
- anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD;
- anar.bits.media_100BT4 = bmsr.bits.media_100BT4;
- anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD;
- anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD;
- anar.bits.pause = 1;
- anar.bits.asymmetric = 1;
- mii_write (dev, phy_addr, MII_ANAR, anar.image);
+ bmsr = mii_read (dev, phy_addr, MII_BMSR);
+ anar = mii_read (dev, phy_addr, MII_ANAR) &
+ ~MII_ANAR_100BX_FD &
+ ~MII_ANAR_100BX_HD &
+ ~MII_ANAR_100BT4 &
+ ~MII_ANAR_10BT_FD &
+ ~MII_ANAR_10BT_HD;
+ if (bmsr & MII_BMSR_100BX_FD)
+ anar |= MII_ANAR_100BX_FD;
+ if (bmsr & MII_BMSR_100BX_HD)
+ anar |= MII_ANAR_100BX_HD;
+ if (bmsr & MII_BMSR_100BT4)
+ anar |= MII_ANAR_100BT4;
+ if (bmsr & MII_BMSR_10BT_FD)
+ anar |= MII_ANAR_10BT_FD;
+ if (bmsr & MII_BMSR_10BT_HD)
+ anar |= MII_ANAR_10BT_HD;
+ anar |= MII_ANAR_PAUSE | MII_ANAR_ASYMMETRIC;
+ mii_write (dev, phy_addr, MII_ANAR, anar);
/* Enable Auto crossover */
- pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
- pscr.bits.mdi_crossover_mode = 3; /* 11'b */
- mii_write (dev, phy_addr, MII_PHY_SCR