aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/airo.c46
-rw-r--r--drivers/net/wireless/arlan-main.c4
-rw-r--r--drivers/net/wireless/atmel.c11
-rw-r--r--drivers/net/wireless/bcm43xx/Kconfig3
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h17
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c8
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.c44
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h8
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c53
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h6
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c3
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.c92
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.h16
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.c115
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.h9
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c115
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h16
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c15
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c4
-rw-r--r--drivers/net/wireless/orinoco.c6
-rw-r--r--drivers/net/wireless/wavelan.c2
22 files changed, 361 insertions, 234 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index bad09ebdb50b..e0874cbfefea 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -6,7 +6,7 @@ menu "Wireless LAN (non-hamradio)"
6 depends on NETDEVICES 6 depends on NETDEVICES
7 7
8config NET_RADIO 8config NET_RADIO
9 bool "Wireless LAN drivers (non-hamradio)" 9 bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
10 select WIRELESS_EXT 10 select WIRELESS_EXT
11 ---help--- 11 ---help---
12 Support for wireless LANs and everything having to do with radio, 12 Support for wireless LANs and everything having to do with radio,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 108d9fed8f07..00764ddd74d8 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -3139,6 +3139,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3139 } 3139 }
3140 if ( status & EV_LINK ) { 3140 if ( status & EV_LINK ) {
3141 union iwreq_data wrqu; 3141 union iwreq_data wrqu;
3142 int scan_forceloss = 0;
3142 /* The link status has changed, if you want to put a 3143 /* The link status has changed, if you want to put a
3143 monitor hook in, do it here. (Remember that 3144 monitor hook in, do it here. (Remember that
3144 interrupts are still disabled!) 3145 interrupts are still disabled!)
@@ -3157,7 +3158,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3157 code) */ 3158 code) */
3158#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason 3159#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
3159 code) */ 3160 code) */
3160#define ASSOCIATED 0x0400 /* Assocatied */ 3161#define ASSOCIATED 0x0400 /* Associated */
3162#define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
3161#define RC_RESERVED 0 /* Reserved return code */ 3163#define RC_RESERVED 0 /* Reserved return code */
3162#define RC_NOREASON 1 /* Unspecified reason */ 3164#define RC_NOREASON 1 /* Unspecified reason */
3163#define RC_AUTHINV 2 /* Previous authentication invalid */ 3165#define RC_AUTHINV 2 /* Previous authentication invalid */
@@ -3174,44 +3176,30 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3174 leaving BSS */ 3176 leaving BSS */
3175#define RC_NOAUTH 9 /* Station requesting (Re)Association is not 3177#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
3176 Authenticated with the responding station */ 3178 Authenticated with the responding station */
3177 if (newStatus != ASSOCIATED) { 3179 if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
3178 if (auto_wep && !apriv->expires) { 3180 scan_forceloss = 1;
3179 apriv->expires = RUN_AT(3*HZ); 3181 if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
3180 wake_up_interruptible(&apriv->thr_wait);
3181 }
3182 } else {
3183 struct task_struct *task = apriv->task;
3184 if (auto_wep) 3182 if (auto_wep)
3185 apriv->expires = 0; 3183 apriv->expires = 0;
3186 if (task) 3184 if (apriv->task)
3187 wake_up_process (task); 3185 wake_up_process (apriv->task);
3188 set_bit(FLAG_UPDATE_UNI, &apriv->flags); 3186 set_bit(FLAG_UPDATE_UNI, &apriv->flags);
3189 set_bit(FLAG_UPDATE_MULTI, &apriv->flags); 3187 set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
3190 } 3188
3191 /* Question : is ASSOCIATED the only status
3192 * that is valid ? We want to catch handover
3193 * and reassociations as valid status
3194 * Jean II */
3195 if(newStatus == ASSOCIATED) {
3196#if 0
3197 /* FIXME: Grabbing scan results here
3198 * seems to be too early??? Just wait for
3199 * timeout instead. */
3200 if (apriv->scan_timeout > 0) {
3201 set_bit(JOB_SCAN_RESULTS, &apriv->flags);
3202 wake_up_interruptible(&apriv->thr_wait);
3203 }
3204#endif
3205 if (down_trylock(&apriv->sem) != 0) { 3189 if (down_trylock(&apriv->sem) != 0) {
3206 set_bit(JOB_EVENT, &apriv->flags); 3190 set_bit(JOB_EVENT, &apriv->flags);
3207 wake_up_interruptible(&apriv->thr_wait); 3191 wake_up_interruptible(&apriv->thr_wait);
3208 } else 3192 } else
3209 airo_send_event(dev); 3193 airo_send_event(dev);
3210 } else { 3194 } else if (!scan_forceloss) {
3211 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); 3195 if (auto_wep && !apriv->expires) {
3212 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3196 apriv->expires = RUN_AT(3*HZ);
3197 wake_up_interruptible(&apriv->thr_wait);
3198 }
3213 3199
3214 /* Send event to user space */ 3200 /* Send event to user space */
3201 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3202 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3215 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); 3203 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
3216 } 3204 }
3217 } 3205 }
@@ -7136,10 +7124,10 @@ static int airo_set_scan(struct net_device *dev,
7136 goto out; 7124 goto out;
7137 7125
7138 /* Initiate a scan command */ 7126 /* Initiate a scan command */
7127 ai->scan_timeout = RUN_AT(3*HZ);
7139 memset(&cmd, 0, sizeof(cmd)); 7128 memset(&cmd, 0, sizeof(cmd));
7140 cmd.cmd=CMD_LISTBSS; 7129 cmd.cmd=CMD_LISTBSS;
7141 issuecommand(ai, &cmd, &rsp); 7130 issuecommand(ai, &cmd, &rsp);
7142 ai->scan_timeout = RUN_AT(3*HZ);
7143 wake = 1; 7131 wake = 1;
7144 7132
7145out: 7133out:
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index 0e1ac338cac1..bed6823d9809 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -1838,7 +1838,7 @@ struct net_device * __init arlan_probe(int unit)
1838} 1838}
1839 1839
1840#ifdef MODULE 1840#ifdef MODULE
1841int init_module(void) 1841int __init init_module(void)
1842{ 1842{
1843 int i = 0; 1843 int i = 0;
1844 1844
@@ -1860,7 +1860,7 @@ int init_module(void)
1860} 1860}
1861 1861
1862 1862
1863void cleanup_module(void) 1863void __exit cleanup_module(void)
1864{ 1864{
1865 int i = 0; 1865 int i = 0;
1866 struct net_device *dev; 1866 struct net_device *dev;
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 87afa6878f26..8606c88886fc 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -3463,6 +3463,7 @@ static void atmel_command_irq(struct atmel_private *priv)
3463 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET)); 3463 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3464 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET)); 3464 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3465 int fast_scan; 3465 int fast_scan;
3466 union iwreq_data wrqu;
3466 3467
3467 if (status == CMD_STATUS_IDLE || 3468 if (status == CMD_STATUS_IDLE ||
3468 status == CMD_STATUS_IN_PROGRESS) 3469 status == CMD_STATUS_IN_PROGRESS)
@@ -3487,6 +3488,7 @@ static void atmel_command_irq(struct atmel_private *priv)
3487 atmel_scan(priv, 1); 3488 atmel_scan(priv, 1);
3488 } else { 3489 } else {
3489 int bss_index = retrieve_bss(priv); 3490 int bss_index = retrieve_bss(priv);
3491 int notify_scan_complete = 1;
3490 if (bss_index != -1) { 3492 if (bss_index != -1) {
3491 atmel_join_bss(priv, bss_index); 3493 atmel_join_bss(priv, bss_index);
3492 } else if (priv->operating_mode == IW_MODE_ADHOC && 3494 } else if (priv->operating_mode == IW_MODE_ADHOC &&
@@ -3495,8 +3497,14 @@ static void atmel_command_irq(struct atmel_private *priv)
3495 } else { 3497 } else {
3496 priv->fast_scan = !fast_scan; 3498 priv->fast_scan = !fast_scan;
3497 atmel_scan(priv, 1); 3499 atmel_scan(priv, 1);
3500 notify_scan_complete = 0;
3498 } 3501 }
3499 priv->site_survey_state = SITE_SURVEY_COMPLETED; 3502 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3503 if (notify_scan_complete) {
3504 wrqu.data.length = 0;
3505 wrqu.data.flags = 0;
3506 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3507 }
3500 } 3508 }
3501 break; 3509 break;
3502 3510
@@ -3509,6 +3517,9 @@ static void atmel_command_irq(struct atmel_private *priv)
3509 priv->site_survey_state = SITE_SURVEY_COMPLETED; 3517 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3510 if (priv->station_is_associated) { 3518 if (priv->station_is_associated) {
3511 atmel_enter_state(priv, STATION_STATE_READY); 3519 atmel_enter_state(priv, STATION_STATE_READY);
3520 wrqu.data.length = 0;
3521 wrqu.data.flags = 0;
3522 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3512 } else { 3523 } else {
3513 atmel_scan(priv, 1); 3524 atmel_scan(priv, 1);
3514 } 3525 }
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig
index 418465600a77..25ea4748f0b9 100644
--- a/drivers/net/wireless/bcm43xx/Kconfig
+++ b/drivers/net/wireless/bcm43xx/Kconfig
@@ -17,8 +17,11 @@ config BCM43XX_DEBUG
17 17
18config BCM43XX_DMA 18config BCM43XX_DMA
19 bool 19 bool
20 depends on BCM43XX
21
20config BCM43XX_PIO 22config BCM43XX_PIO
21 bool 23 bool
24 depends on BCM43XX
22 25
23choice 26choice
24 prompt "BCM43xx data transfer mode" 27 prompt "BCM43xx data transfer mode"
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index dcadd295de4f..2e83083935e1 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -15,7 +15,6 @@
15 15
16#include "bcm43xx_debugfs.h" 16#include "bcm43xx_debugfs.h"
17#include "bcm43xx_leds.h" 17#include "bcm43xx_leds.h"
18#include "bcm43xx_sysfs.h"
19 18
20 19
21#define PFX KBUILD_MODNAME ": " 20#define PFX KBUILD_MODNAME ": "
@@ -638,8 +637,6 @@ struct bcm43xx_key {
638}; 637};
639 638
640struct bcm43xx_private { 639struct bcm43xx_private {
641 struct bcm43xx_sysfs sysfs;
642
643 struct ieee80211_device *ieee; 640 struct ieee80211_device *ieee;
644 struct ieee80211softmac_device *softmac; 641 struct ieee80211softmac_device *softmac;
645 642
@@ -772,6 +769,20 @@ struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
772 return ieee80211softmac_priv(dev); 769 return ieee80211softmac_priv(dev);
773} 770}
774 771
772struct device;
773
774static inline
775struct bcm43xx_private * dev_to_bcm(struct device *dev)
776{
777 struct net_device *net_dev;
778 struct bcm43xx_private *bcm;
779
780 net_dev = dev_get_drvdata(dev);
781 bcm = bcm43xx_priv(net_dev);
782
783 return bcm;
784}
785
775 786
776/* Helper function, which returns a boolean. 787/* Helper function, which returns a boolean.
777 * TRUE, if PIO is used; FALSE, if DMA is used. 788 * TRUE, if PIO is used; FALSE, if DMA is used.
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
index d2c3401e9b70..35a4fcb6d923 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -452,12 +452,12 @@ void bcm43xx_printk_dump(const char *data,
452 size_t i; 452 size_t i;
453 char c; 453 char c;
454 454
455 printk(KERN_INFO PFX "Data dump (%s, %u bytes):", 455 printk(KERN_INFO PFX "Data dump (%s, %zd bytes):",
456 description, size); 456 description, size);
457 for (i = 0; i < size; i++) { 457 for (i = 0; i < size; i++) {
458 c = data[i]; 458 c = data[i];
459 if (i % 8 == 0) 459 if (i % 8 == 0)
460 printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff); 460 printk("\n" KERN_INFO PFX "0x%08zx: 0x%02x, ", i, c & 0xff);
461 else 461 else
462 printk("0x%02x, ", c & 0xff); 462 printk("0x%02x, ", c & 0xff);
463 } 463 }
@@ -472,12 +472,12 @@ void bcm43xx_printk_bitdump(const unsigned char *data,
472 int j; 472 int j;
473 const unsigned char *d; 473 const unsigned char *d;
474 474
475 printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***", 475 printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***",
476 description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); 476 description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
477 for (i = 0; i < bytes; i++) { 477 for (i = 0; i < bytes; i++) {
478 d = data + i; 478 d = data + i;
479 if (i % 8 == 0) 479 if (i % 8 == 0)
480 printk("\n" KERN_INFO PFX "0x%08x: ", i); 480 printk("\n" KERN_INFO PFX "0x%08zx: ", i);
481 if (msb_to_lsb) { 481 if (msb_to_lsb) {
482 for (j = 7; j >= 0; j--) { 482 for (j = 7; j >= 0; j--) {
483 if (*d & (1 << j)) 483 if (*d & (1 << j))
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index c3681b8f09b4..d0318e525ba7 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -196,8 +196,9 @@ static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
196 } 196 }
197 if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { 197 if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
198 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " 198 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
199 "(0x%08x, len: %lu)\n", 199 "(0x%llx, len: %lu)\n",
200 ring->dmabase, BCM43xx_DMA_RINGMEMSIZE); 200 (unsigned long long)ring->dmabase,
201 BCM43xx_DMA_RINGMEMSIZE);
201 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, 202 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
202 ring->vbase, ring->dmabase); 203 ring->vbase, ring->dmabase);
203 return -ENOMEM; 204 return -ENOMEM;
@@ -307,8 +308,8 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
307 unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); 308 unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
308 dev_kfree_skb_any(skb); 309 dev_kfree_skb_any(skb);
309 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " 310 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
310 "(0x%08x, len: %u)\n", 311 "(0x%llx, len: %u)\n",
311 dmaaddr, ring->rx_buffersize); 312 (unsigned long long)dmaaddr, ring->rx_buffersize);
312 return -ENOMEM; 313 return -ENOMEM;
313 } 314 }
314 meta->skb = skb; 315 meta->skb = skb;
@@ -623,25 +624,28 @@ err_destroy_tx0:
623static u16 generate_cookie(struct bcm43xx_dmaring *ring, 624static u16 generate_cookie(struct bcm43xx_dmaring *ring,
624 int slot) 625 int slot)
625{ 626{
626 u16 cookie = 0x0000; 627 u16 cookie = 0xF000;
627 628
628 /* Use the upper 4 bits of the cookie as 629 /* Use the upper 4 bits of the cookie as
629 * DMA controller ID and store the slot number 630 * DMA controller ID and store the slot number
630 * in the lower 12 bits 631 * in the lower 12 bits.
632 * Note that the cookie must never be 0, as this
633 * is a special value used in RX path.
631 */ 634 */
632 switch (ring->mmio_base) { 635 switch (ring->mmio_base) {
633 default: 636 default:
634 assert(0); 637 assert(0);
635 case BCM43xx_MMIO_DMA1_BASE: 638 case BCM43xx_MMIO_DMA1_BASE:
639 cookie = 0xA000;
636 break; 640 break;
637 case BCM43xx_MMIO_DMA2_BASE: 641 case BCM43xx_MMIO_DMA2_BASE:
638 cookie = 0x1000; 642 cookie = 0xB000;
639 break; 643 break;
640 case BCM43xx_MMIO_DMA3_BASE: 644 case BCM43xx_MMIO_DMA3_BASE:
641 cookie = 0x2000; 645 cookie = 0xC000;
642 break; 646 break;
643 case BCM43xx_MMIO_DMA4_BASE: 647 case BCM43xx_MMIO_DMA4_BASE:
644 cookie = 0x3000; 648 cookie = 0xD000;
645 break; 649 break;
646 } 650 }
647 assert(((u16)slot & 0xF000) == 0x0000); 651 assert(((u16)slot & 0xF000) == 0x0000);
@@ -659,16 +663,16 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
659 struct bcm43xx_dmaring *ring = NULL; 663 struct bcm43xx_dmaring *ring = NULL;
660 664
661 switch (cookie & 0xF000) { 665 switch (cookie & 0xF000) {
662 case 0x0000: 666 case 0xA000:
663 ring = dma->tx_ring0; 667 ring = dma->tx_ring0;
664 break; 668 break;
665 case 0x1000: 669 case 0xB000:
666 ring = dma->tx_ring1; 670 ring = dma->tx_ring1;
667 break; 671 break;
668 case 0x2000: 672 case 0xC000:
669 ring = dma->tx_ring2; 673 ring = dma->tx_ring2;
670 break; 674 break;
671 case 0x3000: 675 case 0xD000:
672 ring = dma->tx_ring3; 676 ring = dma->tx_ring3;
673 break; 677 break;
674 default: 678 default:
@@ -729,8 +733,8 @@ static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
729 if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { 733 if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
730 return_slot(ring, slot); 734 return_slot(ring, slot);
731 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " 735 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
732 "(0x%08x, len: %u)\n", 736 "(0x%llx, len: %u)\n",
733 meta->dmaaddr, skb->len); 737 (unsigned long long)meta->dmaaddr, skb->len);
734 return -ENOMEM; 738 return -ENOMEM;
735 } 739 }
736 740
@@ -838,8 +842,18 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
838 /* We received an xmit status. */ 842 /* We received an xmit status. */
839 struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; 843 struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
840 struct bcm43xx_xmitstatus stat; 844 struct bcm43xx_xmitstatus stat;
845 int i = 0;
841 846
842 stat.cookie = le16_to_cpu(hw->cookie); 847 stat.cookie = le16_to_cpu(hw->cookie);
848 while (stat.cookie == 0) {
849 if (unlikely(++i >= 10000)) {
850 assert(0);
851 break;
852 }
853 udelay(2);
854 barrier();
855 stat.cookie = le16_to_cpu(hw->cookie);
856 }
843 stat.flags = hw->flags; 857 stat.flags = hw->flags;
844 stat.cnt1 = hw->cnt1; 858 stat.cnt1 = hw->cnt1;
845 stat.cnt2 = hw->cnt2; 859 stat.cnt2 = hw->cnt2;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
index 2d520e4b0276..b7d77638ba8c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -213,6 +213,14 @@ static inline
213void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) 213void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
214{ 214{
215} 215}
216static inline
217void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
218{
219}
220static inline
221void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
222{
223}
216 224
217#endif /* CONFIG_BCM43XX_DMA */ 225#endif /* CONFIG_BCM43XX_DMA */
218#endif /* BCM43xx_DMA_H_ */ 226#endif /* BCM43xx_DMA_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index c37371fc9e01..7ed18cad29f7 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -52,6 +52,7 @@
52#include "bcm43xx_wx.h" 52#include "bcm43xx_wx.h"
53#include "bcm43xx_ethtool.h" 53#include "bcm43xx_ethtool.h"
54#include "bcm43xx_xmit.h" 54#include "bcm43xx_xmit.h"
55#include "bcm43xx_sysfs.h"
55 56
56 57
57MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); 58MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
@@ -938,9 +939,9 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
938 return 0; 939 return 0;
939} 940}
940 941
941static void bcm43xx_geo_init(struct bcm43xx_private *bcm) 942static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
942{ 943{
943 struct ieee80211_geo geo; 944 struct ieee80211_geo *geo;
944 struct ieee80211_channel *chan; 945 struct ieee80211_channel *chan;
945 int have_a = 0, have_bg = 0; 946 int have_a = 0, have_bg = 0;
946 int i; 947 int i;
@@ -948,7 +949,10 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
948 struct bcm43xx_phyinfo *phy; 949 struct bcm43xx_phyinfo *phy;
949 const char *iso_country; 950 const char *iso_country;
950 951
951 memset(&geo, 0, sizeof(geo)); 952 geo = kzalloc(sizeof(*geo), GFP_KERNEL);
953 if (!geo)
954 return -ENOMEM;
955
952 for (i = 0; i < bcm->nr_80211_available; i++) { 956 for (i = 0; i < bcm->nr_80211_available; i++) {
953 phy = &(bcm->core_80211_ext[i].phy); 957 phy = &(bcm->core_80211_ext[i].phy);
954 switch (phy->type) { 958 switch (phy->type) {
@@ -966,31 +970,36 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
966 iso_country = bcm43xx_locale_iso(bcm->sprom.locale); 970 iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
967 971
968 if (have_a) { 972 if (have_a) {
969 for (i = 0, channel = 0; channel < 201; channel++) { 973 for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
970 chan = &geo.a[i++]; 974 channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
975 chan = &geo->a[i++];
971 chan->freq = bcm43xx_channel_to_freq_a(channel); 976 chan->freq = bcm43xx_channel_to_freq_a(channel);
972 chan->channel = channel; 977 chan->channel = channel;
973 } 978 }
974 geo.a_channels = i; 979 geo->a_channels = i;
975 } 980 }
976 if (have_bg) { 981 if (have_bg) {
977 for (i = 0, channel = 1; channel < 15; channel++) { 982 for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
978 chan = &geo.bg[i++]; 983 channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
984 chan = &geo->bg[i++];
979 chan->freq = bcm43xx_channel_to_freq_bg(channel); 985 chan->freq = bcm43xx_channel_to_freq_bg(channel);
980 chan->channel = channel; 986 chan->channel = channel;
981 } 987 }
982 geo.bg_channels = i; 988 geo->bg_channels = i;
983 } 989 }
984 memcpy(geo.name, iso_country, 2); 990 memcpy(geo->name, iso_country, 2);
985 if (0 /*TODO: Outdoor use only */) 991 if (0 /*TODO: Outdoor use only */)
986 geo.name[2] = 'O'; 992 geo->name[2] = 'O';
987 else if (0 /*TODO: Indoor use only */) 993 else if (0 /*TODO: Indoor use only */)
988 geo.name[2] = 'I'; 994 geo->name[2] = 'I';
989 else 995 else
990 geo.name[2] = ' '; 996 geo->name[2] = ' ';
991 geo.name[3] = '\0'; 997 geo->name[3] = '\0';
998
999 ieee80211_set_geo(bcm->ieee, geo);
1000 kfree(geo);
992 1001
993 ieee80211_set_geo(bcm->ieee, &geo); 1002 return 0;
994} 1003}
995 1004
996/* DummyTransmission function, as documented on 1005/* DummyTransmission function, as documented on
@@ -3262,6 +3271,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3262 bcm43xx_sysfs_register(bcm); 3271 bcm43xx_sysfs_register(bcm);
3263 //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though... 3272 //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
3264 3273
3274 /*FIXME: This should be handled by softmac instead. */
3275 schedule_work(&bcm->softmac->associnfo.work);
3276
3265 assert(err == 0); 3277 assert(err == 0);
3266out: 3278out:
3267 return err; 3279 return err;
@@ -3478,16 +3490,17 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3478 goto err_80211_unwind; 3490 goto err_80211_unwind;
3479 bcm43xx_wireless_core_disable(bcm); 3491 bcm43xx_wireless_core_disable(bcm);
3480 } 3492 }
3493 err = bcm43xx_geo_init(bcm);
3494 if (err)
3495 goto err_80211_unwind;
3481 bcm43xx_pctl_set_crystal(bcm, 0); 3496 bcm43xx_pctl_set_crystal(bcm, 0);
3482 3497
3483 /* Set the MAC address in the networking subsystem */ 3498 /* Set the MAC address in the networking subsystem */
3484 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) 3499 if (is_valid_ether_addr(bcm->sprom.et1macaddr))
3485 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6); 3500 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3486 else 3501 else
3487 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6); 3502 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3488 3503
3489 bcm43xx_geo_init(bcm);
3490
3491 snprintf(bcm->nick, IW_ESSID_MAX_SIZE, 3504 snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3492 "Broadcom %04X", bcm->chip_id); 3505 "Broadcom %04X", bcm->chip_id);
3493 3506
@@ -3522,6 +3535,7 @@ static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
3522 err = bcm43xx_pio_tx(bcm, txb); 3535 err = bcm43xx_pio_tx(bcm, txb);
3523 else 3536 else
3524 err = bcm43xx_dma_tx(bcm, txb); 3537 err = bcm43xx_dma_tx(bcm, txb);
3538 bcm->net_dev->trans_start = jiffies;
3525 3539
3526 return err; 3540 return err;
3527} 3541}
@@ -3935,9 +3949,6 @@ static int bcm43xx_resume(struct pci_dev *pdev)
3935 3949
3936 netif_device_attach(net_dev); 3950 netif_device_attach(net_dev);
3937 3951
3938 /*FIXME: This should be handled by softmac instead. */
3939 schedule_work(&bcm->softmac->associnfo.work);
3940
3941 dprintk(KERN_INFO PFX "Device resumed.\n"); 3952 dprintk(KERN_INFO PFX "Device resumed.\n");
3942 3953
3943 return 0; 3954 return 0;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
index eca79a38594a..30a202b258b5 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
@@ -118,12 +118,14 @@ int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm,
118static inline 118static inline
119int bcm43xx_is_valid_channel_a(u8 channel) 119int bcm43xx_is_valid_channel_a(u8 channel)
120{ 120{
121 return (channel <= 200); 121 return (channel >= IEEE80211_52GHZ_MIN_CHANNEL
122 && channel <= IEEE80211_52GHZ_MAX_CHANNEL);
122} 123}
123static inline 124static inline
124int bcm43xx_is_valid_channel_bg(u8 channel) 125int bcm43xx_is_valid_channel_bg(u8 channel)
125{ 126{
126 return (channel >= 1 && channel <= 14); 127 return (channel >= IEEE80211_24GHZ_MIN_CHANNEL
128 && channel <= IEEE80211_24GHZ_MAX_CHANNEL);
127} 129}
128static inline 130static inline
129int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm, 131int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index 0a66f43ca0c0..b0abac515530 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -1287,7 +1287,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
1287 if (radio->revision == 8) 1287 if (radio->revision == 8)
1288 bcm43xx_phy_write(bcm, 0x0805, 0x3230); 1288 bcm43xx_phy_write(bcm, 0x0805, 0x3230);
1289 bcm43xx_phy_init_pctl(bcm); 1289 bcm43xx_phy_init_pctl(bcm);
1290 if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) { 1290 if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) {
1291 bcm43xx_phy_write(bcm, 0x0429, 1291 bcm43xx_phy_write(bcm, 0x0429,
1292 bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF); 1292 bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
1293 bcm43xx_phy_write(bcm, 0x04C3, 1293 bcm43xx_phy_write(bcm, 0x04C3,
@@ -2151,6 +2151,7 @@ int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm)
2151 phy->tssi2dbm = NULL; 2151 phy->tssi2dbm = NULL;
2152 printk(KERN_ERR PFX "Could not generate " 2152 printk(KERN_ERR PFX "Could not generate "
2153 "tssi2dBm table\n"); 2153 "tssi2dBm table\n");
2154 kfree(dyn_tssi2dbm);
2154 return -ENODEV; 2155 return -ENODEV;
2155 } 2156 }
2156 phy->tssi2dbm = dyn_tssi2dbm; 2157 phy->tssi2dbm = dyn_tssi2dbm;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
index c59ddd40680d..0aa1bd269a25 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
@@ -27,6 +27,7 @@
27#include "bcm43xx_pio.h" 27#include "bcm43xx_pio.h"
28#include "bcm43xx_main.h" 28#include "bcm43xx_main.h"
29#include "bcm43xx_xmit.h" 29#include "bcm43xx_xmit.h"
30#include "bcm43xx_power.h"
30 31
31#include <linux/delay.h> 32#include <linux/delay.h>
32 33
@@ -44,10 +45,10 @@ static void tx_octet(struct bcm43xx_pioqueue *queue,
44 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, 45 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
45 octet); 46 octet);
46 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, 47 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
47 BCM43xx_PIO_TXCTL_WRITEHI); 48 BCM43xx_PIO_TXCTL_WRITELO);
48 } else { 49 } else {
49 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, 50 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
50 BCM43xx_PIO_TXCTL_WRITEHI); 51 BCM43xx_PIO_TXCTL_WRITELO);
51 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, 52 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
52 octet); 53 octet);
53 } 54 }
@@ -103,7 +104,7 @@ static void tx_complete(struct bcm43xx_pioqueue *queue,
103 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, 104 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
104 skb->data[skb->len - 1]); 105 skb->data[skb->len - 1]);
105 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, 106 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
106 BCM43xx_PIO_TXCTL_WRITEHI | 107 BCM43xx_PIO_TXCTL_WRITELO |
107 BCM43xx_PIO_TXCTL_COMPLETE); 108 BCM43xx_PIO_TXCTL_COMPLETE);
108 } else { 109 } else {
109 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, 110 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
@@ -112,9 +113,10 @@ static void tx_complete(struct bcm43xx_pioqueue *queue,
112} 113}
113 114
114static u16 generate_cookie(struct bcm43xx_pioqueue *queue, 115static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
115 int packetindex) 116 struct bcm43xx_pio_txpacket *packet)
116{ 117{
117 u16 cookie = 0x0000; 118 u16 cookie = 0x0000;
119 int packetindex;
118 120
119 /* We use the upper 4 bits for the PIO 121 /* We use the upper 4 bits for the PIO
120 * controller ID and the lower 12 bits 122 * controller ID and the lower 12 bits
@@ -135,6 +137,7 @@ static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
135 default: 137 default:
136 assert(0); 138 assert(0);
137 } 139 }
140 packetindex = pio_txpacket_getindex(packet);
138 assert(((u16)packetindex & 0xF000) == 0x0000); 141 assert(((u16)packetindex & 0xF000) == 0x0000);
139 cookie |= (u16)packetindex; 142 cookie |= (u16)packetindex;
140 143
@@ -184,7 +187,7 @@ static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue,
184 bcm43xx_generate_txhdr(queue->bcm, 187 bcm43xx_generate_txhdr(queue->bcm,
185 &txhdr, skb->data, skb->len, 188 &txhdr, skb->data, skb->len,
186 (packet->xmitted_frags == 0), 189 (packet->xmitted_frags == 0),
187 generate_cookie(queue, pio_txpacket_getindex(packet))); 190 generate_cookie(queue, packet));
188 191
189 tx_start(queue); 192 tx_start(queue);
190 octets = skb->len + sizeof(txhdr); 193 octets = skb->len + sizeof(txhdr);
@@ -241,7 +244,7 @@ static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet)
241 queue->tx_devq_packets++; 244 queue->tx_devq_packets++;
242 queue->tx_devq_used += octets; 245 queue->tx_devq_used += octets;
243 246
244 assert(packet->xmitted_frags <= packet->txb->nr_frags); 247 assert(packet->xmitted_frags < packet->txb->nr_frags);
245 packet->xmitted_frags++; 248 packet->xmitted_frags++;
246 packet->xmitted_octets += octets; 249 packet->xmitted_octets += octets;
247 } 250 }
@@ -257,8 +260,14 @@ static void tx_tasklet(unsigned long d)
257 unsigned long flags; 260 unsigned long flags;
258 struct bcm43xx_pio_txpacket *packet, *tmp_packet; 261 struct bcm43xx_pio_txpacket *packet, *tmp_packet;
259 int err; 262 int err;
263 u16 txctl;
260 264
261 bcm43xx_lock_mmio(bcm, flags); 265 bcm43xx_lock_mmio(bcm, flags);
266
267 txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
268 if (txctl & BCM43xx_PIO_TXCTL_SUSPEND)
269 goto out_unlock;
270
262 list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { 271 list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
263 assert(packet->xmitted_frags < packet->txb->nr_frags); 272 assert(packet->xmitted_frags < packet->txb->nr_frags);
264 if (packet->xmitted_frags == 0) { 273 if (packet->xmitted_frags == 0) {
@@ -288,6 +297,7 @@ static void tx_tasklet(unsigned long d)
288 next_packet: 297 next_packet:
289 continue; 298 continue;
290 } 299 }
300out_unlock:
291 bcm43xx_unlock_mmio(bcm, flags); 301 bcm43xx_unlock_mmio(bcm, flags);
292} 302}
293 303
@@ -330,12 +340,19 @@ struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm,
330 (unsigned long)queue); 340 (unsigned long)queue);
331 341
332 value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); 342 value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
333 value |= BCM43xx_SBF_XFER_REG_BYTESWAP; 343 value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP;
334 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); 344 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
335 345
336 qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); 346 qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
347 if (qsize == 0) {
348 printk(KERN_ERR PFX "ERROR: This card does not support PIO "
349 "operation mode. Please use DMA mode "
350 "(module parameter pio=0).\n");
351 goto err_freequeue;
352 }
337 if (qsize <= BCM43xx_PIO_TXQADJUST) { 353 if (qsize <= BCM43xx_PIO_TXQADJUST) {
338 printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", qsize); 354 printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n",
355 qsize);
339 goto err_freequeue; 356 goto err_freequeue;
340 } 357 }
341 qsize -= BCM43xx_PIO_TXQADJUST; 358 qsize -= BCM43xx_PIO_TXQADJUST;
@@ -444,15 +461,10 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
444{ 461{
445 struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; 462 struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1;
446 struct bcm43xx_pio_txpacket *packet; 463 struct bcm43xx_pio_txpacket *packet;
447 u16 tmp;
448 464
449 assert(!queue->tx_suspended); 465 assert(!queue->tx_suspended);
450 assert(!list_empty(&queue->txfree)); 466 assert(!list_empty(&queue->txfree));
451 467
452 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
453 if (tmp & BCM43xx_PIO_TXCTL_SUSPEND)
454 return -EBUSY;
455
456 packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); 468 packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list);
457 packet->txb = txb; 469 packet->txb = txb;
458 packet->xmitted_frags = 0; 470 packet->xmitted_frags = 0;
@@ -462,7 +474,7 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
462 assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); 474 assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS);
463 475
464 /* Suspend TX, if we are out of packets in the "free" queue. */ 476 /* Suspend TX, if we are out of packets in the "free" queue. */
465 if (unlikely(list_empty(&queue->txfree))) { 477 if (list_empty(&queue->txfree)) {
466 netif_stop_queue(queue->bcm->net_dev); 478 netif_stop_queue(queue->bcm->net_dev);
467 queue->tx_suspended = 1; 479 queue->tx_suspended = 1;
468 } 480 }
@@ -480,15 +492,15 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
480 492
481 queue = parse_cookie(bcm, status->cookie, &packet); 493 queue = parse_cookie(bcm, status->cookie, &packet);
482 assert(queue); 494 assert(queue);
483//TODO 495
484if (!queue)
485return;
486 free_txpacket(packet, 1); 496 free_txpacket(packet, 1);
487 if (unlikely(queue->tx_suspended)) { 497 if (queue->tx_suspended) {
488 queue->tx_suspended = 0; 498 queue->tx_suspended = 0;
489 netif_wake_queue(queue->bcm->net_dev); 499 netif_wake_queue(queue->bcm->net_dev);
490 } 500 }
491 /* If there are packets on the txqueue, poke the tasklet. */ 501 /* If there are packets on the txqueue, poke the tasklet
502 * to transmit them.
503 */
492 if (!list_empty(&queue->txqueue)) 504 if (!list_empty(&queue->txqueue))
493 tasklet_schedule(&queue->txtask); 505 tasklet_schedule(&queue->txtask);
494} 506}
@@ -519,12 +531,9 @@ void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
519 int i, preamble_readwords; 531 int i, preamble_readwords;
520 struct sk_buff *skb; 532 struct sk_buff *skb;
521 533
522return;
523 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); 534 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
524 if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) { 535 if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE))
525 dprintkl(KERN_ERR PFX "PIO RX: No data available\n");//TODO: remove this printk.
526 return; 536 return;
527 }
528 bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, 537 bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
529 BCM43xx_PIO_RXCTL_DATAAVAILABLE); 538 BCM43xx_PIO_RXCTL_DATAAVAILABLE);
530 539
@@ -538,8 +547,7 @@ return;
538 return; 547 return;
539data_ready: 548data_ready:
540 549
541//FIXME: endianess in this function. 550 len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
542 len = le16_to_cpu(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA));
543 if (unlikely(len > 0x700)) { 551 if (unlikely(len > 0x700)) {
544 pio_rx_error(queue, 0, "len > 0x700"); 552 pio_rx_error(queue, 0, "len > 0x700");
545 return; 553 return;
@@ -555,7 +563,7 @@ data_ready:
555 preamble_readwords = 18 / sizeof(u16); 563 preamble_readwords = 18 / sizeof(u16);
556 for (i = 0; i < preamble_readwords; i++) { 564 for (i = 0; i < preamble_readwords; i++) {
557 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); 565 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
558 preamble[i + 1] = cpu_to_be16(tmp);//FIXME? 566 preamble[i + 1] = cpu_to_le16(tmp);
559 } 567 }
560 rxhdr = (struct bcm43xx_rxhdr *)preamble; 568 rxhdr = (struct bcm43xx_rxhdr *)preamble;
561 rxflags2 = le16_to_cpu(rxhdr->flags2); 569 rxflags2 = le16_to_cpu(rxhdr->flags2);
@@ -591,16 +599,40 @@ data_ready:
591 } 599 }
592 skb_put(skb, len); 600 skb_put(skb, len);
593 for (i = 0; i < len - 1; i += 2) { 601 for (i = 0; i < len - 1; i += 2) {
594 tmp = cpu_to_be16(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); 602 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
595 *((u16 *)(skb->data + i)) = tmp; 603 *((u16 *)(skb->data + i)) = cpu_to_le16(tmp);
596 } 604 }
597 if (len % 2) { 605 if (len % 2) {
598 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); 606 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
599 skb->data[len - 1] = (tmp & 0x00FF); 607 skb->data[len - 1] = (tmp & 0x00FF);
608/* The specs say the following is required, but
609 * it is wrong and corrupts the PLCP. If we don't do
610 * this, the PLCP seems to be correct. So ifdef it out for now.
611 */
612#if 0
600 if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) 613 if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME)
601 skb->data[0x20] = (tmp & 0xFF00) >> 8; 614 skb->data[2] = (tmp & 0xFF00) >> 8;
602 else 615 else
603 skb->data[0x1E] = (tmp & 0xFF00) >> 8; 616 skb->data[0] = (tmp & 0xFF00) >> 8;
617#endif
604 } 618 }
619 skb_trim(skb, len - IEEE80211_FCS_LEN);
605 bcm43xx_rx(queue->bcm, skb, rxhdr); 620 bcm43xx_rx(queue->bcm, skb, rxhdr);
606} 621}
622
623void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
624{
625 bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1);
626 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
627 bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
628 | BCM43xx_PIO_TXCTL_SUSPEND);
629}
630
631void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
632{
633 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
634 bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
635 & ~BCM43xx_PIO_TXCTL_SUSPEND);
636 bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1);
637 tasklet_schedule(&queue->txtask);
638}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
index 970627bc1769..dfc78209e3a3 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
@@ -14,8 +14,8 @@
14#define BCM43xx_PIO_RXCTL 0x08 14#define BCM43xx_PIO_RXCTL 0x08
15#define BCM43xx_PIO_RXDATA 0x0A 15#define BCM43xx_PIO_RXDATA 0x0A
16 16
17#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 0) 17#define BCM43xx_PIO_TXCTL_WRITELO (1 << 0)
18#define BCM43xx_PIO_TXCTL_WRITELO (1 << 1) 18#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 1)
19#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) 19#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2)
20#define BCM43xx_PIO_TXCTL_INIT (1 << 3) 20#define BCM43xx_PIO_TXCTL_INIT (1 << 3)
21#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) 21#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7)
@@ -95,6 +95,7 @@ void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue,
95 u16 offset, u16 value) 95 u16 offset, u16 value)
96{ 96{
97 bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); 97 bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value);
98 mmiowb();
98} 99}
99 100
100 101
@@ -107,6 +108,9 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
107 struct bcm43xx_xmitstatus *status); 108 struct bcm43xx_xmitstatus *status);
108void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); 109void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue);
109 110
111void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue);
112void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue);
113
110#else /* CONFIG_BCM43XX_PIO */ 114#else /* CONFIG_BCM43XX_PIO */
111 115
112static inline 116static inline
@@ -133,6 +137,14 @@ static inline
133void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) 137void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
134{ 138{
135} 139}
140static inline
141void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
142{
143}
144static inline
145void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
146{
147}
136 148
137#endif /* CONFIG_BCM43XX_PIO */ 149#endif /* CONFIG_BCM43XX_PIO */
138#endif /* BCM43xx_PIO_H_ */ 150#endif /* BCM43xx_PIO_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
index 3c92b62807c5..6569da3a7a39 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
@@ -35,77 +35,101 @@
35#include "bcm43xx_main.h" 35#include "bcm43xx_main.h"
36 36
37 37
38/* Get the Slow Clock Source */
39static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm)
40{
41 u32 tmp;
42 int err;
43
44 assert(bcm->current_core == &bcm->core_chipcommon);
45 if (bcm->current_core->rev < 6) {
46 if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA ||
47 bcm->bustype == BCM43xx_BUSTYPE_SB)
48 return BCM43xx_PCTL_CLKSRC_XTALOS;
49 if (bcm->bustype == BCM43xx_BUSTYPE_PCI) {
50 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
51 assert(!err);
52 if (tmp & 0x10)
53 return BCM43xx_PCTL_CLKSRC_PCI;
54 return BCM43xx_PCTL_CLKSRC_XTALOS;
55 }
56 }
57 if (bcm->current_core->rev < 10) {
58 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
59 tmp &= 0x7;
60 if (tmp == 0)
61 return BCM43xx_PCTL_CLKSRC_LOPWROS;
62 if (tmp == 1)
63 return BCM43xx_PCTL_CLKSRC_XTALOS;
64 if (tmp == 2)
65 return BCM43xx_PCTL_CLKSRC_PCI;
66 }
67
68 return BCM43xx_PCTL_CLKSRC_XTALOS;
69}
70
38/* Get max/min slowclock frequency 71/* Get max/min slowclock frequency
39 * as described in http://bcm-specs.sipsolutions.net/PowerControl 72 * as described in http://bcm-specs.sipsolutions.net/PowerControl
40 */ 73 */
41static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, 74static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
42 int get_max) 75 int get_max)
43{ 76{
44 int limit = 0; 77 int limit;
78 int clocksrc;
45 int divisor; 79 int divisor;
46 int selection;
47 int err;
48 u32 tmp; 80 u32 tmp;
49 struct bcm43xx_coreinfo *old_core;
50 81
51 if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) 82 assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL);
52 goto out; 83 assert(bcm->current_core == &bcm->core_chipcommon);
53 old_core = bcm->current_core;
54 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
55 if (err)
56 goto out;
57 84
85 clocksrc = bcm43xx_pctl_get_slowclksrc(bcm);
58 if (bcm->current_core->rev < 6) { 86 if (bcm->current_core->rev < 6) {
59 if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) || 87 switch (clocksrc) {
60 (bcm->bustype == BCM43xx_BUSTYPE_SB)) { 88 case BCM43xx_PCTL_CLKSRC_PCI:
61 selection = 1; 89 divisor = 64;
90 break;
91 case BCM43xx_PCTL_CLKSRC_XTALOS:
62 divisor = 32; 92 divisor = 32;
63 } else { 93 break;
64 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); 94 default:
65 if (err) { 95 assert(0);
66 printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n"); 96 divisor = 1;
67 goto out_switchback;
68 }
69 if (tmp & 0x10) {
70 /* PCI */
71 selection = 2;
72 divisor = 64;
73 } else {
74 /* XTAL */
75 selection = 1;
76 divisor = 32;
77 }
78 } 97 }
79 } else if (bcm->current_core->rev < 10) { 98 } else if (bcm->current_core->rev < 10) {
80 selection = (tmp & 0x07); 99 switch (clocksrc) {
81 if (selection) { 100 case BCM43xx_PCTL_CLKSRC_LOPWROS:
101 divisor = 1;
102 break;
103 case BCM43xx_PCTL_CLKSRC_XTALOS:
104 case BCM43xx_PCTL_CLKSRC_PCI:
82 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); 105 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
83 divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); 106 divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
84 } else 107 divisor *= 4;
108 break;
109 default:
110 assert(0);
85 divisor = 1; 111 divisor = 1;
112 }
86 } else { 113 } else {
87 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); 114 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
88 divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); 115 divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
89 selection = 1; 116 divisor *= 4;
90 } 117 }
91 118
92 switch (selection) { 119 switch (clocksrc) {
93 case 0: 120 case BCM43xx_PCTL_CLKSRC_LOPWROS:
94 /* LPO */
95 if (get_max) 121 if (get_max)
96 limit = 43000; 122 limit = 43000;
97 else 123 else
98 limit = 25000; 124 limit = 25000;
99 break; 125 break;
100 case 1: 126 case BCM43xx_PCTL_CLKSRC_XTALOS:
101 /* XTAL */
102 if (get_max) 127 if (get_max)
103 limit = 20200000; 128 limit = 20200000;
104 else 129 else
105 limit = 19800000; 130 limit = 19800000;
106 break; 131 break;
107 case 2: 132 case BCM43xx_PCTL_CLKSRC_PCI:
108 /* PCI */
109 if (get_max) 133 if (get_max)
110 limit = 34000000; 134 limit = 34000000;
111 else 135 else
@@ -113,17 +137,14 @@ static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
113 break; 137 break;
114 default: 138 default:
115 assert(0); 139 assert(0);
140 limit = 0;
116 } 141 }
117 limit /= divisor; 142 limit /= divisor;
118 143
119out_switchback:
120 err = bcm43xx_switch_core(bcm, old_core);
121 assert(err == 0);
122
123out:
124 return limit; 144 return limit;
125} 145}
126 146
147
127/* init power control 148/* init power control
128 * as described in http://bcm-specs.sipsolutions.net/PowerControl 149 * as described in http://bcm-specs.sipsolutions.net/PowerControl
129 */ 150 */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/drivers/net/wireless/bcm43xx/bcm43xx_power.h
index 5f63640810bd..c966ab3a5a8c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_power.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.h
@@ -33,6 +33,15 @@
33 33
34#include <linux/types.h> 34#include <linux/types.h>
35 35
36/* Clock sources */
37enum {
38 /* PCI clock */
39 BCM43xx_PCTL_CLKSRC_PCI,
40 /* Crystal slow clock oscillator */
41 BCM43xx_PCTL_CLKSRC_XTALOS,
42 /* Low power oscillator */
43 BCM43xx_PCTL_CLKSRC_LOPWROS,
44};
36 45
37struct bcm43xx_private; 46struct bcm43xx_private;
38 47
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
index c44d890b949b..b438f48e891d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -71,14 +71,46 @@ static int get_boolean(const char *buf, size_t count)
71 return -EINVAL; 71 return -EINVAL;
72} 72}
73 73
74static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
75{
76 int i, pos = 0;
77
78 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
79 pos += snprintf(buf + pos, buf_len - pos - 1,
80 "%04X", swab16(sprom[i]) & 0xFFFF);
81 }
82 pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
83
84 return pos + 1;
85}
86
87static int hex2sprom(u16 *sprom, const char *dump, size_t len)
88{
89 char tmp[5] = { 0 };
90 int cnt = 0;
91 unsigned long parsed;
92
93 if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
94 return -EINVAL;
95
96 while (cnt < BCM43xx_SPROM_SIZE) {
97 memcpy(tmp, dump, 4);
98 dump += 4;
99 parsed = simple_strtoul(tmp, NULL, 16);
100 sprom[cnt++] = swab16((u16)parsed);
101 }
102
103 return 0;
104}
105
74static ssize_t bcm43xx_attr_sprom_show(struct device *dev, 106static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
75 struct device_attribute *attr, 107 struct device_attribute *attr,
76 char *buf) 108 char *buf)
77{ 109{
78 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); 110 struct bcm43xx_private *bcm = dev_to_bcm(dev);
79 u16 *sprom; 111 u16 *sprom;
80 unsigned long flags; 112 unsigned long flags;
81 int i, err; 113 int err;
82 114
83 if (!capable(CAP_NET_ADMIN)) 115 if (!capable(CAP_NET_ADMIN))
84 return -EPERM; 116 return -EPERM;
@@ -91,55 +123,53 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
91 bcm43xx_lock_mmio(bcm, flags); 123 bcm43xx_lock_mmio(bcm, flags);
92 assert(bcm->initialized); 124 assert(bcm->initialized);
93 err = bcm43xx_sprom_read(bcm, sprom); 125 err = bcm43xx_sprom_read(bcm, sprom);
94 if (!err) { 126 if (!err)
95 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { 127 err = sprom2hex(sprom, buf, PAGE_SIZE);
96 buf[i * 2] = sprom[i] & 0x00FF;
97 buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8;
98 }
99 }
100 bcm43xx_unlock_mmio(bcm, flags); 128 bcm43xx_unlock_mmio(bcm, flags);
101 kfree(sprom); 129 kfree(sprom);
102 130
103 return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16); 131 return err;
104} 132}
105 133
106static ssize_t bcm43xx_attr_sprom_store(struct device *dev, 134static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
107 struct device_attribute *attr, 135 struct device_attribute *attr,
108 const char *buf, size_t count) 136 const char *buf, size_t count)
109{ 137{
110 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); 138 struct bcm43xx_private *bcm = dev_to_bcm(dev);
111 u16 *sprom; 139 u16 *sprom;
112 unsigned long flags; 140 unsigned long flags;
113 int i, err; 141 int err;
114 142
115 if (!capable(CAP_NET_ADMIN)) 143 if (!capable(CAP_NET_ADMIN))
116 return -EPERM; 144 return -EPERM;
117 145
118 if (count != BCM43xx_SPROM_SIZE * sizeof(u16))
119 return -EINVAL;
120 sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), 146 sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
121 GFP_KERNEL); 147 GFP_KERNEL);
122 if (!sprom) 148 if (!sprom)
123 return -ENOMEM; 149 return -ENOMEM;
124 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { 150 err = hex2sprom(sprom, buf, count);
125 sprom[i] = buf[i * 2] & 0xFF; 151 if (err)
126 sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8; 152 goto out_kfree;
127 }
128 bcm43xx_lock_mmio(bcm, flags); 153 bcm43xx_lock_mmio(bcm, flags);
129 assert(bcm->initialized); 154 assert(bcm->initialized);
130 err = bcm43xx_sprom_write(bcm, sprom); 155 err = bcm43xx_sprom_write(bcm, sprom);
131 bcm43xx_unlock_mmio(bcm, flags); 156 bcm43xx_unlock_mmio(bcm, flags);
157out_kfree:
132 kfree(sprom); 158 kfree(sprom);
133 159
134 return err ? err : count; 160 return err ? err : count;
135 161
136} 162}
137 163
164static DEVICE_ATTR(sprom, 0600,
165 bcm43xx_attr_sprom_show,
166 bcm43xx_attr_sprom_store);
167
138static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, 168static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
139 struct device_attribute *attr, 169 struct device_attribute *attr,
140 char *buf) 170 char *buf)
141{ 171{
142 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); 172 struct bcm43xx_private *bcm = dev_to_bcm(dev);
143 unsigned long flags; 173 unsigned long flags;
144 int err; 174 int err;
145 ssize_t count = 0; 175 ssize_t count = 0;
@@ -175,7 +205,7 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
175 struct device_attribute *attr, 205 struct device_attribute *attr,
176 const char *buf, size_t count) 206 const char *buf, size_t count)
177{ 207{
178 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); 208 struct bcm43xx_private *bcm = dev_to_bcm(dev);
179 unsigned long flags; 209 unsigned long flags;
180 int err; 210 int err;
181 int mode; 211 int mode;
@@ -215,11 +245,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
215 return err ? err : count; 245 return err ? err : count;
216} 246}
217 247
248static DEVICE_ATTR(interference, 0644,
249 bcm43xx_attr_interfmode_show,
250 bcm43xx_attr_interfmode_store);
251
218static ssize_t bcm43xx_attr_preamble_show(struct device *dev, 252static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
219 struct device_attribute *attr, 253 struct device_attribute *attr,
220 char *buf) 254 char *buf)
221{ 255{
222 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); 256 struct bcm43xx_private *bcm = dev_to_bcm(dev);
223 unsigned long flags; 257 unsigned long flags;
224 int err; 258 int err;
225 ssize_t count; 259 ssize_t count;
@@ -245,7 +279,7 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
245 struct device_attribute *attr, 279 struct device_attribute *attr,
246 const char *buf, size_t count) 280 const char *buf, size_t count)
247{ 281{
248 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); 282 struct bcm43xx_private *bcm = dev_to_bcm(dev);
249 unsigned long flags; 283 unsigned long flags;
250 int err; 284 int err;
251 int value; 285 int value;
@@ -267,56 +301,41 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
267 return err ? err : count; 301 return err ? err : count;
268} 302}
269 303
304static DEVICE_ATTR(shortpreamble, 0644,
305 bcm43xx_attr_preamble_show,
306 bcm43xx_attr_preamble_store);
307
270int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) 308int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
271{ 309{
272 struct device *dev = &bcm->pci_dev->dev; 310 struct device *dev = &bcm->pci_dev->dev;
273 struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
274 int err; 311 int err;
275 312
276 assert(bcm->initialized); 313 assert(bcm->initialized);
277 314
278 sysfs->attr_sprom.attr.name = "sprom"; 315 err = device_create_file(dev, &dev_attr_sprom);
279 sysfs->attr_sprom.attr.owner = THIS_MODULE;
280 sysfs->attr_sprom.attr.mode = 0600;
281 sysfs->attr_sprom.show = bcm43xx_attr_sprom_show;
282 sysfs->attr_sprom.store = bcm43xx_attr_sprom_store;
283 err = device_create_file(dev, &sysfs->attr_sprom);
284 if (err) 316 if (err)
285 goto out; 317 goto out;
286 318 err = device_create_file(dev, &dev_attr_interference);
287 sysfs->attr_interfmode.attr.name = "interference";
288 sysfs->attr_interfmode.attr.owner = THIS_MODULE;
289 sysfs->attr_interfmode.attr.mode = 0600;
290 sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show;
291 sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store;
292 err = device_create_file(dev, &sysfs->attr_interfmode);
293 if (err) 319 if (err)
294 goto err_remove_sprom; 320 goto err_remove_sprom;
295 321 err = device_create_file(dev, &dev_attr_shortpreamble);
296 sysfs->attr_preamble.attr.name = "shortpreamble";
297 sysfs->attr_preamble.attr.owner = THIS_MODULE;
298 sysfs->attr_preamble.attr.mode = 0600;
299 sysfs->attr_preamble.show = bcm43xx_attr_preamble_show;
300 sysfs->attr_preamble.store = bcm43xx_attr_preamble_store;
301 err = device_create_file(dev, &sysfs->attr_preamble);
302 if (err) 322 if (err)
303 goto err_remove_interfmode; 323 goto err_remove_interfmode;
304 324
305out: 325out:
306 return err; 326 return err;
307err_remove_interfmode: 327err_remove_interfmode:
308 device_remove_file(dev, &sysfs->attr_interfmode); 328 device_remove_file(dev, &dev_attr_interference);
309err_remove_sprom: 329err_remove_sprom:
310 device_remove_file(dev, &sysfs->attr_sprom); 330 device_remove_file(dev, &dev_attr_sprom);
311 goto out; 331 goto out;
312} 332}
313 333
314void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) 334void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
315{ 335{
316 struct device *dev = &bcm->pci_dev->dev; 336 struct device *dev = &bcm->pci_dev->dev;
317 struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
318 337
319 device_remove_file(dev, &sysfs->attr_preamble); 338 device_remove_file(dev, &dev_attr_shortpreamble);
320 device_remove_file(dev, &sysfs->attr_interfmode); 339 device_remove_file(dev, &dev_attr_interference);
321 device_remove_file(dev, &sysfs->attr_sprom); 340 device_remove_file(dev, &dev_attr_sprom);
322} 341}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
index 57f14514e3e0..cc701df71e2a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
@@ -1,22 +1,6 @@
1#ifndef BCM43xx_SYSFS_H_ 1#ifndef BCM43xx_SYSFS_H_
2#define BCM43xx_SYSFS_H_ 2#define BCM43xx_SYSFS_H_
3 3
4#include <linux/device.h>
5
6
7struct bcm43xx_sysfs {
8 struct device_attribute attr_sprom;
9 struct device_attribute attr_interfmode;
10 struct device_attribute attr_preamble;
11};
12
13#define devattr_to_bcm(attr, attr_name) ({ \
14 struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \
15 __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \
16 __p = container_of(__s, struct bcm43xx_private, sysfs); \
17 __p; \
18 })
19
20struct bcm43xx_private; 4struct bcm43xx_private;
21 5
22int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); 6int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 3daee828ef4b..b45063974ae9 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -182,8 +182,11 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev,
182 mode = BCM43xx_INITIAL_IWMODE; 182 mode = BCM43xx_INITIAL_IWMODE;
183 183
184 bcm43xx_lock_mmio(bcm, flags); 184 bcm43xx_lock_mmio(bcm, flags);
185 if (bcm->ieee->iw_mode != mode) 185 if (bcm->initialized) {
186 bcm43xx_set_iwmode(bcm, mode); 186 if (bcm->ieee->iw_mode != mode)
187 bcm43xx_set_iwmode(bcm, mode);
188 } else
189 bcm->ieee->iw_mode = mode;
187 bcm43xx_unlock_mmio(bcm, flags); 190 bcm43xx_unlock_mmio(bcm, flags);
188 191
189 return 0; 192 return 0;
@@ -962,22 +965,22 @@ static const struct iw_priv_args bcm43xx_priv_wx_args[] = {
962 { 965 {
963 .cmd = PRIV_WX_SET_SHORTPREAMBLE, 966 .cmd = PRIV_WX_SET_SHORTPREAMBLE,
964 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 967 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
965 .name = "set_shortpreambl", 968 .name = "set_shortpreamb",
966 }, 969 },
967 { 970 {
968 .cmd = PRIV_WX_GET_SHORTPREAMBLE, 971 .cmd = PRIV_WX_GET_SHORTPREAMBLE,
969 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 972 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
970 .name = "get_shortpreambl", 973 .name = "get_shortpreamb",
971 }, 974 },
972 { 975 {
973 .cmd = PRIV_WX_SET_SWENCRYPTION, 976 .cmd = PRIV_WX_SET_SWENCRYPTION,
974 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 977 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
975 .name = "set_swencryption", 978 .name = "set_swencrypt",
976 }, 979 },
977 { 980 {
978 .cmd = PRIV_WX_GET_SWENCRYPTION, 981 .cmd = PRIV_WX_GET_SWENCRYPTION,
979 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 982 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
980 .name = "get_swencryption", 983 .name = "get_swencrypt",
981 }, 984 },
982 { 985 {
983 .cmd = PRIV_WX_SPROM_WRITE, 986 .cmd = PRIV_WX_SPROM_WRITE,
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 8b37e824dfcb..8399de581893 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1860,7 +1860,7 @@ static char * __prism2_translate_scan(local_info_t *local,
1860 memset(&iwe, 0, sizeof(iwe)); 1860 memset(&iwe, 0, sizeof(iwe));
1861 iwe.cmd = SIOCGIWFREQ; 1861 iwe.cmd = SIOCGIWFREQ;
1862 if (scan) { 1862 if (scan) {
1863 chan = scan->chid; 1863 chan = le16_to_cpu(scan->chid);
1864 } else if (bss) { 1864 } else if (bss) {
1865 chan = bss->chan; 1865 chan = bss->chan;
1866 } else { 1866 } else {
@@ -1868,7 +1868,7 @@ static char * __prism2_translate_scan(local_info_t *local,
1868 } 1868 }
1869 1869
1870 if (chan > 0) { 1870 if (chan > 0) {
1871 iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000; 1871 iwe.u.freq.m = freq_list[chan - 1] * 100000;
1872 iwe.u.freq.e = 1; 1872 iwe.u.freq.e = 1;
1873 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1873 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
1874 IW_EV_FREQ_LEN); 1874 IW_EV_FREQ_LEN);
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8dfdfbd5966c..c2d0b09e0418 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -390,7 +390,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
390 } 390 }
391 } else { 391 } else {
392 struct { 392 struct {
393 __le16 qual, signal, noise; 393 __le16 qual, signal, noise, unused;
394 } __attribute__ ((packed)) cq; 394 } __attribute__ ((packed)) cq;
395 395
396 err = HERMES_READ_RECORD(hw, USER_BAP, 396 err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -812,7 +812,6 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
812 if (datalen > IEEE80211_DATA_LEN + 12) { 812 if (datalen > IEEE80211_DATA_LEN + 12) {
813 printk(KERN_DEBUG "%s: oversized monitor frame, " 813 printk(KERN_DEBUG "%s: oversized monitor frame, "
814 "data length = %d\n", dev->name, datalen); 814 "data length = %d\n", dev->name, datalen);
815 err = -EIO;
816 stats->rx_length_errors++; 815 stats->rx_length_errors++;
817 goto update_stats; 816 goto update_stats;
818 } 817 }
@@ -821,8 +820,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
821 if (!skb) { 820 if (!skb) {
822 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n", 821 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
823 dev->name); 822 dev->name);
824 err = -ENOMEM; 823 goto update_stats;
825 goto drop;
826 } 824 }
827 825
828 /* Copy the 802.11 header to the skb */ 826 /* Copy the 802.11 header to the skb */
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index ff192e96268a..dade4b903579 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -4306,7 +4306,7 @@ out:
4306 * Insertion of the module 4306 * Insertion of the module
4307 * I'm now quite proud of the multi-device support. 4307 * I'm now quite proud of the multi-device support.
4308 */ 4308 */
4309int init_module(void) 4309int __init init_module(void)
4310{ 4310{
4311 int ret = -EIO; /* Return error if no cards found */ 4311 int ret = -EIO; /* Return error if no cards found */
4312 int i; 4312 int i;