Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (40 commits)
  r8169: prevent bit sign expansion error in mdio_write
  r8169: revert 7da97ec96a (bis repetita)
  sky2: new pci id's
  ax88796: add superh to kconfig dependencies
  qla3xxx: bugfix: Fix bad logical operation in link state machine.
  qla3xxx: bugfix: Move link state machine into a worker thread
  pasemi_mac: Fix CRC checks
  pasemi_mac: Don't set replace-source-address descriptor bits
  bonding: don't validate address at device open
  bonding: fix rtnl locking merge error
  sky2: netpoll on port 0 only
  b43: Fix kconfig dependencies for rfkill and leds
  b43legacy: Fix sparse warning
  b43: properly request pcmcia IRQ
  b43legacy: fix shared IRQ race condition
  b43: fix shared IRQ race condition
  b43legacy: add me as maintainer and fix URLs
  b43legacy: fix possible buffer overrun in debugfs
  b43: Rewrite and fix rfkill init
  b43: debugfs SHM read buffer overrun fix
  ...
This commit is contained in:
Linus Torvalds 2007-11-10 14:23:56 -08:00
commit 1da63a2131
26 changed files with 286 additions and 230 deletions

View file

@ -787,23 +787,25 @@ B43 WIRELESS DRIVER
P: Michael Buesch P: Michael Buesch
M: mb@bu3sch.de M: mb@bu3sch.de
P: Stefano Brivio P: Stefano Brivio
M: st3@riseup.net M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
W: http://bcm43xx.berlios.de/ W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained S: Maintained
B43LEGACY WIRELESS DRIVER B43LEGACY WIRELESS DRIVER
P: Larry Finger P: Larry Finger
M: Larry.Finger@lwfinger.net M: Larry.Finger@lwfinger.net
P: Stefano Brivio
M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
W: http://bcm43xx.berlios.de/ W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained S: Maintained
BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION) BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION)
P: Larry Finger P: Larry Finger
M: Larry.Finger@lwfinger.net M: Larry.Finger@lwfinger.net
P: Stefano Brivio P: Stefano Brivio
M: st3@riseup.net M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
W: http://bcm43xx.berlios.de/ W: http://bcm43xx.berlios.de/
S: Maintained S: Maintained

View file

@ -235,7 +235,7 @@ source "drivers/net/arm/Kconfig"
config AX88796 config AX88796
tristate "ASIX AX88796 NE2000 clone support" tristate "ASIX AX88796 NE2000 clone support"
depends on ARM || MIPS depends on ARM || MIPS || SUPERH
select CRC32 select CRC32
select MII select MII
help help

View file

@ -4405,6 +4405,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
bond_dev->set_multicast_list = bond_set_multicast_list; bond_dev->set_multicast_list = bond_set_multicast_list;
bond_dev->change_mtu = bond_change_mtu; bond_dev->change_mtu = bond_change_mtu;
bond_dev->set_mac_address = bond_set_mac_address; bond_dev->set_mac_address = bond_set_mac_address;
bond_dev->validate_addr = NULL;
bond_set_mode_ops(bond, bond->params.mode); bond_set_mode_ops(bond, bond->params.mode);

View file

