diff options
author | Paul Mackerras <paulus@samba.org> | 2006-12-03 23:59:07 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-03 23:59:07 -0500 |
commit | 79acbb3ff2d8095b692e1502b9eb2ccec348de26 (patch) | |
tree | 6ab773e5a8f9de2cd6443362b21d0d6fffe3b35e /drivers/net/wireless/bcm43xx | |
parent | 19a79859e168640f8e16d7b216d211c1c52b687a (diff) | |
parent | 2b5f6dcce5bf94b9b119e9ed8d537098ec61c3d2 (diff) |
Merge branch 'linux-2.6' into for-linus
Diffstat (limited to 'drivers/net/wireless/bcm43xx')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 32 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_dma.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_leds.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_leds.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 279 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_power.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_xmit.c | 18 |
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; |
761 | out: | 779 | out: |
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); |
315 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); | 316 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); |
316 | 317 | ||
318 | /* Helper function that returns the dma mask for this device. */ | ||
319 | static inline | ||
320 | u64 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 | ||
51 | int bcm43xx_leds_init(struct bcm43xx_private *bcm); | 57 | int 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 | ||
1470 | static 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 | |||
1466 | static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) | 1487 | static 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 | ||
2985 | static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) | 3001 | static 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); | ||
2999 | out: | 3023 | out: |
3000 | return err; | 3024 | return err; |
3001 | } | 3025 | } |
3002 | 3026 | ||
3027 | static 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 | |||
3033 | static 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 | |||
3040 | static 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 | |||
3055 | out_switch_back: | 3139 | out_switch_back: |
3056 | err = bcm43xx_switch_core(bcm, old_core); | 3140 | err = bcm43xx_switch_core(bcm, old_core); |
3057 | out: | 3141 | out: |
@@ -3120,57 +3204,42 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) | |||
3120 | 3204 | ||
3121 | static void do_periodic_work(struct bcm43xx_private *bcm) | 3205 | static 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 | */ | ||
3143 | static 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 | |||
3160 | static void bcm43xx_periodic_work_handler(void *d) | 3218 | static 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 | ||
3943 | static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev) | ||
3944 | { | ||
3945 | return &(bcm43xx_priv(net_dev)->ieee->stats); | ||
3946 | } | ||
3947 | |||
3948 | static void bcm43xx_net_tx_timeout(struct net_device *net_dev) | 4016 | static 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 | ||
54 | static int bcm43xx_wx_get_name(struct net_device *net_dev, | 51 | static 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); |