aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-10-15 18:03:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-10-15 18:03:17 -0400
commitc3da31485f074a6f598b67045b08e2e15d908310 (patch)
tree64f9ad3d3752e80de2b22b47cbea8f8512dc5d59 /drivers/net/wireless/b43
parentbd0704111e625ebe75418531550cf471215c3267 (diff)
parent8f7e524ce33ca81b663711404709396165da3cbd (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (53 commits) vmxnet: fix 2 build problems net: add support for STMicroelectronics Ethernet controllers. net: ks8851_mll uses mii interfaces net/fec_mpc52xx: Fix kernel panic on FEC error net: Fix OF platform drivers coldplug/hotplug when compiled as modules TI DaVinci EMAC: Clear statistics register properly. r8169: partial support and phy init for the 8168d irda/sa1100_ir: check return value of startup hook udp: Fix udp_poll() and ioctl() WAN: fix Cisco HDLC handshaking. tcp: fix tcp_defer_accept to consider the timeout 3c574_cs: spin_lock the set_multicast_list function net: Teach pegasus driver to ignore bluetoother adapters with clashing Vendor:Product IDs netxen: fix pci bar mapping ethoc: fix warning from 32bit build libertas: fix build net: VMware virtual Ethernet NIC driver: vmxnet3 net: Fix IXP 2000 network driver building. libertas: fix build mac80211: document ieee80211_rx() context requirement ...
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/b43.h168
-rw-r--r--drivers/net/wireless/b43/leds.c4
-rw-r--r--drivers/net/wireless/b43/leds.h4
-rw-r--r--drivers/net/wireless/b43/main.c7
-rw-r--r--drivers/net/wireless/b43/pio.c78
-rw-r--r--drivers/net/wireless/b43/xmit.c5
6 files changed, 144 insertions, 122 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index fa1549a03c71..660716214d49 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -607,82 +607,7 @@ struct b43_qos_params {
607 struct ieee80211_tx_queue_params p; 607 struct ieee80211_tx_queue_params p;
608}; 608};
609 609
610struct b43_wldev; 610struct b43_wl;
611
612/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
613struct b43_wl {
614 /* Pointer to the active wireless device on this chip */
615 struct b43_wldev *current_dev;
616 /* Pointer to the ieee80211 hardware data structure */
617 struct ieee80211_hw *hw;
618
619 /* Global driver mutex. Every operation must run with this mutex locked. */
620 struct mutex mutex;
621 /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
622 * handler, only. This basically is just the IRQ mask register. */
623 spinlock_t hardirq_lock;
624
625 /* The number of queues that were registered with the mac80211 subsystem
626 * initially. This is a backup copy of hw->queues in case hw->queues has
627 * to be dynamically lowered at runtime (Firmware does not support QoS).
628 * hw->queues has to be restored to the original value before unregistering
629 * from the mac80211 subsystem. */
630 u16 mac80211_initially_registered_queues;
631
632 /* We can only have one operating interface (802.11 core)
633 * at a time. General information about this interface follows.
634 */
635
636 struct ieee80211_vif *vif;
637 /* The MAC address of the operating interface. */
638 u8 mac_addr[ETH_ALEN];
639 /* Current BSSID */
640 u8 bssid[ETH_ALEN];
641 /* Interface type. (NL80211_IFTYPE_XXX) */
642 int if_type;
643 /* Is the card operating in AP, STA or IBSS mode? */
644 bool operating;
645 /* filter flags */
646 unsigned int filter_flags;
647 /* Stats about the wireless interface */
648 struct ieee80211_low_level_stats ieee_stats;
649
650#ifdef CONFIG_B43_HWRNG
651 struct hwrng rng;
652 bool rng_initialized;
653 char rng_name[30 + 1];
654#endif /* CONFIG_B43_HWRNG */
655
656 /* List of all wireless devices on this chip */
657 struct list_head devlist;
658 u8 nr_devs;
659
660 bool radiotap_enabled;
661 bool radio_enabled;
662
663 /* The beacon we are currently using (AP or IBSS mode). */
664 struct sk_buff *current_beacon;
665 bool beacon0_uploaded;
666 bool beacon1_uploaded;
667 bool beacon_templates_virgin; /* Never wrote the templates? */
668 struct work_struct beacon_update_trigger;
669
670 /* The current QOS parameters for the 4 queues. */
671 struct b43_qos_params qos_params[4];
672
673 /* Work for adjustment of the transmission power.
674 * This is scheduled when we determine that the actual TX output
675 * power doesn't match what we want. */
676 struct work_struct txpower_adjust_work;
677
678 /* Packet transmit work */
679 struct work_struct tx_work;
680 /* Queue of packets to be transmitted. */
681 struct sk_buff_head tx_queue;
682
683 /* The device LEDs. */
684 struct b43_leds leds;
685};
686 611
687/* The type of the firmware file. */ 612/* The type of the firmware file. */
688enum b43_firmware_file_type { 613enum b43_firmware_file_type {
@@ -824,6 +749,97 @@ struct b43_wldev {
824#endif 749#endif
825}; 750};
826 751
752/*
753 * Include goes here to avoid a dependency problem.
754 * A better fix would be to integrate xmit.h into b43.h.
755 */
756#include "xmit.h"
757
758/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
759struct b43_wl {
760 /* Pointer to the active wireless device on this chip */
761 struct b43_wldev *current_dev;
762 /* Pointer to the ieee80211 hardware data structure */
763 struct ieee80211_hw *hw;
764
765 /* Global driver mutex. Every operation must run with this mutex locked. */
766 struct mutex mutex;
767 /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
768 * handler, only. This basically is just the IRQ mask register. */
769 spinlock_t hardirq_lock;
770
771 /* The number of queues that were registered with the mac80211 subsystem
772 * initially. This is a backup copy of hw->queues in case hw->queues has
773 * to be dynamically lowered at runtime (Firmware does not support QoS).
774 * hw->queues has to be restored to the original value before unregistering
775 * from the mac80211 subsystem. */
776 u16 mac80211_initially_registered_queues;
777
778 /* We can only have one operating interface (802.11 core)
779 * at a time. General information about this interface follows.
780 */
781
782 struct ieee80211_vif *vif;
783 /* The MAC address of the operating interface. */
784 u8 mac_addr[ETH_ALEN];
785 /* Current BSSID */
786 u8 bssid[ETH_ALEN];
787 /* Interface type. (NL80211_IFTYPE_XXX) */
788 int if_type;
789 /* Is the card operating in AP, STA or IBSS mode? */
790 bool operating;
791 /* filter flags */
792 unsigned int filter_flags;
793 /* Stats about the wireless interface */
794 struct ieee80211_low_level_stats ieee_stats;
795
796#ifdef CONFIG_B43_HWRNG
797 struct hwrng rng;
798 bool rng_initialized;
799 char rng_name[30 + 1];
800#endif /* CONFIG_B43_HWRNG */
801
802 /* List of all wireless devices on this chip */
803 struct list_head devlist;
804 u8 nr_devs;
805
806 bool radiotap_enabled;
807 bool radio_enabled;
808
809 /* The beacon we are currently using (AP or IBSS mode). */
810 struct sk_buff *current_beacon;
811 bool beacon0_uploaded;
812 bool beacon1_uploaded;
813 bool beacon_templates_virgin; /* Never wrote the templates? */
814 struct work_struct beacon_update_trigger;
815
816 /* The current QOS parameters for the 4 queues. */
817 struct b43_qos_params qos_params[4];
818
819 /* Work for adjustment of the transmission power.
820 * This is scheduled when we determine that the actual TX output
821 * power doesn't match what we want. */
822 struct work_struct txpower_adjust_work;
823
824 /* Packet transmit work */
825 struct work_struct tx_work;
826 /* Queue of packets to be transmitted. */
827 struct sk_buff_head tx_queue;
828
829 /* The device LEDs. */
830 struct b43_leds leds;
831
832#ifdef CONFIG_B43_PIO
833 /*
834 * RX/TX header/tail buffers used by the frame transmit functions.
835 */
836 struct b43_rxhdr_fw4 rxhdr;
837 struct b43_txhdr txhdr;
838 u8 rx_tail[4];
839 u8 tx_tail[4];
840#endif /* CONFIG_B43_PIO */
841};
842
827static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) 843static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
828{ 844{
829 return hw->priv; 845 return hw->priv;
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index fbe3d4f62ce2..1e8dba488004 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -348,9 +348,9 @@ void b43_leds_register(struct b43_wldev *dev)
348 } 348 }
349} 349}
350 350
351void b43_leds_unregister(struct b43_wldev *dev) 351void b43_leds_unregister(struct b43_wl *wl)
352{ 352{
353 struct b43_leds *leds = &dev->wl->leds; 353 struct b43_leds *leds = &wl->leds;
354 354
355 b43_unregister_led(&leds->led_tx); 355 b43_unregister_led(&leds->led_tx);
356 b43_unregister_led(&leds->led_rx); 356 b43_unregister_led(&leds->led_rx);
diff --git a/drivers/net/wireless/b43/leds.h b/drivers/net/wireless/b43/leds.h
index 9592e4c5a5f5..4c56187810fc 100644
--- a/drivers/net/wireless/b43/leds.h
+++ b/drivers/net/wireless/b43/leds.h
@@ -60,7 +60,7 @@ enum b43_led_behaviour {
60}; 60};
61 61
62void b43_leds_register(struct b43_wldev *dev); 62void b43_leds_register(struct b43_wldev *dev);
63void b43_leds_unregister(struct b43_wldev *dev); 63void b43_leds_unregister(struct b43_wl *wl);
64void b43_leds_init(struct b43_wldev *dev); 64void b43_leds_init(struct b43_wldev *dev);
65void b43_leds_exit(struct b43_wldev *dev); 65void b43_leds_exit(struct b43_wldev *dev);
66void b43_leds_stop(struct b43_wldev *dev); 66void b43_leds_stop(struct b43_wldev *dev);
@@ -76,7 +76,7 @@ struct b43_leds {
76static inline void b43_leds_register(struct b43_wldev *dev) 76static inline void b43_leds_register(struct b43_wldev *dev)
77{ 77{
78} 78}
79static inline void b43_leds_unregister(struct b43_wldev *dev) 79static inline void b43_leds_unregister(struct b43_wl *wl)
80{ 80{
81} 81}
82static inline void b43_leds_init(struct b43_wldev *dev) 82static inline void b43_leds_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9b907a36bb8c..df6b26a0c05e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3874,6 +3874,7 @@ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
3874{ 3874{
3875 struct b43_wl *wl = dev->wl; 3875 struct b43_wl *wl = dev->wl;
3876 struct b43_wldev *orig_dev; 3876 struct b43_wldev *orig_dev;
3877 u32 mask;
3877 3878
3878redo: 3879redo:
3879 if (!dev || b43_status(dev) < B43_STAT_STARTED) 3880 if (!dev || b43_status(dev) < B43_STAT_STARTED)
@@ -3920,7 +3921,8 @@ redo:
3920 goto redo; 3921 goto redo;
3921 return dev; 3922 return dev;
3922 } 3923 }
3923 B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)); 3924 mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
3925 B43_WARN_ON(mask != 0xFFFFFFFF && mask);
3924 3926
3925 /* Drain the TX queue */ 3927 /* Drain the TX queue */
3926 while (skb_queue_len(&wl->tx_queue)) 3928 while (skb_queue_len(&wl->tx_queue))
@@ -4499,6 +4501,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4499 4501
4500 cancel_work_sync(&(wl->beacon_update_trigger)); 4502 cancel_work_sync(&(wl->beacon_update_trigger));
4501 4503
4504 wiphy_rfkill_stop_polling(hw->wiphy);
4502 mutex_lock(&wl->mutex); 4505 mutex_lock(&wl->mutex);
4503 if (b43_status(dev) >= B43_STAT_STARTED) { 4506 if (b43_status(dev) >= B43_STAT_STARTED) {
4504 dev = b43_wireless_core_stop(dev); 4507 dev = b43_wireless_core_stop(dev);
@@ -4997,7 +5000,7 @@ static void b43_remove(struct ssb_device *dev)
4997 5000
4998 if (list_empty(&wl->devlist)) { 5001 if (list_empty(&wl->devlist)) {
4999 b43_rng_exit(wl); 5002 b43_rng_exit(wl);
5000 b43_leds_unregister(wldev); 5003 b43_leds_unregister(wl);
5001 /* Last core on the chip unregistered. 5004 /* Last core on the chip unregistered.
5002 * We can destroy common struct b43_wl. 5005 * We can destroy common struct b43_wl.
5003 */ 5006 */
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 5e87650b07fb..9b9044400218 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -332,6 +332,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
332 unsigned int data_len) 332 unsigned int data_len)
333{ 333{
334 struct b43_wldev *dev = q->dev; 334 struct b43_wldev *dev = q->dev;
335 struct b43_wl *wl = dev->wl;
335 const u8 *data = _data; 336 const u8 *data = _data;
336 337
337 ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; 338 ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
@@ -341,13 +342,12 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
341 q->mmio_base + B43_PIO_TXDATA, 342 q->mmio_base + B43_PIO_TXDATA,
342 sizeof(u16)); 343 sizeof(u16));
343 if (data_len & 1) { 344 if (data_len & 1) {
344 u8 tail[2] = { 0, };
345
346 /* Write the last byte. */ 345 /* Write the last byte. */
347 ctl &= ~B43_PIO_TXCTL_WRITEHI; 346 ctl &= ~B43_PIO_TXCTL_WRITEHI;
348 b43_piotx_write16(q, B43_PIO_TXCTL, ctl); 347 b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
349 tail[0] = data[data_len - 1]; 348 wl->tx_tail[0] = data[data_len - 1];
350 ssb_block_write(dev->dev, tail, 2, 349 wl->tx_tail[1] = 0;
350 ssb_block_write(dev->dev, wl->tx_tail, 2,
351 q->mmio_base + B43_PIO_TXDATA, 351 q->mmio_base + B43_PIO_TXDATA,
352 sizeof(u16)); 352 sizeof(u16));
353 } 353 }
@@ -382,6 +382,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
382 unsigned int data_len) 382 unsigned int data_len)
383{ 383{
384 struct b43_wldev *dev = q->dev; 384 struct b43_wldev *dev = q->dev;
385 struct b43_wl *wl = dev->wl;
385 const u8 *data = _data; 386 const u8 *data = _data;
386 387
387 ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 | 388 ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
@@ -392,29 +393,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
392 q->mmio_base + B43_PIO8_TXDATA, 393 q->mmio_base + B43_PIO8_TXDATA,
393 sizeof(u32)); 394 sizeof(u32));
394 if (data_len & 3) { 395 if (data_len & 3) {
395 u8 tail[4] = { 0, }; 396 wl->tx_tail[3] = 0;
396
397 /* Write the last few bytes. */ 397 /* Write the last few bytes. */
398 ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | 398 ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
399 B43_PIO8_TXCTL_24_31); 399 B43_PIO8_TXCTL_24_31);
400 switch (data_len & 3) { 400 switch (data_len & 3) {
401 case 3: 401 case 3:
402 ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; 402 ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
403 tail[0] = data[data_len - 3]; 403 wl->tx_tail[0] = data[data_len - 3];
404 tail[1] = data[data_len - 2]; 404 wl->tx_tail[1] = data[data_len - 2];
405 tail[2] = data[data_len - 1]; 405 wl->tx_tail[2] = data[data_len - 1];
406 break; 406 break;
407 case 2: 407 case 2:
408 ctl |= B43_PIO8_TXCTL_8_15; 408 ctl |= B43_PIO8_TXCTL_8_15;
409 tail[0] = data[data_len - 2]; 409 wl->tx_tail[0] = data[data_len - 2];
410 tail[1] = data[data_len - 1]; 410 wl->tx_tail[1] = data[data_len - 1];
411 wl->tx_tail[2] = 0;
411 break; 412 break;
412 case 1: 413 case 1:
413 tail[0] = data[data_len - 1]; 414 wl->tx_tail[0] = data[data_len - 1];
415 wl->tx_tail[1] = 0;
416 wl->tx_tail[2] = 0;
414 break; 417 break;
415 } 418 }
416 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); 419 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
417 ssb_block_write(dev->dev, tail, 4, 420 ssb_block_write(dev->dev, wl->tx_tail, 4,
418 q->mmio_base + B43_PIO8_TXDATA, 421 q->mmio_base + B43_PIO8_TXDATA,
419 sizeof(u32)); 422 sizeof(u32));
420 } 423 }
@@ -446,8 +449,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
446static int pio_tx_frame(struct b43_pio_txqueue *q, 449static int pio_tx_frame(struct b43_pio_txqueue *q,
447 struct sk_buff *skb) 450 struct sk_buff *skb)
448{ 451{
452 struct b43_wldev *dev = q->dev;
453 struct b43_wl *wl = dev->wl;
449 struct b43_pio_txpacket *pack; 454 struct b43_pio_txpacket *pack;
450 struct b43_txhdr txhdr;
451 u16 cookie; 455 u16 cookie;
452 int err; 456 int err;
453 unsigned int hdrlen; 457 unsigned int hdrlen;
@@ -458,8 +462,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
458 struct b43_pio_txpacket, list); 462 struct b43_pio_txpacket, list);
459 463
460 cookie = generate_cookie(q, pack); 464 cookie = generate_cookie(q, pack);
461 hdrlen = b43_txhdr_size(q->dev); 465 hdrlen = b43_txhdr_size(dev);
462 err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb, 466 err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
463 info, cookie); 467 info, cookie);
464 if (err) 468 if (err)
465 return err; 469 return err;
@@ -467,15 +471,15 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
467 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { 471 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
468 /* Tell the firmware about the cookie of the last 472 /* Tell the firmware about the cookie of the last
469 * mcast frame, so it can clear the more-data bit in it. */ 473 * mcast frame, so it can clear the more-data bit in it. */
470 b43_shm_write16(q->dev, B43_SHM_SHARED, 474 b43_shm_write16(dev, B43_SHM_SHARED,
471 B43_SHM_SH_MCASTCOOKIE, cookie); 475 B43_SHM_SH_MCASTCOOKIE, cookie);
472 } 476 }
473 477
474 pack->skb = skb; 478 pack->skb = skb;
475 if (q->rev >= 8) 479 if (q->rev >= 8)
476 pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen); 480 pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
477 else 481 else
478 pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen); 482 pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
479 483
480 /* Remove it from the list of available packet slots. 484 /* Remove it from the list of available packet slots.
481 * It will be put back when we receive the status report. */ 485 * It will be put back when we receive the status report. */
@@ -615,14 +619,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
615static bool pio_rx_frame(struct b43_pio_rxqueue *q) 619static bool pio_rx_frame(struct b43_pio_rxqueue *q)
616{ 620{
617 struct b43_wldev *dev = q->dev; 621 struct b43_wldev *dev = q->dev;
618 struct b43_rxhdr_fw4 rxhdr; 622 struct b43_wl *wl = dev->wl;
619 u16 len; 623 u16 len;
620 u32 macstat; 624 u32 macstat;
621 unsigned int i, padding; 625 unsigned int i, padding;
622 struct sk_buff *skb; 626 struct sk_buff *skb;
623 const char *err_msg = NULL; 627 const char *err_msg = NULL;
624 628
625 memset(&rxhdr, 0, sizeof(rxhdr)); 629 memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
626 630
627 /* Check if we have data and wait for it to get ready. */ 631 /* Check if we have data and wait for it to get ready. */
628 if (q->rev >= 8) { 632 if (q->rev >= 8) {
@@ -660,16 +664,16 @@ data_ready:
660 664
661 /* Get the preamble (RX header) */ 665 /* Get the preamble (RX header) */
662 if (q->rev >= 8) { 666 if (q->rev >= 8) {
663 ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), 667 ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
664 q->mmio_base + B43_PIO8_RXDATA, 668 q->mmio_base + B43_PIO8_RXDATA,
665 sizeof(u32)); 669 sizeof(u32));
666 } else { 670 } else {
667 ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), 671 ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
668 q->mmio_base + B43_PIO_RXDATA, 672 q->mmio_base + B43_PIO_RXDATA,
669 sizeof(u16)); 673 sizeof(u16));
670 } 674 }
671 /* Sanity checks. */ 675 /* Sanity checks. */
672 len = le16_to_cpu(rxhdr.frame_len); 676 len = le16_to_cpu(wl->rxhdr.frame_len);
673 if (unlikely(len > 0x700)) { 677 if (unlikely(len > 0x700)) {
674 err_msg = "len > 0x700"; 678 err_msg = "len > 0x700";
675 goto rx_error; 679 goto rx_error;
@@ -679,7 +683,7 @@ data_ready:
679 goto rx_error; 683 goto rx_error;
680 } 684 }
681 685
682 macstat = le32_to_cpu(rxhdr.mac_status); 686 macstat = le32_to_cpu(wl->rxhdr.mac_status);
683 if (macstat & B43_RX_MAC_FCSERR) { 687 if (macstat & B43_RX_MAC_FCSERR) {
684 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { 688 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
685 /* Drop frames with failed FCS. */ 689 /* Drop frames with failed FCS. */
@@ -704,24 +708,22 @@ data_ready:
704 q->mmio_base + B43_PIO8_RXDATA, 708 q->mmio_base + B43_PIO8_RXDATA,
705 sizeof(u32)); 709 sizeof(u32));
706 if (len & 3) { 710 if (len & 3) {
707 u8 tail[4] = { 0, };
708
709 /* Read the last few bytes. */ 711 /* Read the last few bytes. */
710 ssb_block_read(dev->dev, tail, 4, 712 ssb_block_read(dev->dev, wl->rx_tail, 4,
711 q->mmio_base + B43_PIO8_RXDATA, 713 q->mmio_base + B43_PIO8_RXDATA,
712 sizeof(u32)); 714 sizeof(u32));
713 switch (len & 3) { 715 switch (len & 3) {
714 case 3: 716 case 3:
715 skb->data[len + padding - 3] = tail[0]; 717 skb->data[len + padding - 3] = wl->rx_tail[0];
716 skb->data[len + padding - 2] = tail[1]; 718 skb->data[len + padding - 2] = wl->rx_tail[1];
717 skb->data[len + padding - 1] = tail[2]; 719 skb->data[len + padding - 1] = wl->rx_tail[2];
718 break; 720 break;
719 case 2: 721 case 2:
720 skb->data[len + padding - 2] = tail[0]; 722 skb->data[len + padding - 2] = wl->rx_tail[0];
721 skb->data[len + padding - 1] = tail[1]; 723 skb->data[len + padding - 1] = wl->rx_tail[1];
722 break; 724 break;
723 case 1: 725 case 1:
724 skb->data[len + padding - 1] = tail[0]; 726 skb->data[len + padding - 1] = wl->rx_tail[0];
725 break; 727 break;
726 } 728 }
727 } 729 }
@@ -730,17 +732,15 @@ data_ready:
730 q->mmio_base + B43_PIO_RXDATA, 732 q->mmio_base + B43_PIO_RXDATA,
731 sizeof(u16)); 733 sizeof(u16));
732 if (len & 1) { 734 if (len & 1) {
733 u8 tail[2] = { 0, };
734
735 /* Read the last byte. */ 735 /* Read the last byte. */
736 ssb_block_read(dev->dev, tail, 2, 736 ssb_block_read(dev->dev, wl->rx_tail, 2,
737 q->mmio_base + B43_PIO_RXDATA, 737 q->mmio_base + B43_PIO_RXDATA,
738 sizeof(u16)); 738 sizeof(u16));
739 skb->data[len + padding - 1] = tail[0]; 739 skb->data[len + padding - 1] = wl->rx_tail[0];
740 } 740 }
741 } 741 }
742 742
743 b43_rx(q->dev, skb, &rxhdr); 743 b43_rx(q->dev, skb, &wl->rxhdr);
744 744
745 return 1; 745 return 1;
746 746
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index ac9f600995e4..f4e9695ec186 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -27,7 +27,7 @@
27 27
28*/ 28*/
29 29
30#include "xmit.h" 30#include "b43.h"
31#include "phy_common.h" 31#include "phy_common.h"
32#include "dma.h" 32#include "dma.h"
33#include "pio.h" 33#include "pio.h"
@@ -690,7 +690,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
690 } 690 }
691 691
692 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 692 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
693
694 local_bh_disable();
693 ieee80211_rx(dev->wl->hw, skb); 695 ieee80211_rx(dev->wl->hw, skb);
696 local_bh_enable();
694 697
695#if B43_DEBUG 698#if B43_DEBUG
696 dev->rx_count++; 699 dev->rx_count++;