@ -1193,8 +1193,6 @@ static ssize_t bonding_show_active_slave(struct device *d,
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
int count; int count;
rtnl_lock();
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
curr = bond->curr_active_slave; curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
@ -1216,7 +1214,9 @@ static ssize_t bonding_store_active_slave(struct device *d,
struct slave *new_active = NULL; struct slave *new_active = NULL;
struct bonding *bond = to_bond(d); struct bonding *bond = to_bond(d);
rtnl_lock();
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
if (!USES_PRIMARY(bond->params.mode)) { if (!USES_PRIMARY(bond->params.mode)) {
printk(KERN_INFO DRV_NAME printk(KERN_INFO DRV_NAME
": %s: Unable to change active slave; %s is in mode %d\n", ": %s: Unable to change active slave; %s is in mode %d\n",

View file

@ -580,6 +580,16 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
if (macrx & XCT_MACRX_CRC) {
/* CRC error flagged */
mac->netdev->stats.rx_errors++;
mac->netdev->stats.rx_crc_errors++;
dev_kfree_skb_irq(skb);
goto next;
}
if (len < 256) { if (len < 256) {
struct sk_buff *new_skb; struct sk_buff *new_skb;
@ -595,11 +605,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
} else } else
info->skb = NULL; info->skb = NULL;
pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
info->dma = 0; info->dma = 0;
skb_put(skb, len); /* Don't include CRC */
skb_put(skb, len-4);
if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) { if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
@ -614,6 +623,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
skb->protocol = eth_type_trans(skb, mac->netdev); skb->protocol = eth_type_trans(skb, mac->netdev);
netif_receive_skb(skb); netif_receive_skb(skb);
next:
RX_RING(mac, n) = 0; RX_RING(mac, n) = 0;
RX_RING(mac, n+1) = 0; RX_RING(mac, n+1) = 0;
@ -1126,7 +1136,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
unsigned long flags; unsigned long flags;
int i, nfrags; int i, nfrags;
dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD; dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
if (skb->ip_summed == CHECKSUM_PARTIAL) { if (skb->ip_summed == CHECKSUM_PARTIAL) {
const unsigned char *nh = skb_network_header(skb); const unsigned char *nh = skb_network_header(skb);

View file

@ -1456,16 +1456,11 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
PHYAddr[qdev->mac_index]); PHYAddr[qdev->mac_index]);
reg &= ~PHY_GIG_ALL_PARAMS; reg &= ~PHY_GIG_ALL_PARAMS;
if(portConfiguration & if(portConfiguration & PORT_CONFIG_1000MB_SPEED) {
PORT_CONFIG_FULL_DUPLEX_ENABLED & if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED)
PORT_CONFIG_1000MB_SPEED) { reg |= PHY_GIG_ADV_1000F;
reg |= PHY_GIG_ADV_1000F; else
} reg |= PHY_GIG_ADV_1000H;
if(portConfiguration &
PORT_CONFIG_HALF_DUPLEX_ENABLED &
PORT_CONFIG_1000MB_SPEED) {
reg |= PHY_GIG_ADV_1000H;
} }
ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg, ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg,
@ -1645,8 +1640,11 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev)
return 0; return 0;
} }
static void ql_link_state_machine(struct ql3_adapter *qdev) static void ql_link_state_machine_work(struct work_struct *work)
{ {
struct ql3_adapter *qdev =
container_of(work, struct ql3_adapter, link_state_work.work);
u32 curr_link_state; u32 curr_link_state;
unsigned long hw_flags; unsigned long hw_flags;
@ -1661,6 +1659,10 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
"state.\n", qdev->ndev->name); "state.\n", qdev->ndev->name);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
/* Restart timer on 2 second interval. */
mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\
return; return;
} }
@ -1705,6 +1707,9 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
break; break;
} }
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
/* Restart timer on 2 second interval. */
mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
} }
/* /*
@ -3941,19 +3946,7 @@ static void ql_get_board_info(struct ql3_adapter *qdev)
static void ql3xxx_timer(unsigned long ptr) static void ql3xxx_timer(unsigned long ptr)
{ {
struct ql3_adapter *qdev = (struct ql3_adapter *)ptr; struct ql3_adapter *qdev = (struct ql3_adapter *)ptr;
queue_delayed_work(qdev->workqueue, &qdev->link_state_work, 0);
if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) {
printk(KERN_DEBUG PFX
"%s: Reset in progress.\n",
qdev->ndev->name);
goto end;
}
ql_link_state_machine(qdev);
/* Restart timer on 2 second interval. */
end:
mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
} }
static int __devinit ql3xxx_probe(struct pci_dev *pdev, static int __devinit ql3xxx_probe(struct pci_dev *pdev,
@ -4103,6 +4096,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
qdev->workqueue = create_singlethread_workqueue(ndev->name); qdev->workqueue = create_singlethread_workqueue(ndev->name);
INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work); INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work);
INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work); INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work);
INIT_DELAYED_WORK(&qdev->link_state_work, ql_link_state_machine_work);
init_timer(&qdev->adapter_timer); init_timer(&qdev->adapter_timer);
qdev->adapter_timer.function = ql3xxx_timer; qdev->adapter_timer.function = ql3xxx_timer;

View file

