aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcm43xx
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-12-03 23:59:07 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-03 23:59:07 -0500
commit79acbb3ff2d8095b692e1502b9eb2ccec348de26 (patch)
tree6ab773e5a8f9de2cd6443362b21d0d6fffe3b35e /drivers/net/wireless/bcm43xx
parent19a79859e168640f8e16d7b216d211c1c52b687a (diff)
parent2b5f6dcce5bf94b9b119e9ed8d537098ec61c3d2 (diff)
Merge branch 'linux-2.6' into for-linus
Diffstat (limited to 'drivers/net/wireless/bcm43xx')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h32
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.c28
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h18
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c9
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.h6
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c279
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.c28
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c6
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c18
9 files changed, 276 insertions, 148 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index d6a8bf09878e..94dfb92fab5c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -159,6 +159,7 @@
159 159
160/* Chipcommon registers. */ 160/* Chipcommon registers. */
161#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 161#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
162#define BCM43xx_CHIPCOMMON_CTL 0x28
162#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 163#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
163#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 164#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
164#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 165#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
@@ -172,6 +173,33 @@
172/* SBTOPCI2 values. */ 173/* SBTOPCI2 values. */
173#define BCM43xx_SBTOPCI2_PREFETCH 0x4 174#define BCM43xx_SBTOPCI2_PREFETCH 0x4
174#define BCM43xx_SBTOPCI2_BURST 0x8 175#define BCM43xx_SBTOPCI2_BURST 0x8
176#define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20
177
178/* PCI-E core registers. */
179#define BCM43xx_PCIECORE_REG_ADDR 0x0130
180#define BCM43xx_PCIECORE_REG_DATA 0x0134
181#define BCM43xx_PCIECORE_MDIO_CTL 0x0128
182#define BCM43xx_PCIECORE_MDIO_DATA 0x012C
183
184/* PCI-E registers. */
185#define BCM43xx_PCIE_TLP_WORKAROUND 0x0004
186#define BCM43xx_PCIE_DLLP_LINKCTL 0x0100
187
188/* PCI-E MDIO bits. */
189#define BCM43xx_PCIE_MDIO_ST 0x40000000
190#define BCM43xx_PCIE_MDIO_WT 0x10000000
191#define BCM43xx_PCIE_MDIO_DEV 22
192#define BCM43xx_PCIE_MDIO_REG 18
193#define BCM43xx_PCIE_MDIO_TA 0x00020000
194#define BCM43xx_PCIE_MDIO_TC 0x0100
195
196/* MDIO devices. */
197#define BCM43xx_MDIO_SERDES_RX 0x1F
198
199/* SERDES RX registers. */
200#define BCM43xx_SERDES_RXTIMER 0x2
201#define BCM43xx_SERDES_CDR 0x6
202#define BCM43xx_SERDES_CDR_BW 0x7
175 203
176/* Chipcommon capabilities. */ 204/* Chipcommon capabilities. */
177#define BCM43xx_CAPABILITIES_PCTL 0x00040000 205#define BCM43xx_CAPABILITIES_PCTL 0x00040000
@@ -221,6 +249,7 @@
221#define BCM43xx_COREID_USB20_HOST 0x819 249#define BCM43xx_COREID_USB20_HOST 0x819
222#define BCM43xx_COREID_USB20_DEV 0x81a 250#define BCM43xx_COREID_USB20_DEV 0x81a
223#define BCM43xx_COREID_SDIO_HOST 0x81b 251#define BCM43xx_COREID_SDIO_HOST 0x81b
252#define BCM43xx_COREID_PCIE 0x820
224 253
225/* Core Information Registers */ 254/* Core Information Registers */
226#define BCM43xx_CIR_BASE 0xf00 255#define BCM43xx_CIR_BASE 0xf00
@@ -365,6 +394,9 @@
365#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7 394#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
366#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4 395#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
367 396
397/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
398#define RX_RSSI_MAX 60
399
368/* Max size of a security key */ 400/* Max size of a security key */
369#define BCM43xx_SEC_KEYSIZE 16 401#define BCM43xx_SEC_KEYSIZE 16
370/* Security algorithms. */ 402/* Security algorithms. */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index 76e3aed4b471..978ed099e285 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -705,11 +705,30 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
705 struct bcm43xx_dmaring *ring; 705 struct bcm43xx_dmaring *ring;
706 int err = -ENOMEM; 706 int err = -ENOMEM;
707 int dma64 = 0; 707 int dma64 = 0;
708 u32 sbtmstatehi; 708 u64 mask = bcm43xx_get_supported_dma_mask(bcm);
709 int nobits;
709 710
710 sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); 711 if (mask == DMA_64BIT_MASK) {
711 if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
712 dma64 = 1; 712 dma64 = 1;
713 nobits = 64;
714 } else if (mask == DMA_32BIT_MASK)
715 nobits = 32;
716 else
717 nobits = 30;
718 err = pci_set_dma_mask(bcm->pci_dev, mask);
719 err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
720 if (err) {
721#ifdef CONFIG_BCM43XX_PIO
722 printk(KERN_WARNING PFX "DMA not supported on this device."
723 " Falling back to PIO.\n");
724 bcm->__using_pio = 1;
725 return -ENOSYS;
726#else
727 printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
728 "Please recompile the driver with PIO support.\n");
729 return -ENODEV;
730#endif /* CONFIG_BCM43XX_PIO */
731 }
713 732
714 /* setup TX DMA channels. */ 733 /* setup TX DMA channels. */
715 ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); 734 ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@@ -755,8 +774,7 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
755 dma->rx_ring3 = ring; 774 dma->rx_ring3 = ring;
756 } 775 }
757 776
758 dprintk(KERN_INFO PFX "%s DMA initialized\n", 777 dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
759 dma64 ? "64-bit" : "32-bit");
760 err = 0; 778 err = 0;
761out: 779out:
762 return err; 780 return err;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
index e04bcaddd1d0..d1105e569a41 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -4,6 +4,7 @@
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/spinlock.h> 5#include <linux/spinlock.h>
6#include <linux/workqueue.h> 6#include <linux/workqueue.h>
7#include <linux/dma-mapping.h>
7#include <linux/linkage.h> 8#include <linux/linkage.h>
8#include <asm/atomic.h> 9#include <asm/atomic.h>
9 10
@@ -314,6 +315,23 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
314 struct ieee80211_txb *txb); 315 struct ieee80211_txb *txb);
315void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); 316void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
316 317
318/* Helper function that returns the dma mask for this device. */
319static inline
320u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm)
321{
322 int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) &
323 BCM43xx_SBTMSTATEHIGH_DMA64BIT;
324 u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0);
325 u32 mask = BCM43xx_DMA32_TXADDREXT_MASK;
326
327 if (dma64)
328 return DMA_64BIT_MASK;
329 bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask);
330 if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask)
331 return DMA_32BIT_MASK;
332 return DMA_30BIT_MASK;
333}
334
317#else /* CONFIG_BCM43XX_DMA */ 335#else /* CONFIG_BCM43XX_DMA */
318 336
319 337
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index c3f90c8563d9..7d383a27b927 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -189,20 +189,24 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
189 case BCM43xx_LED_INACTIVE: 189 case BCM43xx_LED_INACTIVE:
190 continue; 190 continue;
191 case BCM43xx_LED_OFF: 191 case BCM43xx_LED_OFF:
192 case BCM43xx_LED_BCM4303_3:
192 break; 193 break;
193 case BCM43xx_LED_ON: 194 case BCM43xx_LED_ON:
194 turn_on = 1; 195 turn_on = 1;
195 break; 196 break;
196 case BCM43xx_LED_ACTIVITY: 197 case BCM43xx_LED_ACTIVITY:
198 case BCM43xx_LED_BCM4303_0:
197 turn_on = activity; 199 turn_on = activity;
198 break; 200 break;
199 case BCM43xx_LED_RADIO_ALL: 201 case BCM43xx_LED_RADIO_ALL:
200 turn_on = radio->enabled; 202 turn_on = radio->enabled;
201 break; 203 break;
202 case BCM43xx_LED_RADIO_A: 204 case BCM43xx_LED_RADIO_A:
205 case BCM43xx_LED_BCM4303_2:
203 turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); 206 turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A);
204 break; 207 break;
205 case BCM43xx_LED_RADIO_B: 208 case BCM43xx_LED_RADIO_B:
209 case BCM43xx_LED_BCM4303_1:
206 turn_on = (radio->enabled && 210 turn_on = (radio->enabled &&
207 (phy->type == BCM43xx_PHYTYPE_B || 211 (phy->type == BCM43xx_PHYTYPE_B ||
208 phy->type == BCM43xx_PHYTYPE_G)); 212 phy->type == BCM43xx_PHYTYPE_G));
@@ -242,7 +246,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
242 //TODO 246 //TODO
243 break; 247 break;
244 case BCM43xx_LED_ASSOC: 248 case BCM43xx_LED_ASSOC:
245 if (bcm->softmac->associated) 249 if (bcm->softmac->associnfo.associated)
246 turn_on = 1; 250 turn_on = 1;
247 break; 251 break;
248#ifdef CONFIG_BCM43XX_DEBUG 252#ifdef CONFIG_BCM43XX_DEBUG
@@ -257,7 +261,8 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
257 continue; 261 continue;
258#endif /* CONFIG_BCM43XX_DEBUG */ 262#endif /* CONFIG_BCM43XX_DEBUG */
259 default: 263 default:
260 assert(0); 264 dprintkl(KERN_INFO PFX "Bad value in leds_update,"
265 " led->behaviour: 0x%x\n", led->behaviour);
261 }; 266 };
262 267
263 if (led->activelow) 268 if (led->activelow)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
index d3716cf3aebc..811e14a81198 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
@@ -46,6 +46,12 @@ enum { /* LED behaviour values */
46 BCM43xx_LED_TEST_BLINKSLOW, 46 BCM43xx_LED_TEST_BLINKSLOW,
47 BCM43xx_LED_TEST_BLINKMEDIUM, 47 BCM43xx_LED_TEST_BLINKMEDIUM,
48 BCM43xx_LED_TEST_BLINKFAST, 48 BCM43xx_LED_TEST_BLINKFAST,
49
50 /* Misc values for BCM4303 */
51 BCM43xx_LED_BCM4303_0 = 0x2B,
52 BCM43xx_LED_BCM4303_1 = 0x78,
53 BCM43xx_LED_BCM4303_2 = 0x2E,
54 BCM43xx_LED_BCM4303_3 = 0x19,
49}; 55};
50 56
51int bcm43xx_leds_init(struct bcm43xx_private *bcm); 57int bcm43xx_leds_init(struct bcm43xx_private *bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index bad3452ea893..5b3c27359a18 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -130,6 +130,10 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
130 { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 130 { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
131 /* Broadcom 4307 802.11b */ 131 /* Broadcom 4307 802.11b */
132 { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 132 { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133 /* Broadcom 4311 802.11(a)/b/g */
134 { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135 /* Broadcom 4312 802.11a/b/g */
136 { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133 /* Broadcom 4318 802.11b/g */ 137 /* Broadcom 4318 802.11b/g */
134 { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 138 { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135 /* Broadcom 4319 802.11a/b/g */ 139 /* Broadcom 4319 802.11a/b/g */
@@ -746,7 +750,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
746 if (err) 750 if (err)
747 goto err_ctlreg; 751 goto err_ctlreg;
748 spromctl |= 0x10; /* SPROM WRITE enable. */ 752 spromctl |= 0x10; /* SPROM WRITE enable. */
749 bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); 753 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
750 if (err) 754 if (err)
751 goto err_ctlreg; 755 goto err_ctlreg;
752 /* We must burn lots of CPU cycles here, but that does not 756 /* We must burn lots of CPU cycles here, but that does not
@@ -768,7 +772,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
768 mdelay(20); 772 mdelay(20);
769 } 773 }
770 spromctl &= ~0x10; /* SPROM WRITE enable. */ 774 spromctl &= ~0x10; /* SPROM WRITE enable. */
771 bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); 775 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
772 if (err) 776 if (err)
773 goto err_ctlreg; 777 goto err_ctlreg;
774 mdelay(500); 778 mdelay(500);
@@ -1463,6 +1467,23 @@ static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1463 } 1467 }
1464} 1468}
1465 1469
1470static void drain_txstatus_queue(struct bcm43xx_private *bcm)
1471{
1472 u32 dummy;
1473
1474 if (bcm->current_core->rev < 5)
1475 return;
1476 /* Read all entries from the microcode TXstatus FIFO
1477 * and throw them away.
1478 */
1479 while (1) {
1480 dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1481 if (!dummy)
1482 break;
1483 dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1484 }
1485}
1486
1466static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) 1487static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
1467{ 1488{
1468 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); 1489 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
@@ -2583,8 +2604,9 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2583 /* fetch sb_id_hi from core information registers */ 2604 /* fetch sb_id_hi from core information registers */
2584 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); 2605 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2585 2606
2586 core_id = (sb_id_hi & 0xFFF0) >> 4; 2607 core_id = (sb_id_hi & 0x8FF0) >> 4;
2587 core_rev = (sb_id_hi & 0xF); 2608 core_rev = (sb_id_hi & 0x7000) >> 8;
2609 core_rev |= (sb_id_hi & 0xF);
2588 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; 2610 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2589 2611
2590 /* if present, chipcommon is always core 0; read the chipid from it */ 2612 /* if present, chipcommon is always core 0; read the chipid from it */
@@ -2662,14 +2684,10 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2662 bcm->chip_id, bcm->chip_rev); 2684 bcm->chip_id, bcm->chip_rev);
2663 dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count); 2685 dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2664 if (bcm->core_chipcommon.available) { 2686 if (bcm->core_chipcommon.available) {
2665 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", 2687 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x\n",
2666 core_id, core_rev, core_vendor, 2688 core_id, core_rev, core_vendor);
2667 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled");
2668 }
2669
2670 if (bcm->core_chipcommon.available)
2671 current_core = 1; 2689 current_core = 1;
2672 else 2690 } else
2673 current_core = 0; 2691 current_core = 0;
2674 for ( ; current_core < core_count; current_core++) { 2692 for ( ; current_core < core_count; current_core++) {
2675 struct bcm43xx_coreinfo *core; 2693 struct bcm43xx_coreinfo *core;
@@ -2687,13 +2705,13 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2687 core_rev = (sb_id_hi & 0xF); 2705 core_rev = (sb_id_hi & 0xF);
2688 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; 2706 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2689 2707
2690 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", 2708 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x\n",
2691 current_core, core_id, core_rev, core_vendor, 2709 current_core, core_id, core_rev, core_vendor);
2692 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" );
2693 2710
2694 core = NULL; 2711 core = NULL;
2695 switch (core_id) { 2712 switch (core_id) {
2696 case BCM43xx_COREID_PCI: 2713 case BCM43xx_COREID_PCI:
2714 case BCM43xx_COREID_PCIE:
2697 core = &bcm->core_pci; 2715 core = &bcm->core_pci;
2698 if (core->available) { 2716 if (core->available) {
2699 printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); 2717 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
@@ -2732,12 +2750,12 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2732 case 6: 2750 case 6:
2733 case 7: 2751 case 7:
2734 case 9: 2752 case 9:
2753 case 10:
2735 break; 2754 break;
2736 default: 2755 default:
2737 printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n", 2756 printk(KERN_WARNING PFX
2757 "Unsupported 80211 core revision %u\n",
2738 core_rev); 2758 core_rev);
2739 err = -ENODEV;
2740 goto out;
2741 } 2759 }
2742 bcm->nr_80211_available++; 2760 bcm->nr_80211_available++;
2743 core->priv = ext_80211; 2761 core->priv = ext_80211;
@@ -2851,16 +2869,11 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2851 u32 sbimconfiglow; 2869 u32 sbimconfiglow;
2852 u8 limit; 2870 u8 limit;
2853 2871
2854 if (bcm->chip_rev < 5) { 2872 if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
2855 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); 2873 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
2856 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; 2874 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
2857 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; 2875 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
2858 if (bcm->bustype == BCM43xx_BUSTYPE_PCI) 2876 sbimconfiglow |= 0x32;
2859 sbimconfiglow |= 0x32;
2860 else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
2861 sbimconfiglow |= 0x53;
2862 else
2863 assert(0);
2864 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); 2877 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
2865 } 2878 }
2866 2879
@@ -2925,10 +2938,13 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2925 bcm43xx_write16(bcm, 0x043C, 0x000C); 2938 bcm43xx_write16(bcm, 0x043C, 0x000C);
2926 2939
2927 if (active_wlcore) { 2940 if (active_wlcore) {
2928 if (bcm43xx_using_pio(bcm)) 2941 if (bcm43xx_using_pio(bcm)) {
2929 err = bcm43xx_pio_init(bcm); 2942 err = bcm43xx_pio_init(bcm);
2930 else 2943 } else {
2931 err = bcm43xx_dma_init(bcm); 2944 err = bcm43xx_dma_init(bcm);
2945 if (err == -ENOSYS)
2946 err = bcm43xx_pio_init(bcm);
2947 }
2932 if (err) 2948 if (err)
2933 goto err_chip_cleanup; 2949 goto err_chip_cleanup;
2934 } 2950 }
@@ -2984,22 +3000,64 @@ static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
2984 3000
2985static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) 3001static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
2986{ 3002{
2987 int err; 3003 int err = 0;
2988 struct bcm43xx_coreinfo *old_core;
2989 3004
2990 old_core = bcm->current_core; 3005 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
2991 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2992 if (err)
2993 goto out;
2994 3006
2995 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); 3007 if (bcm->core_chipcommon.available) {
3008 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
3009 if (err)
3010 goto out;
3011
3012 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3013
3014 /* this function is always called when a PCI core is mapped */
3015 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3016 if (err)
3017 goto out;
3018 } else
3019 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3020
3021 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
2996 3022
2997 bcm43xx_switch_core(bcm, old_core);
2998 assert(err == 0);
2999out: 3023out:
3000 return err; 3024 return err;
3001} 3025}
3002 3026
3027static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
3028{
3029 bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
3030 return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
3031}
3032
3033static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
3034 u32 data)
3035{
3036 bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
3037 bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
3038}
3039
3040static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
3041 u16 data)
3042{
3043 int i;
3044
3045 bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
3046 bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
3047 BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
3048 (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
3049 data);
3050 udelay(10);
3051
3052 for (i = 0; i < 10; i++) {
3053 if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
3054 BCM43xx_PCIE_MDIO_TC)
3055 break;
3056 msleep(1);
3057 }
3058 bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
3059}
3060
3003/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. 3061/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
3004 * To enable core 0, pass a core_mask of 1<<0 3062 * To enable core 0, pass a core_mask of 1<<0
3005 */ 3063 */
@@ -3019,7 +3077,8 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
3019 if (err) 3077 if (err)
3020 goto out; 3078 goto out;
3021 3079
3022 if (bcm->core_pci.rev < 6) { 3080 if (bcm->current_core->rev < 6 ||
3081 bcm->current_core->id == BCM43xx_COREID_PCI) {
3023 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); 3082 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
3024 value |= (1 << backplane_flag_nr); 3083 value |= (1 << backplane_flag_nr);
3025 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); 3084 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
@@ -3037,21 +3096,46 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
3037 } 3096 }
3038 } 3097 }
3039 3098
3040 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); 3099 if (bcm->current_core->id == BCM43xx_COREID_PCI) {
3041 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; 3100 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3042 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); 3101 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3043 3102 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3044 if (bcm->core_pci.rev < 5) { 3103
3045 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); 3104 if (bcm->current_core->rev < 5) {
3046 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) 3105 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3047 & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; 3106 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3048 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) 3107 & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3049 & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; 3108 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3050 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); 3109 & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3051 err = bcm43xx_pcicore_commit_settings(bcm); 3110 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3052 assert(err == 0); 3111 err = bcm43xx_pcicore_commit_settings(bcm);
3112 assert(err == 0);
3113 } else if (bcm->current_core->rev >= 11) {
3114 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3115 value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
3116 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3117 }
3118 } else {
3119 if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
3120 value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
3121 value |= 0x8;
3122 bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
3123 value);
3124 }
3125 if (bcm->current_core->rev == 0) {
3126 bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3127 BCM43xx_SERDES_RXTIMER, 0x8128);
3128 bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3129 BCM43xx_SERDES_CDR, 0x0100);
3130 bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3131 BCM43xx_SERDES_CDR_BW, 0x1466);
3132 } else if (bcm->current_core->rev == 1) {
3133 value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
3134 value |= 0x40;
3135 bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
3136 value);
3137 }
3053 } 3138 }
3054
3055out_switch_back: 3139out_switch_back:
3056 err = bcm43xx_switch_core(bcm, old_core); 3140 err = bcm43xx_switch_core(bcm, old_core);
3057out: 3141out:
@@ -3120,57 +3204,42 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3120 3204
3121static void do_periodic_work(struct bcm43xx_private *bcm) 3205static void do_periodic_work(struct bcm43xx_private *bcm)
3122{ 3206{
3123 unsigned int state; 3207 if (bcm->periodic_state % 8 == 0)
3124
3125 state = bcm->periodic_state;
3126 if (state % 8 == 0)
3127 bcm43xx_periodic_every120sec(bcm); 3208 bcm43xx_periodic_every120sec(bcm);
3128 if (state % 4 == 0) 3209 if (bcm->periodic_state % 4 == 0)
3129 bcm43xx_periodic_every60sec(bcm); 3210 bcm43xx_periodic_every60sec(bcm);
3130 if (state % 2 == 0) 3211 if (bcm->periodic_state % 2 == 0)
3131 bcm43xx_periodic_every30sec(bcm); 3212 bcm43xx_periodic_every30sec(bcm);
3132 if (state % 1 == 0) 3213 bcm43xx_periodic_every15sec(bcm);
3133 bcm43xx_periodic_every15sec(bcm);
3134 bcm->periodic_state = state + 1;
3135 3214
3136 schedule_delayed_work(&bcm->periodic_work, HZ * 15); 3215 schedule_delayed_work(&bcm->periodic_work, HZ * 15);
3137} 3216}
3138 3217
3139/* Estimate a "Badness" value based on the periodic work
3140 * state-machine state. "Badness" is worse (bigger), if the
3141 * periodic work will take longer.
3142 */
3143static int estimate_periodic_work_badness(unsigned int state)
3144{
3145 int badness = 0;
3146
3147 if (state % 8 == 0) /* every 120 sec */
3148 badness += 10;
3149 if (state % 4 == 0) /* every 60 sec */
3150 badness += 5;
3151 if (state % 2 == 0) /* every 30 sec */
3152 badness += 1;
3153 if (state % 1 == 0) /* every 15 sec */
3154 badness += 1;
3155
3156#define BADNESS_LIMIT 4
3157 return badness;
3158}
3159
3160static void bcm43xx_periodic_work_handler(void *d) 3218static void bcm43xx_periodic_work_handler(void *d)
3161{ 3219{
3162 struct bcm43xx_private *bcm = d; 3220 struct bcm43xx_private *bcm = d;
3221 struct net_device *net_dev = bcm->net_dev;
3163 unsigned long flags; 3222 unsigned long flags;
3164 u32 savedirqs = 0; 3223 u32 savedirqs = 0;
3165 int badness; 3224 unsigned long orig_trans_start = 0;
3166 3225
3167 badness = estimate_periodic_work_badness(bcm->periodic_state); 3226 mutex_lock(&bcm->mutex);
3168 if (badness > BADNESS_LIMIT) { 3227 if (unlikely(bcm->periodic_state % 4 == 0)) {
3169 /* Periodic work will take a long time, so we want it to 3228 /* Periodic work will take a long time, so we want it to
3170 * be preemtible. 3229 * be preemtible.
3171 */ 3230 */
3172 mutex_lock(&bcm->mutex); 3231
3173 netif_tx_disable(bcm->net_dev); 3232 netif_tx_lock_bh(net_dev);
3233 /* We must fake a started transmission here, as we are going to
3234 * disable TX. If we wouldn't fake a TX, it would be possible to
3235 * trigger the netdev watchdog, if the last real TX is already
3236 * some time on the past (slightly less than 5secs)
3237 */
3238 orig_trans_start = net_dev->trans_start;
3239 net_dev->trans_start = jiffies;
3240 netif_stop_queue(net_dev);
3241 netif_tx_unlock_bh(net_dev);
3242
3174 spin_lock_irqsave(&bcm->irq_lock, flags); 3243 spin_lock_irqsave(&bcm->irq_lock, flags);
3175 bcm43xx_mac_suspend(bcm); 3244 bcm43xx_mac_suspend(bcm);
3176 if (bcm43xx_using_pio(bcm)) 3245 if (bcm43xx_using_pio(bcm))
@@ -3182,13 +3251,12 @@ static void bcm43xx_periodic_work_handler(void *d)
3182 /* Periodic work should take short time, so we want low 3251 /* Periodic work should take short time, so we want low
3183 * locking overhead. 3252 * locking overhead.
3184 */ 3253 */
3185 mutex_lock(&bcm->mutex);
3186 spin_lock_irqsave(&bcm->irq_lock, flags); 3254 spin_lock_irqsave(&bcm->irq_lock, flags);
3187 } 3255 }
3188 3256
3189 do_periodic_work(bcm); 3257 do_periodic_work(bcm);
3190 3258
3191 if (badness > BADNESS_LIMIT) { 3259 if (unlikely(bcm->periodic_state % 4 == 0)) {
3192 spin_lock_irqsave(&bcm->irq_lock, flags); 3260 spin_lock_irqsave(&bcm->irq_lock, flags);
3193 tasklet_enable(&bcm->isr_tasklet); 3261 tasklet_enable(&bcm->isr_tasklet);
3194 bcm43xx_interrupt_enable(bcm, savedirqs); 3262 bcm43xx_interrupt_enable(bcm, savedirqs);
@@ -3196,8 +3264,10 @@ static void bcm43xx_periodic_work_handler(void *d)
3196 bcm43xx_pio_thaw_txqueues(bcm); 3264 bcm43xx_pio_thaw_txqueues(bcm);
3197 bcm43xx_mac_enable(bcm); 3265 bcm43xx_mac_enable(bcm);
3198 netif_wake_queue(bcm->net_dev); 3266 netif_wake_queue(bcm->net_dev);
3267 net_dev->trans_start = orig_trans_start;
3199 } 3268 }
3200 mmiowb(); 3269 mmiowb();
3270 bcm->periodic_state++;
3201 spin_unlock_irqrestore(&bcm->irq_lock, flags); 3271 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3202 mutex_unlock(&bcm->mutex); 3272 mutex_unlock(&bcm->mutex);
3203} 3273}
@@ -3516,6 +3586,7 @@ int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
3516 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); 3586 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3517 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); 3587 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3518 bcm43xx_security_init(bcm); 3588 bcm43xx_security_init(bcm);
3589 drain_txstatus_queue(bcm);
3519 ieee80211softmac_start(bcm->net_dev); 3590 ieee80211softmac_start(bcm->net_dev);
3520 3591
3521 /* Let's go! Be careful after enabling the IRQs. 3592 /* Let's go! Be careful after enabling the IRQs.
@@ -3642,7 +3713,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3642 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; 3713 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3643 break; 3714 break;
3644 case BCM43xx_PHYTYPE_G: 3715 case BCM43xx_PHYTYPE_G:
3645 if (phy_rev > 7) 3716 if (phy_rev > 8)
3646 phy_rev_ok = 0; 3717 phy_rev_ok = 0;
3647 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | 3718 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3648 IEEE80211_CCK_MODULATION; 3719 IEEE80211_CCK_MODULATION;
@@ -3654,6 +3725,8 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3654 phy_type); 3725 phy_type);
3655 return -ENODEV; 3726 return -ENODEV;
3656 }; 3727 };
3728 bcm->ieee->perfect_rssi = RX_RSSI_MAX;
3729 bcm->ieee->worst_rssi = 0;
3657 if (!phy_rev_ok) { 3730 if (!phy_rev_ok) {
3658 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n", 3731 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3659 phy_rev); 3732 phy_rev);
@@ -3940,11 +4013,6 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3940 return NETDEV_TX_OK; 4013 return NETDEV_TX_OK;
3941} 4014}
3942 4015
3943static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
3944{
3945 return &(bcm43xx_priv(net_dev)->ieee->stats);
3946}
3947
3948static void bcm43xx_net_tx_timeout(struct net_device *net_dev) 4016static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3949{ 4017{
3950 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 4018 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
@@ -3993,8 +4061,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3993 struct net_device *net_dev, 4061 struct net_device *net_dev,
3994 struct pci_dev *pci_dev) 4062 struct pci_dev *pci_dev)
3995{ 4063{
3996 int err;
3997
3998 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); 4064 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3999 bcm->ieee = netdev_priv(net_dev); 4065 bcm->ieee = netdev_priv(net_dev);
4000 bcm->softmac = ieee80211_priv(net_dev); 4066 bcm->softmac = ieee80211_priv(net_dev);
@@ -4012,22 +4078,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
4012 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 4078 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
4013 (unsigned long)bcm); 4079 (unsigned long)bcm);
4014 tasklet_disable_nosync(&bcm->isr_tasklet); 4080 tasklet_disable_nosync(&bcm->isr_tasklet);
4015 if (modparam_pio) { 4081 if (modparam_pio)
4016 bcm->__using_pio = 1; 4082 bcm->__using_pio = 1;
4017 } else {
4018 err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
4019 err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
4020 if (err) {
4021#ifdef CONFIG_BCM43XX_PIO
4022 printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
4023 bcm->__using_pio = 1;
4024#else
4025 printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
4026 "Recompile the driver with PIO support, please.\n");
4027 return -ENODEV;
4028#endif /* CONFIG_BCM43XX_PIO */
4029 }
4030 }
4031 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; 4083 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
4032 4084
4033 /* default to sw encryption for now */ 4085 /* default to sw encryption for now */
@@ -4074,7 +4126,6 @@ static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
4074 4126
4075 net_dev->open = bcm43xx_net_open; 4127 net_dev->open = bcm43xx_net_open;
4076 net_dev->stop = bcm43xx_net_stop; 4128 net_dev->stop = bcm43xx_net_stop;
4077 net_dev->get_stats = bcm43xx_net_get_stats;
4078 net_dev->tx_timeout = bcm43xx_net_tx_timeout; 4129 net_dev->tx_timeout = bcm43xx_net_tx_timeout;
4079#ifdef CONFIG_NET_POLL_CONTROLLER 4130#ifdef CONFIG_NET_POLL_CONTROLLER
4080 net_dev->poll_controller = bcm43xx_net_poll_controller; 4131 net_dev->poll_controller = bcm43xx_net_poll_controller;
@@ -4208,7 +4259,11 @@ static int bcm43xx_resume(struct pci_dev *pdev)
4208 dprintk(KERN_INFO PFX "Resuming...\n"); 4259 dprintk(KERN_INFO PFX "Resuming...\n");
4209 4260
4210 pci_set_power_state(pdev, 0); 4261 pci_set_power_state(pdev, 0);
4211 pci_enable_device(pdev); 4262 err = pci_enable_device(pdev);
4263 if (err) {
4264 printk(KERN_ERR PFX "Failure with pci_enable_device!\n");
4265 return err;
4266 }
4212 pci_restore_state(pdev); 4267 pci_restore_state(pdev);
4213 4268
4214 bcm43xx_chipset_attach(bcm); 4269 bcm43xx_chipset_attach(bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
index 6569da3a7a39..7e774f410953 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
@@ -153,8 +153,6 @@ int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
153 int err, maxfreq; 153 int err, maxfreq;
154 struct bcm43xx_coreinfo *old_core; 154 struct bcm43xx_coreinfo *old_core;
155 155
156 if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
157 return 0;
158 old_core = bcm->current_core; 156 old_core = bcm->current_core;
159 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); 157 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
160 if (err == -ENODEV) 158 if (err == -ENODEV)
@@ -162,11 +160,27 @@ int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
162 if (err) 160 if (err)
163 goto out; 161 goto out;
164 162
165 maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); 163 if (bcm->chip_id == 0x4321) {
166 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, 164 if (bcm->chip_rev == 0)
167 (maxfreq * 150 + 999999) / 1000000); 165 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4);
168 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, 166 if (bcm->chip_rev == 1)
169 (maxfreq * 15 + 999999) / 1000000); 167 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4);
168 }
169
170 if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) {
171 if (bcm->current_core->rev >= 10) {
172 /* Set Idle Power clock rate to 1Mhz */
173 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL,
174 (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL)
175 & 0x0000FFFF) | 0x40000);
176 } else {
177 maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
178 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
179 (maxfreq * 150 + 999999) / 1000000);
180 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
181 (maxfreq * 15 + 999999) / 1000000);
182 }
183 }
170 184
171 err = bcm43xx_switch_core(bcm, old_core); 185 err = bcm43xx_switch_core(bcm, old_core);
172 assert(err == 0); 186 assert(err == 0);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 9b7b15cf6561..a659442b9c15 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -47,9 +47,6 @@
47#define BCM43xx_WX_VERSION 18 47#define BCM43xx_WX_VERSION 18
48 48
49#define MAX_WX_STRING 80 49#define MAX_WX_STRING 80
50/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
51#define RX_RSSI_MAX 60
52
53 50
54static int bcm43xx_wx_get_name(struct net_device *net_dev, 51static int bcm43xx_wx_get_name(struct net_device *net_dev,
55 struct iw_request_info *info, 52 struct iw_request_info *info,
@@ -693,6 +690,7 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
693 bcm->ieee->host_encrypt = !!on; 690 bcm->ieee->host_encrypt = !!on;
694 bcm->ieee->host_decrypt = !!on; 691 bcm->ieee->host_decrypt = !!on;
695 bcm->ieee->host_build_iv = !on; 692 bcm->ieee->host_build_iv = !on;
693 bcm->ieee->host_strip_iv_icv = !on;
696 spin_unlock_irqrestore(&bcm->irq_lock, flags); 694 spin_unlock_irqrestore(&bcm->irq_lock, flags);
697 mutex_unlock(&bcm->mutex); 695 mutex_unlock(&bcm->mutex);
698 696
@@ -847,7 +845,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
847 unsigned long flags; 845 unsigned long flags;
848 846
849 wstats = &bcm->stats.wstats; 847 wstats = &bcm->stats.wstats;
850 if (!mac->associated) { 848 if (!mac->associnfo.associated) {
851 wstats->miss.beacon = 0; 849 wstats->miss.beacon = 0;
852// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? 850// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
853 wstats->discard.retries = 0; 851 wstats->discard.retries = 0;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
index 0159e4e93201..3e2462671690 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
@@ -544,24 +544,6 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
544 } 544 }
545 545
546 frame_ctl = le16_to_cpu(wlhdr->frame_ctl); 546 frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
547 if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) {
548 frame_ctl &= ~IEEE80211_FCTL_PROTECTED;
549 wlhdr->frame_ctl = cpu_to_le16(frame_ctl);
550 /* trim IV and ICV */
551 /* FIXME: this must be done only for WEP encrypted packets */
552 if (skb->len < 32) {
553 dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag "
554 "set and length < 32)\n");
555 return -EINVAL;
556 } else {
557 memmove(skb->data + 4, skb->data, 24);
558 skb_pull(skb, 4);
559 skb_trim(skb, skb->len - 4);
560 stats.len -= 8;
561 }
562 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
563 }
564
565 switch (WLAN_FC_GET_TYPE(frame_ctl)) { 547 switch (WLAN_FC_GET_TYPE(frame_ctl)) {
566 case IEEE80211_FTYPE_MGMT: 548 case IEEE80211_FTYPE_MGMT:
567 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats); 549 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);