forked from Minki/linux
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 ...
This commit is contained in:
commit
8b2d1833a2
@ -61,7 +61,10 @@ Transmit path guidelines:
|
||||
2) Do not forget to update netdev->trans_start to jiffies after
|
||||
each new tx packet is given to the hardware.
|
||||
|
||||
3) Do not forget that once you return 0 from your hard_start_xmit
|
||||
3) A hard_start_xmit method must not modify the shared parts of a
|
||||
cloned SKB.
|
||||
|
||||
4) Do not forget that once you return 0 from your hard_start_xmit
|
||||
method, it is your driver's responsibility to free up the SKB
|
||||
and in some finite amount of time.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
printk (KERN_INFO "Operating at 100 Mbps, ");
|
||||
} else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) {
|
||||
printk (KERN_INFO "Operating at 10 Mbps, ");
|
||||
} else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) {
|
||||
__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, ");
|
||||
break;
|
||||
case 0:
|
||||
printk (KERN_INFO "Operating at 10 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, pscr.image);
|
||||
pscr = mii_read (dev, phy_addr, MII_PHY_SCR);
|
||||
pscr |= 3 << 5; /* 11'b */
|
||||
mii_write (dev, phy_addr, MII_PHY_SCR, pscr);
|
||||
|
||||
/* Soft reset PHY */
|
||||
mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
|
||||
bmcr.image = 0;
|
||||
bmcr.bits.an_enable = 1;
|
||||
bmcr.bits.restart_an = 1;
|
||||
bmcr.bits.reset = 1;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN | MII_BMCR_RESET;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
mdelay(1);
|
||||
} else {
|
||||
/* Force speed setting */
|
||||
/* 1) Disable Auto crossover */
|
||||
pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
|
||||
pscr.bits.mdi_crossover_mode = 0;
|
||||
mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);
|
||||
pscr = mii_read (dev, phy_addr, MII_PHY_SCR);
|
||||
pscr &= ~(3 << 5);
|
||||
mii_write (dev, phy_addr, MII_PHY_SCR, pscr);
|
||||
|
||||
/* 2) PHY Reset */
|
||||
bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
|
||||
bmcr.bits.reset = 1;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
bmcr = mii_read (dev, phy_addr, MII_BMCR);
|
||||
bmcr |= MII_BMCR_RESET;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
|
||||
/* 3) Power Down */
|
||||
bmcr.image = 0x1940; /* must be 0x1940 */
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
bmcr = 0x1940; /* must be 0x1940 */
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
mdelay (100); /* wait a certain time */
|
||||
|
||||
/* 4) Advertise nothing */
|
||||
mii_write (dev, phy_addr, MII_ANAR, 0);
|
||||
|
||||
/* 5) Set media and Power Up */
|
||||
bmcr.image = 0;
|
||||
bmcr.bits.power_down = 1;
|
||||
bmcr = MII_BMCR_POWER_DOWN;
|
||||
if (np->speed == 100) {
|
||||
bmcr.bits.speed100 = 1;
|
||||
bmcr.bits.speed1000 = 0;
|
||||
bmcr |= MII_BMCR_SPEED_100;
|
||||
printk (KERN_INFO "Manual 100 Mbps, ");
|
||||
} else if (np->speed == 10) {
|
||||
bmcr.bits.speed100 = 0;
|
||||
bmcr.bits.speed1000 = 0;
|
||||
printk (KERN_INFO "Manual 10 Mbps, ");
|
||||
}
|
||||
if (np->full_duplex) {
|
||||
bmcr.bits.duplex_mode = 1;
|
||||
bmcr |= MII_BMCR_DUPLEX_MODE;
|
||||
printk ("Full duplex\n");
|
||||
} else {
|
||||
bmcr.bits.duplex_mode = 0;
|
||||
printk ("Half duplex\n");
|
||||
}
|
||||
#if 0
|
||||
/* Set 1000BaseT Master/Slave setting */
|
||||
mscr.image = mii_read (dev, phy_addr, MII_MSCR);
|
||||
mscr.bits.cfg_enable = 1;
|
||||
mscr.bits.cfg_value = 0;
|
||||
mscr = mii_read (dev, phy_addr, MII_MSCR);
|
||||
mscr |= MII_MSCR_CFG_ENABLE;
|
||||
mscr &= ~MII_MSCR_CFG_VALUE = 0;
|
||||
#endif
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
mdelay(10);
|
||||
}
|
||||
return 0;
|
||||
@ -1627,43 +1631,42 @@ mii_set_media (struct net_device *dev)
|
||||
static int
|
||||
mii_get_media_pcs (struct net_device *dev)
|
||||
{
|
||||
ANAR_PCS_t negotiate;
|
||||
BMSR_t bmsr;
|
||||
BMCR_t bmcr;
|
||||
__u16 negotiate;
|
||||
__u16 bmsr;
|
||||
int phy_addr;
|
||||
struct netdev_private *np;
|
||||
|
||||
np = netdev_priv(dev);
|
||||
phy_addr = np->phy_addr;
|
||||
|
||||
bmsr.image = mii_read (dev, phy_addr, PCS_BMSR);
|
||||
bmsr = mii_read (dev, phy_addr, PCS_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, PCS_ANAR) &
|
||||
negotiate = mii_read (dev, phy_addr, PCS_ANAR) &
|
||||
mii_read (dev, phy_addr, PCS_ANLPAR);
|
||||
np->speed = 1000;
|
||||
if (negotiate.bits.full_duplex) {
|
||||
if (negotiate & PCS_ANAR_FULL_DUPLEX) {
|
||||
printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
|
||||
np->full_duplex = 1;
|
||||
} else {
|
||||
printk (KERN_INFO "Auto 1000 Mbps, half duplex\n");
|
||||
np->full_duplex = 0;
|
||||
}
|
||||
if (negotiate.bits.pause) {
|
||||
if (negotiate & PCS_ANAR_PAUSE) {
|
||||
np->tx_flow &= 1;
|
||||
np->rx_flow &= 1;
|
||||
} else if (negotiate.bits.asymmetric) {
|
||||
} else if (negotiate & PCS_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, PCS_BMCR);
|
||||
__u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR);
|
||||
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");
|
||||
@ -1684,9 +1687,9 @@ mii_get_media_pcs (struct net_device *dev)
|
||||
static int
|
||||
mii_set_media_pcs (struct net_device *dev)
|
||||
{
|
||||
BMCR_t bmcr;
|
||||
ESR_t esr;
|
||||
ANAR_PCS_t anar;
|
||||
__u16 bmcr;
|
||||
__u16 esr;
|
||||
__u16 anar;
|
||||
int phy_addr;
|
||||
struct netdev_private *np;
|
||||
np = netdev_priv(dev);
|
||||
@ -1695,41 +1698,37 @@ mii_set_media_pcs (struct net_device *dev)
|
||||
/* Auto-Negotiation? */
|
||||
if (np->an_enable) {
|
||||
/* Advertise capabilities */
|
||||
esr.image = mii_read (dev, phy_addr, PCS_ESR);
|
||||
anar.image = mii_read (dev, phy_addr, MII_ANAR);
|
||||
anar.bits.half_duplex =
|
||||
esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD;
|
||||
anar.bits.full_duplex =
|
||||
esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD;
|
||||
anar.bits.pause = 1;
|
||||
anar.bits.asymmetric = 1;
|
||||
mii_write (dev, phy_addr, MII_ANAR, anar.image);
|
||||
esr = mii_read (dev, phy_addr, PCS_ESR);
|
||||
anar = mii_read (dev, phy_addr, MII_ANAR) &
|
||||
~PCS_ANAR_HALF_DUPLEX &
|
||||
~PCS_ANAR_FULL_DUPLEX;
|
||||
if (esr & (MII_ESR_1000BT_HD | MII_ESR_1000BX_HD))
|
||||
anar |= PCS_ANAR_HALF_DUPLEX;
|
||||
if (esr & (MII_ESR_1000BT_FD | MII_ESR_1000BX_FD))
|
||||
anar |= PCS_ANAR_FULL_DUPLEX;
|
||||
anar |= PCS_ANAR_PAUSE | PCS_ANAR_ASYMMETRIC;
|
||||
mii_write (dev, phy_addr, MII_ANAR, anar);
|
||||
|
||||
/* Soft reset PHY */
|
||||
mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
|
||||
bmcr.image = 0;
|
||||
bmcr.bits.an_enable = 1;
|
||||
bmcr.bits.restart_an = 1;
|
||||
bmcr.bits.reset = 1;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
bmcr = MII_BMCR_AN_ENABLE | MII_BMCR_RESTART_AN |
|
||||
MII_BMCR_RESET;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
mdelay(1);
|
||||
} else {
|
||||
/* Force speed setting */
|
||||
/* PHY Reset */
|
||||
bmcr.image = 0;
|
||||
bmcr.bits.reset = 1;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
bmcr = MII_BMCR_RESET;
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
mdelay(10);
|
||||
bmcr.image = 0;
|
||||
bmcr.bits.an_enable = 0;
|
||||
if (np->full_duplex) {
|
||||
bmcr.bits.duplex_mode = 1;
|
||||
bmcr = MII_BMCR_DUPLEX_MODE;
|
||||
printk (KERN_INFO "Manual full duplex\n");
|
||||
} else {
|
||||
bmcr.bits.duplex_mode = 0;
|
||||
bmcr = 0;
|
||||
printk (KERN_INFO "Manual half duplex\n");
|
||||
}
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
|
||||
mii_write (dev, phy_addr, MII_BMCR, bmcr);
|
||||
mdelay(10);
|
||||
|
||||
/* Advertise nothing */
|
||||
|
@ -298,23 +298,6 @@ enum _pcs_reg {
|
||||
};
|
||||
|
||||
/* Basic Mode Control Register */
|
||||
typedef union t_MII_BMCR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 _bit_5_0:6; // bit 5:0
|
||||
u16 speed1000:1; // bit 6
|
||||
u16 col_test_enable:1; // bit 7
|
||||
u16 duplex_mode:1; // bit 8
|
||||
u16 restart_an:1; // bit 9
|
||||
u16 isolate:1; // bit 10
|
||||
u16 power_down:1; // bit 11
|
||||
u16 an_enable:1; // bit 12
|
||||
u16 speed100:1; // bit 13
|
||||
u16 loopback:1; // bit 14
|
||||
u16 reset:1; // bit 15
|
||||
} bits;
|
||||
} BMCR_t, *PBMCR_t;
|
||||
|
||||
enum _mii_bmcr {
|
||||
MII_BMCR_RESET = 0x8000,
|
||||
MII_BMCR_LOOP_BACK = 0x4000,
|
||||
@ -333,28 +316,6 @@ enum _mii_bmcr {
|
||||
};
|
||||
|
||||
/* Basic Mode Status Register */
|
||||
typedef union t_MII_BMSR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 ext_capability:1; // bit 0
|
||||
u16 japper_detect:1; // bit 1
|
||||
u16 link_status:1; // bit 2
|
||||
u16 an_ability:1; // bit 3
|
||||
u16 remote_fault:1; // bit 4
|
||||
u16 an_complete:1; // bit 5
|
||||
u16 preamble_supp:1; // bit 6
|
||||
u16 _bit_7:1; // bit 7
|
||||
u16 ext_status:1; // bit 8
|
||||
u16 media_100BT2_HD:1; // bit 9
|
||||
u16 media_100BT2_FD:1; // bit 10
|
||||
u16 media_10BT_HD:1; // bit 11
|
||||
u16 media_10BT_FD:1; // bit 12
|
||||
u16 media_100BX_HD:1; // bit 13
|
||||
u16 media_100BX_FD:1; // bit 14
|
||||
u16 media_100BT4:1; // bit 15
|
||||
} bits;
|
||||
} BMSR_t, *PBMSR_t;
|
||||
|
||||
enum _mii_bmsr {
|
||||
MII_BMSR_100BT4 = 0x8000,
|
||||
MII_BMSR_100BX_FD = 0x4000,
|
||||
@ -374,24 +335,6 @@ enum _mii_bmsr {
|
||||
};
|
||||
|
||||
/* ANAR */
|
||||
typedef union t_MII_ANAR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 selector:5; // bit 4:0
|
||||
u16 media_10BT_HD:1; // bit 5
|
||||
u16 media_10BT_FD:1; // bit 6
|
||||
u16 media_100BX_HD:1; // bit 7
|
||||
u16 media_100BX_FD:1; // bit 8
|
||||
u16 media_100BT4:1; // bit 9
|
||||
u16 pause:1; // bit 10
|
||||
u16 asymmetric:1; // bit 11
|
||||
u16 _bit12:1; // bit 12
|
||||
u16 remote_fault:1; // bit 13
|
||||
u16 _bit14:1; // bit 14
|
||||
u16 next_page:1; // bit 15
|
||||
} bits;
|
||||
} ANAR_t, *PANAR_t;
|
||||
|
||||
enum _mii_anar {
|
||||
MII_ANAR_NEXT_PAGE = 0x8000,
|
||||
MII_ANAR_REMOTE_FAULT = 0x4000,
|
||||
@ -407,24 +350,6 @@ enum _mii_anar {
|
||||
};
|
||||
|
||||
/* ANLPAR */
|
||||
typedef union t_MII_ANLPAR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 selector:5; // bit 4:0
|
||||
u16 media_10BT_HD:1; // bit 5
|
||||
u16 media_10BT_FD:1; // bit 6
|
||||
u16 media_100BX_HD:1; // bit 7
|
||||
u16 media_100BX_FD:1; // bit 8
|
||||
u16 media_100BT4:1; // bit 9
|
||||
u16 pause:1; // bit 10
|
||||
u16 asymmetric:1; // bit 11
|
||||
u16 _bit12:1; // bit 12
|
||||
u16 remote_fault:1; // bit 13
|
||||
u16 _bit14:1; // bit 14
|
||||
u16 next_page:1; // bit 15
|
||||
} bits;
|
||||
} ANLPAR_t, *PANLPAR_t;
|
||||
|
||||
enum _mii_anlpar {
|
||||
MII_ANLPAR_NEXT_PAGE = MII_ANAR_NEXT_PAGE,
|
||||
MII_ANLPAR_REMOTE_FAULT = MII_ANAR_REMOTE_FAULT,
|
||||
@ -439,18 +364,6 @@ enum _mii_anlpar {
|
||||
};
|
||||
|
||||
/* Auto-Negotiation Expansion Register */
|
||||
typedef union t_MII_ANER {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 lp_negotiable:1; // bit 0
|
||||
u16 page_received:1; // bit 1
|
||||
u16 nextpagable:1; // bit 2
|
||||
u16 lp_nextpagable:1; // bit 3
|
||||
u16 pdetect_fault:1; // bit 4
|
||||
u16 _bit15_5:11; // bit 15:5
|
||||
} bits;
|
||||
} ANER_t, *PANER_t;
|
||||
|
||||
enum _mii_aner {
|
||||
MII_ANER_PAR_DETECT_FAULT = 0x0010,
|
||||
MII_ANER_LP_NEXTPAGABLE = 0x0008,
|
||||
@ -460,19 +373,6 @@ enum _mii_aner {
|
||||
};
|
||||
|
||||
/* MASTER-SLAVE Control Register */
|
||||
typedef union t_MII_MSCR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 _bit_7_0:8; // bit 7:0
|
||||
u16 media_1000BT_HD:1; // bit 8
|
||||
u16 media_1000BT_FD:1; // bit 9
|
||||
u16 port_type:1; // bit 10
|
||||
u16 cfg_value:1; // bit 11
|
||||
u16 cfg_enable:1; // bit 12
|
||||
u16 test_mode:3; // bit 15:13
|
||||
} bits;
|
||||
} MSCR_t, *PMSCR_t;
|
||||
|
||||
enum _mii_mscr {
|
||||
MII_MSCR_TEST_MODE = 0xe000,
|
||||
MII_MSCR_CFG_ENABLE = 0x1000,
|
||||
@ -483,20 +383,6 @@ enum _mii_mscr {
|
||||
};
|
||||
|
||||
/* MASTER-SLAVE Status Register */
|
||||
typedef union t_MII_MSSR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 idle_err_count:8; // bit 7:0
|
||||
u16 _bit_9_8:2; // bit 9:8
|
||||
u16 lp_1000BT_HD:1; // bit 10
|
||||
u16 lp_1000BT_FD:1; // bit 11
|
||||
u16 remote_rcv_status:1; // bit 12
|
||||
u16 local_rcv_status:1; // bit 13
|
||||
u16 cfg_resolution:1; // bit 14
|
||||
u16 cfg_fault:1; // bit 15
|
||||
} bits;
|
||||
} MSSR_t, *PMSSR_t;
|
||||
|
||||
enum _mii_mssr {
|
||||
MII_MSSR_CFG_FAULT = 0x8000,
|
||||
MII_MSSR_CFG_RES = 0x4000,
|
||||
@ -508,17 +394,6 @@ enum _mii_mssr {
|
||||
};
|
||||
|
||||
/* IEEE Extened Status Register */
|
||||
typedef union t_MII_ESR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 _bit_11_0:12; // bit 11:0
|
||||
u16 media_1000BT_HD:2; // bit 12
|
||||
u16 media_1000BT_FD:1; // bit 13
|
||||
u16 media_1000BX_HD:1; // bit 14
|
||||
u16 media_1000BX_FD:1; // bit 15
|
||||
} bits;
|
||||
} ESR_t, *PESR_t;
|
||||
|
||||
enum _mii_esr {
|
||||
MII_ESR_1000BX_FD = 0x8000,
|
||||
MII_ESR_1000BX_HD = 0x4000,
|
||||
@ -526,6 +401,7 @@ enum _mii_esr {
|
||||
MII_ESR_1000BT_HD = 0x1000,
|
||||
};
|
||||
/* PHY Specific Control Register */
|
||||
#if 0
|
||||
typedef union t_MII_PHY_SCR {
|
||||
u16 image;
|
||||
struct {
|
||||
@ -543,6 +419,7 @@ typedef union t_MII_PHY_SCR {
|
||||
u16 xmit_fifo_depth:2; // bit 15:14
|
||||
} bits;
|
||||
} PHY_SCR_t, *PPHY_SCR_t;
|
||||
#endif
|
||||
|
||||
typedef enum t_MII_ADMIN_STATUS {
|
||||
adm_reset,
|
||||
@ -556,21 +433,6 @@ typedef enum t_MII_ADMIN_STATUS {
|
||||
/* PCS control and status registers bitmap as the same as MII */
|
||||
/* PCS Extended Status register bitmap as the same as MII */
|
||||
/* PCS ANAR */
|
||||
typedef union t_PCS_ANAR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 _bit_4_0:5; // bit 4:0
|
||||
u16 full_duplex:1; // bit 5
|
||||
u16 half_duplex:1; // bit 6
|
||||
u16 asymmetric:1; // bit 7
|
||||
u16 pause:1; // bit 8
|
||||
u16 _bit_11_9:3; // bit 11:9
|
||||
u16 remote_fault:2; // bit 13:12
|
||||
u16 _bit_14:1; // bit 14
|
||||
u16 next_page:1; // bit 15
|
||||
} bits;
|
||||
} ANAR_PCS_t, *PANAR_PCS_t;
|
||||
|
||||
enum _pcs_anar {
|
||||
PCS_ANAR_NEXT_PAGE = 0x8000,
|
||||
PCS_ANAR_REMOTE_FAULT = 0x3000,
|
||||
@ -580,21 +442,6 @@ enum _pcs_anar {
|
||||
PCS_ANAR_FULL_DUPLEX = 0x0020,
|
||||
};
|
||||
/* PCS ANLPAR */
|
||||
typedef union t_PCS_ANLPAR {
|
||||
u16 image;
|
||||
struct {
|
||||
u16 _bit_4_0:5; // bit 4:0
|
||||
u16 full_duplex:1; // bit 5
|
||||
u16 half_duplex:1; // bit 6
|
||||
u16 asymmetric:1; // bit 7
|
||||
u16 pause:1; // bit 8
|
||||
u16 _bit_11_9:3; // bit 11:9
|
||||
u16 remote_fault:2; // bit 13:12
|
||||
u16 _bit_14:1; // bit 14
|
||||
u16 next_page:1; // bit 15
|
||||
} bits;
|
||||
} ANLPAR_PCS_t, *PANLPAR_PCS_t;
|
||||
|
||||
enum _pcs_anlpar {
|
||||
PCS_ANLPAR_NEXT_PAGE = PCS_ANAR_NEXT_PAGE,
|
||||
PCS_ANLPAR_REMOTE_FAULT = PCS_ANAR_REMOTE_FAULT,
|
||||
|
@ -857,21 +857,14 @@ static void init_tfdlist(struct net_device *dev)
|
||||
static void ipg_nic_txfree(struct net_device *dev)
|
||||
{
|
||||
struct ipg_nic_private *sp = netdev_priv(dev);
|
||||
void __iomem *ioaddr = sp->ioaddr;
|
||||
unsigned int curr;
|
||||
u64 txd_map;
|
||||
unsigned int released, pending;
|
||||
|
||||
txd_map = (u64)sp->txd_map;
|
||||
curr = ipg_r32(TFD_LIST_PTR_0) -
|
||||
do_div(txd_map, sizeof(struct ipg_tx)) - 1;
|
||||
unsigned int released, pending, dirty;
|
||||
|
||||
IPG_DEBUG_MSG("_nic_txfree\n");
|
||||
|
||||
pending = sp->tx_current - sp->tx_dirty;
|
||||
dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;
|
||||
|
||||
for (released = 0; released < pending; released++) {
|
||||
unsigned int dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;
|
||||
struct sk_buff *skb = sp->TxBuff[dirty];
|
||||
struct ipg_tx *txfd = sp->txd + dirty;
|
||||
|
||||
@ -882,11 +875,8 @@ static void ipg_nic_txfree(struct net_device *dev)
|
||||
* If the TFDDone bit is set, free the associated
|
||||
* buffer.
|
||||
*/
|
||||
if (dirty == curr)
|
||||
break;
|
||||
|
||||
/* Setup TFDDONE for compatible issue. */
|
||||
txfd->tfc |= cpu_to_le64(IPG_TFC_TFDDONE);
|
||||
if (!(txfd->tfc & cpu_to_le64(IPG_TFC_TFDDONE)))
|
||||
break;
|
||||
|
||||
/* Free the transmit buffer. */
|
||||
if (skb) {
|
||||
@ -898,6 +888,7 @@ static void ipg_nic_txfree(struct net_device *dev)
|
||||
|
||||
sp->TxBuff[dirty] = NULL;
|
||||
}
|
||||
dirty = (dirty + 1) % IPG_TFDLIST_LENGTH;
|
||||
}
|
||||
|
||||
sp->tx_dirty += released;
|
||||
@ -1630,6 +1621,8 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
|
||||
#ifdef JUMBO_FRAME
|
||||
ipg_nic_rxrestore(dev);
|
||||
#endif
|
||||
spin_lock(&sp->lock);
|
||||
|
||||
/* Get interrupt source information, and acknowledge
|
||||
* some (i.e. TxDMAComplete, RxDMAComplete, RxEarly,
|
||||
* IntRequested, MacControlFrame, LinkEvent) interrupts
|
||||
@ -1647,9 +1640,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
|
||||
handled = 1;
|
||||
|
||||
if (unlikely(!netif_running(dev)))
|
||||
goto out;
|
||||
|
||||
spin_lock(&sp->lock);
|
||||
goto out_unlock;
|
||||
|
||||
/* If RFDListEnd interrupt, restore all used RFDs. */
|
||||
if (status & IPG_IS_RFD_LIST_END) {
|
||||
@ -1733,9 +1724,9 @@ out_enable:
|
||||
ipg_w16(IPG_IE_TX_DMA_COMPLETE | IPG_IE_RX_DMA_COMPLETE |
|
||||
IPG_IE_HOST_ERROR | IPG_IE_INT_REQUESTED | IPG_IE_TX_COMPLETE |
|
||||
IPG_IE_LINK_EVENT | IPG_IE_UPDATE_STATS, INT_ENABLE);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&sp->lock);
|
||||
out:
|
||||
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
|
||||
@ -1943,10 +1934,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
*/
|
||||
if (sp->tenmbpsmode)
|
||||
txfd->tfc |= cpu_to_le64(IPG_TFC_TXINDICATE);
|
||||
else if (!((sp->tx_current - sp->tx_dirty + 1) >
|
||||
IPG_FRAMESBETWEENTXDMACOMPLETES)) {
|
||||
txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
|
||||
}
|
||||
txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
|
||||
/* Based on compilation option, determine if FCS is to be
|
||||
* appended to transmit frame by IPG.
|
||||
*/
|
||||
@ -2003,7 +1991,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
ipg_w32(IPG_DC_TX_DMA_POLL_NOW, DMA_CTRL);
|
||||
|
||||
if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH))
|
||||
netif_wake_queue(dev);
|
||||
netif_stop_queue(dev);
|
||||
|
||||
spin_unlock_irqrestore(&sp->lock, flags);
|
||||
|
||||
|
@ -187,14 +187,16 @@ enum Window1 {
|
||||
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 { /* Window 4: Xcvr/media bits. */
|
||||
@ -342,7 +344,7 @@ static int tc574_config(struct pcmcia_device *link)
|
||||
kio_addr_t ioaddr;
|
||||
__be16 *phys_addr;
|
||||
char *cardname;
|
||||
union wn3_config config;
|
||||
__u32 config;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
phys_addr = (__be16 *)dev->dev_addr;
|
||||
@ -401,9 +403,9 @@ static int tc574_config(struct pcmcia_device *link)
|
||||
outw(0<<11, ioaddr + RunnerRdCtrl);
|
||||
printk(KERN_INFO " ASIC rev %d,", mcr>>3);
|
||||
EL3WINDOW(3);
|
||||
config.i = inl(ioaddr + Wn3_Config);
|
||||
lp->default_media = config.u.xcvr;
|
||||
lp->autoselect = config.u.autoselect;
|
||||
config = inl(ioaddr + Wn3_Config);
|
||||
lp->default_media = (config & Xcvr) >> Xcvr_shift;
|
||||
lp->autoselect = config & Autoselect ? 1 : 0;
|
||||
}
|
||||
|
||||
init_timer(&lp->media);
|
||||
@ -464,8 +466,9 @@ static int tc574_config(struct pcmcia_device *link)
|
||||
dev->name, cardname, dev->base_addr, dev->irq,
|
||||
print_mac(mac, dev->dev_addr));
|
||||
printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
|
||||
8 << config.u.ram_size, ram_split[config.u.ram_split],
|
||||
config.u.autoselect ? "autoselect " : "");
|
||||
8 << config & Ram_size,
|
||||
ram_split[(config & Ram_split) >> Ram_split_shift],
|
||||
config & Autoselect ? "autoselect " : "");
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -84,7 +84,7 @@
|
||||
#include "s2io.h"
|
||||
#include "s2io-regs.h"
|
||||
|
||||
#define DRV_VERSION "2.0.26.10"
|
||||
#define DRV_VERSION "2.0.26.17"
|
||||
|
||||
/* S2io Driver name & version. */
|
||||
static char s2io_driver_name[] = "Neterion";
|
||||
@ -3848,8 +3848,6 @@ static int s2io_open(struct net_device *dev)
|
||||
netif_carrier_off(dev);
|
||||
sp->last_link_state = 0;
|
||||
|
||||
napi_enable(&sp->napi);
|
||||
|
||||
if (sp->config.intr_type == MSI_X) {
|
||||
int ret = s2io_enable_msi_x(sp);
|
||||
|
||||
@ -3892,7 +3890,6 @@ static int s2io_open(struct net_device *dev)
|
||||
return 0;
|
||||
|
||||
hw_init_failed:
|
||||
napi_disable(&sp->napi);
|
||||
if (sp->config.intr_type == MSI_X) {
|
||||
if (sp->entries) {
|
||||
kfree(sp->entries);
|
||||
@ -3932,7 +3929,6 @@ static int s2io_close(struct net_device *dev)
|
||||
return 0;
|
||||
|
||||
netif_stop_queue(dev);
|
||||
napi_disable(&sp->napi);
|
||||
/* Reset card, kill tasklet and free Tx and Rx buffers. */
|
||||
s2io_card_down(sp);
|
||||
|
||||
@ -6796,6 +6792,8 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
|
||||
struct XENA_dev_config __iomem *bar0 = sp->bar0;
|
||||
unsigned long flags;
|
||||
register u64 val64 = 0;
|
||||
struct config_param *config;
|
||||
config = &sp->config;
|
||||
|
||||
if (!is_s2io_card_up(sp))
|
||||
return;
|
||||
@ -6807,6 +6805,10 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
|
||||
}
|
||||
clear_bit(__S2IO_STATE_CARD_UP, &sp->state);
|
||||
|
||||
/* Disable napi */
|
||||
if (config->napi)
|
||||
napi_disable(&sp->napi);
|
||||
|
||||
/* disable Tx and Rx traffic on the NIC */
|
||||
if (do_io)
|
||||
stop_nic(sp);
|
||||
@ -6900,6 +6902,11 @@ static int s2io_card_up(struct s2io_nic * sp)
|
||||
DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
|
||||
atomic_read(&sp->rx_bufs_left[i]));
|
||||
}
|
||||
|
||||
/* Initialise napi */
|
||||
if (config->napi)
|
||||
napi_enable(&sp->napi);
|
||||
|
||||
/* Maintain the state prior to the open */
|
||||
if (sp->promisc_flg)
|
||||
sp->promisc_flg = 0;
|
||||
|
@ -3949,7 +3949,7 @@ static __exit void sky2_debug_cleanup(void)
|
||||
/* Initialize network device */
|
||||
static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
|
||||
unsigned port,
|
||||
int highmem)
|
||||
int highmem, int wol)
|
||||
{
|
||||
struct sky2_port *sky2;
|
||||
struct net_device *dev = alloc_etherdev(sizeof(*sky2));
|
||||
@ -3989,7 +3989,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
|
||||
sky2->speed = -1;
|
||||
sky2->advertising = sky2_supported_modes(hw);
|
||||
sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
|
||||
sky2->wol = sky2_wol_supported(hw) & WAKE_MAGIC;
|
||||
sky2->wol = wol;
|
||||
|
||||
spin_lock_init(&sky2->phy_lock);
|
||||
sky2->tx_pending = TX_DEF_PENDING;
|
||||
@ -4086,12 +4086,24 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devinit pci_wake_enabled(struct pci_dev *dev)
|
||||
{
|
||||
int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
|
||||
u16 value;
|
||||
|
||||
if (!pm)
|
||||
return 0;
|
||||
if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value))
|
||||
return 0;
|
||||
return value & PCI_PM_CTRL_PME_ENABLE;
|
||||
}
|
||||
|
||||
static int __devinit sky2_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct sky2_hw *hw;
|
||||
int err, using_dac = 0;
|
||||
int err, using_dac = 0, wol_default;
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err) {
|
||||
@ -4124,6 +4136,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
|
||||
}
|
||||
}
|
||||
|
||||
wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0;
|
||||
|
||||
err = -ENOMEM;
|
||||
hw = kzalloc(sizeof(*hw), GFP_KERNEL);
|
||||
if (!hw) {
|
||||
@ -4167,7 +4181,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
|
||||
|
||||
sky2_reset(hw);
|
||||
|
||||
dev = sky2_init_netdev(hw, 0, using_dac);
|
||||
dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
|
||||
if (!dev) {
|
||||
err = -ENOMEM;
|
||||
goto err_out_free_pci;
|
||||
@ -4204,7 +4218,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
|
||||
if (hw->ports > 1) {
|
||||
struct net_device *dev1;
|
||||
|
||||
dev1 = sky2_init_netdev(hw, 1, using_dac);
|
||||
dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
|
||||
if (!dev1)
|
||||
dev_warn(&pdev->dev, "allocation for second device failed\n");
|
||||
else if ((err = register_netdev(dev1))) {
|
||||
|
@ -139,19 +139,21 @@ struct thingie {
|
||||
};
|
||||
|
||||
struct TxFD {
|
||||
u32 state;
|
||||
u32 next;
|
||||
u32 data;
|
||||
u32 complete;
|
||||
__le32 state;
|
||||
__le32 next;
|
||||
__le32 data;
|
||||
__le32 complete;
|
||||
u32 jiffies; /* Allows sizeof(TxFD) == sizeof(RxFD) + extra hack */
|
||||
/* FWIW, datasheet calls that "dummy" and says that card
|
||||
* never looks at it; neither does the driver */
|
||||
};
|
||||
|
||||
struct RxFD {
|
||||
u32 state1;
|
||||
u32 next;
|
||||
u32 data;
|
||||
u32 state2;
|
||||
u32 end;
|
||||
__le32 state1;
|
||||
__le32 next;
|
||||
__le32 data;
|
||||
__le32 state2;
|
||||
__le32 end;
|
||||
};
|
||||
|
||||
#define DUMMY_SKB_SIZE 64
|
||||
@ -181,7 +183,7 @@ struct RxFD {
|
||||
#define SCC_REG_START(dpriv) (SCC_START+(dpriv->dev_id)*SCC_OFFSET)
|
||||
|
||||
struct dscc4_pci_priv {
|
||||
u32 *iqcfg;
|
||||
__le32 *iqcfg;
|
||||
int cfg_cur;
|
||||
spinlock_t lock;
|
||||
struct pci_dev *pdev;
|
||||
@ -197,8 +199,8 @@ struct dscc4_dev_priv {
|
||||
|
||||
struct RxFD *rx_fd;
|
||||
struct TxFD *tx_fd;
|
||||
u32 *iqrx;
|
||||
u32 *iqtx;
|
||||
__le32 *iqrx;
|
||||
__le32 *iqtx;
|
||||
|
||||
/* FIXME: check all the volatile are required */
|
||||
volatile u32 tx_current;
|
||||
@ -298,7 +300,7 @@ struct dscc4_dev_priv {
|
||||
#define BrrExpMask 0x00000f00
|
||||
#define BrrMultMask 0x0000003f
|
||||
#define EncodingMask 0x00700000
|
||||
#define Hold 0x40000000
|
||||
#define Hold cpu_to_le32(0x40000000)
|
||||
#define SccBusy 0x10000000
|
||||
#define PowerUp 0x80000000
|
||||
#define Vis 0x00001000
|
||||
@ -307,14 +309,14 @@ struct dscc4_dev_priv {
|
||||
#define FrameRdo 0x40
|
||||
#define FrameCrc 0x20
|
||||
#define FrameRab 0x10
|
||||
#define FrameAborted 0x00000200
|
||||
#define FrameEnd 0x80000000
|
||||
#define DataComplete 0x40000000
|
||||
#define FrameAborted cpu_to_le32(0x00000200)
|
||||
#define FrameEnd cpu_to_le32(0x80000000)
|
||||
#define DataComplete cpu_to_le32(0x40000000)
|
||||
#define LengthCheck 0x00008000
|
||||
#define SccEvt 0x02000000
|
||||
#define NoAck 0x00000200
|
||||
#define Action 0x00000001
|
||||
#define HiDesc 0x20000000
|
||||
#define HiDesc cpu_to_le32(0x20000000)
|
||||
|
||||
/* SCC events */
|
||||
#define RxEvt 0xf0000000
|
||||
@ -489,8 +491,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
|
||||
skbuff = dpriv->tx_skbuff;
|
||||
for (i = 0; i < TX_RING_SIZE; i++) {
|
||||
if (*skbuff) {
|
||||
pci_unmap_single(pdev, tx_fd->data, (*skbuff)->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
pci_unmap_single(pdev, le32_to_cpu(tx_fd->data),
|
||||
(*skbuff)->len, PCI_DMA_TODEVICE);
|
||||
dev_kfree_skb(*skbuff);
|
||||
}
|
||||
skbuff++;
|
||||
@ -500,7 +502,7 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
|
||||
skbuff = dpriv->rx_skbuff;
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
if (*skbuff) {
|
||||
pci_unmap_single(pdev, rx_fd->data,
|
||||
pci_unmap_single(pdev, le32_to_cpu(rx_fd->data),
|
||||
RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
|
||||
dev_kfree_skb(*skbuff);
|
||||
}
|
||||
@ -522,10 +524,10 @@ static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
|
||||
dpriv->rx_skbuff[dirty] = skb;
|
||||
if (skb) {
|
||||
skb->protocol = hdlc_type_trans(skb, dev);
|
||||
rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
|
||||
len, PCI_DMA_FROMDEVICE);
|
||||
rx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev,
|
||||
skb->data, len, PCI_DMA_FROMDEVICE));
|
||||
} else {
|
||||
rx_fd->data = (u32) NULL;
|
||||
rx_fd->data = 0;
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -587,7 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
|
||||
|
||||
do {
|
||||
if (!(dpriv->flags & (NeedIDR | NeedIDT)) ||
|
||||
(dpriv->iqtx[cur] & Xpr))
|
||||
(dpriv->iqtx[cur] & cpu_to_le32(Xpr)))
|
||||
break;
|
||||
smp_rmb();
|
||||
schedule_timeout_uninterruptible(10);
|
||||
@ -650,8 +652,9 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
|
||||
printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__);
|
||||
goto refill;
|
||||
}
|
||||
pkt_len = TO_SIZE(rx_fd->state2);
|
||||
pci_unmap_single(pdev, rx_fd->data, RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
|
||||
pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2));
|
||||
pci_unmap_single(pdev, le32_to_cpu(rx_fd->data),
|
||||
RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
|
||||
if ((skb->data[--pkt_len] & FrameOk) == FrameOk) {
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += pkt_len;
|
||||
@ -679,7 +682,7 @@ refill:
|
||||
}
|
||||
dscc4_rx_update(dpriv, dev);
|
||||
rx_fd->state2 = 0x00000000;
|
||||
rx_fd->end = 0xbabeface;
|
||||
rx_fd->end = cpu_to_le32(0xbabeface);
|
||||
}
|
||||
|
||||
static void dscc4_free1(struct pci_dev *pdev)
|
||||
@ -772,8 +775,8 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
|
||||
}
|
||||
/* Global interrupt queue */
|
||||
writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1);
|
||||
priv->iqcfg = (u32 *) pci_alloc_consistent(pdev,
|
||||
IRQ_RING_SIZE*sizeof(u32), &priv->iqcfg_dma);
|
||||
priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev,
|
||||
IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma);
|
||||
if (!priv->iqcfg)
|
||||
goto err_free_irq_5;
|
||||
writel(priv->iqcfg_dma, ioaddr + IQCFG);
|
||||
@ -786,7 +789,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
|
||||
*/
|
||||
for (i = 0; i < dev_per_card; i++) {
|
||||
dpriv = priv->root + i;
|
||||
dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev,
|
||||
dpriv->iqtx = (__le32 *) pci_alloc_consistent(pdev,
|
||||
IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma);
|
||||
if (!dpriv->iqtx)
|
||||
goto err_free_iqtx_6;
|
||||
@ -794,7 +797,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
|
||||
}
|
||||
for (i = 0; i < dev_per_card; i++) {
|
||||
dpriv = priv->root + i;
|
||||
dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev,
|
||||
dpriv->iqrx = (__le32 *) pci_alloc_consistent(pdev,
|
||||
IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma);
|
||||
if (!dpriv->iqrx)
|
||||
goto err_free_iqrx_7;
|
||||
@ -1156,8 +1159,8 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
dpriv->tx_skbuff[next] = skb;
|
||||
tx_fd = dpriv->tx_fd + next;
|
||||
tx_fd->state = FrameEnd | TO_STATE_TX(skb->len);
|
||||
tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
tx_fd->data = cpu_to_le32(pci_map_single(ppriv->pdev, skb->data, skb->len,
|
||||
PCI_DMA_TODEVICE));
|
||||
tx_fd->complete = 0x00000000;
|
||||
tx_fd->jiffies = jiffies;
|
||||
mb();
|
||||
@ -1508,7 +1511,7 @@ static irqreturn_t dscc4_irq(int irq, void *token)
|
||||
if (state & Cfg) {
|
||||
if (debug > 0)
|
||||
printk(KERN_DEBUG "%s: CfgIV\n", DRV_NAME);
|
||||
if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & Arf)
|
||||
if (priv->iqcfg[priv->cfg_cur++%IRQ_RING_SIZE] & cpu_to_le32(Arf))
|
||||
printk(KERN_ERR "%s: %s failed\n", dev->name, "CFG");
|
||||
if (!(state &= ~Cfg))
|
||||
goto out;
|
||||
@ -1541,7 +1544,7 @@ static void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,
|
||||
|
||||
try:
|
||||
cur = dpriv->iqtx_current%IRQ_RING_SIZE;
|
||||
state = dpriv->iqtx[cur];
|
||||
state = le32_to_cpu(dpriv->iqtx[cur]);
|
||||
if (!state) {
|
||||
if (debug > 4)
|
||||
printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name,
|
||||
@ -1580,7 +1583,7 @@ try:
|
||||
tx_fd = dpriv->tx_fd + cur;
|
||||
skb = dpriv->tx_skbuff[cur];
|
||||
if (skb) {
|
||||
pci_unmap_single(ppriv->pdev, tx_fd->data,
|
||||
pci_unmap_single(ppriv->pdev, le32_to_cpu(tx_fd->data),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
if (tx_fd->state & FrameEnd) {
|
||||
stats->tx_packets++;
|
||||
@ -1711,7 +1714,7 @@ static void dscc4_rx_irq(struct dscc4_pci_priv *priv,
|
||||
|
||||
try:
|
||||
cur = dpriv->iqrx_current%IRQ_RING_SIZE;
|
||||
state = dpriv->iqrx[cur];
|
||||
state = le32_to_cpu(dpriv->iqrx[cur]);
|
||||
if (!state)
|
||||
return;
|
||||
dpriv->iqrx[cur] = 0;
|
||||
@ -1755,7 +1758,7 @@ try:
|
||||
goto try;
|
||||
rx_fd->state1 &= ~Hold;
|
||||
rx_fd->state2 = 0x00000000;
|
||||
rx_fd->end = 0xbabeface;
|
||||
rx_fd->end = cpu_to_le32(0xbabeface);
|
||||
//}
|
||||
goto try;
|
||||
}
|
||||
@ -1834,7 +1837,7 @@ try:
|
||||
hdlc_stats(dev)->rx_over_errors++;
|
||||
rx_fd->state1 |= Hold;
|
||||
rx_fd->state2 = 0x00000000;
|
||||
rx_fd->end = 0xbabeface;
|
||||
rx_fd->end = cpu_to_le32(0xbabeface);
|
||||
} else
|
||||
dscc4_rx_skb(dpriv, dev);
|
||||
} while (1);
|
||||
@ -1904,8 +1907,9 @@ static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
|
||||
skb_copy_to_linear_data(skb, version,
|
||||
strlen(version) % DUMMY_SKB_SIZE);
|
||||
tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE);
|
||||
tx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
|
||||
DUMMY_SKB_SIZE, PCI_DMA_TODEVICE);
|
||||
tx_fd->data = cpu_to_le32(pci_map_single(dpriv->pci_priv->pdev,
|
||||
skb->data, DUMMY_SKB_SIZE,
|
||||
PCI_DMA_TODEVICE));
|
||||
dpriv->tx_skbuff[last] = skb;
|
||||
}
|
||||
return skb;
|
||||
@ -1937,8 +1941,8 @@ static int dscc4_init_ring(struct net_device *dev)
|
||||
tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE);
|
||||
tx_fd->complete = 0x00000000;
|
||||
/* FIXME: NULL should be ok - to be tried */
|
||||
tx_fd->data = dpriv->tx_fd_dma;
|
||||
(tx_fd++)->next = (u32)(dpriv->tx_fd_dma +
|
||||
tx_fd->data = cpu_to_le32(dpriv->tx_fd_dma);
|
||||
(tx_fd++)->next = cpu_to_le32(dpriv->tx_fd_dma +
|
||||
(++i%TX_RING_SIZE)*sizeof(*tx_fd));
|
||||
} while (i < TX_RING_SIZE);
|
||||
|
||||
@ -1951,12 +1955,12 @@ static int dscc4_init_ring(struct net_device *dev)
|
||||
/* size set by the host. Multiple of 4 bytes please */
|
||||
rx_fd->state1 = HiDesc;
|
||||
rx_fd->state2 = 0x00000000;
|
||||
rx_fd->end = 0xbabeface;
|
||||
rx_fd->end = cpu_to_le32(0xbabeface);
|
||||
rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU);
|
||||
// FIXME: return value verifiee mais traitement suspect
|
||||
if (try_get_rx_skb(dpriv, dev) >= 0)
|
||||
dpriv->rx_dirty++;
|
||||
(rx_fd++)->next = (u32)(dpriv->rx_fd_dma +
|
||||
(rx_fd++)->next = cpu_to_le32(dpriv->rx_fd_dma +
|
||||
(++i%RX_RING_SIZE)*sizeof(*rx_fd));
|
||||
} while (i < RX_RING_SIZE);
|
||||
|
||||
|
@ -890,16 +890,8 @@ write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v,
|
||||
static void
|
||||
lmc_ssi_watchdog (lmc_softc_t * const sc)
|
||||
{
|
||||
u_int16_t mii17;
|
||||
struct ssicsr2
|
||||
{
|
||||
unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1, led1:1,
|
||||
led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1;
|
||||
};
|
||||
struct ssicsr2 *ssicsr;
|
||||
mii17 = lmc_mii_readreg (sc, 0, 17);
|
||||
ssicsr = (struct ssicsr2 *) &mii17;
|
||||
if (ssicsr->cable == 7)
|
||||
u_int16_t mii17 = lmc_mii_readreg (sc, 0, 17);
|
||||
if (((mii17 >> 3) & 7) == 7)
|
||||
{
|
||||
lmc_led_off (sc, LMC_MII16_LED2);
|
||||
}
|
||||
|
@ -44,9 +44,15 @@ enum {
|
||||
#define PR_RES 0x80
|
||||
|
||||
struct sbni_csr1 {
|
||||
unsigned rxl : 5;
|
||||
unsigned rate : 2;
|
||||
unsigned : 1;
|
||||
#ifdef __LITTLE_ENDIAN_BITFIELD
|
||||
u8 rxl : 5;
|
||||
u8 rate : 2;
|
||||
u8 : 1;
|
||||
#else
|
||||
u8 : 1;
|
||||
u8 rate : 2;
|
||||
u8 rxl : 5;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* fields in frame header */
|
||||
|
@ -138,8 +138,11 @@ void b43_rfkill_init(struct b43_wldev *dev)
|
||||
rfk->rfkill->user_claim_unsupported = 1;
|
||||
|
||||
rfk->poll_dev = input_allocate_polled_device();
|
||||
if (!rfk->poll_dev)
|
||||
goto err_free_rfk;
|
||||
if (!rfk->poll_dev) {
|
||||
rfkill_free(rfk->rfkill);
|
||||
goto err_freed_rfk;
|
||||
}
|
||||
|
||||
rfk->poll_dev->private = dev;
|
||||
rfk->poll_dev->poll = b43_rfkill_poll;
|
||||
rfk->poll_dev->poll_interval = 1000; /* msecs */
|
||||
@ -175,8 +178,7 @@ err_unreg_rfk:
|
||||
err_free_polldev:
|
||||
input_free_polled_device(rfk->poll_dev);
|
||||
rfk->poll_dev = NULL;
|
||||
err_free_rfk:
|
||||
rfkill_free(rfk->rfkill);
|
||||
err_freed_rfk:
|
||||
rfk->rfkill = NULL;
|
||||
out_error:
|
||||
rfk->registered = 0;
|
||||
@ -195,6 +197,5 @@ void b43_rfkill_exit(struct b43_wldev *dev)
|
||||
rfkill_unregister(rfk->rfkill);
|
||||
input_free_polled_device(rfk->poll_dev);
|
||||
rfk->poll_dev = NULL;
|
||||
rfkill_free(rfk->rfkill);
|
||||
rfk->rfkill = NULL;
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ static void prism2_plx_remove(struct pci_dev *pdev)
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
|
||||
|
||||
static struct pci_driver prism2_plx_drv_id = {
|
||||
static struct pci_driver prism2_plx_driver = {
|
||||
.name = "hostap_plx",
|
||||
.id_table = prism2_plx_id_table,
|
||||
.probe = prism2_plx_probe,
|
||||
@ -618,13 +618,13 @@ static struct pci_driver prism2_plx_drv_id = {
|
||||
|
||||
static int __init init_prism2_plx(void)
|
||||
{
|
||||
return pci_register_driver(&prism2_plx_drv_id);
|
||||
return pci_register_driver(&prism2_plx_driver);
|
||||
}
|
||||
|
||||
|
||||
static void __exit exit_prism2_plx(void)
|
||||
{
|
||||
pci_unregister_driver(&prism2_plx_drv_id);
|
||||
pci_unregister_driver(&prism2_plx_driver);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4935,7 +4935,7 @@ static int ipw_queue_reset(struct ipw_priv *priv)
|
||||
/**
|
||||
* Reclaim Tx queue entries no more used by NIC.
|
||||
*
|
||||
* When FW adwances 'R' index, all entries between old and
|
||||
* When FW advances 'R' index, all entries between old and
|
||||
* new 'R' index need to be reclaimed. As result, some free space
|
||||
* forms. If there is enough free space (> low mark), wake Tx queue.
|
||||
*
|
||||
|
@ -871,6 +871,10 @@ static int if_sdio_probe(struct sdio_func *func,
|
||||
if (sscanf(func->card->info[i],
|
||||
"ID: %x", &model) == 1)
|
||||
break;
|
||||
if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
|
||||
model = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == func->card->num_info) {
|
||||
|
@ -149,7 +149,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
|
||||
* The data behind the ieee80211 header must be
|
||||
* aligned on a 4 byte boundary.
|
||||
*/
|
||||
align = NET_IP_ALIGN + (2 * (header_size % 4 == 0));
|
||||
align = header_size % 4;
|
||||
|
||||
/*
|
||||
* Allocate the sk_buffer, initialize it and copy
|
||||
|
@ -245,13 +245,20 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
|
||||
* Allocate a new sk buffer to replace the current one.
|
||||
* If allocation fails, we should drop the current frame
|
||||
* so we can recycle the existing sk buffer for the new frame.
|
||||
* As alignment we use 2 and not NET_IP_ALIGN because we need
|
||||
* to be sure we have 2 bytes room in the head. (NET_IP_ALIGN
|
||||
* can be 0 on some hardware). We use these 2 bytes for frame
|
||||
* alignment later, we assume that the chance that
|
||||
* header_size % 4 == 2 is bigger then header_size % 2 == 0
|
||||
* and thus optimize alignment by reserving the 2 bytes in
|
||||
* advance.
|
||||
*/
|
||||
frame_size = entry->ring->data_size + entry->ring->desc_size;
|
||||
skb = dev_alloc_skb(frame_size + NET_IP_ALIGN);
|
||||
skb = dev_alloc_skb(frame_size + 2);
|
||||
if (!skb)
|
||||
goto skip_entry;
|
||||
|
||||
skb_reserve(skb, NET_IP_ALIGN);
|
||||
skb_reserve(skb, 2);
|
||||
skb_put(skb, frame_size);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user