@ -1286,6 +1286,7 @@ struct ql3_adapter {
struct workqueue_struct *workqueue; struct workqueue_struct *workqueue;
struct delayed_work reset_work; struct delayed_work reset_work;
struct delayed_work tx_timeout_work; struct delayed_work tx_timeout_work;
struct delayed_work link_state_work;
u32 max_frame_size; u32 max_frame_size;
u32 device_id; u32 device_id;
u16 phyType; u16 phyType;

View file

@ -171,6 +171,8 @@ static struct pci_device_id rtl8169_pci_tbl[] = {
{ PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 },
{ PCI_VENDOR_ID_LINKSYS, 0x1032, { PCI_VENDOR_ID_LINKSYS, 0x1032,
PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
{ 0x0001, 0x8168,
PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 },
{0,}, {0,},
}; };
@ -468,7 +470,7 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{ {
int i; int i;
RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value); RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
for (i = 20; i > 0; i--) { for (i = 20; i > 0; i--) {
/* /*
@ -485,7 +487,7 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
{ {
int i, value = -1; int i, value = -1;
RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16); RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
for (i = 20; i > 0; i--) { for (i = 20; i > 0; i--) {
/* /*
@ -493,7 +495,7 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
* the specified MII register. * the specified MII register.
*/ */
if (RTL_R32(PHYAR) & 0x80000000) { if (RTL_R32(PHYAR) & 0x80000000) {
value = (int) (RTL_R32(PHYAR) & 0xFFFF); value = RTL_R32(PHYAR) & 0xffff;
break; break;
} }
udelay(25); udelay(25);
@ -1245,16 +1247,6 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
} }
static void rtl8168b_hw_phy_config(void __iomem *ioaddr)
{
struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0000 },
{ 0x10, 0xf41b },
{ 0x1f, 0x0000 }
};
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
static void rtl8168cp_hw_phy_config(void __iomem *ioaddr) static void rtl8168cp_hw_phy_config(void __iomem *ioaddr)
{ {
@ -1324,11 +1316,6 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_04: case RTL_GIGA_MAC_VER_04:
rtl8169sb_hw_phy_config(ioaddr); rtl8169sb_hw_phy_config(ioaddr);
break; break;
case RTL_GIGA_MAC_VER_11:
case RTL_GIGA_MAC_VER_12:
case RTL_GIGA_MAC_VER_17:
rtl8168b_hw_phy_config(ioaddr);
break;
case RTL_GIGA_MAC_VER_18: case RTL_GIGA_MAC_VER_18:
rtl8168cp_hw_phy_config(ioaddr); rtl8168cp_hw_phy_config(ioaddr);
break; break;
@ -1739,7 +1726,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->features |= rtl_try_msi(pdev, ioaddr, cfg); tp->features |= rtl_try_msi(pdev, ioaddr, cfg);
RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W8(Cfg9346, Cfg9346_Lock);
if (RTL_R8(PHYstatus) & TBI_Enable) { if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) &&
(RTL_R8(PHYstatus) & TBI_Enable)) {
tp->set_speed = rtl8169_set_speed_tbi; tp->set_speed = rtl8169_set_speed_tbi;
tp->get_settings = rtl8169_gset_tbi; tp->get_settings = rtl8169_gset_tbi;
tp->phy_reset_enable = rtl8169_tbi_reset_enable; tp->phy_reset_enable = rtl8169_tbi_reset_enable;

View file

@ -52,7 +52,7 @@
#include "sky2.h" #include "sky2.h"
#define DRV_NAME "sky2" #define DRV_NAME "sky2"
#define DRV_VERSION "1.19" #define DRV_VERSION "1.20"
#define PFX DRV_NAME " " #define PFX DRV_NAME " "
/* /*
@ -121,6 +121,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
@ -134,6 +135,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
{ 0 } { 0 }
}; };
@ -156,7 +158,7 @@ static const char *yukon2_name[] = {
static void sky2_set_multicast(struct net_device *dev); static void sky2_set_multicast(struct net_device *dev);
/* Access to external PHY */ /* Access to PHY via serial interconnect */
static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
{ {
int i; int i;
@ -166,13 +168,22 @@ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg)); GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
for (i = 0; i < PHY_RETRIES; i++) { for (i = 0; i < PHY_RETRIES; i++) {
if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
if (ctrl == 0xffff)
goto io_error;
if (!(ctrl & GM_SMI_CT_BUSY))
return 0; return 0;
udelay(1);
udelay(10);
} }
printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name); dev_warn(&hw->pdev->dev,"%s: phy write timeout\n", hw->dev[port]->name);
return -ETIMEDOUT; return -ETIMEDOUT;
io_error:
dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
return -EIO;
} }
static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val) static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
@ -183,23 +194,29 @@ static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
| GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
for (i = 0; i < PHY_RETRIES; i++) { for (i = 0; i < PHY_RETRIES; i++) {
if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) { u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
if (ctrl == 0xffff)
goto io_error;
if (ctrl & GM_SMI_CT_RD_VAL) {
*val = gma_read16(hw, port, GM_SMI_DATA); *val = gma_read16(hw, port, GM_SMI_DATA);
return 0; return 0;
} }
udelay(1); udelay(10);
} }
dev_warn(&hw->pdev->dev, "%s: phy read timeout\n", hw->dev[port]->name);
return -ETIMEDOUT; return -ETIMEDOUT;
io_error:
dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
return -EIO;
} }
static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
{ {
u16 v; u16 v;
__gm_phy_read(hw, port, reg, &v);
if (__gm_phy_read(hw, port, reg, &v) != 0)
printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
return v; return v;
} }
@ -273,8 +290,6 @@ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
/* disable all GMAC IRQ's */ /* disable all GMAC IRQ's */
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
/* disable PHY IRQs */
gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */
gma_write16(hw, port, GM_MC_ADDR_H2, 0); gma_write16(hw, port, GM_MC_ADDR_H2, 0);
@ -1805,29 +1820,6 @@ static void sky2_link_up(struct sky2_port *sky2)
sky2_write8(hw, SK_REG(port, LNK_LED_REG), sky2_write8(hw, SK_REG(port, LNK_LED_REG),
LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
if (hw->flags & SKY2_HW_NEWER_PHY) {
u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */
switch(sky2->speed) {
case SPEED_10:
led |= PHY_M_LEDC_INIT_CTRL(7);
break;
case SPEED_100:
led |= PHY_M_LEDC_STA1_CTRL(7);
break;
case SPEED_1000:
led |= PHY_M_LEDC_STA0_CTRL(7);
break;
}
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
}
if (netif_msg_link(sky2)) if (netif_msg_link(sky2))
printk(KERN_INFO PFX printk(KERN_INFO PFX
"%s: Link is up at %d Mbps, %s duplex, flow control %s\n", "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
@ -2247,20 +2239,26 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
do { do {
struct sky2_port *sky2; struct sky2_port *sky2;
struct sky2_status_le *le = hw->st_le + hw->st_idx; struct sky2_status_le *le = hw->st_le + hw->st_idx;
unsigned port = le->css & CSS_LINK_BIT; unsigned port;
struct net_device *dev; struct net_device *dev;
struct sk_buff *skb; struct sk_buff *skb;
u32 status; u32 status;
u16 length; u16 length;
u8 opcode = le->opcode;
if (!(opcode & HW_OWNER))
break;
hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
port = le->css & CSS_LINK_BIT;
dev = hw->dev[port]; dev = hw->dev[port];
sky2 = netdev_priv(dev); sky2 = netdev_priv(dev);
length = le16_to_cpu(le->length); length = le16_to_cpu(le->length);
status = le32_to_cpu(le->status); status = le32_to_cpu(le->status);
switch (le->opcode & ~HW_OWNER) { le->opcode = 0;
switch (opcode & ~HW_OWNER) {
case OP_RXSTAT: case OP_RXSTAT:
++rx[port]; ++rx[port];
skb = sky2_receive(dev, length, status); skb = sky2_receive(dev, length, status);
@ -2353,7 +2351,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
default: default:
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_WARNING PFX printk(KERN_WARNING PFX
"unknown status opcode 0x%x\n", le->opcode); "unknown status opcode 0x%x\n", opcode);
} }
} while (hw->st_idx != idx); } while (hw->st_idx != idx);
@ -2439,13 +2437,26 @@ static void sky2_hw_intr(struct sky2_hw *hw)
if (status & Y2_IS_PCI_EXP) { if (status & Y2_IS_PCI_EXP) {
/* PCI-Express uncorrectable Error occurred */ /* PCI-Express uncorrectable Error occurred */
int pos = pci_find_aer_capability(hw->pdev); int aer = pci_find_aer_capability(hw->pdev);
u32 err; u32 err;
pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err); if (aer) {
pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS,
&err);
pci_cleanup_aer_uncorrect_error_status(pdev);
} else {
/* Either AER not configured, or not working
* because of bad MMCONFIG, so just do recover
* manually.
*/
err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
0xfffffffful);
}
if (net_ratelimit()) if (net_ratelimit())
dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
pci_cleanup_aer_uncorrect_error_status(pdev);
} }
if (status & Y2_HWE_L1_MASK) if (status & Y2_HWE_L1_MASK)
@ -2791,6 +2802,9 @@ static void sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, B0_CTST, CS_RST_SET); sky2_write8(hw, B0_CTST, CS_RST_SET);
sky2_write8(hw, B0_CTST, CS_RST_CLR); sky2_write8(hw, B0_CTST, CS_RST_CLR);
/* allow writes to PCI config */
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
/* clear PCI errors, if any */ /* clear PCI errors, if any */
pci_read_config_word(pdev, PCI_STATUS, &status); pci_read_config_word(pdev, PCI_STATUS, &status);
status |= PCI_STATUS_ERROR_BITS; status |= PCI_STATUS_ERROR_BITS;
@ -2800,9 +2814,18 @@ static void sky2_reset(struct sky2_hw *hw)
cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (cap) { if (cap) {
/* Check for advanced error reporting */ if (pci_find_aer_capability(pdev)) {
pci_cleanup_aer_uncorrect_error_status(pdev); /* Check for advanced error reporting */
pci_cleanup_aer_correct_error_status(pdev); pci_cleanup_aer_uncorrect_error_status(pdev);
pci_cleanup_aer_correct_error_status(pdev);
} else {
dev_warn(&pdev->dev,
"PCI Express Advanced Error Reporting"
" not configured or MMCONFIG problem?\n");
sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
0xfffffffful);
}
/* If error bit is stuck on ignore it */ /* If error bit is stuck on ignore it */
if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP) if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
@ -3974,7 +3997,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
dev->tx_timeout = sky2_tx_timeout; dev->tx_timeout = sky2_tx_timeout;
dev->watchdog_timeo = TX_WATCHDOG; dev->watchdog_timeo = TX_WATCHDOG;
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = sky2_netpoll; if (port == 0)
dev->poll_controller = sky2_netpoll;
#endif #endif
sky2 = netdev_priv(dev); sky2 = netdev_priv(dev);

View file

@ -247,7 +247,8 @@ enum csr_regs {
B3_PA_CTRL = 0x01f0, B3_PA_CTRL = 0x01f0,
B3_PA_TEST = 0x01f2, B3_PA_TEST = 0x01f2,
Y2_CFG_SPC = 0x1c00, Y2_CFG_SPC = 0x1c00, /* PCI config space region */
Y2_CFG_AER = 0x1d00, /* PCI Advanced Error Report region */
}; };
/* B0_CTST 16 bit Control/Status register */ /* B0_CTST 16 bit Control/Status register */

View file

@ -224,6 +224,21 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
} }
} }
#elif defined(CONFIG_MACH_ZYLONITE)
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
#define SMC_USE_PXA_DMA 1
#define SMC_inb(a, r) readb((a) + (r))
#define SMC_inw(a, r) readw((a) + (r))
#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
#define SMC_outb(v, a, r) writeb(v, (a) + (r))
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#elif defined(CONFIG_ARCH_OMAP) #elif defined(CONFIG_ARCH_OMAP)
/* We can only do 16-bit reads and writes in the static memory space. */ /* We can only do 16-bit reads and writes in the static memory space. */

View file

@ -325,7 +325,7 @@ config HERMES
Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya, Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
PRO/Wireless, and Symbol Spectrum24 High Rate amongst others. IPW2011, and Symbol Spectrum24 High Rate amongst others.
This option includes the guts of the driver, but in order to This option includes the guts of the driver, but in order to
actually use a card you will also need to enable support for PCMCIA actually use a card you will also need to enable support for PCMCIA

View file

@ -61,16 +61,18 @@ config B43_PCMCIA
If unsure, say N. If unsure, say N.
# LED support # This config option automatically enables b43 LEDS support,
# if it's possible.
config B43_LEDS config B43_LEDS
bool bool
depends on B43 && MAC80211_LEDS depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43)
default y default y
# RFKILL support # This config option automatically enables b43 RFKILL support,
# if it's possible.
config B43_RFKILL config B43_RFKILL
bool bool
depends on B43 && RFKILL && RFKILL_INPUT && INPUT_POLLDEV depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43)
default y default y
config B43_DEBUG config B43_DEBUG

View file

@ -128,7 +128,7 @@ static ssize_t shm_read_file(struct b43_wldev *dev,
__le16 *le16buf = (__le16 *)buf; __le16 *le16buf = (__le16 *)buf;
for (i = 0; i < 0x1000; i++) { for (i = 0; i < 0x1000; i++) {
if (bufsize <= 0) if (bufsize < sizeof(tmp))
break; break;
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i); tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i);
le16buf[i] = cpu_to_le16(tmp); le16buf[i] = cpu_to_le16(tmp);

View file

@ -2985,6 +2985,16 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
if (b43_status(dev) < B43_STAT_STARTED) if (b43_status(dev) < B43_STAT_STARTED)
return; return;
/* Disable and sync interrupts. We must do this before than
* setting the status to INITIALIZED, as the interrupt handler
* won't care about IRQs then. */
spin_lock_irqsave(&wl->irq_lock, flags);
dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43_synchronize_irq(dev);
b43_set_status(dev, B43_STAT_INITIALIZED); b43_set_status(dev, B43_STAT_INITIALIZED);
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
@ -2995,13 +3005,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy. ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy.
/* Disable and sync interrupts. */
spin_lock_irqsave(&wl->irq_lock, flags);
dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43_synchronize_irq(dev);
b43_mac_suspend(dev); b43_mac_suspend(dev);
free_irq(dev->dev->irq, dev); free_irq(dev->dev->irq, dev);
b43dbg(wl, "Wireless interface stopped\n"); b43dbg(wl, "Wireless interface stopped\n");
@ -3661,7 +3664,6 @@ static int b43_setup_modes(struct b43_wldev *dev,
static void b43_wireless_core_detach(struct b43_wldev *dev) static void b43_wireless_core_detach(struct b43_wldev *dev)
{ {
b43_rfkill_free(dev);
/* We release firmware that late to not be required to re-request /* We release firmware that late to not be required to re-request
* is all the time when we reinit the core. */ * is all the time when we reinit the core. */
b43_release_firmware(dev); b43_release_firmware(dev);
@ -3747,7 +3749,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
if (!wl->current_dev) if (!wl->current_dev)
wl->current_dev = dev; wl->current_dev = dev;
INIT_WORK(&dev->restart_work, b43_chip_reset); INIT_WORK(&dev->restart_work, b43_chip_reset);
b43_rfkill_alloc(dev);
b43_radio_turn_off(dev, 1); b43_radio_turn_off(dev, 1);
b43_switch_analog(dev, 0); b43_switch_analog(dev, 0);

View file

@ -65,12 +65,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
tuple_t tuple; tuple_t tuple;
cisparse_t parse; cisparse_t parse;
int err = -ENOMEM; int err = -ENOMEM;
int res; int res = 0;
unsigned char buf[64]; unsigned char buf[64];
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb) if (!ssb)
goto out; goto out_error;
err = -ENODEV; err = -ENODEV;
tuple.DesiredTuple = CISTPL_CONFIG; tuple.DesiredTuple = CISTPL_CONFIG;
@ -96,10 +96,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
dev->io.NumPorts2 = 0; dev->io.NumPorts2 = 0;
dev->io.Attributes2 = 0; dev->io.Attributes2 = 0;
win.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
WIN_ENABLE | WIN_DATA_WIDTH_16 |
WIN_USE_WAIT;
win.Base = 0; win.Base = 0;
win.Size = SSB_CORE_SIZE; win.Size = SSB_CORE_SIZE;
win.AccessSpeed = 1000; win.AccessSpeed = 250;
res = pcmcia_request_window(&dev, &win, &dev->win); res = pcmcia_request_window(&dev, &win, &dev->win);
if (res != CS_SUCCESS) if (res != CS_SUCCESS)
goto err_kfree_ssb; goto err_kfree_ssb;
@ -108,21 +110,34 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
mem.Page = 0; mem.Page = 0;
res = pcmcia_map_mem_page(dev->win, &mem); res = pcmcia_map_mem_page(dev->win, &mem);
if (res != CS_SUCCESS) if (res != CS_SUCCESS)
goto err_kfree_ssb; goto err_disable;
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
dev->irq.Handler = NULL; /* The handler is registered later. */
dev->irq.Instance = NULL;
res = pcmcia_request_irq(dev, &dev->irq);
if (res != CS_SUCCESS)
goto err_disable;
res = pcmcia_request_configuration(dev, &dev->conf); res = pcmcia_request_configuration(dev, &dev->conf);
if (res != CS_SUCCESS) if (res != CS_SUCCESS)
goto err_disable; goto err_disable;
err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
if (err)
goto err_disable;
dev->priv = ssb; dev->priv = ssb;
out: return 0;
return err;
err_disable: err_disable:
pcmcia_disable_device(dev); pcmcia_disable_device(dev);
err_kfree_ssb: err_kfree_ssb:
kfree(ssb); kfree(ssb);
out_error:
printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
res, err);
return err; return err;
} }
@ -131,22 +146,21 @@ static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
struct ssb_bus *ssb = dev->priv; struct ssb_bus *ssb = dev->priv;
ssb_bus_unregister(ssb); ssb_bus_unregister(ssb);
pcmcia_release_window(dev->win);
pcmcia_disable_device(dev); pcmcia_disable_device(dev);
kfree(ssb); kfree(ssb);
dev->priv = NULL; dev->priv = NULL;
} }
static struct pcmcia_driver b43_pcmcia_driver = { static struct pcmcia_driver b43_pcmcia_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .drv = {
.name = "b43-pcmcia", .name = "b43-pcmcia",
}, },
.id_table = b43_pcmcia_tbl, .id_table = b43_pcmcia_tbl,
.probe = b43_pcmcia_probe, .probe = b43_pcmcia_probe,
.remove = b43_pcmcia_remove, .remove = __devexit_p(b43_pcmcia_remove),
.suspend = b43_pcmcia_suspend, .suspend = b43_pcmcia_suspend,
.resume = b43_pcmcia_resume, .resume = b43_pcmcia_resume,
}; };
int b43_pcmcia_init(void) int b43_pcmcia_init(void)

View file

@ -47,32 +47,35 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
struct b43_wldev *dev = poll_dev->private; struct b43_wldev *dev = poll_dev->private;
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
bool enabled; bool enabled;
bool report_change = 0;
mutex_lock(&wl->mutex); mutex_lock(&wl->mutex);
B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED); B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
enabled = b43_is_hw_radio_enabled(dev); enabled = b43_is_hw_radio_enabled(dev);
if (unlikely(enabled != dev->radio_hw_enable)) { if (unlikely(enabled != dev->radio_hw_enable)) {
dev->radio_hw_enable = enabled; dev->radio_hw_enable = enabled;
report_change = 1;
b43info(wl, "Radio hardware status changed to %s\n", b43info(wl, "Radio hardware status changed to %s\n",
enabled ? "ENABLED" : "DISABLED"); enabled ? "ENABLED" : "DISABLED");
mutex_unlock(&wl->mutex); }
mutex_unlock(&wl->mutex);
if (unlikely(report_change))
input_report_key(poll_dev->input, KEY_WLAN, enabled); input_report_key(poll_dev->input, KEY_WLAN, enabled);
} else
mutex_unlock(&wl->mutex);
} }
/* Called when the RFKILL toggled in software. /* Called when the RFKILL toggled in software. */
* This is called without locking. */
static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
{ {
struct b43_wldev *dev = data; struct b43_wldev *dev = data;
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
int err = 0; int err = 0;
mutex_lock(&wl->mutex); if (!wl->rfkill.registered)
if (b43_status(dev) < B43_STAT_INITIALIZED) return 0;
goto out_unlock;
mutex_lock(&wl->mutex);
B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
switch (state) { switch (state) {
case RFKILL_STATE_ON: case RFKILL_STATE_ON:
if (!dev->radio_hw_enable) { if (!dev->radio_hw_enable) {
@ -89,7 +92,6 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
b43_radio_turn_off(dev, 0); b43_radio_turn_off(dev, 0);
break; break;
} }
out_unlock: out_unlock:
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
@ -98,11 +100,11 @@ out_unlock:
char * b43_rfkill_led_name(struct b43_wldev *dev) char * b43_rfkill_led_name(struct b43_wldev *dev)
{ {
struct b43_wl *wl = dev->wl; struct b43_rfkill *rfk = &(dev->wl->rfkill);
if (!wl->rfkill.rfkill) if (!rfk->registered)
return NULL; return NULL;
return rfkill_get_led_name(wl->rfkill.rfkill); return rfkill_get_led_name(rfk->rfkill);
} }
void b43_rfkill_init(struct b43_wldev *dev) void b43_rfkill_init(struct b43_wldev *dev)
@ -111,53 +113,13 @@ void b43_rfkill_init(struct b43_wldev *dev)
struct b43_rfkill *rfk = &(wl->rfkill); struct b43_rfkill *rfk = &(wl->rfkill);
int err; int err;
if (rfk->rfkill) { rfk->registered = 0;
err = rfkill_register(rfk->rfkill);
if (err) {
b43warn(wl, "Failed to register RF-kill button\n");
goto err_free_rfk;
}
}
if (rfk->poll_dev) {
err = input_register_polled_device(rfk->poll_dev);
if (err) {
b43warn(wl, "Failed to register RF-kill polldev\n");
goto err_free_polldev;
}
}
return;
err_free_rfk:
rfkill_free(rfk->rfkill);
rfk->rfkill = NULL;
err_free_polldev:
input_free_polled_device(rfk->poll_dev);
rfk->poll_dev = NULL;
}
void b43_rfkill_exit(struct b43_wldev *dev)
{
struct b43_rfkill *rfk = &(dev->wl->rfkill);
if (rfk->poll_dev)
input_unregister_polled_device(rfk->poll_dev);
if (rfk->rfkill)
rfkill_unregister(rfk->rfkill);
}
void b43_rfkill_alloc(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
struct b43_rfkill *rfk = &(wl->rfkill);
snprintf(rfk->name, sizeof(rfk->name),
"b43-%s", wiphy_name(wl->hw->wiphy));
rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
if (!rfk->rfkill) { if (!rfk->rfkill)
b43warn(wl, "Failed to allocate RF-kill button\n"); goto out_error;
return; snprintf(rfk->name, sizeof(rfk->name),
} "b43-%s", wiphy_name(wl->hw->wiphy));
rfk->rfkill->name = rfk->name; rfk->rfkill->name = rfk->name;
rfk->rfkill->state = RFKILL_STATE_ON; rfk->rfkill->state = RFKILL_STATE_ON;
rfk->rfkill->data = dev; rfk->rfkill->data = dev;
@ -165,18 +127,45 @@ void b43_rfkill_alloc(struct b43_wldev *dev)
rfk->rfkill->user_claim_unsupported = 1; rfk->rfkill->user_claim_unsupported = 1;
rfk->poll_dev = input_allocate_polled_device(); rfk->poll_dev = input_allocate_polled_device();
if (rfk->poll_dev) { if (!rfk->poll_dev)
rfk->poll_dev->private = dev; goto err_free_rfk;
rfk->poll_dev->poll = b43_rfkill_poll; rfk->poll_dev->private = dev;
rfk->poll_dev->poll_interval = 1000; /* msecs */ rfk->poll_dev->poll = b43_rfkill_poll;
} else rfk->poll_dev->poll_interval = 1000; /* msecs */
b43warn(wl, "Failed to allocate RF-kill polldev\n");
err = rfkill_register(rfk->rfkill);
if (err)
goto err_free_polldev;
err = input_register_polled_device(rfk->poll_dev);
if (err)
goto err_unreg_rfk;
rfk->registered = 1;
return;
err_unreg_rfk:
rfkill_unregister(rfk->rfkill);
err_free_polldev:
input_free_polled_device(rfk->poll_dev);
rfk->poll_dev = NULL;
err_free_rfk:
rfkill_free(rfk->rfkill);
rfk->rfkill = NULL;
out_error:
rfk->registered = 0;
b43warn(wl, "RF-kill button init failed\n");
} }
void b43_rfkill_free(struct b43_wldev *dev) void b43_rfkill_exit(struct b43_wldev *dev)
{ {
struct b43_rfkill *rfk = &(dev->wl->rfkill); struct b43_rfkill *rfk = &(dev->wl->rfkill);
if (!rfk->registered)
return;
rfk->registered = 0;
input_unregister_polled_device(rfk->poll_dev);
rfkill_unregister(rfk->rfkill);
input_free_polled_device(rfk->poll_dev); input_free_polled_device(rfk->poll_dev);
rfk->poll_dev = NULL; rfk->poll_dev = NULL;
rfkill_free(rfk->rfkill); rfkill_free(rfk->rfkill);

View file

@ -15,14 +15,14 @@ struct b43_rfkill {
struct rfkill *rfkill; struct rfkill *rfkill;
/* The poll device for the RFKILL input button */ /* The poll device for the RFKILL input button */
struct input_polled_dev *poll_dev; struct input_polled_dev *poll_dev;
/* Did initialization succeed? Used for freeing. */
bool registered;
/* The unique name of this rfkill switch */ /* The unique name of this rfkill switch */
char name[32]; char name[sizeof("b43-phy4294967295")];
}; };
/* All the init functions return void, because we are not interested /* The init function returns void, because we are not interested
* in failing the b43 init process when rfkill init failed. */ * in failing the b43 init process when rfkill init failed. */
void b43_rfkill_alloc(struct b43_wldev *dev);
void b43_rfkill_free(struct b43_wldev *dev);
void b43_rfkill_init(struct b43_wldev *dev); void b43_rfkill_init(struct b43_wldev *dev);
void b43_rfkill_exit(struct b43_wldev *dev); void b43_rfkill_exit(struct b43_wldev *dev);
@ -36,12 +36,6 @@ struct b43_rfkill {
/* empty */ /* empty */
}; };
static inline void b43_rfkill_alloc(struct b43_wldev *dev)
{
}
static inline void b43_rfkill_free(struct b43_wldev *dev)
{
}
static inline void b43_rfkill_init(struct b43_wldev *dev) static inline void b43_rfkill_init(struct b43_wldev *dev)
{ {
} }

View file

@ -124,7 +124,7 @@ static ssize_t shm_read_file(struct b43legacy_wldev *dev, char *buf, size_t bufs
__le16 *le16buf = (__le16 *)buf; __le16 *le16buf = (__le16 *)buf;
for (i = 0; i < 0x1000; i++) { for (i = 0; i < 0x1000; i++) {
if (bufsize <= 0) if (bufsize < sizeof(tmp))
break; break;
tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, 2 * i); tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, 2 * i);
le16buf[i] = cpu_to_le16(tmp); le16buf[i] = cpu_to_le16(tmp);

View file

@ -2781,6 +2781,17 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
if (b43legacy_status(dev) < B43legacy_STAT_STARTED) if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
return; return;
/* Disable and sync interrupts. We must do this before than
* setting the status to INITIALIZED, as the interrupt handler
* won't care about IRQs then. */
spin_lock_irqsave(&wl->irq_lock, flags);
dev->irq_savedstate = b43legacy_interrupt_disable(dev,
B43legacy_IRQ_ALL);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43legacy_synchronize_irq(dev);
b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
@ -2791,14 +2802,6 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */ ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */
/* Disable and sync interrupts. */
spin_lock_irqsave(&wl->irq_lock, flags);
dev->irq_savedstate = b43legacy_interrupt_disable(dev,
B43legacy_IRQ_ALL);
b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43legacy_synchronize_irq(dev);
b43legacy_mac_suspend(dev); b43legacy_mac_suspend(dev);
free_irq(dev->dev->irq, dev); free_irq(dev->dev->irq, dev);
b43legacydbg(wl, "Wireless interface stopped\n"); b43legacydbg(wl, "Wireless interface stopped\n");
@ -3332,7 +3335,7 @@ out_mutex_unlock:
return err; return err;
} }
void b43legacy_stop(struct ieee80211_hw *hw) static void b43legacy_stop(struct ieee80211_hw *hw)
{ {
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev = wl->current_dev; struct b43legacy_wldev *dev = wl->current_dev;

View file

@ -444,7 +444,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_pci_id_table); MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
static struct pci_driver prism2_pci_drv_id = { static struct pci_driver prism2_pci_driver = {
.name = "hostap_pci", .name = "hostap_pci",
.id_table = prism2_pci_id_table, .id_table = prism2_pci_id_table,
.probe = prism2_pci_probe, .probe = prism2_pci_probe,
@ -458,13 +458,13 @@ static struct pci_driver prism2_pci_drv_id = {
static int __init init_prism2_pci(void) static int __init init_prism2_pci(void)
{ {
return pci_register_driver(&prism2_pci_drv_id); return pci_register_driver(&prism2_pci_driver);
} }
static void __exit exit_prism2_pci(void) static void __exit exit_prism2_pci(void)
{ {
pci_unregister_driver(&prism2_pci_drv_id); pci_unregister_driver(&prism2_pci_driver);
} }

View file

@ -1267,7 +1267,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
IPW2100_INTA_FATAL_ERROR | IPW2100_INTA_FATAL_ERROR |
IPW2100_INTA_PARITY_ERROR); IPW2100_INTA_PARITY_ERROR);
} }
} while (i--); } while (--i);
/* Clear out any pending INTAs since we aren't supposed to have /* Clear out any pending INTAs since we aren't supposed to have
* interrupts enabled at this point... */ * interrupts enabled at this point... */
@ -1339,7 +1339,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
break; break;
} while (i--); } while (--i);
priv->status &= ~STATUS_RESET_PENDING; priv->status &= ~STATUS_RESET_PENDING;

View file

@ -912,6 +912,10 @@ static int wlan_cmd_set_boot2_ver(wlan_private * priv,
return 0; return 0;
} }
/*
* Note: NEVER use libertas_queue_cmd() with addtail==0 other than for
* the command timer, because it does not account for queued commands.
*/
void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail) void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
{ {
unsigned long flags; unsigned long flags;
@ -941,10 +945,11 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
spin_lock_irqsave(&adapter->driver_lock, flags); spin_lock_irqsave(&adapter->driver_lock, flags);
if (addtail) if (addtail) {
list_add_tail((struct list_head *)cmdnode, list_add_tail((struct list_head *)cmdnode,
&adapter->cmdpendingq); &adapter->cmdpendingq);
else adapter->nr_cmd_pending++;
} else
list_add((struct list_head *)cmdnode, &adapter->cmdpendingq); list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
spin_unlock_irqrestore(&adapter->driver_lock, flags); spin_unlock_irqrestore(&adapter->driver_lock, flags);
@ -1412,7 +1417,6 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdnode->cmdwaitqwoken = 0; cmdnode->cmdwaitqwoken = 0;
libertas_queue_cmd(adapter, cmdnode, 1); libertas_queue_cmd(adapter, cmdnode, 1);
adapter->nr_cmd_pending++;
wake_up_interruptible(&priv->waitq); wake_up_interruptible(&priv->waitq);
if (wait_option & CMD_OPTION_WAITFORRSP) { if (wait_option & CMD_OPTION_WAITFORRSP) {

View file

@ -148,11 +148,11 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
{ {
int i; int i;
for (i = 0; i < 500; i++) { for (i = 0; i < 1000; i++) {
u8 val = if_cs_read8(card, addr); u8 val = if_cs_read8(card, addr);
if (val == reg) if (val == reg)
return i; return i;
udelay(100); udelay(500);
} }
return -ETIME; return -ETIME;
} }
@ -878,6 +878,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
goto out3; goto out3;
} }
/* Clear any interrupt cause that happend while sending
* firmware/initializing card */
if_cs_write16(card, IF_CS_C_INT_CAUSE, IF_CS_C_IC_MASK);
if_cs_enable_ints(card); if_cs_enable_ints(card);
/* And finally bring the card up */ /* And finally bring the card up */

View file

@ -182,12 +182,14 @@ static int if_sdio_handle_data(struct if_sdio_card *card,
goto out; goto out;
} }
skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + NET_IP_ALIGN);
if (!skb) { if (!skb) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
skb_reserve(skb, NET_IP_ALIGN);
data = skb_put(skb, size); data = skb_put(skb, size);
memcpy(data, buffer, size); memcpy(data, buffer, size);

View file

@ -196,6 +196,14 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_dev *rt2x00dev = hw->priv;
struct interface *intf = &rt2x00dev->interface; struct interface *intf = &rt2x00dev->interface;
/* FIXME: Beaconing is broken in rt2x00. */
if (conf->type == IEEE80211_IF_TYPE_IBSS ||
conf->type == IEEE80211_IF_TYPE_AP) {
ERROR(rt2x00dev,
"rt2x00 does not support Adhoc or Master mode");
return -EOPNOTSUPP;
}
/* /*
* Don't allow interfaces to be added while * Don't allow interfaces to be added while
* either the device has disappeared or when * either the device has disappeared or when