aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/b44.c144
-rw-r--r--drivers/net/wireless/at76c50x-usb.c108
-rw-r--r--drivers/net/wireless/at76c50x-usb.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c20
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h19
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c373
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c79
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h9
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c152
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h310
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c13
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/gpio.c7
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c24
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c82
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c9
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c64
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c116
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c743
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h78
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c372
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c118
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h (renamed from drivers/net/wireless/ath/ath9k/ar9003_initvals.h)254
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h1785
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c185
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c714
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c513
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h298
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h88
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c314
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h77
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c68
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c29
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c618
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c71
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h37
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c163
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c491
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c86
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c240
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h98
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c58
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c416
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c184
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c296
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h67
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c150
-rw-r--r--drivers/net/wireless/b43/dma.c69
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/b43legacy/dma.c49
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c3
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c18
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c7
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig6
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c203
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c95
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c345
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c (renamed from drivers/net/wireless/iwlwifi/iwl-calib.c)26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c91
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c233
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c278
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c82
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c123
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c366
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c266
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c88
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h92
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c242
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c134
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c138
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c12
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c4
-rw-r--r--drivers/net/wireless/libertas/Makefile3
-rw-r--r--drivers/net/wireless/libertas/assoc.c2264
-rw-r--r--drivers/net/wireless/libertas/assoc.h155
-rw-r--r--drivers/net/wireless/libertas/cfg.c2038
-rw-r--r--drivers/net/wireless/libertas/cfg.h21
-rw-r--r--drivers/net/wireless/libertas/cmd.c124
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c111
-rw-r--r--drivers/net/wireless/libertas/debugfs.c54
-rw-r--r--drivers/net/wireless/libertas/decl.h10
-rw-r--r--drivers/net/wireless/libertas/dev.h68
-rw-r--r--drivers/net/wireless/libertas/ethtool.c29
-rw-r--r--drivers/net/wireless/libertas/host.h28
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c58
-rw-r--r--drivers/net/wireless/libertas/if_usb.c12
-rw-r--r--drivers/net/wireless/libertas/main.c305
-rw-r--r--drivers/net/wireless/libertas/mesh.c6
-rw-r--r--drivers/net/wireless/libertas/mesh.h5
-rw-r--r--drivers/net/wireless/libertas/rx.c121
-rw-r--r--drivers/net/wireless/libertas/scan.c1354
-rw-r--r--drivers/net/wireless/libertas/scan.h63
-rw-r--r--drivers/net/wireless/libertas/tx.c12
-rw-r--r--drivers/net/wireless/libertas/wext.c2353
-rw-r--r--drivers/net/wireless/libertas/wext.h17
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c5
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c5
-rw-r--r--drivers/net/wireless/mwl8k.c12
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c4
-rw-r--r--drivers/net/wireless/orinoco/wext.c4
-rw-r--r--drivers/net/wireless/p54/eeprom.c4
-rw-r--r--drivers/net/wireless/p54/p54spi.c5
-rw-r--r--drivers/net/wireless/p54/p54usb.c6
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c11
-rw-r--r--drivers/net/wireless/rndis_wlan.c56
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h57
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c210
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c136
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h19
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c106
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h37
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h42
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c47
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h26
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c51
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c43
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c33
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h19
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c59
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c51
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c2
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_sdio.c40
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c41
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h28
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c10
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ini.h123
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c95
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c11
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c36
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/ssb/driver_chipcommon.c25
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c17
-rw-r--r--drivers/ssb/main.c76
-rw-r--r--drivers/ssb/pci.c15
193 files changed, 12880 insertions, 11723 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 293f9c16e786..3d52538df6c4 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -150,9 +150,8 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
150 unsigned long offset, 150 unsigned long offset,
151 enum dma_data_direction dir) 151 enum dma_data_direction dir)
152{ 152{
153 ssb_dma_sync_single_range_for_device(sdev, dma_base, 153 dma_sync_single_for_device(sdev->dma_dev, dma_base + offset,
154 offset & dma_desc_align_mask, 154 dma_desc_sync_size, dir);
155 dma_desc_sync_size, dir);
156} 155}
157 156
158static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, 157static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
@@ -160,9 +159,8 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
160 unsigned long offset, 159 unsigned long offset,
161 enum dma_data_direction dir) 160 enum dma_data_direction dir)
162{ 161{
163 ssb_dma_sync_single_range_for_cpu(sdev, dma_base, 162 dma_sync_single_for_cpu(sdev->dma_dev, dma_base + offset,
164 offset & dma_desc_align_mask, 163 dma_desc_sync_size, dir);
165 dma_desc_sync_size, dir);
166} 164}
167 165
168static inline unsigned long br32(const struct b44 *bp, unsigned long reg) 166static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
@@ -608,10 +606,10 @@ static void b44_tx(struct b44 *bp)
608 606
609 BUG_ON(skb == NULL); 607 BUG_ON(skb == NULL);
610 608
611 ssb_dma_unmap_single(bp->sdev, 609 dma_unmap_single(bp->sdev->dma_dev,
612 rp->mapping, 610 rp->mapping,
613 skb->len, 611 skb->len,
614 DMA_TO_DEVICE); 612 DMA_TO_DEVICE);
615 rp->skb = NULL; 613 rp->skb = NULL;
616 dev_kfree_skb_irq(skb); 614 dev_kfree_skb_irq(skb);
617 } 615 }
@@ -648,29 +646,29 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
648 if (skb == NULL) 646 if (skb == NULL)
649 return -ENOMEM; 647 return -ENOMEM;
650 648
651 mapping = ssb_dma_map_single(bp->sdev, skb->data, 649 mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
652 RX_PKT_BUF_SZ, 650 RX_PKT_BUF_SZ,
653 DMA_FROM_DEVICE); 651 DMA_FROM_DEVICE);
654 652
655 /* Hardware bug work-around, the chip is unable to do PCI DMA 653 /* Hardware bug work-around, the chip is unable to do PCI DMA
656 to/from anything above 1GB :-( */ 654 to/from anything above 1GB :-( */
657 if (ssb_dma_mapping_error(bp->sdev, mapping) || 655 if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
658 mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) { 656 mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
659 /* Sigh... */ 657 /* Sigh... */
660 if (!ssb_dma_mapping_error(bp->sdev, mapping)) 658 if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
661 ssb_dma_unmap_single(bp->sdev, mapping, 659 dma_unmap_single(bp->sdev->dma_dev, mapping,
662 RX_PKT_BUF_SZ, DMA_FROM_DEVICE); 660 RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
663 dev_kfree_skb_any(skb); 661 dev_kfree_skb_any(skb);
664 skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); 662 skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
665 if (skb == NULL) 663 if (skb == NULL)
666 return -ENOMEM; 664 return -ENOMEM;
667 mapping = ssb_dma_map_single(bp->sdev, skb->data, 665 mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
668 RX_PKT_BUF_SZ, 666 RX_PKT_BUF_SZ,
669 DMA_FROM_DEVICE); 667 DMA_FROM_DEVICE);
670 if (ssb_dma_mapping_error(bp->sdev, mapping) || 668 if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
671 mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) { 669 mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
672 if (!ssb_dma_mapping_error(bp->sdev, mapping)) 670 if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
673 ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE); 671 dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
674 dev_kfree_skb_any(skb); 672 dev_kfree_skb_any(skb);
675 return -ENOMEM; 673 return -ENOMEM;
676 } 674 }
@@ -745,9 +743,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
745 dest_idx * sizeof(*dest_desc), 743 dest_idx * sizeof(*dest_desc),
746 DMA_BIDIRECTIONAL); 744 DMA_BIDIRECTIONAL);
747 745
748 ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping, 746 dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
749 RX_PKT_BUF_SZ, 747 RX_PKT_BUF_SZ,
750 DMA_FROM_DEVICE); 748 DMA_FROM_DEVICE);
751} 749}
752 750
753static int b44_rx(struct b44 *bp, int budget) 751static int b44_rx(struct b44 *bp, int budget)
@@ -767,9 +765,9 @@ static int b44_rx(struct b44 *bp, int budget)
767 struct rx_header *rh; 765 struct rx_header *rh;
768 u16 len; 766 u16 len;
769 767
770 ssb_dma_sync_single_for_cpu(bp->sdev, map, 768 dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
771 RX_PKT_BUF_SZ, 769 RX_PKT_BUF_SZ,
772 DMA_FROM_DEVICE); 770 DMA_FROM_DEVICE);
773 rh = (struct rx_header *) skb->data; 771 rh = (struct rx_header *) skb->data;
774 len = le16_to_cpu(rh->len); 772 len = le16_to_cpu(rh->len);
775 if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) || 773 if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) ||
@@ -801,8 +799,8 @@ static int b44_rx(struct b44 *bp, int budget)
801 skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); 799 skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
802 if (skb_size < 0) 800 if (skb_size < 0)
803 goto drop_it; 801 goto drop_it;
804 ssb_dma_unmap_single(bp->sdev, map, 802 dma_unmap_single(bp->sdev->dma_dev, map,
805 skb_size, DMA_FROM_DEVICE); 803 skb_size, DMA_FROM_DEVICE);
806 /* Leave out rx_header */ 804 /* Leave out rx_header */
807 skb_put(skb, len + RX_PKT_OFFSET); 805 skb_put(skb, len + RX_PKT_OFFSET);
808 skb_pull(skb, RX_PKT_OFFSET); 806 skb_pull(skb, RX_PKT_OFFSET);
@@ -954,24 +952,24 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
954 goto err_out; 952 goto err_out;
955 } 953 }
956 954
957 mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE); 955 mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
958 if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) { 956 if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
959 struct sk_buff *bounce_skb; 957 struct sk_buff *bounce_skb;
960 958
961 /* Chip can't handle DMA to/from >1GB, use bounce buffer */ 959 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
962 if (!ssb_dma_mapping_error(bp->sdev, mapping)) 960 if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
963 ssb_dma_unmap_single(bp->sdev, mapping, len, 961 dma_unmap_single(bp->sdev->dma_dev, mapping, len,
964 DMA_TO_DEVICE); 962 DMA_TO_DEVICE);
965 963
966 bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA); 964 bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA);
967 if (!bounce_skb) 965 if (!bounce_skb)
968 goto err_out; 966 goto err_out;
969 967
970 mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data, 968 mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
971 len, DMA_TO_DEVICE); 969 len, DMA_TO_DEVICE);
972 if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) { 970 if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
973 if (!ssb_dma_mapping_error(bp->sdev, mapping)) 971 if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
974 ssb_dma_unmap_single(bp->sdev, mapping, 972 dma_unmap_single(bp->sdev->dma_dev, mapping,
975 len, DMA_TO_DEVICE); 973 len, DMA_TO_DEVICE);
976 dev_kfree_skb_any(bounce_skb); 974 dev_kfree_skb_any(bounce_skb);
977 goto err_out; 975 goto err_out;
@@ -1068,8 +1066,8 @@ static void b44_free_rings(struct b44 *bp)
1068 1066
1069 if (rp->skb == NULL) 1067 if (rp->skb == NULL)
1070 continue; 1068 continue;
1071 ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ, 1069 dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
1072 DMA_FROM_DEVICE); 1070 DMA_FROM_DEVICE);
1073 dev_kfree_skb_any(rp->skb); 1071 dev_kfree_skb_any(rp->skb);
1074 rp->skb = NULL; 1072 rp->skb = NULL;
1075 } 1073 }
@@ -1080,8 +1078,8 @@ static void b44_free_rings(struct b44 *bp)
1080 1078
1081 if (rp->skb == NULL) 1079 if (rp->skb == NULL)
1082 continue; 1080 continue;
1083 ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len, 1081 dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
1084 DMA_TO_DEVICE); 1082 DMA_TO_DEVICE);
1085 dev_kfree_skb_any(rp->skb); 1083 dev_kfree_skb_any(rp->skb);
1086 rp->skb = NULL; 1084 rp->skb = NULL;
1087 } 1085 }
@@ -1103,14 +1101,12 @@ static void b44_init_rings(struct b44 *bp)
1103 memset(bp->tx_ring, 0, B44_TX_RING_BYTES); 1101 memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
1104 1102
1105 if (bp->flags & B44_FLAG_RX_RING_HACK) 1103 if (bp->flags & B44_FLAG_RX_RING_HACK)
1106 ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma, 1104 dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
1107 DMA_TABLE_BYTES, 1105 DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
1108 DMA_BIDIRECTIONAL);
1109 1106
1110 if (bp->flags & B44_FLAG_TX_RING_HACK) 1107 if (bp->flags & B44_FLAG_TX_RING_HACK)
1111 ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma, 1108 dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
1112 DMA_TABLE_BYTES, 1109 DMA_TABLE_BYTES, DMA_TO_DEVICE);
1113 DMA_TO_DEVICE);
1114 1110
1115 for (i = 0; i < bp->rx_pending; i++) { 1111 for (i = 0; i < bp->rx_pending; i++) {
1116 if (b44_alloc_rx_skb(bp, -1, i) < 0) 1112 if (b44_alloc_rx_skb(bp, -1, i) < 0)
@@ -1130,27 +1126,23 @@ static void b44_free_consistent(struct b44 *bp)
1130 bp->tx_buffers = NULL; 1126 bp->tx_buffers = NULL;
1131 if (bp->rx_ring) { 1127 if (bp->rx_ring) {
1132 if (bp->flags & B44_FLAG_RX_RING_HACK) { 1128 if (bp->flags & B44_FLAG_RX_RING_HACK) {
1133 ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma, 1129 dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
1134 DMA_TABLE_BYTES, 1130 DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
1135 DMA_BIDIRECTIONAL);
1136 kfree(bp->rx_ring); 1131 kfree(bp->rx_ring);
1137 } else 1132 } else
1138 ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES, 1133 dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
1139 bp->rx_ring, bp->rx_ring_dma, 1134 bp->rx_ring, bp->rx_ring_dma);
1140 GFP_KERNEL);
1141 bp->rx_ring = NULL; 1135 bp->rx_ring = NULL;
1142 bp->flags &= ~B44_FLAG_RX_RING_HACK; 1136 bp->flags &= ~B44_FLAG_RX_RING_HACK;
1143 } 1137 }
1144 if (bp->tx_ring) { 1138 if (bp->tx_ring) {
1145 if (bp->flags & B44_FLAG_TX_RING_HACK) { 1139 if (bp->flags & B44_FLAG_TX_RING_HACK) {
1146 ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma, 1140 dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
1147 DMA_TABLE_BYTES, 1141 DMA_TABLE_BYTES, DMA_TO_DEVICE);
1148 DMA_TO_DEVICE);
1149 kfree(bp->tx_ring); 1142 kfree(bp->tx_ring);
1150 } else 1143 } else
1151 ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES, 1144 dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
1152 bp->tx_ring, bp->tx_ring_dma, 1145 bp->tx_ring, bp->tx_ring_dma);
1153 GFP_KERNEL);
1154 bp->tx_ring = NULL; 1146 bp->tx_ring = NULL;
1155 bp->flags &= ~B44_FLAG_TX_RING_HACK; 1147 bp->flags &= ~B44_FLAG_TX_RING_HACK;
1156 } 1148 }
@@ -1175,7 +1167,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
1175 goto out_err; 1167 goto out_err;
1176 1168
1177 size = DMA_TABLE_BYTES; 1169 size = DMA_TABLE_BYTES;
1178 bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->rx_ring_dma, gfp); 1170 bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
1171 &bp->rx_ring_dma, gfp);
1179 if (!bp->rx_ring) { 1172 if (!bp->rx_ring) {
1180 /* Allocation may have failed due to pci_alloc_consistent 1173 /* Allocation may have failed due to pci_alloc_consistent
1181 insisting on use of GFP_DMA, which is more restrictive 1174 insisting on use of GFP_DMA, which is more restrictive
@@ -1187,11 +1180,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
1187 if (!rx_ring) 1180 if (!rx_ring)
1188 goto out_err; 1181 goto out_err;
1189 1182
1190 rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring, 1183 rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
1191 DMA_TABLE_BYTES, 1184 DMA_TABLE_BYTES,
1192 DMA_BIDIRECTIONAL); 1185 DMA_BIDIRECTIONAL);
1193 1186
1194 if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) || 1187 if (dma_mapping_error(bp->sdev->dma_dev, rx_ring_dma) ||
1195 rx_ring_dma + size > DMA_BIT_MASK(30)) { 1188 rx_ring_dma + size > DMA_BIT_MASK(30)) {
1196 kfree(rx_ring); 1189 kfree(rx_ring);
1197 goto out_err; 1190 goto out_err;
@@ -1202,7 +1195,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
1202 bp->flags |= B44_FLAG_RX_RING_HACK; 1195 bp->flags |= B44_FLAG_RX_RING_HACK;
1203 } 1196 }
1204 1197
1205 bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp); 1198 bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
1199 &bp->tx_ring_dma, gfp);
1206 if (!bp->tx_ring) { 1200 if (!bp->tx_ring) {
1207 /* Allocation may have failed due to ssb_dma_alloc_consistent 1201 /* Allocation may have failed due to ssb_dma_alloc_consistent
1208 insisting on use of GFP_DMA, which is more restrictive 1202 insisting on use of GFP_DMA, which is more restrictive
@@ -1214,11 +1208,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
1214 if (!tx_ring) 1208 if (!tx_ring)
1215 goto out_err; 1209 goto out_err;
1216 1210
1217 tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring, 1211 tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
1218 DMA_TABLE_BYTES, 1212 DMA_TABLE_BYTES,
1219 DMA_TO_DEVICE); 1213 DMA_TO_DEVICE);
1220 1214
1221 if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) || 1215 if (dma_mapping_error(bp->sdev->dma_dev, tx_ring_dma) ||
1222 tx_ring_dma + size > DMA_BIT_MASK(30)) { 1216 tx_ring_dma + size > DMA_BIT_MASK(30)) {
1223 kfree(tx_ring); 1217 kfree(tx_ring);
1224 goto out_err; 1218 goto out_err;
@@ -2176,12 +2170,14 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
2176 "Failed to powerup the bus\n"); 2170 "Failed to powerup the bus\n");
2177 goto err_out_free_dev; 2171 goto err_out_free_dev;
2178 } 2172 }
2179 err = ssb_dma_set_mask(sdev, DMA_BIT_MASK(30)); 2173
2180 if (err) { 2174 if (dma_set_mask(sdev->dma_dev, DMA_BIT_MASK(30)) ||
2175 dma_set_coherent_mask(sdev->dma_dev, DMA_BIT_MASK(30))) {
2181 dev_err(sdev->dev, 2176 dev_err(sdev->dev,
2182 "Required 30BIT DMA mask unsupported by the system\n"); 2177 "Required 30BIT DMA mask unsupported by the system\n");
2183 goto err_out_powerdown; 2178 goto err_out_powerdown;
2184 } 2179 }
2180
2185 err = b44_get_invariants(bp); 2181 err = b44_get_invariants(bp);
2186 if (err) { 2182 if (err) {
2187 dev_err(sdev->dev, 2183 dev_err(sdev->dev,
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 8a2d4afc74f8..98328b7f8332 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -7,6 +7,7 @@
7 * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com> 7 * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
8 * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org> 8 * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
9 * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi> 9 * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
10 * Copyright (c) 2010 Sebastian Smolorz <sesmo@gmx.net>
10 * 11 *
11 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as 13 * modify it under the terms of the GNU General Public License as
@@ -1649,6 +1650,58 @@ exit:
1649 return NULL; 1650 return NULL;
1650} 1651}
1651 1652
1653static int at76_join(struct at76_priv *priv)
1654{
1655 struct at76_req_join join;
1656 int ret;
1657
1658 memset(&join, 0, sizeof(struct at76_req_join));
1659 memcpy(join.essid, priv->essid, priv->essid_size);
1660 join.essid_size = priv->essid_size;
1661 memcpy(join.bssid, priv->bssid, ETH_ALEN);
1662 join.bss_type = INFRASTRUCTURE_MODE;
1663 join.channel = priv->channel;
1664 join.timeout = cpu_to_le16(2000);
1665
1666 at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
1667 ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
1668 sizeof(struct at76_req_join));
1669
1670 if (ret < 0) {
1671 printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
1672 wiphy_name(priv->hw->wiphy), ret);
1673 return 0;
1674 }
1675
1676 ret = at76_wait_completion(priv, CMD_JOIN);
1677 at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
1678 if (ret != CMD_STATUS_COMPLETE) {
1679 printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
1680 wiphy_name(priv->hw->wiphy), ret);
1681 return 0;
1682 }
1683
1684 at76_set_pm_mode(priv);
1685
1686 return 0;
1687}
1688
1689static void at76_work_join_bssid(struct work_struct *work)
1690{
1691 struct at76_priv *priv = container_of(work, struct at76_priv,
1692 work_join_bssid);
1693
1694 if (priv->device_unplugged)
1695 return;
1696
1697 mutex_lock(&priv->mtx);
1698
1699 if (is_valid_ether_addr(priv->bssid))
1700 at76_join(priv);
1701
1702 mutex_unlock(&priv->mtx);
1703}
1704
1652static void at76_mac80211_tx_callback(struct urb *urb) 1705static void at76_mac80211_tx_callback(struct urb *urb)
1653{ 1706{
1654 struct at76_priv *priv = urb->context; 1707 struct at76_priv *priv = urb->context;
@@ -1686,6 +1739,7 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1686 struct at76_priv *priv = hw->priv; 1739 struct at76_priv *priv = hw->priv;
1687 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; 1740 struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
1688 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1741 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1742 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1689 int padding, submit_len, ret; 1743 int padding, submit_len, ret;
1690 1744
1691 at76_dbg(DBG_MAC80211, "%s()", __func__); 1745 at76_dbg(DBG_MAC80211, "%s()", __func__);
@@ -1696,6 +1750,21 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1696 return NETDEV_TX_BUSY; 1750 return NETDEV_TX_BUSY;
1697 } 1751 }
1698 1752
1753 /* The following code lines are important when the device is going to
1754 * authenticate with a new bssid. The driver must send CMD_JOIN before
1755 * an authentication frame is transmitted. For this to succeed, the
1756 * correct bssid of the AP must be known. As mac80211 does not inform
1757 * drivers about the bssid prior to the authentication process the
1758 * following workaround is necessary. If the TX frame is an
1759 * authentication frame extract the bssid and send the CMD_JOIN. */
1760 if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) {
1761 if (compare_ether_addr(priv->bssid, mgmt->bssid)) {
1762 memcpy(priv->bssid, mgmt->bssid, ETH_ALEN);
1763 ieee80211_queue_work(hw, &priv->work_join_bssid);
1764 return NETDEV_TX_BUSY;
1765 }
1766 }
1767
1699 ieee80211_stop_queues(hw); 1768 ieee80211_stop_queues(hw);
1700 1769
1701 at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ 1770 at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
@@ -1770,6 +1839,7 @@ static void at76_mac80211_stop(struct ieee80211_hw *hw)
1770 at76_dbg(DBG_MAC80211, "%s()", __func__); 1839 at76_dbg(DBG_MAC80211, "%s()", __func__);
1771 1840
1772 cancel_delayed_work(&priv->dwork_hw_scan); 1841 cancel_delayed_work(&priv->dwork_hw_scan);
1842 cancel_work_sync(&priv->work_join_bssid);
1773 cancel_work_sync(&priv->work_set_promisc); 1843 cancel_work_sync(&priv->work_set_promisc);
1774 1844
1775 mutex_lock(&priv->mtx); 1845 mutex_lock(&priv->mtx);
@@ -1818,42 +1888,6 @@ static void at76_remove_interface(struct ieee80211_hw *hw,
1818 at76_dbg(DBG_MAC80211, "%s()", __func__); 1888 at76_dbg(DBG_MAC80211, "%s()", __func__);
1819} 1889}
1820 1890
1821static int at76_join(struct at76_priv *priv)
1822{
1823 struct at76_req_join join;
1824 int ret;
1825
1826 memset(&join, 0, sizeof(struct at76_req_join));
1827 memcpy(join.essid, priv->essid, priv->essid_size);
1828 join.essid_size = priv->essid_size;
1829 memcpy(join.bssid, priv->bssid, ETH_ALEN);
1830 join.bss_type = INFRASTRUCTURE_MODE;
1831 join.channel = priv->channel;
1832 join.timeout = cpu_to_le16(2000);
1833
1834 at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
1835 ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
1836 sizeof(struct at76_req_join));
1837
1838 if (ret < 0) {
1839 printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
1840 wiphy_name(priv->hw->wiphy), ret);
1841 return 0;
1842 }
1843
1844 ret = at76_wait_completion(priv, CMD_JOIN);
1845 at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
1846 if (ret != CMD_STATUS_COMPLETE) {
1847 printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
1848 wiphy_name(priv->hw->wiphy), ret);
1849 return 0;
1850 }
1851
1852 at76_set_pm_mode(priv);
1853
1854 return 0;
1855}
1856
1857static void at76_dwork_hw_scan(struct work_struct *work) 1891static void at76_dwork_hw_scan(struct work_struct *work)
1858{ 1892{
1859 struct at76_priv *priv = container_of(work, struct at76_priv, 1893 struct at76_priv *priv = container_of(work, struct at76_priv,
@@ -2107,6 +2141,7 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
2107 mutex_init(&priv->mtx); 2141 mutex_init(&priv->mtx);
2108 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); 2142 INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
2109 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); 2143 INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
2144 INIT_WORK(&priv->work_join_bssid, at76_work_join_bssid);
2110 INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan); 2145 INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
2111 2146
2112 tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0); 2147 tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0);
@@ -2508,5 +2543,6 @@ MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
2508MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); 2543MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
2509MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>"); 2544MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
2510MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>"); 2545MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
2546MODULE_AUTHOR("Sebastian Smolorz <sesmo@gmx.net>");
2511MODULE_DESCRIPTION(DRIVER_DESC); 2547MODULE_DESCRIPTION(DRIVER_DESC);
2512MODULE_LICENSE("GPL"); 2548MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h
index 1ec5ccffdbc0..db89d72df4f3 100644
--- a/drivers/net/wireless/at76c50x-usb.h
+++ b/drivers/net/wireless/at76c50x-usb.h
@@ -387,6 +387,7 @@ struct at76_priv {
387 /* work queues */ 387 /* work queues */
388 struct work_struct work_set_promisc; 388 struct work_struct work_set_promisc;
389 struct work_struct work_submit_rx; 389 struct work_struct work_submit_rx;
390 struct work_struct work_join_bssid;
390 struct delayed_work dwork_hw_scan; 391 struct delayed_work dwork_hw_scan;
391 392
392 struct tasklet_struct rx_tasklet; 393 struct tasklet_struct rx_tasklet;
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
index cc09595b781a..2242a140e4fe 100644
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -13,5 +13,6 @@ ath5k-y += base.o
13ath5k-y += led.o 13ath5k-y += led.o
14ath5k-y += rfkill.o 14ath5k-y += rfkill.o
15ath5k-y += ani.o 15ath5k-y += ani.o
16ath5k-y += sysfs.o
16ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o 17ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
17obj-$(CONFIG_ATH5K) += ath5k.o 18obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index f2311ab35504..26dbe65fedb0 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -74,8 +74,8 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
74 const s8 fr[] = { -78, -80 }; 74 const s8 fr[] = { -78, -80 };
75#endif 75#endif
76 if (level < 0 || level >= ARRAY_SIZE(sz)) { 76 if (level < 0 || level >= ARRAY_SIZE(sz)) {
77 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, 77 ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range",
78 "level out of range %d", level); 78 level);
79 return; 79 return;
80 } 80 }
81 81
@@ -106,8 +106,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
106 106
107 if (level < 0 || level >= ARRAY_SIZE(val) || 107 if (level < 0 || level >= ARRAY_SIZE(val) ||
108 level > ah->ah_sc->ani_state.max_spur_level) { 108 level > ah->ah_sc->ani_state.max_spur_level) {
109 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, 109 ATH5K_ERR(ah->ah_sc, "spur immunity level %d out of range",
110 "level out of range %d", level); 110 level);
111 return; 111 return;
112 } 112 }
113 113
@@ -130,8 +130,7 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
130 const int val[] = { 0, 4, 8 }; 130 const int val[] = { 0, 4, 8 };
131 131
132 if (level < 0 || level >= ARRAY_SIZE(val)) { 132 if (level < 0 || level >= ARRAY_SIZE(val)) {
133 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, 133 ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
134 "level out of range %d", level);
135 return; 134 return;
136 } 135 }
137 136
@@ -481,14 +480,15 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
481 struct ath5k_ani_state *as = &ah->ah_sc->ani_state; 480 struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
482 int listen, ofdm_high, ofdm_low, cck_high, cck_low; 481 int listen, ofdm_high, ofdm_low, cck_high, cck_low;
483 482
484 if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
485 return;
486
487 /* get listen time since last call and add it to the counter because we 483 /* get listen time since last call and add it to the counter because we
488 * might not have restarted the "ani period" last time */ 484 * might not have restarted the "ani period" last time.
485 * always do this to calculate the busy time also in manual mode */
489 listen = ath5k_hw_ani_get_listen_time(ah, as); 486 listen = ath5k_hw_ani_get_listen_time(ah, as);
490 as->listen_time += listen; 487 as->listen_time += listen;
491 488
489 if (as->ani_mode != ATH5K_ANI_MODE_AUTO)
490 return;
491
492 ath5k_ani_save_and_clear_phy_errors(ah, as); 492 ath5k_ani_save_and_clear_phy_errors(ah, as);
493 493
494 ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; 494 ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 2785946f659a..ea6362a8988d 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -204,6 +204,7 @@
204#define AR5K_TUNE_TPC_TXPOWER false 204#define AR5K_TUNE_TPC_TXPOWER false
205#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */ 205#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */
206#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ 206#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */
207#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */
207 208
208#define AR5K_INIT_CARR_SENSE_EN 1 209#define AR5K_INIT_CARR_SENSE_EN 1
209 210
@@ -565,7 +566,7 @@ enum ath5k_pkt_type {
565) 566)
566 567
567/* 568/*
568 * DMA size definitions (2^n+2) 569 * DMA size definitions (2^(n+2))
569 */ 570 */
570enum ath5k_dmasize { 571enum ath5k_dmasize {
571 AR5K_DMASIZE_4B = 0, 572 AR5K_DMASIZE_4B = 0,
@@ -1118,6 +1119,7 @@ struct ath5k_hw {
1118 /* Calibration timestamp */ 1119 /* Calibration timestamp */
1119 unsigned long ah_cal_next_full; 1120 unsigned long ah_cal_next_full;
1120 unsigned long ah_cal_next_ani; 1121 unsigned long ah_cal_next_ani;
1122 unsigned long ah_cal_next_nf;
1121 1123
1122 /* Calibration mask */ 1124 /* Calibration mask */
1123 u8 ah_cal_mask; 1125 u8 ah_cal_mask;
@@ -1125,15 +1127,10 @@ struct ath5k_hw {
1125 /* 1127 /*
1126 * Function pointers 1128 * Function pointers
1127 */ 1129 */
1128 int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
1129 u32 size, unsigned int flags);
1130 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1130 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1131 unsigned int, unsigned int, int, enum ath5k_pkt_type, 1131 unsigned int, unsigned int, int, enum ath5k_pkt_type,
1132 unsigned int, unsigned int, unsigned int, unsigned int, 1132 unsigned int, unsigned int, unsigned int, unsigned int,
1133 unsigned int, unsigned int, unsigned int, unsigned int); 1133 unsigned int, unsigned int, unsigned int, unsigned int);
1134 int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1135 unsigned int, unsigned int, unsigned int, unsigned int,
1136 unsigned int, unsigned int);
1137 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1134 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1138 struct ath5k_tx_status *); 1135 struct ath5k_tx_status *);
1139 int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1136 int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
@@ -1148,6 +1145,9 @@ struct ath5k_hw {
1148int ath5k_hw_attach(struct ath5k_softc *sc); 1145int ath5k_hw_attach(struct ath5k_softc *sc);
1149void ath5k_hw_detach(struct ath5k_hw *ah); 1146void ath5k_hw_detach(struct ath5k_hw *ah);
1150 1147
1148int ath5k_sysfs_register(struct ath5k_softc *sc);
1149void ath5k_sysfs_unregister(struct ath5k_softc *sc);
1150
1151/* LED functions */ 1151/* LED functions */
1152int ath5k_init_leds(struct ath5k_softc *sc); 1152int ath5k_init_leds(struct ath5k_softc *sc);
1153void ath5k_led_enable(struct ath5k_softc *sc); 1153void ath5k_led_enable(struct ath5k_softc *sc);
@@ -1231,6 +1231,11 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1231 1231
1232/* Hardware Descriptor Functions */ 1232/* Hardware Descriptor Functions */
1233int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); 1233int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
1234int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
1235 u32 size, unsigned int flags);
1236int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
1237 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
1238 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3);
1234 1239
1235/* GPIO Functions */ 1240/* GPIO Functions */
1236void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); 1241void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
@@ -1270,6 +1275,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1270void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); 1275void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
1271int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, 1276int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1272 struct ieee80211_channel *channel); 1277 struct ieee80211_channel *channel);
1278void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
1273/* Spur mitigation */ 1279/* Spur mitigation */
1274bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, 1280bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
1275 struct ieee80211_channel *channel); 1281 struct ieee80211_channel *channel);
@@ -1280,6 +1286,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1280int ath5k_hw_phy_disable(struct ath5k_hw *ah); 1286int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1281/* Antenna control */ 1287/* Antenna control */
1282void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); 1288void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
1289void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
1283/* TX power setup */ 1290/* TX power setup */
1284int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, 1291int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1285 u8 ee_mode, u8 txpower); 1292 u8 ee_mode, u8 txpower);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 31c008042bfe..b32e28caeee2 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -352,8 +352,6 @@ err_free:
352 */ 352 */
353void ath5k_hw_detach(struct ath5k_hw *ah) 353void ath5k_hw_detach(struct ath5k_hw *ah)
354{ 354{
355 ATH5K_TRACE(ah->ah_sc);
356
357 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); 355 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
358 356
359 if (ah->ah_rf_banks != NULL) 357 if (ah->ah_rf_banks != NULL)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 648972df369d..20328bdd138b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -311,7 +311,8 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
311static int ath5k_txbuf_setup(struct ath5k_softc *sc, 311static int ath5k_txbuf_setup(struct ath5k_softc *sc,
312 struct ath5k_buf *bf, 312 struct ath5k_buf *bf,
313 struct ath5k_txq *txq, int padsize); 313 struct ath5k_txq *txq, int padsize);
314static inline void ath5k_txbuf_free(struct ath5k_softc *sc, 314
315static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc,
315 struct ath5k_buf *bf) 316 struct ath5k_buf *bf)
316{ 317{
317 BUG_ON(!bf); 318 BUG_ON(!bf);
@@ -321,9 +322,11 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
321 PCI_DMA_TODEVICE); 322 PCI_DMA_TODEVICE);
322 dev_kfree_skb_any(bf->skb); 323 dev_kfree_skb_any(bf->skb);
323 bf->skb = NULL; 324 bf->skb = NULL;
325 bf->skbaddr = 0;
326 bf->desc->ds_data = 0;
324} 327}
325 328
326static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, 329static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc,
327 struct ath5k_buf *bf) 330 struct ath5k_buf *bf)
328{ 331{
329 struct ath5k_hw *ah = sc->ah; 332 struct ath5k_hw *ah = sc->ah;
@@ -336,6 +339,8 @@ static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
336 PCI_DMA_FROMDEVICE); 339 PCI_DMA_FROMDEVICE);
337 dev_kfree_skb_any(bf->skb); 340 dev_kfree_skb_any(bf->skb);
338 bf->skb = NULL; 341 bf->skb = NULL;
342 bf->skbaddr = 0;
343 bf->desc->ds_data = 0;
339} 344}
340 345
341 346
@@ -352,7 +357,6 @@ static void ath5k_txq_release(struct ath5k_softc *sc);
352static int ath5k_rx_start(struct ath5k_softc *sc); 357static int ath5k_rx_start(struct ath5k_softc *sc);
353static void ath5k_rx_stop(struct ath5k_softc *sc); 358static void ath5k_rx_stop(struct ath5k_softc *sc);
354static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, 359static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
355 struct ath5k_desc *ds,
356 struct sk_buff *skb, 360 struct sk_buff *skb,
357 struct ath5k_rx_status *rs); 361 struct ath5k_rx_status *rs);
358static void ath5k_tasklet_rx(unsigned long data); 362static void ath5k_tasklet_rx(unsigned long data);
@@ -578,7 +582,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
578 spin_lock_init(&sc->block); 582 spin_lock_init(&sc->block);
579 583
580 /* Set private data */ 584 /* Set private data */
581 pci_set_drvdata(pdev, hw); 585 pci_set_drvdata(pdev, sc);
582 586
583 /* Setup interrupt handler */ 587 /* Setup interrupt handler */
584 ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); 588 ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
@@ -694,25 +698,23 @@ err:
694static void __devexit 698static void __devexit
695ath5k_pci_remove(struct pci_dev *pdev) 699ath5k_pci_remove(struct pci_dev *pdev)
696{ 700{
697 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 701 struct ath5k_softc *sc = pci_get_drvdata(pdev);
698 struct ath5k_softc *sc = hw->priv;
699 702
700 ath5k_debug_finish_device(sc); 703 ath5k_debug_finish_device(sc);
701 ath5k_detach(pdev, hw); 704 ath5k_detach(pdev, sc->hw);
702 ath5k_hw_detach(sc->ah); 705 ath5k_hw_detach(sc->ah);
703 kfree(sc->ah); 706 kfree(sc->ah);
704 free_irq(pdev->irq, sc); 707 free_irq(pdev->irq, sc);
705 pci_iounmap(pdev, sc->iobase); 708 pci_iounmap(pdev, sc->iobase);
706 pci_release_region(pdev, 0); 709 pci_release_region(pdev, 0);
707 pci_disable_device(pdev); 710 pci_disable_device(pdev);
708 ieee80211_free_hw(hw); 711 ieee80211_free_hw(sc->hw);
709} 712}
710 713
711#ifdef CONFIG_PM_SLEEP 714#ifdef CONFIG_PM_SLEEP
712static int ath5k_pci_suspend(struct device *dev) 715static int ath5k_pci_suspend(struct device *dev)
713{ 716{
714 struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); 717 struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
715 struct ath5k_softc *sc = hw->priv;
716 718
717 ath5k_led_off(sc); 719 ath5k_led_off(sc);
718 return 0; 720 return 0;
@@ -721,8 +723,7 @@ static int ath5k_pci_suspend(struct device *dev)
721static int ath5k_pci_resume(struct device *dev) 723static int ath5k_pci_resume(struct device *dev)
722{ 724{
723 struct pci_dev *pdev = to_pci_dev(dev); 725 struct pci_dev *pdev = to_pci_dev(dev);
724 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 726 struct ath5k_softc *sc = pci_get_drvdata(pdev);
725 struct ath5k_softc *sc = hw->priv;
726 727
727 /* 728 /*
728 * Suspend/Resume resets the PCI configuration space, so we have to 729 * Suspend/Resume resets the PCI configuration space, so we have to
@@ -768,7 +769,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
768 * return false w/o doing anything. MAC's that do 769 * return false w/o doing anything. MAC's that do
769 * support it will return true w/o doing anything. 770 * support it will return true w/o doing anything.
770 */ 771 */
771 ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); 772 ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
773
772 if (ret < 0) 774 if (ret < 0)
773 goto err; 775 goto err;
774 if (ret > 0) 776 if (ret > 0)
@@ -864,6 +866,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
864 866
865 ath5k_init_leds(sc); 867 ath5k_init_leds(sc);
866 868
869 ath5k_sysfs_register(sc);
870
867 return 0; 871 return 0;
868err_queues: 872err_queues:
869 ath5k_txq_release(sc); 873 ath5k_txq_release(sc);
@@ -899,6 +903,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
899 ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); 903 ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
900 ath5k_unregister_leds(sc); 904 ath5k_unregister_leds(sc);
901 905
906 ath5k_sysfs_unregister(sc);
902 /* 907 /*
903 * NB: can't reclaim these until after ieee80211_ifdetach 908 * NB: can't reclaim these until after ieee80211_ifdetach
904 * returns because we'll get called back to reclaim node 909 * returns because we'll get called back to reclaim node
@@ -1111,8 +1116,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
1111static int 1116static int
1112ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) 1117ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
1113{ 1118{
1114 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", 1119 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
1115 sc->curchan->center_freq, chan->center_freq); 1120 "channel set, resetting (%u -> %u MHz)\n",
1121 sc->curchan->center_freq, chan->center_freq);
1116 1122
1117 /* 1123 /*
1118 * To switch channels clear any pending DMA operations; 1124 * To switch channels clear any pending DMA operations;
@@ -1228,21 +1234,23 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1228 * not get overrun under high load (as can happen with a 1234 * not get overrun under high load (as can happen with a
1229 * 5212 when ANI processing enables PHY error frames). 1235 * 5212 when ANI processing enables PHY error frames).
1230 * 1236 *
1231 * To insure the last descriptor is self-linked we create 1237 * To ensure the last descriptor is self-linked we create
1232 * each descriptor as self-linked and add it to the end. As 1238 * each descriptor as self-linked and add it to the end. As
1233 * each additional descriptor is added the previous self-linked 1239 * each additional descriptor is added the previous self-linked
1234 * entry is ``fixed'' naturally. This should be safe even 1240 * entry is "fixed" naturally. This should be safe even
1235 * if DMA is happening. When processing RX interrupts we 1241 * if DMA is happening. When processing RX interrupts we
1236 * never remove/process the last, self-linked, entry on the 1242 * never remove/process the last, self-linked, entry on the
1237 * descriptor list. This insures the hardware always has 1243 * descriptor list. This ensures the hardware always has
1238 * someplace to write a new frame. 1244 * someplace to write a new frame.
1239 */ 1245 */
1240 ds = bf->desc; 1246 ds = bf->desc;
1241 ds->ds_link = bf->daddr; /* link to self */ 1247 ds->ds_link = bf->daddr; /* link to self */
1242 ds->ds_data = bf->skbaddr; 1248 ds->ds_data = bf->skbaddr;
1243 ret = ah->ah_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); 1249 ret = ath5k_hw_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0);
1244 if (ret) 1250 if (ret) {
1251 ATH5K_ERR(sc, "%s: could not setup RX desc\n", __func__);
1245 return ret; 1252 return ret;
1253 }
1246 1254
1247 if (sc->rxlink != NULL) 1255 if (sc->rxlink != NULL)
1248 *sc->rxlink = bf->daddr; 1256 *sc->rxlink = bf->daddr;
@@ -1347,7 +1355,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1347 mrr_tries[i] = info->control.rates[i + 1].count; 1355 mrr_tries[i] = info->control.rates[i + 1].count;
1348 } 1356 }
1349 1357
1350 ah->ah_setup_mrr_tx_desc(ah, ds, 1358 ath5k_hw_setup_mrr_tx_desc(ah, ds,
1351 mrr_rate[0], mrr_tries[0], 1359 mrr_rate[0], mrr_tries[0],
1352 mrr_rate[1], mrr_tries[1], 1360 mrr_rate[1], mrr_tries[1],
1353 mrr_rate[2], mrr_tries[2]); 1361 mrr_rate[2], mrr_tries[2]);
@@ -1443,17 +1451,20 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
1443{ 1451{
1444 struct ath5k_buf *bf; 1452 struct ath5k_buf *bf;
1445 1453
1446 ath5k_txbuf_free(sc, sc->bbuf); 1454 ath5k_txbuf_free_skb(sc, sc->bbuf);
1447 list_for_each_entry(bf, &sc->txbuf, list) 1455 list_for_each_entry(bf, &sc->txbuf, list)
1448 ath5k_txbuf_free(sc, bf); 1456 ath5k_txbuf_free_skb(sc, bf);
1449 list_for_each_entry(bf, &sc->rxbuf, list) 1457 list_for_each_entry(bf, &sc->rxbuf, list)
1450 ath5k_rxbuf_free(sc, bf); 1458 ath5k_rxbuf_free_skb(sc, bf);
1451 1459
1452 /* Free memory associated with all descriptors */ 1460 /* Free memory associated with all descriptors */
1453 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); 1461 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
1462 sc->desc = NULL;
1463 sc->desc_daddr = 0;
1454 1464
1455 kfree(sc->bufptr); 1465 kfree(sc->bufptr);
1456 sc->bufptr = NULL; 1466 sc->bufptr = NULL;
1467 sc->bbuf = NULL;
1457} 1468}
1458 1469
1459 1470
@@ -1602,7 +1613,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1602 list_for_each_entry_safe(bf, bf0, &txq->q, list) { 1613 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
1603 ath5k_debug_printtxbuf(sc, bf); 1614 ath5k_debug_printtxbuf(sc, bf);
1604 1615
1605 ath5k_txbuf_free(sc, bf); 1616 ath5k_txbuf_free_skb(sc, bf);
1606 1617
1607 spin_lock_bh(&sc->txbuflock); 1618 spin_lock_bh(&sc->txbuflock);
1608 list_move_tail(&bf->list, &sc->txbuf); 1619 list_move_tail(&bf->list, &sc->txbuf);
@@ -1721,8 +1732,8 @@ ath5k_rx_stop(struct ath5k_softc *sc)
1721} 1732}
1722 1733
1723static unsigned int 1734static unsigned int
1724ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, 1735ath5k_rx_decrypted(struct ath5k_softc *sc, struct sk_buff *skb,
1725 struct sk_buff *skb, struct ath5k_rx_status *rs) 1736 struct ath5k_rx_status *rs)
1726{ 1737{
1727 struct ath5k_hw *ah = sc->ah; 1738 struct ath5k_hw *ah = sc->ah;
1728 struct ath_common *common = ath5k_hw_common(ah); 1739 struct ath_common *common = ath5k_hw_common(ah);
@@ -1889,9 +1900,138 @@ static int ath5k_remove_padding(struct sk_buff *skb)
1889} 1900}
1890 1901
1891static void 1902static void
1892ath5k_tasklet_rx(unsigned long data) 1903ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
1904 struct ath5k_rx_status *rs)
1893{ 1905{
1894 struct ieee80211_rx_status *rxs; 1906 struct ieee80211_rx_status *rxs;
1907
1908 /* The MAC header is padded to have 32-bit boundary if the
1909 * packet payload is non-zero. The general calculation for
1910 * padsize would take into account odd header lengths:
1911 * padsize = (4 - hdrlen % 4) % 4; However, since only
1912 * even-length headers are used, padding can only be 0 or 2
1913 * bytes and we can optimize this a bit. In addition, we must
1914 * not try to remove padding from short control frames that do
1915 * not have payload. */
1916 ath5k_remove_padding(skb);
1917
1918 rxs = IEEE80211_SKB_RXCB(skb);
1919
1920 rxs->flag = 0;
1921 if (unlikely(rs->rs_status & AR5K_RXERR_MIC))
1922 rxs->flag |= RX_FLAG_MMIC_ERROR;
1923
1924 /*
1925 * always extend the mac timestamp, since this information is
1926 * also needed for proper IBSS merging.
1927 *
1928 * XXX: it might be too late to do it here, since rs_tstamp is
1929 * 15bit only. that means TSF extension has to be done within
1930 * 32768usec (about 32ms). it might be necessary to move this to
1931 * the interrupt handler, like it is done in madwifi.
1932 *
1933 * Unfortunately we don't know when the hardware takes the rx
1934 * timestamp (beginning of phy frame, data frame, end of rx?).
1935 * The only thing we know is that it is hardware specific...
1936 * On AR5213 it seems the rx timestamp is at the end of the
1937 * frame, but i'm not sure.
1938 *
1939 * NOTE: mac80211 defines mactime at the beginning of the first
1940 * data symbol. Since we don't have any time references it's
1941 * impossible to comply to that. This affects IBSS merge only
1942 * right now, so it's not too bad...
1943 */
1944 rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp);
1945 rxs->flag |= RX_FLAG_TSFT;
1946
1947 rxs->freq = sc->curchan->center_freq;
1948 rxs->band = sc->curband->band;
1949
1950 rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi;
1951
1952 rxs->antenna = rs->rs_antenna;
1953
1954 if (rs->rs_antenna > 0 && rs->rs_antenna < 5)
1955 sc->stats.antenna_rx[rs->rs_antenna]++;
1956 else
1957 sc->stats.antenna_rx[0]++; /* invalid */
1958
1959 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs->rs_rate);
1960 rxs->flag |= ath5k_rx_decrypted(sc, skb, rs);
1961
1962 if (rxs->rate_idx >= 0 && rs->rs_rate ==
1963 sc->curband->bitrates[rxs->rate_idx].hw_value_short)
1964 rxs->flag |= RX_FLAG_SHORTPRE;
1965
1966 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
1967
1968 ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);
1969
1970 /* check beacons in IBSS mode */
1971 if (sc->opmode == NL80211_IFTYPE_ADHOC)
1972 ath5k_check_ibss_tsf(sc, skb, rxs);
1973
1974 ieee80211_rx(sc->hw, skb);
1975}
1976
1977/** ath5k_frame_receive_ok() - Do we want to receive this frame or not?
1978 *
1979 * Check if we want to further process this frame or not. Also update
1980 * statistics. Return true if we want this frame, false if not.
1981 */
1982static bool
1983ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
1984{
1985 sc->stats.rx_all_count++;
1986
1987 if (unlikely(rs->rs_status)) {
1988 if (rs->rs_status & AR5K_RXERR_CRC)
1989 sc->stats.rxerr_crc++;
1990 if (rs->rs_status & AR5K_RXERR_FIFO)
1991 sc->stats.rxerr_fifo++;
1992 if (rs->rs_status & AR5K_RXERR_PHY) {
1993 sc->stats.rxerr_phy++;
1994 if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32)
1995 sc->stats.rxerr_phy_code[rs->rs_phyerr]++;
1996 return false;
1997 }
1998 if (rs->rs_status & AR5K_RXERR_DECRYPT) {
1999 /*
2000 * Decrypt error. If the error occurred
2001 * because there was no hardware key, then
2002 * let the frame through so the upper layers
2003 * can process it. This is necessary for 5210
2004 * parts which have no way to setup a ``clear''
2005 * key cache entry.
2006 *
2007 * XXX do key cache faulting
2008 */
2009 sc->stats.rxerr_decrypt++;
2010 if (rs->rs_keyix == AR5K_RXKEYIX_INVALID &&
2011 !(rs->rs_status & AR5K_RXERR_CRC))
2012 return true;
2013 }
2014 if (rs->rs_status & AR5K_RXERR_MIC) {
2015 sc->stats.rxerr_mic++;
2016 return true;
2017 }
2018
2019 /* let crypto-error packets fall through in MNTR */
2020 if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
2021 sc->opmode != NL80211_IFTYPE_MONITOR)
2022 return false;
2023 }
2024
2025 if (unlikely(rs->rs_more)) {
2026 sc->stats.rxerr_jumbo++;
2027 return false;
2028 }
2029 return true;
2030}
2031
2032static void
2033ath5k_tasklet_rx(unsigned long data)
2034{
1895 struct ath5k_rx_status rs = {}; 2035 struct ath5k_rx_status rs = {};
1896 struct sk_buff *skb, *next_skb; 2036 struct sk_buff *skb, *next_skb;
1897 dma_addr_t next_skb_addr; 2037 dma_addr_t next_skb_addr;
@@ -1901,7 +2041,6 @@ ath5k_tasklet_rx(unsigned long data)
1901 struct ath5k_buf *bf; 2041 struct ath5k_buf *bf;
1902 struct ath5k_desc *ds; 2042 struct ath5k_desc *ds;
1903 int ret; 2043 int ret;
1904 int rx_flag;
1905 2044
1906 spin_lock(&sc->rxbuflock); 2045 spin_lock(&sc->rxbuflock);
1907 if (list_empty(&sc->rxbuf)) { 2046 if (list_empty(&sc->rxbuf)) {
@@ -1909,8 +2048,6 @@ ath5k_tasklet_rx(unsigned long data)
1909 goto unlock; 2048 goto unlock;
1910 } 2049 }
1911 do { 2050 do {
1912 rx_flag = 0;
1913
1914 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); 2051 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
1915 BUG_ON(bf->skb == NULL); 2052 BUG_ON(bf->skb == NULL);
1916 skb = bf->skb; 2053 skb = bf->skb;
@@ -1926,137 +2063,30 @@ ath5k_tasklet_rx(unsigned long data)
1926 else if (unlikely(ret)) { 2063 else if (unlikely(ret)) {
1927 ATH5K_ERR(sc, "error in processing rx descriptor\n"); 2064 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1928 sc->stats.rxerr_proc++; 2065 sc->stats.rxerr_proc++;
1929 spin_unlock(&sc->rxbuflock); 2066 break;
1930 return;
1931 } 2067 }
1932 2068
1933 sc->stats.rx_all_count++; 2069 if (ath5k_receive_frame_ok(sc, &rs)) {
1934 2070 next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
1935 if (unlikely(rs.rs_status)) {
1936 if (rs.rs_status & AR5K_RXERR_CRC)
1937 sc->stats.rxerr_crc++;
1938 if (rs.rs_status & AR5K_RXERR_FIFO)
1939 sc->stats.rxerr_fifo++;
1940 if (rs.rs_status & AR5K_RXERR_PHY) {
1941 sc->stats.rxerr_phy++;
1942 if (rs.rs_phyerr > 0 && rs.rs_phyerr < 32)
1943 sc->stats.rxerr_phy_code[rs.rs_phyerr]++;
1944 goto next;
1945 }
1946 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1947 /*
1948 * Decrypt error. If the error occurred
1949 * because there was no hardware key, then
1950 * let the frame through so the upper layers
1951 * can process it. This is necessary for 5210
1952 * parts which have no way to setup a ``clear''
1953 * key cache entry.
1954 *
1955 * XXX do key cache faulting
1956 */
1957 sc->stats.rxerr_decrypt++;
1958 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1959 !(rs.rs_status & AR5K_RXERR_CRC))
1960 goto accept;
1961 }
1962 if (rs.rs_status & AR5K_RXERR_MIC) {
1963 rx_flag |= RX_FLAG_MMIC_ERROR;
1964 sc->stats.rxerr_mic++;
1965 goto accept;
1966 }
1967 2071
1968 /* let crypto-error packets fall through in MNTR */ 2072 /*
1969 if ((rs.rs_status & 2073 * If we can't replace bf->skb with a new skb under
1970 ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || 2074 * memory pressure, just skip this packet
1971 sc->opmode != NL80211_IFTYPE_MONITOR) 2075 */
2076 if (!next_skb)
1972 goto next; 2077 goto next;
1973 }
1974
1975 if (unlikely(rs.rs_more)) {
1976 sc->stats.rxerr_jumbo++;
1977 goto next;
1978
1979 }
1980accept:
1981 next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
1982
1983 /*
1984 * If we can't replace bf->skb with a new skb under memory
1985 * pressure, just skip this packet
1986 */
1987 if (!next_skb)
1988 goto next;
1989
1990 pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,
1991 PCI_DMA_FROMDEVICE);
1992 skb_put(skb, rs.rs_datalen);
1993
1994 /* The MAC header is padded to have 32-bit boundary if the
1995 * packet payload is non-zero. The general calculation for
1996 * padsize would take into account odd header lengths:
1997 * padsize = (4 - hdrlen % 4) % 4; However, since only
1998 * even-length headers are used, padding can only be 0 or 2
1999 * bytes and we can optimize this a bit. In addition, we must
2000 * not try to remove padding from short control frames that do
2001 * not have payload. */
2002 ath5k_remove_padding(skb);
2003
2004 rxs = IEEE80211_SKB_RXCB(skb);
2005
2006 /*
2007 * always extend the mac timestamp, since this information is
2008 * also needed for proper IBSS merging.
2009 *
2010 * XXX: it might be too late to do it here, since rs_tstamp is
2011 * 15bit only. that means TSF extension has to be done within
2012 * 32768usec (about 32ms). it might be necessary to move this to
2013 * the interrupt handler, like it is done in madwifi.
2014 *
2015 * Unfortunately we don't know when the hardware takes the rx
2016 * timestamp (beginning of phy frame, data frame, end of rx?).
2017 * The only thing we know is that it is hardware specific...
2018 * On AR5213 it seems the rx timestamp is at the end of the
2019 * frame, but i'm not sure.
2020 *
2021 * NOTE: mac80211 defines mactime at the beginning of the first
2022 * data symbol. Since we don't have any time references it's
2023 * impossible to comply to that. This affects IBSS merge only
2024 * right now, so it's not too bad...
2025 */
2026 rxs->mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
2027 rxs->flag = rx_flag | RX_FLAG_TSFT;
2028
2029 rxs->freq = sc->curchan->center_freq;
2030 rxs->band = sc->curband->band;
2031
2032 rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi;
2033
2034 rxs->antenna = rs.rs_antenna;
2035
2036 if (rs.rs_antenna > 0 && rs.rs_antenna < 5)
2037 sc->stats.antenna_rx[rs.rs_antenna]++;
2038 else
2039 sc->stats.antenna_rx[0]++; /* invalid */
2040
2041 rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
2042 rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
2043
2044 if (rxs->rate_idx >= 0 && rs.rs_rate ==
2045 sc->curband->bitrates[rxs->rate_idx].hw_value_short)
2046 rxs->flag |= RX_FLAG_SHORTPRE;
2047 2078
2048 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 2079 pci_unmap_single(sc->pdev, bf->skbaddr,
2080 common->rx_bufsize,
2081 PCI_DMA_FROMDEVICE);
2049 2082
2050 ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi); 2083 skb_put(skb, rs.rs_datalen);
2051 2084
2052 /* check beacons in IBSS mode */ 2085 ath5k_receive_frame(sc, skb, &rs);
2053 if (sc->opmode == NL80211_IFTYPE_ADHOC)
2054 ath5k_check_ibss_tsf(sc, skb, rxs);
2055 2086
2056 ieee80211_rx(sc->hw, skb); 2087 bf->skb = next_skb;
2057 2088 bf->skbaddr = next_skb_addr;
2058 bf->skb = next_skb; 2089 }
2059 bf->skbaddr = next_skb_addr;
2060next: 2090next:
2061 list_move_tail(&bf->list, &sc->rxbuf); 2091 list_move_tail(&bf->list, &sc->rxbuf);
2062 } while (ath5k_rxbuf_setup(sc, bf) == 0); 2092 } while (ath5k_rxbuf_setup(sc, bf) == 0);
@@ -2065,8 +2095,6 @@ unlock:
2065} 2095}
2066 2096
2067 2097
2068
2069
2070/*************\ 2098/*************\
2071* TX Handling * 2099* TX Handling *
2072\*************/ 2100\*************/
@@ -2298,6 +2326,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2298 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, 2326 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2299 "stuck beacon time (%u missed)\n", 2327 "stuck beacon time (%u missed)\n",
2300 sc->bmisscount); 2328 sc->bmisscount);
2329 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2330 "stuck beacon, resetting\n");
2301 tasklet_schedule(&sc->restq); 2331 tasklet_schedule(&sc->restq);
2302 } 2332 }
2303 return; 2333 return;
@@ -2647,7 +2677,7 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2647 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2677 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2648 "putting device to sleep\n"); 2678 "putting device to sleep\n");
2649 } 2679 }
2650 ath5k_txbuf_free(sc, sc->bbuf); 2680 ath5k_txbuf_free_skb(sc, sc->bbuf);
2651 2681
2652 mmiowb(); 2682 mmiowb();
2653 mutex_unlock(&sc->lock); 2683 mutex_unlock(&sc->lock);
@@ -2705,6 +2735,8 @@ ath5k_intr(int irq, void *dev_id)
2705 * Fatal errors are unrecoverable. 2735 * Fatal errors are unrecoverable.
2706 * Typically these are caused by DMA errors. 2736 * Typically these are caused by DMA errors.
2707 */ 2737 */
2738 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2739 "fatal int, resetting\n");
2708 tasklet_schedule(&sc->restq); 2740 tasklet_schedule(&sc->restq);
2709 } else if (unlikely(status & AR5K_INT_RXORN)) { 2741 } else if (unlikely(status & AR5K_INT_RXORN)) {
2710 /* 2742 /*
@@ -2717,8 +2749,11 @@ ath5k_intr(int irq, void *dev_id)
2717 * this guess is copied from the HAL. 2749 * this guess is copied from the HAL.
2718 */ 2750 */
2719 sc->stats.rxorn_intr++; 2751 sc->stats.rxorn_intr++;
2720 if (ah->ah_mac_srev < AR5K_SREV_AR5212) 2752 if (ah->ah_mac_srev < AR5K_SREV_AR5212) {
2753 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2754 "rx overrun, resetting\n");
2721 tasklet_schedule(&sc->restq); 2755 tasklet_schedule(&sc->restq);
2756 }
2722 else 2757 else
2723 tasklet_schedule(&sc->rxtq); 2758 tasklet_schedule(&sc->rxtq);
2724 } else { 2759 } else {
@@ -2785,10 +2820,6 @@ ath5k_tasklet_calibrate(unsigned long data)
2785 /* Only full calibration for now */ 2820 /* Only full calibration for now */
2786 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; 2821 ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
2787 2822
2788 /* Stop queues so that calibration
2789 * doesn't interfere with tx */
2790 ieee80211_stop_queues(sc->hw);
2791
2792 ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", 2823 ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
2793 ieee80211_frequency_to_channel(sc->curchan->center_freq), 2824 ieee80211_frequency_to_channel(sc->curchan->center_freq),
2794 sc->curchan->hw_value); 2825 sc->curchan->hw_value);
@@ -2806,8 +2837,16 @@ ath5k_tasklet_calibrate(unsigned long data)
2806 ieee80211_frequency_to_channel( 2837 ieee80211_frequency_to_channel(
2807 sc->curchan->center_freq)); 2838 sc->curchan->center_freq));
2808 2839
2809 /* Wake queues */ 2840 /* Noise floor calibration interrupts rx/tx path while I/Q calibration
2810 ieee80211_wake_queues(sc->hw); 2841 * doesn't. We stop the queues so that calibration doesn't interfere
2842 * with TX and don't run it as often */
2843 if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) {
2844 ah->ah_cal_next_nf = jiffies +
2845 msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF);
2846 ieee80211_stop_queues(sc->hw);
2847 ath5k_hw_update_noise_floor(ah);
2848 ieee80211_wake_queues(sc->hw);
2849 }
2811 2850
2812 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; 2851 ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
2813} 2852}
@@ -2926,6 +2965,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2926 2965
2927 ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); 2966 ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode);
2928 2967
2968 ah->ah_cal_next_full = jiffies;
2969 ah->ah_cal_next_ani = jiffies;
2970 ah->ah_cal_next_nf = jiffies;
2971
2929 /* 2972 /*
2930 * Change channels and update the h/w rate map if we're switching; 2973 * Change channels and update the h/w rate map if we're switching;
2931 * e.g. 11a to 11b/g. 2974 * e.g. 11a to 11b/g.
@@ -3360,7 +3403,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3360 3403
3361 ath5k_debug_dump_skb(sc, skb, "BC ", 1); 3404 ath5k_debug_dump_skb(sc, skb, "BC ", 1);
3362 3405
3363 ath5k_txbuf_free(sc, sc->bbuf); 3406 ath5k_txbuf_free_skb(sc, sc->bbuf);
3364 sc->bbuf->skb = skb; 3407 sc->bbuf->skb = skb;
3365 ret = ath5k_beacon_setup(sc, sc->bbuf); 3408 ret = ath5k_beacon_setup(sc, sc->bbuf);
3366 if (ret) 3409 if (ret)
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
index 74f007126f41..beae519aa735 100644
--- a/drivers/net/wireless/ath/ath5k/caps.c
+++ b/drivers/net/wireless/ath/ath5k/caps.c
@@ -34,7 +34,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
34{ 34{
35 u16 ee_header; 35 u16 ee_header;
36 36
37 ATH5K_TRACE(ah->ah_sc);
38 /* Capabilities stored in the EEPROM */ 37 /* Capabilities stored in the EEPROM */
39 ee_header = ah->ah_capabilities.cap_eeprom.ee_header; 38 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
40 39
@@ -123,8 +122,6 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
123 enum ath5k_capability_type cap_type, 122 enum ath5k_capability_type cap_type,
124 u32 capability, u32 *result) 123 u32 capability, u32 *result)
125{ 124{
126 ATH5K_TRACE(ah->ah_sc);
127
128 switch (cap_type) { 125 switch (cap_type) {
129 case AR5K_CAP_NUM_TXQUEUES: 126 case AR5K_CAP_NUM_TXQUEUES:
130 if (result) { 127 if (result) {
@@ -173,8 +170,6 @@ yes:
173int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, 170int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
174 u16 assoc_id) 171 u16 assoc_id)
175{ 172{
176 ATH5K_TRACE(ah->ah_sc);
177
178 if (ah->ah_version == AR5K_AR5210) { 173 if (ah->ah_version == AR5K_AR5210) {
179 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, 174 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
180 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); 175 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
@@ -186,8 +181,6 @@ int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
186 181
187int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) 182int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
188{ 183{
189 ATH5K_TRACE(ah->ah_sc);
190
191 if (ah->ah_version == AR5K_AR5210) { 184 if (ah->ah_version == AR5K_AR5210) {
192 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, 185 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
193 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); 186 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 6fb5c5ffa5b1..8c638865c712 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -278,6 +278,7 @@ static ssize_t write_file_reset(struct file *file,
278 size_t count, loff_t *ppos) 278 size_t count, loff_t *ppos)
279{ 279{
280 struct ath5k_softc *sc = file->private_data; 280 struct ath5k_softc *sc = file->private_data;
281 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "debug file triggered reset\n");
281 tasklet_schedule(&sc->restq); 282 tasklet_schedule(&sc->restq);
282 return count; 283 return count;
283} 284}
@@ -307,7 +308,6 @@ static const struct {
307 { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, 308 { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
308 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, 309 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
309 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, 310 { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" },
310 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
311 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, 311 { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" },
312 { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, 312 { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
313}; 313};
@@ -426,6 +426,13 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
426 "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", 426 "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
427 (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); 427 (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
428 428
429 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
430 len += snprintf(buf+len, sizeof(buf)-len,
431 "\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v);
432 v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
433 len += snprintf(buf+len, sizeof(buf)-len,
434 "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
435
429 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 436 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
430} 437}
431 438
@@ -729,6 +736,66 @@ static const struct file_operations fops_ani = {
729}; 736};
730 737
731 738
739/* debugfs: queues etc */
740
741static ssize_t read_file_queue(struct file *file, char __user *user_buf,
742 size_t count, loff_t *ppos)
743{
744 struct ath5k_softc *sc = file->private_data;
745 char buf[700];
746 unsigned int len = 0;
747
748 struct ath5k_txq *txq;
749 struct ath5k_buf *bf, *bf0;
750 int i, n = 0;
751
752 len += snprintf(buf+len, sizeof(buf)-len,
753 "available txbuffers: %d\n", sc->txbuf_len);
754
755 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
756 txq = &sc->txqs[i];
757
758 len += snprintf(buf+len, sizeof(buf)-len,
759 "%02d: %ssetup\n", i, txq->setup ? "" : "not ");
760
761 if (!txq->setup)
762 continue;
763
764 list_for_each_entry_safe(bf, bf0, &txq->q, list)
765 n++;
766 len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n);
767 }
768
769 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
770}
771
772static ssize_t write_file_queue(struct file *file,
773 const char __user *userbuf,
774 size_t count, loff_t *ppos)
775{
776 struct ath5k_softc *sc = file->private_data;
777 char buf[20];
778
779 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
780 return -EFAULT;
781
782 if (strncmp(buf, "start", 5) == 0)
783 ieee80211_wake_queues(sc->hw);
784 else if (strncmp(buf, "stop", 4) == 0)
785 ieee80211_stop_queues(sc->hw);
786
787 return count;
788}
789
790
791static const struct file_operations fops_queue = {
792 .read = read_file_queue,
793 .write = write_file_queue,
794 .open = ath5k_debugfs_open,
795 .owner = THIS_MODULE,
796};
797
798
732/* init */ 799/* init */
733 800
734void 801void
@@ -772,6 +839,11 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
772 S_IWUSR | S_IRUSR, 839 S_IWUSR | S_IRUSR,
773 sc->debug.debugfs_phydir, sc, 840 sc->debug.debugfs_phydir, sc,
774 &fops_ani); 841 &fops_ani);
842
843 sc->debug.debugfs_queue = debugfs_create_file("queue",
844 S_IWUSR | S_IRUSR,
845 sc->debug.debugfs_phydir, sc,
846 &fops_queue);
775} 847}
776 848
777void 849void
@@ -790,6 +862,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
790 debugfs_remove(sc->debug.debugfs_antenna); 862 debugfs_remove(sc->debug.debugfs_antenna);
791 debugfs_remove(sc->debug.debugfs_frameerrors); 863 debugfs_remove(sc->debug.debugfs_frameerrors);
792 debugfs_remove(sc->debug.debugfs_ani); 864 debugfs_remove(sc->debug.debugfs_ani);
865 debugfs_remove(sc->debug.debugfs_queue);
793 debugfs_remove(sc->debug.debugfs_phydir); 866 debugfs_remove(sc->debug.debugfs_phydir);
794} 867}
795 868
@@ -852,7 +925,7 @@ ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
852 ds, (unsigned long long)bf->daddr, 925 ds, (unsigned long long)bf->daddr,
853 ds->ds_link, ds->ds_data, 926 ds->ds_link, ds->ds_data,
854 rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1, 927 rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
855 rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0, 928 rd->rx_stat.rx_status_0, rd->rx_stat.rx_status_1,
856 !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'); 929 !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
857} 930}
858 931
@@ -867,7 +940,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
867 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) 940 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
868 return; 941 return;
869 942
870 printk(KERN_DEBUG "rx queue %x, link %p\n", 943 printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
871 ath5k_hw_get_rxdp(ah), sc->rxlink); 944 ath5k_hw_get_rxdp(ah), sc->rxlink);
872 945
873 spin_lock_bh(&sc->rxbuflock); 946 spin_lock_bh(&sc->rxbuflock);
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
index ddd5b3a99e8d..606ae94a9157 100644
--- a/drivers/net/wireless/ath/ath5k/debug.h
+++ b/drivers/net/wireless/ath/ath5k/debug.h
@@ -77,6 +77,7 @@ struct ath5k_dbg_info {
77 struct dentry *debugfs_antenna; 77 struct dentry *debugfs_antenna;
78 struct dentry *debugfs_frameerrors; 78 struct dentry *debugfs_frameerrors;
79 struct dentry *debugfs_ani; 79 struct dentry *debugfs_ani;
80 struct dentry *debugfs_queue;
80}; 81};
81 82
82/** 83/**
@@ -115,18 +116,12 @@ enum ath5k_debug_level {
115 ATH5K_DEBUG_DUMP_RX = 0x00000100, 116 ATH5K_DEBUG_DUMP_RX = 0x00000100,
116 ATH5K_DEBUG_DUMP_TX = 0x00000200, 117 ATH5K_DEBUG_DUMP_TX = 0x00000200,
117 ATH5K_DEBUG_DUMPBANDS = 0x00000400, 118 ATH5K_DEBUG_DUMPBANDS = 0x00000400,
118 ATH5K_DEBUG_TRACE = 0x00001000,
119 ATH5K_DEBUG_ANI = 0x00002000, 119 ATH5K_DEBUG_ANI = 0x00002000,
120 ATH5K_DEBUG_ANY = 0xffffffff 120 ATH5K_DEBUG_ANY = 0xffffffff
121}; 121};
122 122
123#ifdef CONFIG_ATH5K_DEBUG 123#ifdef CONFIG_ATH5K_DEBUG
124 124
125#define ATH5K_TRACE(_sc) do { \
126 if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
127 printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
128 } while (0)
129
130#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \ 125#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
131 if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \ 126 if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
132 ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \ 127 ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
@@ -168,8 +163,6 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
168 163
169#include <linux/compiler.h> 164#include <linux/compiler.h>
170 165
171#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
172
173static inline void __attribute__ ((format (printf, 3, 4))) 166static inline void __attribute__ ((format (printf, 3, 4)))
174ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} 167ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
175 168
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
index 7d7b646ab65a..43244382f213 100644
--- a/drivers/net/wireless/ath/ath5k/desc.c
+++ b/drivers/net/wireless/ath/ath5k/desc.c
@@ -91,14 +91,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
91 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; 91 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
92 92
93 /* 93 /*
94 * Verify and set header length 94 * Verify and set header length (only 5210)
95 * XXX: I only found that on 5210 code, does it work on 5211 ?
96 */ 95 */
97 if (ah->ah_version == AR5K_AR5210) { 96 if (ah->ah_version == AR5K_AR5210) {
98 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) 97 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)
99 return -EINVAL; 98 return -EINVAL;
100 tx_ctl->tx_control_0 |= 99 tx_ctl->tx_control_0 |=
101 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); 100 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);
102 } 101 }
103 102
104 /*Differences between 5210-5211*/ 103 /*Differences between 5210-5211*/
@@ -110,11 +109,11 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
110 case AR5K_PKT_TYPE_PIFS: 109 case AR5K_PKT_TYPE_PIFS:
111 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; 110 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
112 default: 111 default:
113 frame_type = type /*<< 2 ?*/; 112 frame_type = type;
114 } 113 }
115 114
116 tx_ctl->tx_control_0 |= 115 tx_ctl->tx_control_0 |=
117 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | 116 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |
118 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); 117 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
119 118
120 } else { 119 } else {
@@ -123,21 +122,30 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
123 AR5K_REG_SM(antenna_mode, 122 AR5K_REG_SM(antenna_mode,
124 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); 123 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
125 tx_ctl->tx_control_1 |= 124 tx_ctl->tx_control_1 |=
126 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); 125 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);
127 } 126 }
127
128#define _TX_FLAGS(_c, _flag) \ 128#define _TX_FLAGS(_c, _flag) \
129 if (flags & AR5K_TXDESC_##_flag) { \ 129 if (flags & AR5K_TXDESC_##_flag) { \
130 tx_ctl->tx_control_##_c |= \ 130 tx_ctl->tx_control_##_c |= \
131 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ 131 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \
132 } 132 }
133 133#define _TX_FLAGS_5211(_c, _flag) \
134 if (flags & AR5K_TXDESC_##_flag) { \
135 tx_ctl->tx_control_##_c |= \
136 AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \
137 }
134 _TX_FLAGS(0, CLRDMASK); 138 _TX_FLAGS(0, CLRDMASK);
135 _TX_FLAGS(0, VEOL);
136 _TX_FLAGS(0, INTREQ); 139 _TX_FLAGS(0, INTREQ);
137 _TX_FLAGS(0, RTSENA); 140 _TX_FLAGS(0, RTSENA);
138 _TX_FLAGS(1, NOACK); 141
142 if (ah->ah_version == AR5K_AR5211) {
143 _TX_FLAGS_5211(0, VEOL);
144 _TX_FLAGS_5211(1, NOACK);
145 }
139 146
140#undef _TX_FLAGS 147#undef _TX_FLAGS
148#undef _TX_FLAGS_5211
141 149
142 /* 150 /*
143 * WEP crap 151 * WEP crap
@@ -147,7 +155,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
147 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 155 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
148 tx_ctl->tx_control_1 |= 156 tx_ctl->tx_control_1 |=
149 AR5K_REG_SM(key_index, 157 AR5K_REG_SM(key_index,
150 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); 158 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);
151 } 159 }
152 160
153 /* 161 /*
@@ -156,7 +164,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
156 if ((ah->ah_version == AR5K_AR5210) && 164 if ((ah->ah_version == AR5K_AR5210) &&
157 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) 165 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
158 tx_ctl->tx_control_1 |= rtscts_duration & 166 tx_ctl->tx_control_1 |= rtscts_duration &
159 AR5K_2W_TX_DESC_CTL1_RTS_DURATION; 167 AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;
160 168
161 return 0; 169 return 0;
162} 170}
@@ -176,7 +184,6 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
176 struct ath5k_hw_4w_tx_ctl *tx_ctl; 184 struct ath5k_hw_4w_tx_ctl *tx_ctl;
177 unsigned int frame_len; 185 unsigned int frame_len;
178 186
179 ATH5K_TRACE(ah->ah_sc);
180 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 187 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
181 188
182 /* 189 /*
@@ -256,7 +263,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
256 if (key_index != AR5K_TXKEYIX_INVALID) { 263 if (key_index != AR5K_TXKEYIX_INVALID) {
257 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 264 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
258 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, 265 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
259 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); 266 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
260 } 267 }
261 268
262 /* 269 /*
@@ -278,13 +285,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
278/* 285/*
279 * Initialize a 4-word multi rate retry tx control descriptor on 5212 286 * Initialize a 4-word multi rate retry tx control descriptor on 5212
280 */ 287 */
281static int 288int
282ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 289ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
283 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, 290 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
284 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) 291 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
285{ 292{
286 struct ath5k_hw_4w_tx_ctl *tx_ctl; 293 struct ath5k_hw_4w_tx_ctl *tx_ctl;
287 294
295 /* no mrr support for cards older than 5212 */
296 if (ah->ah_version < AR5K_AR5212)
297 return 0;
298
288 /* 299 /*
289 * Rates can be 0 as long as the retry count is 0 too. 300 * Rates can be 0 as long as the retry count is 0 too.
290 * A zero rate and nonzero retry count will put the HW into a mode where 301 * A zero rate and nonzero retry count will put the HW into a mode where
@@ -324,15 +335,6 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
324 return 0; 335 return 0;
325} 336}
326 337
327/* no mrr support for cards older than 5212 */
328static int
329ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
330 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
331 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
332{
333 return 0;
334}
335
336/* 338/*
337 * Proccess the tx status descriptor on 5210/5211 339 * Proccess the tx status descriptor on 5210/5211
338 */ 340 */
@@ -342,8 +344,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
342 struct ath5k_hw_2w_tx_ctl *tx_ctl; 344 struct ath5k_hw_2w_tx_ctl *tx_ctl;
343 struct ath5k_hw_tx_status *tx_status; 345 struct ath5k_hw_tx_status *tx_status;
344 346
345 ATH5K_TRACE(ah->ah_sc);
346
347 tx_ctl = &desc->ud.ds_tx5210.tx_ctl; 347 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
348 tx_status = &desc->ud.ds_tx5210.tx_stat; 348 tx_status = &desc->ud.ds_tx5210.tx_stat;
349 349
@@ -396,8 +396,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
396 struct ath5k_hw_4w_tx_ctl *tx_ctl; 396 struct ath5k_hw_4w_tx_ctl *tx_ctl;
397 struct ath5k_hw_tx_status *tx_status; 397 struct ath5k_hw_tx_status *tx_status;
398 398
399 ATH5K_TRACE(ah->ah_sc);
400
401 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 399 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
402 tx_status = &desc->ud.ds_tx5212.tx_stat; 400 tx_status = &desc->ud.ds_tx5212.tx_stat;
403 401
@@ -419,11 +417,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
419 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 417 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
420 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 418 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
421 ts->ts_antenna = (tx_status->tx_status_1 & 419 ts->ts_antenna = (tx_status->tx_status_1 &
422 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; 420 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
423 ts->ts_status = 0; 421 ts->ts_status = 0;
424 422
425 ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, 423 ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
426 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX); 424 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
427 425
428 /* The longretry counter has the number of un-acked retries 426 /* The longretry counter has the number of un-acked retries
429 * for the final rate. To get the total number of retries 427 * for the final rate. To get the total number of retries
@@ -485,12 +483,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
485/* 483/*
486 * Initialize an rx control descriptor 484 * Initialize an rx control descriptor
487 */ 485 */
488static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 486int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
489 u32 size, unsigned int flags) 487 u32 size, unsigned int flags)
490{ 488{
491 struct ath5k_hw_rx_ctl *rx_ctl; 489 struct ath5k_hw_rx_ctl *rx_ctl;
492 490
493 ATH5K_TRACE(ah->ah_sc);
494 rx_ctl = &desc->ud.ds_rx.rx_ctl; 491 rx_ctl = &desc->ud.ds_rx.rx_ctl;
495 492
496 /* 493 /*
@@ -502,10 +499,11 @@ static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
502 */ 499 */
503 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); 500 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
504 501
502 if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN))
503 return -EINVAL;
504
505 /* Setup descriptor */ 505 /* Setup descriptor */
506 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; 506 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
507 if (unlikely(rx_ctl->rx_control_1 != size))
508 return -EINVAL;
509 507
510 if (flags & AR5K_RXDESC_INTREQ) 508 if (flags & AR5K_RXDESC_INTREQ)
511 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; 509 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
@@ -521,13 +519,15 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
521{ 519{
522 struct ath5k_hw_rx_status *rx_status; 520 struct ath5k_hw_rx_status *rx_status;
523 521
524 rx_status = &desc->ud.ds_rx.u.rx_stat; 522 rx_status = &desc->ud.ds_rx.rx_stat;
525 523
526 /* No frame received / not ready */ 524 /* No frame received / not ready */
527 if (unlikely(!(rx_status->rx_status_1 & 525 if (unlikely(!(rx_status->rx_status_1 &
528 AR5K_5210_RX_DESC_STATUS1_DONE))) 526 AR5K_5210_RX_DESC_STATUS1_DONE)))
529 return -EINPROGRESS; 527 return -EINPROGRESS;
530 528
529 memset(rs, 0, sizeof(struct ath5k_rx_status));
530
531 /* 531 /*
532 * Frame receive status 532 * Frame receive status
533 */ 533 */
@@ -537,15 +537,23 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
537 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); 537 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
538 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 538 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
539 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); 539 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
540 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
541 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);
542 rs->rs_more = !!(rx_status->rx_status_0 & 540 rs->rs_more = !!(rx_status->rx_status_0 &
543 AR5K_5210_RX_DESC_STATUS0_MORE); 541 AR5K_5210_RX_DESC_STATUS0_MORE);
544 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ 542 /* TODO: this timestamp is 13 bit, later on we assume 15 bit!
543 * also the HAL code for 5210 says the timestamp is bits [10..22] of the
544 * TSF, and extends the timestamp here to 15 bit.
545 * we need to check on 5210...
546 */
545 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 547 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
546 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 548 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
547 rs->rs_status = 0; 549
548 rs->rs_phyerr = 0; 550 if (ah->ah_version == AR5K_AR5211)
551 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
552 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211);
553 else
554 rs->rs_antenna = (rx_status->rx_status_0 &
555 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210)
556 ? 2 : 1;
549 557
550 /* 558 /*
551 * Key table status 559 * Key table status
@@ -560,19 +568,21 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
560 * Receive/descriptor errors 568 * Receive/descriptor errors
561 */ 569 */
562 if (!(rx_status->rx_status_1 & 570 if (!(rx_status->rx_status_1 &
563 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 571 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
564 if (rx_status->rx_status_1 & 572 if (rx_status->rx_status_1 &
565 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) 573 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
566 rs->rs_status |= AR5K_RXERR_CRC; 574 rs->rs_status |= AR5K_RXERR_CRC;
567 575
568 if (rx_status->rx_status_1 & 576 /* only on 5210 */
569 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) 577 if ((ah->ah_version == AR5K_AR5210) &&
578 (rx_status->rx_status_1 &
579 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210))
570 rs->rs_status |= AR5K_RXERR_FIFO; 580 rs->rs_status |= AR5K_RXERR_FIFO;
571 581
572 if (rx_status->rx_status_1 & 582 if (rx_status->rx_status_1 &
573 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { 583 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
574 rs->rs_status |= AR5K_RXERR_PHY; 584 rs->rs_status |= AR5K_RXERR_PHY;
575 rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, 585 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
576 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); 586 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
577 } 587 }
578 588
@@ -588,22 +598,20 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
588 * Proccess the rx status descriptor on 5212 598 * Proccess the rx status descriptor on 5212
589 */ 599 */
590static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, 600static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
591 struct ath5k_desc *desc, struct ath5k_rx_status *rs) 601 struct ath5k_desc *desc,
602 struct ath5k_rx_status *rs)
592{ 603{
593 struct ath5k_hw_rx_status *rx_status; 604 struct ath5k_hw_rx_status *rx_status;
594 struct ath5k_hw_rx_error *rx_err;
595 605
596 ATH5K_TRACE(ah->ah_sc); 606 rx_status = &desc->ud.ds_rx.rx_stat;
597 rx_status = &desc->ud.ds_rx.u.rx_stat;
598
599 /* Overlay on error */
600 rx_err = &desc->ud.ds_rx.u.rx_err;
601 607
602 /* No frame received / not ready */ 608 /* No frame received / not ready */
603 if (unlikely(!(rx_status->rx_status_1 & 609 if (unlikely(!(rx_status->rx_status_1 &
604 AR5K_5212_RX_DESC_STATUS1_DONE))) 610 AR5K_5212_RX_DESC_STATUS1_DONE)))
605 return -EINPROGRESS; 611 return -EINPROGRESS;
606 612
613 memset(rs, 0, sizeof(struct ath5k_rx_status));
614
607 /* 615 /*
608 * Frame receive status 616 * Frame receive status
609 */ 617 */
@@ -619,15 +627,13 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
619 AR5K_5212_RX_DESC_STATUS0_MORE); 627 AR5K_5212_RX_DESC_STATUS0_MORE);
620 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 628 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
621 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 629 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
622 rs->rs_status = 0;
623 rs->rs_phyerr = 0;
624 630
625 /* 631 /*
626 * Key table status 632 * Key table status
627 */ 633 */
628 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) 634 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
629 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 635 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
630 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); 636 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
631 else 637 else
632 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 638 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
633 639
@@ -635,7 +641,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
635 * Receive/descriptor errors 641 * Receive/descriptor errors
636 */ 642 */
637 if (!(rx_status->rx_status_1 & 643 if (!(rx_status->rx_status_1 &
638 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 644 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
639 if (rx_status->rx_status_1 & 645 if (rx_status->rx_status_1 &
640 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) 646 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
641 rs->rs_status |= AR5K_RXERR_CRC; 647 rs->rs_status |= AR5K_RXERR_CRC;
@@ -643,9 +649,10 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
643 if (rx_status->rx_status_1 & 649 if (rx_status->rx_status_1 &
644 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { 650 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
645 rs->rs_status |= AR5K_RXERR_PHY; 651 rs->rs_status |= AR5K_RXERR_PHY;
646 rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, 652 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
647 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); 653 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
648 ath5k_ani_phy_error_report(ah, rs->rs_phyerr); 654 if (!ah->ah_capabilities.cap_has_phyerr_counters)
655 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
649 } 656 }
650 657
651 if (rx_status->rx_status_1 & 658 if (rx_status->rx_status_1 &
@@ -656,7 +663,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
656 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) 663 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
657 rs->rs_status |= AR5K_RXERR_MIC; 664 rs->rs_status |= AR5K_RXERR_MIC;
658 } 665 }
659
660 return 0; 666 return 0;
661} 667}
662 668
@@ -665,29 +671,15 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
665 */ 671 */
666int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) 672int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
667{ 673{
668
669 if (ah->ah_version != AR5K_AR5210 &&
670 ah->ah_version != AR5K_AR5211 &&
671 ah->ah_version != AR5K_AR5212)
672 return -ENOTSUPP;
673
674 if (ah->ah_version == AR5K_AR5212) { 674 if (ah->ah_version == AR5K_AR5212) {
675 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
676 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; 675 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
677 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
678 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; 676 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
679 } else { 677 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
680 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; 678 } else if (ah->ah_version <= AR5K_AR5211) {
681 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; 679 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
682 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
683 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; 680 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
684 }
685
686 if (ah->ah_version == AR5K_AR5212)
687 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
688 else if (ah->ah_version <= AR5K_AR5211)
689 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; 681 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
690 682 } else
683 return -ENOTSUPP;
691 return 0; 684 return 0;
692} 685}
693
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index 64538fbe4167..b2adb2a281c2 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -17,28 +17,24 @@
17 */ 17 */
18 18
19/* 19/*
20 * Internal RX/TX descriptor structures 20 * RX/TX descriptor structures
21 * (rX: reserved fields possibily used by future versions of the ar5k chipset)
22 */ 21 */
23 22
24/* 23/*
25 * common hardware RX control descriptor 24 * Common hardware RX control descriptor
26 */ 25 */
27struct ath5k_hw_rx_ctl { 26struct ath5k_hw_rx_ctl {
28 u32 rx_control_0; /* RX control word 0 */ 27 u32 rx_control_0; /* RX control word 0 */
29 u32 rx_control_1; /* RX control word 1 */ 28 u32 rx_control_1; /* RX control word 1 */
30} __packed; 29} __packed;
31 30
32/* RX control word 0 field/sflags */
33#define AR5K_DESC_RX_CTL0 0x00000000
34
35/* RX control word 1 fields/flags */ 31/* RX control word 1 fields/flags */
36#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff 32#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */
37#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 33#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 /* RX interrupt request */
38 34
39/* 35/*
40 * common hardware RX status descriptor 36 * Common hardware RX status descriptor
41 * 5210/11 and 5212 differ only in the flags defined below 37 * 5210, 5211 and 5212 differ only in the fields and flags defined below
42 */ 38 */
43struct ath5k_hw_rx_status { 39struct ath5k_hw_rx_status {
44 u32 rx_status_0; /* RX status word 0 */ 40 u32 rx_status_0; /* RX status word 0 */
@@ -47,81 +43,69 @@ struct ath5k_hw_rx_status {
47 43
48/* 5210/5211 */ 44/* 5210/5211 */
49/* RX status word 0 fields/flags */ 45/* RX status word 0 fields/flags */
50#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff 46#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff /* RX data length */
51#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 47#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 /* more desc for this frame */
52#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 48#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210 0x00004000 /* [5210] receive on ant 1 */
49#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 /* reception rate */
53#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15 50#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15
54#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 51#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 /* rssi */
55#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 52#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
56#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 53#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211 0x38000000 /* [5211] receive antenna */
57#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 54#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211_S 27
58 55
59/* RX status word 1 fields/flags */ 56/* RX status word 1 fields/flags */
60#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 57#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 /* descriptor complete */
61#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 58#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* reception success */
62#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 59#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */
63#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008 60#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 0x00000008 /* [5210] FIFO overrun */
64#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 61#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 /* decyption CRC failure */
65#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 62#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 /* PHY error */
66#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5 63#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5
67#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 64#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */
68#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 65#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 /* decyption key index */
69#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9 66#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9
70#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 67#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 /* 13 bit of TSF */
71#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 68#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15
72#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 69#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 /* key cache miss */
73 70
74/* 5212 */ 71/* 5212 */
75/* RX status word 0 fields/flags */ 72/* RX status word 0 fields/flags */
76#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff 73#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff /* RX data length */
77#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 74#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 /* more desc for this frame */
78#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 75#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 /* decompression CRC error */
79#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 76#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 /* reception rate */
80#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15 77#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15
81#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 78#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 /* rssi */
82#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 79#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
83#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 80#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 /* receive antenna */
84#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 81#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
85 82
86/* RX status word 1 fields/flags */ 83/* RX status word 1 fields/flags */
87#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 84#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 /* descriptor complete */
88#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 85#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* frame reception success */
89#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 86#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */
90#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 87#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 /* decryption CRC failure */
91#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 88#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 /* PHY error */
92#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 89#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 /* MIC decrypt error */
93#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 90#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */
94#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 91#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 /* decryption key index */
95#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9 92#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9
96#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 93#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 /* first 15bit of the TSF */
97#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16 94#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16
98#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 95#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 /* key cache miss */
99 96#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE 0x0000ff00 /* phy error code overlays key index and valid fields */
100/* 97#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE_S 8
101 * common hardware RX error descriptor
102 */
103struct ath5k_hw_rx_error {
104 u32 rx_error_0; /* RX status word 0 */
105 u32 rx_error_1; /* RX status word 1 */
106} __packed;
107
108/* RX error word 0 fields/flags */
109#define AR5K_RX_DESC_ERROR0 0x00000000
110
111/* RX error word 1 fields/flags */
112#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00
113#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8
114 98
115/** 99/**
116 * enum ath5k_phy_error_code - PHY Error codes 100 * enum ath5k_phy_error_code - PHY Error codes
117 */ 101 */
118enum ath5k_phy_error_code { 102enum ath5k_phy_error_code {
119 AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun */ 103 AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun, [5210] No error */
120 AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */ 104 AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */
121 AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */ 105 AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */
122 AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */ 106 AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */
123 AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */ 107 AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */
124 AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect */ 108 AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect, [5210] 64 QAM rate */
125 AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */ 109 AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */
126 AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */ 110 AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */
127 /* these are specific to the 5212 */ 111 /* these are specific to the 5212 */
@@ -148,112 +132,111 @@ struct ath5k_hw_2w_tx_ctl {
148} __packed; 132} __packed;
149 133
150/* TX control word 0 fields/flags */ 134/* TX control word 0 fields/flags */
151#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff 135#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
152#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/ 136#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210 0x0003f000 /* [5210] header length */
153#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12 137#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210_S 12
154#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000 138#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000 /* tx rate */
155#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18 139#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18
156#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000 140#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000 /* RTS/CTS enable */
157#define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000 141#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET_5210 0x00800000 /* [5210] long packet */
158#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET 0x00800000 /*[5210]*/ 142#define AR5K_2W_TX_DESC_CTL0_VEOL_5211 0x00800000 /* [5211] virtual end-of-list */
159#define AR5K_2W_TX_DESC_CTL0_VEOL 0x00800000 /*[5211]*/ 143#define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000 /* clear destination mask */
160#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE 0x1c000000 /*[5210]*/ 144#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 /* [5210] antenna selection */
161#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26 145#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 /* [5211] antenna selection */
162#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000
163#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000
164
165#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \ 146#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \
166 (ah->ah_version == AR5K_AR5210 ? \ 147 (ah->ah_version == AR5K_AR5210 ? \
167 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ 148 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \
168 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) 149 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
169
170#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 150#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25
171#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 151#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210 0x1c000000 /* [5210] frame type */
172#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 152#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210_S 26
153#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 /* TX interrupt request */
154#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* key is valid */
173 155
174/* TX control word 1 fields/flags */ 156/* TX control word 1 fields/flags */
175#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff 157#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff /* data buffer length */
176#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 158#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 /* more desc for this frame */
177#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000 159#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5210 0x0007e000 /* [5210] key table index */
178#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000 160#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5211 0x000fe000 /* [5211] key table index */
179 161#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX \
180#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX \
181 (ah->ah_version == AR5K_AR5210 ? \ 162 (ah->ah_version == AR5K_AR5210 ? \
182 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \ 163 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5210 : \
183 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211) 164 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5211)
184 165#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_S 13
185#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 166#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211 0x00700000 /* [5211] frame type */
186#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/ 167#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211_S 20
187#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20 168#define AR5K_2W_TX_DESC_CTL1_NOACK_5211 0x00800000 /* [5211] no ACK */
188#define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/ 169#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210 0xfff80000 /* [5210] lower 13 bit of duration */
189#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/
190 170
191/* Frame types */ 171/* Frame types */
192#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 172#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0
193#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 173#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 1
194#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 174#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 2
195#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c 175#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 3
196#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10 176#define AR5K_AR5211_TX_DESC_FRAME_TYPE_BEACON 3
177#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 4
178#define AR5K_AR5211_TX_DESC_FRAME_TYPE_PRESP 4
197 179
198/* 180/*
199 * 5212 hardware 4-word TX control descriptor 181 * 5212 hardware 4-word TX control descriptor
200 */ 182 */
201struct ath5k_hw_4w_tx_ctl { 183struct ath5k_hw_4w_tx_ctl {
202 u32 tx_control_0; /* TX control word 0 */ 184 u32 tx_control_0; /* TX control word 0 */
185 u32 tx_control_1; /* TX control word 1 */
186 u32 tx_control_2; /* TX control word 2 */
187 u32 tx_control_3; /* TX control word 3 */
188} __packed;
203 189
204#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff 190/* TX control word 0 fields/flags */
205#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000 191#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
192#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000 /* transmit power */
206#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S 16 193#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S 16
207#define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000 194#define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000 /* RTS/CTS enable */
208#define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000 195#define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000 /* virtual end-of-list */
209#define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000 196#define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000 /* clear destination mask */
210#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000 197#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000 /* TX antenna selection */
211#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 198#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25
212#define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000 199#define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000 /* TX interrupt request */
213#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 200#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* destination index valid */
214#define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000 201#define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000 /* precede frame with CTS */
215
216 u32 tx_control_1; /* TX control word 1 */
217 202
218#define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff 203/* TX control word 1 fields/flags */
219#define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000 204#define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff /* data buffer length */
220#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000 205#define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000 /* more desc for this frame */
221#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 206#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX 0x000fe000 /* destination table index */
222#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000 207#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX_S 13
208#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000 /* frame type */
223#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S 20 209#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S 20
224#define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000 210#define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000 /* no ACK */
225#define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000 211#define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000 /* compression processing */
226#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S 25 212#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S 25
227#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000 213#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000 /* length of frame IV */
228#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S 27 214#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S 27
229#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000 215#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000 /* length of frame ICV */
230#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S 29 216#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S 29
231 217
232 u32 tx_control_2; /* TX control word 2 */ 218/* TX control word 2 fields/flags */
233 219#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff /* RTS/CTS duration */
234#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff 220#define AR5K_4W_TX_DESC_CTL2_DURATION_UPD_EN 0x00008000 /* frame duration update */
235#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE 0x00008000 221#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000 /* series 0 max attempts */
236#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000 222#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16
237#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16 223#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000 /* series 1 max attempts */
238#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000 224#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20
239#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20 225#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000 /* series 2 max attempts */
240#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000 226#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24
241#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24 227#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000 /* series 3 max attempts */
242#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000 228#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28
243#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28 229
244 230/* TX control word 3 fields/flags */
245 u32 tx_control_3; /* TX control word 3 */ 231#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f /* series 0 tx rate */
246 232#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0 /* series 1 tx rate */
247#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f
248#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0
249#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S 5 233#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S 5
250#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00 234#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00 /* series 2 tx rate */
251#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S 10 235#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S 10
252#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000 236#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000 /* series 3 tx rate */
253#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S 15 237#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S 15
254#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000 238#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000 /* RTS or CTS rate */
255#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S 20 239#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S 20
256} __packed;
257 240
258/* 241/*
259 * Common TX status descriptor 242 * Common TX status descriptor
@@ -264,37 +247,34 @@ struct ath5k_hw_tx_status {
264} __packed; 247} __packed;
265 248
266/* TX status word 0 fields/flags */ 249/* TX status word 0 fields/flags */
267#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 250#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */
268#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 251#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 /* excessive retries */
269#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 252#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 /* FIFO underrun */
270#define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008 253#define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008 /* TX filter indication */
271/*??? 254/* according to the HAL sources the spec has short/long retry counts reversed.
272#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT 0x000000f0 255 * we have it reversed to the HAL sources as well, for 5210 and 5211.
273#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S 4 256 * For 5212 these fields are defined as RTS_FAIL_COUNT and DATA_FAIL_COUNT,
274*/ 257 * but used respectively as SHORT and LONG retry count in the code later. This
275#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0 258 * is consistent with the definitions here... TODO: check */
259#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0 /* short retry count */
276#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S 4 260#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S 4
277/*??? 261#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00 /* long retry count */
278#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT 0x00000f00
279#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8
280*/
281#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00
282#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S 8 262#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S 8
283#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT 0x0000f000 263#define AR5K_DESC_TX_STATUS0_VIRTCOLL_CT_5211 0x0000f000 /* [5211+] virtual collision count */
284#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12 264#define AR5K_DESC_TX_STATUS0_VIRTCOLL_CT_5212_S 12
285#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 265#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 /* TX timestamp */
286#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 266#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16
287 267
288/* TX status word 1 fields/flags */ 268/* TX status word 1 fields/flags */
289#define AR5K_DESC_TX_STATUS1_DONE 0x00000001 269#define AR5K_DESC_TX_STATUS1_DONE 0x00000001 /* descriptor complete */
290#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe 270#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe /* TX sequence number */
291#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 271#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1
292#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000 272#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000 /* signal strength of ACK */
293#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S 13 273#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S 13
294#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX 0x00600000 274#define AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212 0x00600000 /* [5212] final TX attempt series ix */
295#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21 275#define AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212_S 21
296#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000 276#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS_5212 0x00800000 /* [5212] compression status */
297#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000 277#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212 0x01000000 /* [5212] transmit antenna */
298 278
299/* 279/*
300 * 5210/5211 hardware TX descriptor 280 * 5210/5211 hardware TX descriptor
@@ -313,18 +293,15 @@ struct ath5k_hw_5212_tx_desc {
313} __packed; 293} __packed;
314 294
315/* 295/*
316 * common hardware RX descriptor 296 * Common hardware RX descriptor
317 */ 297 */
318struct ath5k_hw_all_rx_desc { 298struct ath5k_hw_all_rx_desc {
319 struct ath5k_hw_rx_ctl rx_ctl; 299 struct ath5k_hw_rx_ctl rx_ctl;
320 union { 300 struct ath5k_hw_rx_status rx_stat;
321 struct ath5k_hw_rx_status rx_stat;
322 struct ath5k_hw_rx_error rx_err;
323 } u;
324} __packed; 301} __packed;
325 302
326/* 303/*
327 * Atheros hardware descriptor 304 * Atheros hardware DMA descriptor
328 * This is read and written to by the hardware 305 * This is read and written to by the hardware
329 */ 306 */
330struct ath5k_desc { 307struct ath5k_desc {
@@ -346,4 +323,3 @@ struct ath5k_desc {
346#define AR5K_TXDESC_CTSENA 0x0008 323#define AR5K_TXDESC_CTSENA 0x0008
347#define AR5K_TXDESC_INTREQ 0x0010 324#define AR5K_TXDESC_INTREQ 0x0010
348#define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/ 325#define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/
349
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
index 941b51130a6f..484f31870ba8 100644
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -48,7 +48,6 @@
48 */ 48 */
49void ath5k_hw_start_rx_dma(struct ath5k_hw *ah) 49void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
50{ 50{
51 ATH5K_TRACE(ah->ah_sc);
52 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); 51 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
53 ath5k_hw_reg_read(ah, AR5K_CR); 52 ath5k_hw_reg_read(ah, AR5K_CR);
54} 53}
@@ -62,7 +61,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
62{ 61{
63 unsigned int i; 62 unsigned int i;
64 63
65 ATH5K_TRACE(ah->ah_sc);
66 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); 64 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
67 65
68 /* 66 /*
@@ -96,8 +94,6 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
96 */ 94 */
97void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) 95void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
98{ 96{
99 ATH5K_TRACE(ah->ah_sc);
100
101 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); 97 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
102} 98}
103 99
@@ -125,7 +121,6 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
125{ 121{
126 u32 tx_queue; 122 u32 tx_queue;
127 123
128 ATH5K_TRACE(ah->ah_sc);
129 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 124 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
130 125
131 /* Return if queue is declared inactive */ 126 /* Return if queue is declared inactive */
@@ -186,7 +181,6 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
186 unsigned int i = 40; 181 unsigned int i = 40;
187 u32 tx_queue, pending; 182 u32 tx_queue, pending;
188 183
189 ATH5K_TRACE(ah->ah_sc);
190 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 184 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
191 185
192 /* Return if queue is declared inactive */ 186 /* Return if queue is declared inactive */
@@ -297,7 +291,6 @@ u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
297{ 291{
298 u16 tx_reg; 292 u16 tx_reg;
299 293
300 ATH5K_TRACE(ah->ah_sc);
301 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 294 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
302 295
303 /* 296 /*
@@ -340,7 +333,6 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
340{ 333{
341 u16 tx_reg; 334 u16 tx_reg;
342 335
343 ATH5K_TRACE(ah->ah_sc);
344 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 336 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
345 337
346 /* 338 /*
@@ -400,8 +392,6 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
400 u32 trigger_level, imr; 392 u32 trigger_level, imr;
401 int ret = -EIO; 393 int ret = -EIO;
402 394
403 ATH5K_TRACE(ah->ah_sc);
404
405 /* 395 /*
406 * Disable interrupts by setting the mask 396 * Disable interrupts by setting the mask
407 */ 397 */
@@ -451,7 +441,6 @@ done:
451 */ 441 */
452bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah) 442bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
453{ 443{
454 ATH5K_TRACE(ah->ah_sc);
455 return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; 444 return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
456} 445}
457 446
@@ -475,8 +464,6 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
475{ 464{
476 u32 data; 465 u32 data;
477 466
478 ATH5K_TRACE(ah->ah_sc);
479
480 /* 467 /*
481 * Read interrupt status from the Interrupt Status register 468 * Read interrupt status from the Interrupt Status register
482 * on 5210 469 * on 5210
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index ed0263672d6d..ae316fec4a6a 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -35,7 +35,6 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
35{ 35{
36 u32 status, timeout; 36 u32 status, timeout;
37 37
38 ATH5K_TRACE(ah->ah_sc);
39 /* 38 /*
40 * Initialize EEPROM access 39 * Initialize EEPROM access
41 */ 40 */
@@ -715,7 +714,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
715 714
716 /* Only one curve for RF5111 715 /* Only one curve for RF5111
717 * find out which one and place 716 * find out which one and place
718 * in in pd_curves. 717 * in pd_curves.
719 * Note: ee_x_gain is reversed here */ 718 * Note: ee_x_gain is reversed here */
720 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) { 719 for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
721 720
diff --git a/drivers/net/wireless/ath/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c
index 64a27e73d02e..bc90503f4b7a 100644
--- a/drivers/net/wireless/ath/ath5k/gpio.c
+++ b/drivers/net/wireless/ath/ath5k/gpio.c
@@ -34,8 +34,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
34 /*5210 has different led mode handling*/ 34 /*5210 has different led mode handling*/
35 u32 led_5210; 35 u32 led_5210;
36 36
37 ATH5K_TRACE(ah->ah_sc);
38
39 /*Reset led status*/ 37 /*Reset led status*/
40 if (ah->ah_version != AR5K_AR5210) 38 if (ah->ah_version != AR5K_AR5210)
41 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, 39 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
@@ -82,7 +80,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
82 */ 80 */
83int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) 81int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
84{ 82{
85 ATH5K_TRACE(ah->ah_sc);
86 if (gpio >= AR5K_NUM_GPIO) 83 if (gpio >= AR5K_NUM_GPIO)
87 return -EINVAL; 84 return -EINVAL;
88 85
@@ -98,7 +95,6 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
98 */ 95 */
99int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) 96int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
100{ 97{
101 ATH5K_TRACE(ah->ah_sc);
102 if (gpio >= AR5K_NUM_GPIO) 98 if (gpio >= AR5K_NUM_GPIO)
103 return -EINVAL; 99 return -EINVAL;
104 100
@@ -114,7 +110,6 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
114 */ 110 */
115u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) 111u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
116{ 112{
117 ATH5K_TRACE(ah->ah_sc);
118 if (gpio >= AR5K_NUM_GPIO) 113 if (gpio >= AR5K_NUM_GPIO)
119 return 0xffffffff; 114 return 0xffffffff;
120 115
@@ -129,7 +124,6 @@ u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
129int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) 124int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
130{ 125{
131 u32 data; 126 u32 data;
132 ATH5K_TRACE(ah->ah_sc);
133 127
134 if (gpio >= AR5K_NUM_GPIO) 128 if (gpio >= AR5K_NUM_GPIO)
135 return -EINVAL; 129 return -EINVAL;
@@ -153,7 +147,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
153{ 147{
154 u32 data; 148 u32 data;
155 149
156 ATH5K_TRACE(ah->ah_sc);
157 if (gpio >= AR5K_NUM_GPIO) 150 if (gpio >= AR5K_NUM_GPIO)
158 return; 151 return;
159 152
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 5212e275f1c7..86fdb6ddfaaa 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -59,8 +59,6 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
59 59
60 beacon_reg = 0; 60 beacon_reg = 0;
61 61
62 ATH5K_TRACE(ah->ah_sc);
63
64 switch (op_mode) { 62 switch (op_mode) {
65 case NL80211_IFTYPE_ADHOC: 63 case NL80211_IFTYPE_ADHOC:
66 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; 64 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
@@ -173,7 +171,6 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
173 */ 171 */
174static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 172static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
175{ 173{
176 ATH5K_TRACE(ah->ah_sc);
177 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) 174 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
178 <= timeout) 175 <= timeout)
179 return -EINVAL; 176 return -EINVAL;
@@ -192,7 +189,6 @@ static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
192 */ 189 */
193static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 190static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
194{ 191{
195 ATH5K_TRACE(ah->ah_sc);
196 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) 192 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
197 <= timeout) 193 <= timeout)
198 return -EINVAL; 194 return -EINVAL;
@@ -297,7 +293,6 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
297 u32 low_id, high_id; 293 u32 low_id, high_id;
298 u32 pcu_reg; 294 u32 pcu_reg;
299 295
300 ATH5K_TRACE(ah->ah_sc);
301 /* Set new station ID */ 296 /* Set new station ID */
302 memcpy(common->macaddr, mac, ETH_ALEN); 297 memcpy(common->macaddr, mac, ETH_ALEN);
303 298
@@ -357,7 +352,6 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah)
357void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) 352void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
358{ 353{
359 struct ath_common *common = ath5k_hw_common(ah); 354 struct ath_common *common = ath5k_hw_common(ah);
360 ATH5K_TRACE(ah->ah_sc);
361 355
362 /* Cache bssid mask so that we can restore it 356 /* Cache bssid mask so that we can restore it
363 * on reset */ 357 * on reset */
@@ -382,7 +376,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
382 */ 376 */
383void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) 377void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
384{ 378{
385 ATH5K_TRACE(ah->ah_sc);
386 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); 379 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
387} 380}
388 381
@@ -397,7 +390,6 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
397 */ 390 */
398void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) 391void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
399{ 392{
400 ATH5K_TRACE(ah->ah_sc);
401 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); 393 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
402} 394}
403 395
@@ -406,8 +398,6 @@ void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
406 */ 398 */
407void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) 399void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
408{ 400{
409 ATH5K_TRACE(ah->ah_sc);
410 /* Set the multicat filter */
411 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); 401 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
412 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); 402 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
413} 403}
@@ -427,7 +417,6 @@ u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
427{ 417{
428 u32 data, filter = 0; 418 u32 data, filter = 0;
429 419
430 ATH5K_TRACE(ah->ah_sc);
431 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); 420 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
432 421
433 /*Radar detection for 5212*/ 422 /*Radar detection for 5212*/
@@ -457,8 +446,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
457{ 446{
458 u32 data = 0; 447 u32 data = 0;
459 448
460 ATH5K_TRACE(ah->ah_sc);
461
462 /* Set PHY error filter register on 5212*/ 449 /* Set PHY error filter register on 5212*/
463 if (ah->ah_version == AR5K_AR5212) { 450 if (ah->ah_version == AR5K_AR5212) {
464 if (filter & AR5K_RX_FILTER_RADARERR) 451 if (filter & AR5K_RX_FILTER_RADARERR)
@@ -533,8 +520,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
533 520
534 WARN_ON( i == ATH5K_MAX_TSF_READ ); 521 WARN_ON( i == ATH5K_MAX_TSF_READ );
535 522
536 ATH5K_TRACE(ah->ah_sc);
537
538 return (((u64)tsf_upper1 << 32) | tsf_lower); 523 return (((u64)tsf_upper1 << 32) | tsf_lower);
539} 524}
540 525
@@ -548,8 +533,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
548 */ 533 */
549void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64) 534void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
550{ 535{
551 ATH5K_TRACE(ah->ah_sc);
552
553 ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32); 536 ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
554 ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32); 537 ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
555} 538}
@@ -565,8 +548,6 @@ void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
565{ 548{
566 u32 val; 549 u32 val;
567 550
568 ATH5K_TRACE(ah->ah_sc);
569
570 val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF; 551 val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
571 552
572 /* 553 /*
@@ -586,7 +567,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
586{ 567{
587 u32 timer1, timer2, timer3; 568 u32 timer1, timer2, timer3;
588 569
589 ATH5K_TRACE(ah->ah_sc);
590 /* 570 /*
591 * Set the additional timers by mode 571 * Set the additional timers by mode
592 */ 572 */
@@ -674,7 +654,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
674 unsigned int i, type; 654 unsigned int i, type;
675 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; 655 u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
676 656
677 ATH5K_TRACE(ah->ah_sc);
678 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); 657 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
679 658
680 type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); 659 type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
@@ -749,8 +728,6 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
749 bool is_tkip; 728 bool is_tkip;
750 const u8 *key_ptr; 729 const u8 *key_ptr;
751 730
752 ATH5K_TRACE(ah->ah_sc);
753
754 is_tkip = (key->alg == ALG_TKIP); 731 is_tkip = (key->alg == ALG_TKIP);
755 732
756 /* 733 /*
@@ -836,7 +813,6 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
836{ 813{
837 u32 low_id, high_id; 814 u32 low_id, high_id;
838 815
839 ATH5K_TRACE(ah->ah_sc);
840 /* Invalid entry (key table overflow) */ 816 /* Invalid entry (key table overflow) */
841 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); 817 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
842 818
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 492cbb15720d..73c4fcd142bb 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -378,8 +378,6 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
378 u32 data, type; 378 u32 data, type;
379 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 379 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
380 380
381 ATH5K_TRACE(ah->ah_sc);
382
383 if (ah->ah_rf_banks == NULL || 381 if (ah->ah_rf_banks == NULL ||
384 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE) 382 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
385 return AR5K_RFGAIN_INACTIVE; 383 return AR5K_RFGAIN_INACTIVE;
@@ -1167,7 +1165,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1167 * The median of the values in the history is then loaded into the 1165 * The median of the values in the history is then loaded into the
1168 * hardware for its own use for RSSI and CCA measurements. 1166 * hardware for its own use for RSSI and CCA measurements.
1169 */ 1167 */
1170static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) 1168void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1171{ 1169{
1172 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 1170 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1173 u32 val; 1171 u32 val;
@@ -1248,7 +1246,6 @@ static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1248/* 1246/*
1249 * Perform a PHY calibration on RF5110 1247 * Perform a PHY calibration on RF5110
1250 * -Fix BPSK/QAM Constellation (I/Q correction) 1248 * -Fix BPSK/QAM Constellation (I/Q correction)
1251 * -Calculate Noise Floor
1252 */ 1249 */
1253static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, 1250static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1254 struct ieee80211_channel *channel) 1251 struct ieee80211_channel *channel)
@@ -1335,8 +1332,6 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1335 return ret; 1332 return ret;
1336 } 1333 }
1337 1334
1338 ath5k_hw_update_noise_floor(ah);
1339
1340 /* 1335 /*
1341 * Re-enable RX/TX and beacons 1336 * Re-enable RX/TX and beacons
1342 */ 1337 */
@@ -1348,22 +1343,20 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1348} 1343}
1349 1344
1350/* 1345/*
1351 * Perform a PHY calibration on RF5111/5112 and newer chips 1346 * Perform I/Q calibration on RF5111/5112 and newer chips
1352 */ 1347 */
1353static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, 1348static int
1354 struct ieee80211_channel *channel) 1349ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1355{ 1350{
1356 u32 i_pwr, q_pwr; 1351 u32 i_pwr, q_pwr;
1357 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; 1352 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1358 int i; 1353 int i;
1359 ATH5K_TRACE(ah->ah_sc);
1360 1354
1361 if (!ah->ah_calibration || 1355 if (!ah->ah_calibration ||
1362 ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) 1356 ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
1363 goto done; 1357 return 0;
1364 1358
1365 /* Calibration has finished, get the results and re-run */ 1359 /* Calibration has finished, get the results and re-run */
1366
1367 /* work around empty results which can apparently happen on 5212 */ 1360 /* work around empty results which can apparently happen on 5212 */
1368 for (i = 0; i <= 10; i++) { 1361 for (i = 0; i <= 10; i++) {
1369 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); 1362 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
@@ -1384,7 +1377,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1384 1377
1385 /* protect against divide by 0 and loss of sign bits */ 1378 /* protect against divide by 0 and loss of sign bits */
1386 if (i_coffd == 0 || q_coffd < 2) 1379 if (i_coffd == 0 || q_coffd < 2)
1387 goto done; 1380 return -1;
1388 1381
1389 i_coff = (-iq_corr) / i_coffd; 1382 i_coff = (-iq_corr) / i_coffd;
1390 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ 1383 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
@@ -1410,17 +1403,6 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1410 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); 1403 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1411 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN); 1404 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
1412 1405
1413done:
1414
1415 /* TODO: Separate noise floor calibration from I/Q calibration
1416 * since noise floor calibration interrupts rx path while I/Q
1417 * calibration doesn't. We don't need to run noise floor calibration
1418 * as often as I/Q calibration.*/
1419 ath5k_hw_update_noise_floor(ah);
1420
1421 /* Initiate a gain_F calibration */
1422 ath5k_hw_request_rfgain_probe(ah);
1423
1424 return 0; 1406 return 0;
1425} 1407}
1426 1408
@@ -1434,8 +1416,10 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1434 1416
1435 if (ah->ah_radio == AR5K_RF5110) 1417 if (ah->ah_radio == AR5K_RF5110)
1436 ret = ath5k_hw_rf5110_calibrate(ah, channel); 1418 ret = ath5k_hw_rf5110_calibrate(ah, channel);
1437 else 1419 else {
1438 ret = ath5k_hw_rf511x_calibrate(ah, channel); 1420 ret = ath5k_hw_rf511x_iq_calibrate(ah);
1421 ath5k_hw_request_rfgain_probe(ah);
1422 }
1439 1423
1440 return ret; 1424 return ret;
1441} 1425}
@@ -1693,7 +1677,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1693 1677
1694int ath5k_hw_phy_disable(struct ath5k_hw *ah) 1678int ath5k_hw_phy_disable(struct ath5k_hw *ah)
1695{ 1679{
1696 ATH5K_TRACE(ah->ah_sc);
1697 /*Just a try M.F.*/ 1680 /*Just a try M.F.*/
1698 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); 1681 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
1699 1682
@@ -1709,8 +1692,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1709 u32 srev; 1692 u32 srev;
1710 u16 ret; 1693 u16 ret;
1711 1694
1712 ATH5K_TRACE(ah->ah_sc);
1713
1714 /* 1695 /*
1715 * Set the radio chip access register 1696 * Set the radio chip access register
1716 */ 1697 */
@@ -1755,8 +1736,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1755static void /*TODO:Boundary check*/ 1736static void /*TODO:Boundary check*/
1756ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) 1737ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1757{ 1738{
1758 ATH5K_TRACE(ah->ah_sc);
1759
1760 if (ah->ah_version != AR5K_AR5210) 1739 if (ah->ah_version != AR5K_AR5210)
1761 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); 1740 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1762} 1741}
@@ -1789,19 +1768,50 @@ ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
1789 1768
1790 if (enable) { 1769 if (enable) {
1791 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, 1770 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1792 AR5K_PHY_RESTART_DIV_GC, 0xc); 1771 AR5K_PHY_RESTART_DIV_GC, 1);
1793 1772
1794 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, 1773 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1795 AR5K_PHY_FAST_ANT_DIV_EN); 1774 AR5K_PHY_FAST_ANT_DIV_EN);
1796 } else { 1775 } else {
1797 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, 1776 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1798 AR5K_PHY_RESTART_DIV_GC, 0x8); 1777 AR5K_PHY_RESTART_DIV_GC, 0);
1799 1778
1800 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, 1779 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1801 AR5K_PHY_FAST_ANT_DIV_EN); 1780 AR5K_PHY_FAST_ANT_DIV_EN);
1802 } 1781 }
1803} 1782}
1804 1783
1784void
1785ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode)
1786{
1787 u8 ant0, ant1;
1788
1789 /*
1790 * In case a fixed antenna was set as default
1791 * use the same switch table twice.
1792 */
1793 if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
1794 ant0 = ant1 = AR5K_ANT_SWTABLE_A;
1795 else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
1796 ant0 = ant1 = AR5K_ANT_SWTABLE_B;
1797 else {
1798 ant0 = AR5K_ANT_SWTABLE_A;
1799 ant1 = AR5K_ANT_SWTABLE_B;
1800 }
1801
1802 /* Set antenna idle switch table */
1803 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
1804 AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
1805 (ah->ah_ant_ctl[ee_mode][AR5K_ANT_CTL] |
1806 AR5K_PHY_ANT_CTL_TXRX_EN));
1807
1808 /* Set antenna switch tables */
1809 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0],
1810 AR5K_PHY_ANT_SWITCH_TABLE_0);
1811 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1],
1812 AR5K_PHY_ANT_SWITCH_TABLE_1);
1813}
1814
1805/* 1815/*
1806 * Set antenna operating mode 1816 * Set antenna operating mode
1807 */ 1817 */
@@ -1823,8 +1833,6 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1823 1833
1824 def_ant = ah->ah_def_ant; 1834 def_ant = ah->ah_def_ant;
1825 1835
1826 ATH5K_TRACE(ah->ah_sc);
1827
1828 switch (channel->hw_value & CHANNEL_MODES) { 1836 switch (channel->hw_value & CHANNEL_MODES) {
1829 case CHANNEL_A: 1837 case CHANNEL_A:
1830 case CHANNEL_T: 1838 case CHANNEL_T:
@@ -1923,6 +1931,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1923 if (sta_id1) 1931 if (sta_id1)
1924 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1); 1932 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
1925 1933
1934 ath5k_hw_set_antenna_switch(ah, ee_mode);
1926 /* Note: set diversity before default antenna 1935 /* Note: set diversity before default antenna
1927 * because it won't work correctly */ 1936 * because it won't work correctly */
1928 ath5k_hw_set_fast_div(ah, ee_mode, fast_div); 1937 ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
@@ -2988,7 +2997,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2988 u8 type; 2997 u8 type;
2989 int ret; 2998 int ret;
2990 2999
2991 ATH5K_TRACE(ah->ah_sc);
2992 if (txpower > AR5K_TUNE_MAX_TXPOWER) { 3000 if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2993 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); 3001 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
2994 return -EINVAL; 3002 return -EINVAL;
@@ -3084,8 +3092,6 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3084 struct ieee80211_channel *channel = ah->ah_current_channel; 3092 struct ieee80211_channel *channel = ah->ah_current_channel;
3085 u8 ee_mode; 3093 u8 ee_mode;
3086 3094
3087 ATH5K_TRACE(ah->ah_sc);
3088
3089 switch (channel->hw_value & CHANNEL_MODES) { 3095 switch (channel->hw_value & CHANNEL_MODES) {
3090 case CHANNEL_A: 3096 case CHANNEL_A:
3091 case CHANNEL_T: 3097 case CHANNEL_T:
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index f5831da33f7b..4186ff4c6e9c 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -31,7 +31,6 @@ Queue Control Unit, DFS Control Unit Functions
31int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, 31int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
32 struct ath5k_txq_info *queue_info) 32 struct ath5k_txq_info *queue_info)
33{ 33{
34 ATH5K_TRACE(ah->ah_sc);
35 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); 34 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
36 return 0; 35 return 0;
37} 36}
@@ -42,7 +41,6 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
42int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, 41int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
43 const struct ath5k_txq_info *queue_info) 42 const struct ath5k_txq_info *queue_info)
44{ 43{
45 ATH5K_TRACE(ah->ah_sc);
46 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 44 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
47 45
48 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) 46 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
@@ -69,8 +67,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
69 unsigned int queue; 67 unsigned int queue;
70 int ret; 68 int ret;
71 69
72 ATH5K_TRACE(ah->ah_sc);
73
74 /* 70 /*
75 * Get queue by type 71 * Get queue by type
76 */ 72 */
@@ -149,7 +145,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
149u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) 145u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
150{ 146{
151 u32 pending; 147 u32 pending;
152 ATH5K_TRACE(ah->ah_sc);
153 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 148 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
154 149
155 /* Return if queue is declared inactive */ 150 /* Return if queue is declared inactive */
@@ -177,7 +172,6 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
177 */ 172 */
178void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) 173void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
179{ 174{
180 ATH5K_TRACE(ah->ah_sc);
181 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) 175 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
182 return; 176 return;
183 177
@@ -195,7 +189,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
195 u32 cw_min, cw_max, retry_lg, retry_sh; 189 u32 cw_min, cw_max, retry_lg, retry_sh;
196 struct ath5k_txq_info *tq = &ah->ah_txq[queue]; 190 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
197 191
198 ATH5K_TRACE(ah->ah_sc);
199 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 192 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
200 193
201 tq = &ah->ah_txq[queue]; 194 tq = &ah->ah_txq[queue];
@@ -523,8 +516,6 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
523{ 516{
524 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); 517 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
525 518
526 ATH5K_TRACE(ah->ah_sc);
527
528 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) 519 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
529 return -EINVAL; 520 return -EINVAL;
530 521
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 307f80e83f94..498aa28ea9e6 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -201,8 +201,6 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
201 int ret; 201 int ret;
202 u32 mask = val ? val : ~0U; 202 u32 mask = val ? val : ~0U;
203 203
204 ATH5K_TRACE(ah->ah_sc);
205
206 /* Read-and-clear RX Descriptor Pointer*/ 204 /* Read-and-clear RX Descriptor Pointer*/
207 ath5k_hw_reg_read(ah, AR5K_RXDP); 205 ath5k_hw_reg_read(ah, AR5K_RXDP);
208 206
@@ -246,7 +244,6 @@ static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
246 unsigned int i; 244 unsigned int i;
247 u32 staid, data; 245 u32 staid, data;
248 246
249 ATH5K_TRACE(ah->ah_sc);
250 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); 247 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
251 248
252 switch (mode) { 249 switch (mode) {
@@ -393,8 +390,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
393 mode = 0; 390 mode = 0;
394 clock = 0; 391 clock = 0;
395 392
396 ATH5K_TRACE(ah->ah_sc);
397
398 /* Wakeup the device */ 393 /* Wakeup the device */
399 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); 394 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
400 if (ret) { 395 if (ret) {
@@ -734,7 +729,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
734} 729}
735 730
736static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, 731static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
737 struct ieee80211_channel *channel, u8 *ant, u8 ee_mode) 732 struct ieee80211_channel *channel, u8 ee_mode)
738{ 733{
739 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 734 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
740 s16 cck_ofdm_pwr_delta; 735 s16 cck_ofdm_pwr_delta;
@@ -768,17 +763,9 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
768 ee->ee_cck_ofdm_gain_delta; 763 ee->ee_cck_ofdm_gain_delta;
769 } 764 }
770 765
771 /* Set antenna idle switch table */ 766 /* XXX: necessary here? is called from ath5k_hw_set_antenna_mode()
772 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, 767 * too */
773 AR5K_PHY_ANT_CTL_SWTABLE_IDLE, 768 ath5k_hw_set_antenna_switch(ah, ee_mode);
774 (ah->ah_ant_ctl[ee_mode][0] |
775 AR5K_PHY_ANT_CTL_TXRX_EN));
776
777 /* Set antenna switch tables */
778 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
779 AR5K_PHY_ANT_SWITCH_TABLE_0);
780 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
781 AR5K_PHY_ANT_SWITCH_TABLE_1);
782 769
783 /* Noise floor threshold */ 770 /* Noise floor threshold */
784 ath5k_hw_reg_write(ah, 771 ath5k_hw_reg_write(ah,
@@ -855,7 +842,6 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
855 AR5K_PHY_NF_THRESH62, 842 AR5K_PHY_NF_THRESH62,
856 ee->ee_thr_62[ee_mode]); 843 ee->ee_thr_62[ee_mode]);
857 844
858
859 /* False detect backoff for channels 845 /* False detect backoff for channels
860 * that have spur noise. Write the new 846 * that have spur noise. Write the new
861 * cyclic power RSSI threshold. */ 847 * cyclic power RSSI threshold. */
@@ -891,14 +877,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
891 struct ieee80211_channel *channel, bool change_channel) 877 struct ieee80211_channel *channel, bool change_channel)
892{ 878{
893 struct ath_common *common = ath5k_hw_common(ah); 879 struct ath_common *common = ath5k_hw_common(ah);
894 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; 880 u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo;
895 u32 phy_tst1; 881 u32 phy_tst1;
896 u8 mode, freq, ee_mode, ant[2]; 882 u8 mode, freq, ee_mode;
897 int i, ret; 883 int i, ret;
898 884
899 ATH5K_TRACE(ah->ah_sc);
900
901 s_ant = 0;
902 ee_mode = 0; 885 ee_mode = 0;
903 staid1_flags = 0; 886 staid1_flags = 0;
904 tsf_up = 0; 887 tsf_up = 0;
@@ -995,9 +978,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
995 } 978 }
996 } 979 }
997 980
998 /* Save default antenna */
999 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
1000
1001 if (ah->ah_version == AR5K_AR5212) { 981 if (ah->ah_version == AR5K_AR5212) {
1002 /* Restore normal 32/40MHz clock operation 982 /* Restore normal 32/40MHz clock operation
1003 * to avoid register access delay on certain 983 * to avoid register access delay on certain
@@ -1094,22 +1074,17 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1094 /* Write OFDM timings on 5212*/ 1074 /* Write OFDM timings on 5212*/
1095 if (ah->ah_version == AR5K_AR5212 && 1075 if (ah->ah_version == AR5K_AR5212 &&
1096 channel->hw_value & CHANNEL_OFDM) { 1076 channel->hw_value & CHANNEL_OFDM) {
1097 struct ath5k_eeprom_info *ee =
1098 &ah->ah_capabilities.cap_eeprom;
1099 1077
1100 ret = ath5k_hw_write_ofdm_timings(ah, channel); 1078 ret = ath5k_hw_write_ofdm_timings(ah, channel);
1101 if (ret) 1079 if (ret)
1102 return ret; 1080 return ret;
1103 1081
1104 /* Note: According to docs we can have a newer 1082 /* Spur info is available only from EEPROM versions
1105 * EEPROM on old hardware, so we need to verify 1083 * bigger than 5.3 but but the EEPOM routines will use
1106 * that our hardware is new enough to have spur 1084 * static values for older versions */
1107 * mitigation registers (delta phase etc) */ 1085 if (ah->ah_mac_srev >= AR5K_SREV_AR5424)
1108 if (ah->ah_mac_srev >= AR5K_SREV_AR5424 ||
1109 (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
1110 ee->ee_version >= AR5K_EEPROM_VERSION_5_3))
1111 ath5k_hw_set_spur_mitigation_filter(ah, 1086 ath5k_hw_set_spur_mitigation_filter(ah,
1112 channel); 1087 channel);
1113 } 1088 }
1114 1089
1115 /*Enable/disable 802.11b mode on 5111 1090 /*Enable/disable 802.11b mode on 5111
@@ -1123,21 +1098,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1123 AR5K_TXCFG_B_MODE); 1098 AR5K_TXCFG_B_MODE);
1124 } 1099 }
1125 1100
1126 /*
1127 * In case a fixed antenna was set as default
1128 * use the same switch table twice.
1129 */
1130 if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
1131 ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
1132 else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
1133 ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
1134 else {
1135 ant[0] = AR5K_ANT_SWTABLE_A;
1136 ant[1] = AR5K_ANT_SWTABLE_B;
1137 }
1138
1139 /* Commit values from EEPROM */ 1101 /* Commit values from EEPROM */
1140 ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); 1102 ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
1141 1103
1142 } else { 1104 } else {
1143 /* 1105 /*
@@ -1175,8 +1137,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1175 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); 1137 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1176 } 1138 }
1177 } 1139 }
1178
1179 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
1180 } 1140 }
1181 1141
1182 /* Ledstate */ 1142 /* Ledstate */
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c
new file mode 100644
index 000000000000..90757de7bf59
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/sysfs.c
@@ -0,0 +1,116 @@
1#include <linux/device.h>
2#include <linux/pci.h>
3
4#include "base.h"
5#include "ath5k.h"
6#include "reg.h"
7
8#define SIMPLE_SHOW_STORE(name, get, set) \
9static ssize_t ath5k_attr_show_##name(struct device *dev, \
10 struct device_attribute *attr, \
11 char *buf) \
12{ \
13 struct ath5k_softc *sc = dev_get_drvdata(dev); \
14 return snprintf(buf, PAGE_SIZE, "%d\n", get); \
15} \
16 \
17static ssize_t ath5k_attr_store_##name(struct device *dev, \
18 struct device_attribute *attr, \
19 const char *buf, size_t count) \
20{ \
21 struct ath5k_softc *sc = dev_get_drvdata(dev); \
22 int val; \
23 \
24 val = (int)simple_strtoul(buf, NULL, 10); \
25 set(sc->ah, val); \
26 return count; \
27} \
28static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \
29 ath5k_attr_show_##name, ath5k_attr_store_##name)
30
31#define SIMPLE_SHOW(name, get) \
32static ssize_t ath5k_attr_show_##name(struct device *dev, \
33 struct device_attribute *attr, \
34 char *buf) \
35{ \
36 struct ath5k_softc *sc = dev_get_drvdata(dev); \
37 return snprintf(buf, PAGE_SIZE, "%d\n", get); \
38} \
39static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
40
41/*** ANI ***/
42
43SIMPLE_SHOW_STORE(ani_mode, sc->ani_state.ani_mode, ath5k_ani_init);
44SIMPLE_SHOW_STORE(noise_immunity_level, sc->ani_state.noise_imm_level,
45 ath5k_ani_set_noise_immunity_level);
46SIMPLE_SHOW_STORE(spur_level, sc->ani_state.spur_level,
47 ath5k_ani_set_spur_immunity_level);
48SIMPLE_SHOW_STORE(firstep_level, sc->ani_state.firstep_level,
49 ath5k_ani_set_firstep_level);
50SIMPLE_SHOW_STORE(ofdm_weak_signal_detection, sc->ani_state.ofdm_weak_sig,
51 ath5k_ani_set_ofdm_weak_signal_detection);
52SIMPLE_SHOW_STORE(cck_weak_signal_detection, sc->ani_state.cck_weak_sig,
53 ath5k_ani_set_cck_weak_signal_detection);
54SIMPLE_SHOW(spur_level_max, sc->ani_state.max_spur_level);
55
56static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev,
57 struct device_attribute *attr,
58 char *buf)
59{
60 return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL);
61}
62static DEVICE_ATTR(noise_immunity_level_max, S_IRUGO,
63 ath5k_attr_show_noise_immunity_level_max, NULL);
64
65static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev,
66 struct device_attribute *attr,
67 char *buf)
68{
69 return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL);
70}
71static DEVICE_ATTR(firstep_level_max, S_IRUGO,
72 ath5k_attr_show_firstep_level_max, NULL);
73
74static struct attribute *ath5k_sysfs_entries_ani[] = {
75 &dev_attr_ani_mode.attr,
76 &dev_attr_noise_immunity_level.attr,
77 &dev_attr_spur_level.attr,
78 &dev_attr_firstep_level.attr,
79 &dev_attr_ofdm_weak_signal_detection.attr,
80 &dev_attr_cck_weak_signal_detection.attr,
81 &dev_attr_noise_immunity_level_max.attr,
82 &dev_attr_spur_level_max.attr,
83 &dev_attr_firstep_level_max.attr,
84 NULL
85};
86
87static struct attribute_group ath5k_attribute_group_ani = {
88 .name = "ani",
89 .attrs = ath5k_sysfs_entries_ani,
90};
91
92
93/*** register / unregister ***/
94
95int
96ath5k_sysfs_register(struct ath5k_softc *sc)
97{
98 struct device *dev = &sc->pdev->dev;
99 int err;
100
101 err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
102 if (err) {
103 ATH5K_ERR(sc, "failed to create sysfs group\n");
104 return err;
105 }
106
107 return 0;
108}
109
110void
111ath5k_sysfs_unregister(struct ath5k_softc *sc)
112{
113 struct device *dev = &sc->pdev->dev;
114
115 sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
116}
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index dd112be218ab..973ae4f49f35 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -32,7 +32,8 @@ ath9k_hw-y:= \
32 mac.o \ 32 mac.o \
33 ar9002_mac.o \ 33 ar9002_mac.o \
34 ar9003_mac.o \ 34 ar9003_mac.o \
35 ar9003_eeprom.o 35 ar9003_eeprom.o \
36 ar9003_paprd.o
36 37
37obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 38obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
38 39
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index ba8b20f01594..cc648b6ae31c 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -17,8 +17,99 @@
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h" 18#include "hw-ops.h"
19 19
20static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 20struct ani_ofdm_level_entry {
21 struct ath9k_channel *chan) 21 int spur_immunity_level;
22 int fir_step_level;
23 int ofdm_weak_signal_on;
24};
25
26/* values here are relative to the INI */
27
28/*
29 * Legend:
30 *
31 * SI: Spur immunity
32 * FS: FIR Step
33 * WS: OFDM / CCK Weak Signal detection
34 * MRC-CCK: Maximal Ratio Combining for CCK
35 */
36
37static const struct ani_ofdm_level_entry ofdm_level_table[] = {
38 /* SI FS WS */
39 { 0, 0, 1 }, /* lvl 0 */
40 { 1, 1, 1 }, /* lvl 1 */
41 { 2, 2, 1 }, /* lvl 2 */
42 { 3, 2, 1 }, /* lvl 3 (default) */
43 { 4, 3, 1 }, /* lvl 4 */
44 { 5, 4, 1 }, /* lvl 5 */
45 { 6, 5, 1 }, /* lvl 6 */
46 { 7, 6, 1 }, /* lvl 7 */
47 { 7, 7, 1 }, /* lvl 8 */
48 { 7, 8, 0 } /* lvl 9 */
49};
50#define ATH9K_ANI_OFDM_NUM_LEVEL \
51 (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0]))
52#define ATH9K_ANI_OFDM_MAX_LEVEL \
53 (ATH9K_ANI_OFDM_NUM_LEVEL-1)
54#define ATH9K_ANI_OFDM_DEF_LEVEL \
55 3 /* default level - matches the INI settings */
56
57/*
58 * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
59 * With OFDM for single stream you just add up all antenna inputs, you're
60 * only interested in what you get after FFT. Signal aligment is also not
61 * required for OFDM because any phase difference adds up in the frequency
62 * domain.
63 *
64 * MRC requires extra work for use with CCK. You need to align the antenna
65 * signals from the different antenna before you can add the signals together.
66 * You need aligment of signals as CCK is in time domain, so addition can cancel
67 * your signal completely if phase is 180 degrees (think of adding sine waves).
68 * You also need to remove noise before the addition and this is where ANI
69 * MRC CCK comes into play. One of the antenna inputs may be stronger but
70 * lower SNR, so just adding after alignment can be dangerous.
71 *
72 * Regardless of alignment in time, the antenna signals add constructively after
73 * FFT and improve your reception. For more information:
74 *
75 * http://en.wikipedia.org/wiki/Maximal-ratio_combining
76 */
77
78struct ani_cck_level_entry {
79 int fir_step_level;
80 int mrc_cck_on;
81};
82
83static const struct ani_cck_level_entry cck_level_table[] = {
84 /* FS MRC-CCK */
85 { 0, 1 }, /* lvl 0 */
86 { 1, 1 }, /* lvl 1 */
87 { 2, 1 }, /* lvl 2 (default) */
88 { 3, 1 }, /* lvl 3 */
89 { 4, 0 }, /* lvl 4 */
90 { 5, 0 }, /* lvl 5 */
91 { 6, 0 }, /* lvl 6 */
92 { 7, 0 }, /* lvl 7 (only for high rssi) */
93 { 8, 0 } /* lvl 8 (only for high rssi) */
94};
95
96#define ATH9K_ANI_CCK_NUM_LEVEL \
97 (sizeof(cck_level_table)/sizeof(cck_level_table[0]))
98#define ATH9K_ANI_CCK_MAX_LEVEL \
99 (ATH9K_ANI_CCK_NUM_LEVEL-1)
100#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
101 (ATH9K_ANI_CCK_NUM_LEVEL-3)
102#define ATH9K_ANI_CCK_DEF_LEVEL \
103 2 /* default level - matches the INI settings */
104
105/* Private to ani.c */
106static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
107{
108 ath9k_hw_private_ops(ah)->ani_lower_immunity(ah);
109}
110
111int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
112 struct ath9k_channel *chan)
22{ 113{
23 int i; 114 int i;
24 115
@@ -48,7 +139,7 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
48 stats->beacons += REG_READ(ah, AR_BEACON_CNT); 139 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
49} 140}
50 141
51static void ath9k_ani_restart(struct ath_hw *ah) 142static void ath9k_ani_restart_old(struct ath_hw *ah)
52{ 143{
53 struct ar5416AniState *aniState; 144 struct ar5416AniState *aniState;
54 struct ath_common *common = ath9k_hw_common(ah); 145 struct ath_common *common = ath9k_hw_common(ah);
@@ -96,7 +187,42 @@ static void ath9k_ani_restart(struct ath_hw *ah)
96 aniState->cckPhyErrCount = 0; 187 aniState->cckPhyErrCount = 0;
97} 188}
98 189
99static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) 190static void ath9k_ani_restart_new(struct ath_hw *ah)
191{
192 struct ar5416AniState *aniState;
193 struct ath_common *common = ath9k_hw_common(ah);
194
195 if (!DO_ANI(ah))
196 return;
197
198 aniState = ah->curani;
199 aniState->listenTime = 0;
200
201 aniState->ofdmPhyErrBase = 0;
202 aniState->cckPhyErrBase = 0;
203
204 ath_print(common, ATH_DBG_ANI,
205 "Writing ofdmbase=%08x cckbase=%08x\n",
206 aniState->ofdmPhyErrBase,
207 aniState->cckPhyErrBase);
208
209 ENABLE_REGWRITE_BUFFER(ah);
210
211 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
212 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
213 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
214 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
215
216 REGWRITE_BUFFER_FLUSH(ah);
217 DISABLE_REGWRITE_BUFFER(ah);
218
219 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
220
221 aniState->ofdmPhyErrCount = 0;
222 aniState->cckPhyErrCount = 0;
223}
224
225static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
100{ 226{
101 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 227 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
102 struct ar5416AniState *aniState; 228 struct ar5416AniState *aniState;
@@ -168,7 +294,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
168 } 294 }
169} 295}
170 296
171static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) 297static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
172{ 298{
173 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 299 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
174 struct ar5416AniState *aniState; 300 struct ar5416AniState *aniState;
@@ -206,7 +332,125 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
206 } 332 }
207} 333}
208 334
209static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) 335/* Adjust the OFDM Noise Immunity Level */
336static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
337{
338 struct ar5416AniState *aniState = ah->curani;
339 struct ath_common *common = ath9k_hw_common(ah);
340 const struct ani_ofdm_level_entry *entry_ofdm;
341 const struct ani_cck_level_entry *entry_cck;
342
343 aniState->noiseFloor = BEACON_RSSI(ah);
344
345 ath_print(common, ATH_DBG_ANI,
346 "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
347 aniState->ofdmNoiseImmunityLevel,
348 immunityLevel, aniState->noiseFloor,
349 aniState->rssiThrLow, aniState->rssiThrHigh);
350
351 aniState->ofdmNoiseImmunityLevel = immunityLevel;
352
353 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
354 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
355
356 if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
357 ath9k_hw_ani_control(ah,
358 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
359 entry_ofdm->spur_immunity_level);
360
361 if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
362 entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
363 ath9k_hw_ani_control(ah,
364 ATH9K_ANI_FIRSTEP_LEVEL,
365 entry_ofdm->fir_step_level);
366
367 if ((ah->opmode != NL80211_IFTYPE_STATION &&
368 ah->opmode != NL80211_IFTYPE_ADHOC) ||
369 aniState->noiseFloor <= aniState->rssiThrHigh) {
370 if (aniState->ofdmWeakSigDetectOff)
371 /* force on ofdm weak sig detect */
372 ath9k_hw_ani_control(ah,
373 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
374 true);
375 else if (aniState->ofdmWeakSigDetectOff ==
376 entry_ofdm->ofdm_weak_signal_on)
377 ath9k_hw_ani_control(ah,
378 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
379 entry_ofdm->ofdm_weak_signal_on);
380 }
381}
382
383static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
384{
385 struct ar5416AniState *aniState;
386
387 if (!DO_ANI(ah))
388 return;
389
390 aniState = ah->curani;
391
392 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
393 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
394}
395
396/*
397 * Set the ANI settings to match an CCK level.
398 */
399static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
400{
401 struct ar5416AniState *aniState = ah->curani;
402 struct ath_common *common = ath9k_hw_common(ah);
403 const struct ani_ofdm_level_entry *entry_ofdm;
404 const struct ani_cck_level_entry *entry_cck;
405
406 aniState->noiseFloor = BEACON_RSSI(ah);
407 ath_print(common, ATH_DBG_ANI,
408 "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
409 aniState->cckNoiseImmunityLevel, immunityLevel,
410 aniState->noiseFloor, aniState->rssiThrLow,
411 aniState->rssiThrHigh);
412
413 if ((ah->opmode == NL80211_IFTYPE_STATION ||
414 ah->opmode == NL80211_IFTYPE_ADHOC) &&
415 aniState->noiseFloor <= aniState->rssiThrLow &&
416 immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
417 immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
418
419 aniState->cckNoiseImmunityLevel = immunityLevel;
420
421 entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
422 entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
423
424 if (aniState->firstepLevel != entry_cck->fir_step_level &&
425 entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
426 ath9k_hw_ani_control(ah,
427 ATH9K_ANI_FIRSTEP_LEVEL,
428 entry_cck->fir_step_level);
429
430 /* Skip MRC CCK for pre AR9003 families */
431 if (!AR_SREV_9300_20_OR_LATER(ah))
432 return;
433
434 if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
435 ath9k_hw_ani_control(ah,
436 ATH9K_ANI_MRC_CCK,
437 entry_cck->mrc_cck_on);
438}
439
440static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah)
441{
442 struct ar5416AniState *aniState;
443
444 if (!DO_ANI(ah))
445 return;
446
447 aniState = ah->curani;
448
449 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
450 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
451}
452
453static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
210{ 454{
211 struct ar5416AniState *aniState; 455 struct ar5416AniState *aniState;
212 int32_t rssi; 456 int32_t rssi;
@@ -259,9 +503,53 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
259 } 503 }
260} 504}
261 505
506/*
507 * only lower either OFDM or CCK errors per turn
508 * we lower the other one next time
509 */
510static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
511{
512 struct ar5416AniState *aniState;
513
514 aniState = ah->curani;
515
516 /* lower OFDM noise immunity */
517 if (aniState->ofdmNoiseImmunityLevel > 0 &&
518 (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
519 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1);
520 return;
521 }
522
523 /* lower CCK noise immunity */
524 if (aniState->cckNoiseImmunityLevel > 0)
525 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
526}
527
528static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
529{
530 struct ath9k_channel *chan = ah->curchan;
531 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
532 u8 clockrate; /* in MHz */
533
534 if (!ah->curchan) /* should really check for CCK instead */
535 clockrate = ATH9K_CLOCK_RATE_CCK;
536 else if (conf->channel->band == IEEE80211_BAND_2GHZ)
537 clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
538 else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
539 clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
540 else
541 clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
542
543 if (conf_is_ht40(conf))
544 return clockrate * 2;
545
546 return clockrate * 2;
547}
548
262static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) 549static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
263{ 550{
264 struct ar5416AniState *aniState; 551 struct ar5416AniState *aniState;
552 struct ath_common *common = ath9k_hw_common(ah);
265 u32 txFrameCount, rxFrameCount, cycleCount; 553 u32 txFrameCount, rxFrameCount, cycleCount;
266 int32_t listenTime; 554 int32_t listenTime;
267 555
@@ -271,15 +559,31 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
271 559
272 aniState = ah->curani; 560 aniState = ah->curani;
273 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { 561 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
274
275 listenTime = 0; 562 listenTime = 0;
276 ah->stats.ast_ani_lzero++; 563 ah->stats.ast_ani_lzero++;
564 ath_print(common, ATH_DBG_ANI,
565 "1st call: aniState->cycleCount=%d\n",
566 aniState->cycleCount);
277 } else { 567 } else {
278 int32_t ccdelta = cycleCount - aniState->cycleCount; 568 int32_t ccdelta = cycleCount - aniState->cycleCount;
279 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; 569 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
280 int32_t tfdelta = txFrameCount - aniState->txFrameCount; 570 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
281 listenTime = (ccdelta - rfdelta - tfdelta) / 44000; 571 int32_t clock_rate;
572
573 /*
574 * convert HW counter values to ms using mode
575 * specifix clock rate
576 */
577 clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
578
579 listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate;
580
581 ath_print(common, ATH_DBG_ANI,
582 "cyclecount=%d, rfcount=%d, "
583 "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
584 ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
282 } 585 }
586
283 aniState->cycleCount = cycleCount; 587 aniState->cycleCount = cycleCount;
284 aniState->txFrameCount = txFrameCount; 588 aniState->txFrameCount = txFrameCount;
285 aniState->rxFrameCount = rxFrameCount; 589 aniState->rxFrameCount = rxFrameCount;
@@ -287,7 +591,7 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
287 return listenTime; 591 return listenTime;
288} 592}
289 593
290void ath9k_ani_reset(struct ath_hw *ah) 594static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
291{ 595{
292 struct ar5416AniState *aniState; 596 struct ar5416AniState *aniState;
293 struct ath9k_channel *chan = ah->curchan; 597 struct ath9k_channel *chan = ah->curchan;
@@ -340,7 +644,7 @@ void ath9k_ani_reset(struct ath_hw *ah)
340 ah->curani->cckTrigLow = 644 ah->curani->cckTrigLow =
341 ah->config.cck_trig_low; 645 ah->config.cck_trig_low;
342 } 646 }
343 ath9k_ani_restart(ah); 647 ath9k_ani_restart_old(ah);
344 return; 648 return;
345 } 649 }
346 650
@@ -362,7 +666,7 @@ void ath9k_ani_reset(struct ath_hw *ah)
362 666
363 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & 667 ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
364 ~ATH9K_RX_FILTER_PHYERR); 668 ~ATH9K_RX_FILTER_PHYERR);
365 ath9k_ani_restart(ah); 669 ath9k_ani_restart_old(ah);
366 670
367 ENABLE_REGWRITE_BUFFER(ah); 671 ENABLE_REGWRITE_BUFFER(ah);
368 672
@@ -373,8 +677,102 @@ void ath9k_ani_reset(struct ath_hw *ah)
373 DISABLE_REGWRITE_BUFFER(ah); 677 DISABLE_REGWRITE_BUFFER(ah);
374} 678}
375 679
376void ath9k_hw_ani_monitor(struct ath_hw *ah, 680/*
377 struct ath9k_channel *chan) 681 * Restore the ANI parameters in the HAL and reset the statistics.
682 * This routine should be called for every hardware reset and for
683 * every channel change.
684 */
685static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
686{
687 struct ar5416AniState *aniState = ah->curani;
688 struct ath9k_channel *chan = ah->curchan;
689 struct ath_common *common = ath9k_hw_common(ah);
690
691 if (!DO_ANI(ah))
692 return;
693
694 BUG_ON(aniState == NULL);
695 ah->stats.ast_ani_reset++;
696
697 /* only allow a subset of functions in AP mode */
698 if (ah->opmode == NL80211_IFTYPE_AP) {
699 if (IS_CHAN_2GHZ(chan)) {
700 ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
701 ATH9K_ANI_FIRSTEP_LEVEL);
702 if (AR_SREV_9300_20_OR_LATER(ah))
703 ah->ani_function |= ATH9K_ANI_MRC_CCK;
704 } else
705 ah->ani_function = 0;
706 }
707
708 /* always allow mode (on/off) to be controlled */
709 ah->ani_function |= ATH9K_ANI_MODE;
710
711 if (is_scanning ||
712 (ah->opmode != NL80211_IFTYPE_STATION &&
713 ah->opmode != NL80211_IFTYPE_ADHOC)) {
714 /*
715 * If we're scanning or in AP mode, the defaults (ini)
716 * should be in place. For an AP we assume the historical
717 * levels for this channel are probably outdated so start
718 * from defaults instead.
719 */
720 if (aniState->ofdmNoiseImmunityLevel !=
721 ATH9K_ANI_OFDM_DEF_LEVEL ||
722 aniState->cckNoiseImmunityLevel !=
723 ATH9K_ANI_CCK_DEF_LEVEL) {
724 ath_print(common, ATH_DBG_ANI,
725 "Restore defaults: opmode %u "
726 "chan %d Mhz/0x%x is_scanning=%d "
727 "ofdm:%d cck:%d\n",
728 ah->opmode,
729 chan->channel,
730 chan->channelFlags,
731 is_scanning,
732 aniState->ofdmNoiseImmunityLevel,
733 aniState->cckNoiseImmunityLevel);
734
735 ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
736 ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
737 }
738 } else {
739 /*
740 * restore historical levels for this channel
741 */
742 ath_print(common, ATH_DBG_ANI,
743 "Restore history: opmode %u "
744 "chan %d Mhz/0x%x is_scanning=%d "
745 "ofdm:%d cck:%d\n",
746 ah->opmode,
747 chan->channel,
748 chan->channelFlags,
749 is_scanning,
750 aniState->ofdmNoiseImmunityLevel,
751 aniState->cckNoiseImmunityLevel);
752
753 ath9k_hw_set_ofdm_nil(ah,
754 aniState->ofdmNoiseImmunityLevel);
755 ath9k_hw_set_cck_nil(ah,
756 aniState->cckNoiseImmunityLevel);
757 }
758
759 /*
760 * enable phy counters if hw supports or if not, enable phy
761 * interrupts (so we can count each one)
762 */
763 ath9k_ani_restart_new(ah);
764
765 ENABLE_REGWRITE_BUFFER(ah);
766
767 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
768 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
769
770 REGWRITE_BUFFER_FLUSH(ah);
771 DISABLE_REGWRITE_BUFFER(ah);
772}
773
774static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
775 struct ath9k_channel *chan)
378{ 776{
379 struct ar5416AniState *aniState; 777 struct ar5416AniState *aniState;
380 struct ath_common *common = ath9k_hw_common(ah); 778 struct ath_common *common = ath9k_hw_common(ah);
@@ -390,7 +788,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
390 listenTime = ath9k_hw_ani_get_listen_time(ah); 788 listenTime = ath9k_hw_ani_get_listen_time(ah);
391 if (listenTime < 0) { 789 if (listenTime < 0) {
392 ah->stats.ast_ani_lneg++; 790 ah->stats.ast_ani_lneg++;
393 ath9k_ani_restart(ah); 791 ath9k_ani_restart_old(ah);
394 return; 792 return;
395 } 793 }
396 794
@@ -444,21 +842,166 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
444 aniState->cckPhyErrCount <= aniState->listenTime * 842 aniState->cckPhyErrCount <= aniState->listenTime *
445 aniState->cckTrigLow / 1000) 843 aniState->cckTrigLow / 1000)
446 ath9k_hw_ani_lower_immunity(ah); 844 ath9k_hw_ani_lower_immunity(ah);
447 ath9k_ani_restart(ah); 845 ath9k_ani_restart_old(ah);
448 } else if (aniState->listenTime > ah->aniperiod) { 846 } else if (aniState->listenTime > ah->aniperiod) {
449 if (aniState->ofdmPhyErrCount > aniState->listenTime * 847 if (aniState->ofdmPhyErrCount > aniState->listenTime *
450 aniState->ofdmTrigHigh / 1000) { 848 aniState->ofdmTrigHigh / 1000) {
451 ath9k_hw_ani_ofdm_err_trigger(ah); 849 ath9k_hw_ani_ofdm_err_trigger_old(ah);
452 ath9k_ani_restart(ah); 850 ath9k_ani_restart_old(ah);
453 } else if (aniState->cckPhyErrCount > 851 } else if (aniState->cckPhyErrCount >
454 aniState->listenTime * aniState->cckTrigHigh / 852 aniState->listenTime * aniState->cckTrigHigh /
455 1000) { 853 1000) {
456 ath9k_hw_ani_cck_err_trigger(ah); 854 ath9k_hw_ani_cck_err_trigger_old(ah);
457 ath9k_ani_restart(ah); 855 ath9k_ani_restart_old(ah);
856 }
857 }
858}
859
860static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
861 struct ath9k_channel *chan)
862{
863 struct ar5416AniState *aniState;
864 struct ath_common *common = ath9k_hw_common(ah);
865 int32_t listenTime;
866 u32 phyCnt1, phyCnt2;
867 u32 ofdmPhyErrCnt, cckPhyErrCnt;
868 u32 ofdmPhyErrRate, cckPhyErrRate;
869
870 if (!DO_ANI(ah))
871 return;
872
873 aniState = ah->curani;
874 if (WARN_ON(!aniState))
875 return;
876
877 listenTime = ath9k_hw_ani_get_listen_time(ah);
878 if (listenTime <= 0) {
879 ah->stats.ast_ani_lneg++;
880 /* restart ANI period if listenTime is invalid */
881 ath_print(common, ATH_DBG_ANI,
882 "listenTime=%d - on new ani monitor\n",
883 listenTime);
884 ath9k_ani_restart_new(ah);
885 return;
886 }
887
888 aniState->listenTime += listenTime;
889
890 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
891
892 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
893 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
894
895 if (phyCnt1 < aniState->ofdmPhyErrBase ||
896 phyCnt2 < aniState->cckPhyErrBase) {
897 if (phyCnt1 < aniState->ofdmPhyErrBase) {
898 ath_print(common, ATH_DBG_ANI,
899 "phyCnt1 0x%x, resetting "
900 "counter value to 0x%x\n",
901 phyCnt1,
902 aniState->ofdmPhyErrBase);
903 REG_WRITE(ah, AR_PHY_ERR_1,
904 aniState->ofdmPhyErrBase);
905 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
906 AR_PHY_ERR_OFDM_TIMING);
907 }
908 if (phyCnt2 < aniState->cckPhyErrBase) {
909 ath_print(common, ATH_DBG_ANI,
910 "phyCnt2 0x%x, resetting "
911 "counter value to 0x%x\n",
912 phyCnt2,
913 aniState->cckPhyErrBase);
914 REG_WRITE(ah, AR_PHY_ERR_2,
915 aniState->cckPhyErrBase);
916 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
917 AR_PHY_ERR_CCK_TIMING);
918 }
919 return;
920 }
921
922 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
923 ah->stats.ast_ani_ofdmerrs +=
924 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
925 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
926
927 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
928 ah->stats.ast_ani_cckerrs +=
929 cckPhyErrCnt - aniState->cckPhyErrCount;
930 aniState->cckPhyErrCount = cckPhyErrCnt;
931
932 ath_print(common, ATH_DBG_ANI,
933 "Errors: OFDM=0x%08x-0x%08x=%d "
934 "CCK=0x%08x-0x%08x=%d\n",
935 phyCnt1,
936 aniState->ofdmPhyErrBase,
937 ofdmPhyErrCnt,
938 phyCnt2,
939 aniState->cckPhyErrBase,
940 cckPhyErrCnt);
941
942 ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
943 aniState->listenTime;
944 cckPhyErrRate = aniState->cckPhyErrCount * 1000 /
945 aniState->listenTime;
946
947 ath_print(common, ATH_DBG_ANI,
948 "listenTime=%d OFDM:%d errs=%d/s CCK:%d "
949 "errs=%d/s ofdm_turn=%d\n",
950 listenTime, aniState->ofdmNoiseImmunityLevel,
951 ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
952 cckPhyErrRate, aniState->ofdmsTurn);
953
954 if (aniState->listenTime > 5 * ah->aniperiod) {
955 if (ofdmPhyErrRate <= aniState->ofdmTrigLow &&
956 cckPhyErrRate <= aniState->cckTrigLow) {
957 ath_print(common, ATH_DBG_ANI,
958 "1. listenTime=%d OFDM:%d errs=%d/s(<%d) "
959 "CCK:%d errs=%d/s(<%d) -> "
960 "ath9k_hw_ani_lower_immunity()\n",
961 aniState->listenTime,
962 aniState->ofdmNoiseImmunityLevel,
963 ofdmPhyErrRate,
964 aniState->ofdmTrigLow,
965 aniState->cckNoiseImmunityLevel,
966 cckPhyErrRate,
967 aniState->cckTrigLow);
968 ath9k_hw_ani_lower_immunity(ah);
969 aniState->ofdmsTurn = !aniState->ofdmsTurn;
970 }
971 ath_print(common, ATH_DBG_ANI,
972 "1 listenTime=%d ofdm=%d/s cck=%d/s - "
973 "calling ath9k_ani_restart_new()\n",
974 aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate);
975 ath9k_ani_restart_new(ah);
976 } else if (aniState->listenTime > ah->aniperiod) {
977 /* check to see if need to raise immunity */
978 if (ofdmPhyErrRate > aniState->ofdmTrigHigh &&
979 (cckPhyErrRate <= aniState->cckTrigHigh ||
980 aniState->ofdmsTurn)) {
981 ath_print(common, ATH_DBG_ANI,
982 "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> "
983 "ath9k_hw_ani_ofdm_err_trigger_new()\n",
984 aniState->listenTime,
985 aniState->ofdmNoiseImmunityLevel,
986 ofdmPhyErrRate,
987 aniState->ofdmTrigHigh);
988 ath9k_hw_ani_ofdm_err_trigger_new(ah);
989 ath9k_ani_restart_new(ah);
990 aniState->ofdmsTurn = false;
991 } else if (cckPhyErrRate > aniState->cckTrigHigh) {
992 ath_print(common, ATH_DBG_ANI,
993 "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> "
994 "ath9k_hw_ani_cck_err_trigger_new()\n",
995 aniState->listenTime,
996 aniState->cckNoiseImmunityLevel,
997 cckPhyErrRate,
998 aniState->cckTrigHigh);
999 ath9k_hw_ani_cck_err_trigger_new(ah);
1000 ath9k_ani_restart_new(ah);
1001 aniState->ofdmsTurn = true;
458 } 1002 }
459 } 1003 }
460} 1004}
461EXPORT_SYMBOL(ath9k_hw_ani_monitor);
462 1005
463void ath9k_enable_mib_counters(struct ath_hw *ah) 1006void ath9k_enable_mib_counters(struct ath_hw *ah)
464{ 1007{
@@ -495,6 +1038,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
495 REG_WRITE(ah, AR_FILT_OFDM, 0); 1038 REG_WRITE(ah, AR_FILT_OFDM, 0);
496 REG_WRITE(ah, AR_FILT_CCK, 0); 1039 REG_WRITE(ah, AR_FILT_CCK, 0);
497} 1040}
1041EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
498 1042
499u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, 1043u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
500 u32 *rxc_pcnt, 1044 u32 *rxc_pcnt,
@@ -542,7 +1086,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
542 * any of the MIB counters overflow/trigger so don't assume we're 1086 * any of the MIB counters overflow/trigger so don't assume we're
543 * here because a PHY error counter triggered. 1087 * here because a PHY error counter triggered.
544 */ 1088 */
545void ath9k_hw_procmibevent(struct ath_hw *ah) 1089static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
546{ 1090{
547 u32 phyCnt1, phyCnt2; 1091 u32 phyCnt1, phyCnt2;
548 1092
@@ -555,8 +1099,15 @@ void ath9k_hw_procmibevent(struct ath_hw *ah)
555 /* Clear the mib counters and save them in the stats */ 1099 /* Clear the mib counters and save them in the stats */
556 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 1100 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
557 1101
558 if (!DO_ANI(ah)) 1102 if (!DO_ANI(ah)) {
1103 /*
1104 * We must always clear the interrupt cause by
1105 * resetting the phy error regs.
1106 */
1107 REG_WRITE(ah, AR_PHY_ERR_1, 0);
1108 REG_WRITE(ah, AR_PHY_ERR_2, 0);
559 return; 1109 return;
1110 }
560 1111
561 /* NB: these are not reset-on-read */ 1112 /* NB: these are not reset-on-read */
562 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); 1113 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
@@ -584,14 +1135,51 @@ void ath9k_hw_procmibevent(struct ath_hw *ah)
584 * check will never be true. 1135 * check will never be true.
585 */ 1136 */
586 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) 1137 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
587 ath9k_hw_ani_ofdm_err_trigger(ah); 1138 ath9k_hw_ani_ofdm_err_trigger_new(ah);
588 if (aniState->cckPhyErrCount > aniState->cckTrigHigh) 1139 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
589 ath9k_hw_ani_cck_err_trigger(ah); 1140 ath9k_hw_ani_cck_err_trigger_old(ah);
590 /* NB: always restart to insure the h/w counters are reset */ 1141 /* NB: always restart to insure the h/w counters are reset */
591 ath9k_ani_restart(ah); 1142 ath9k_ani_restart_old(ah);
592 } 1143 }
593} 1144}
594EXPORT_SYMBOL(ath9k_hw_procmibevent); 1145
1146/*
1147 * Process a MIB interrupt. We may potentially be invoked because
1148 * any of the MIB counters overflow/trigger so don't assume we're
1149 * here because a PHY error counter triggered.
1150 */
1151static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah)
1152{
1153 u32 phyCnt1, phyCnt2;
1154
1155 /* Reset these counters regardless */
1156 REG_WRITE(ah, AR_FILT_OFDM, 0);
1157 REG_WRITE(ah, AR_FILT_CCK, 0);
1158 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
1159 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
1160
1161 /* Clear the mib counters and save them in the stats */
1162 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
1163
1164 if (!DO_ANI(ah)) {
1165 /*
1166 * We must always clear the interrupt cause by
1167 * resetting the phy error regs.
1168 */
1169 REG_WRITE(ah, AR_PHY_ERR_1, 0);
1170 REG_WRITE(ah, AR_PHY_ERR_2, 0);
1171 return;
1172 }
1173
1174 /* NB: these are not reset-on-read */
1175 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
1176 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
1177
1178 /* NB: always restart to insure the h/w counters are reset */
1179 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
1180 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK))
1181 ath9k_ani_restart_new(ah);
1182}
595 1183
596void ath9k_hw_ani_setup(struct ath_hw *ah) 1184void ath9k_hw_ani_setup(struct ath_hw *ah)
597{ 1185{
@@ -619,22 +1207,70 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
619 1207
620 memset(ah->ani, 0, sizeof(ah->ani)); 1208 memset(ah->ani, 0, sizeof(ah->ani));
621 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { 1209 for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
622 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; 1210 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
623 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; 1211 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
624 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; 1212 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
625 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; 1213
1214 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
1215 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW;
1216
1217 ah->ani[i].spurImmunityLevel =
1218 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1219
1220 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1221
1222 ah->ani[i].ofdmPhyErrBase = 0;
1223 ah->ani[i].cckPhyErrBase = 0;
1224
1225 if (AR_SREV_9300_20_OR_LATER(ah))
1226 ah->ani[i].mrcCCKOff =
1227 !ATH9K_ANI_ENABLE_MRC_CCK;
1228 else
1229 ah->ani[i].mrcCCKOff = true;
1230
1231 ah->ani[i].ofdmsTurn = true;
1232 } else {
1233 ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
1234 ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
1235
1236 ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1237 ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD;
1238
1239 ah->ani[i].spurImmunityLevel =
1240 ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
1241 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
1242
1243 ah->ani[i].ofdmPhyErrBase =
1244 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
1245 ah->ani[i].cckPhyErrBase =
1246 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD;
1247 ah->ani[i].cckWeakSigThreshold =
1248 ATH9K_ANI_CCK_WEAK_SIG_THR;
1249 }
1250
626 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; 1251 ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
627 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; 1252 ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
628 ah->ani[i].ofdmWeakSigDetectOff = 1253 ah->ani[i].ofdmWeakSigDetectOff =
629 !ATH9K_ANI_USE_OFDM_WEAK_SIG; 1254 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
630 ah->ani[i].cckWeakSigThreshold = 1255 ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
631 ATH9K_ANI_CCK_WEAK_SIG_THR; 1256 }
632 ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 1257
633 ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 1258 /*
634 ah->ani[i].ofdmPhyErrBase = 1259 * since we expect some ongoing maintenance on the tables, let's sanity
635 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; 1260 * check here default level should not modify INI setting.
636 ah->ani[i].cckPhyErrBase = 1261 */
637 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; 1262 if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) {
1263 const struct ani_ofdm_level_entry *entry_ofdm;
1264 const struct ani_cck_level_entry *entry_cck;
1265
1266 entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
1267 entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
1268
1269 ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
1270 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
1271 } else {
1272 ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
1273 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
638 } 1274 }
639 1275
640 ath_print(common, ATH_DBG_ANI, 1276 ath_print(common, ATH_DBG_ANI,
@@ -653,7 +1289,34 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
653 1289
654 ath9k_enable_mib_counters(ah); 1290 ath9k_enable_mib_counters(ah);
655 1291
656 ah->aniperiod = ATH9K_ANI_PERIOD;
657 if (ah->config.enable_ani) 1292 if (ah->config.enable_ani)
658 ah->proc_phyerr |= HAL_PROCESS_ANI; 1293 ah->proc_phyerr |= HAL_PROCESS_ANI;
659} 1294}
1295
1296void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah)
1297{
1298 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1299 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1300
1301 priv_ops->ani_reset = ath9k_ani_reset_old;
1302 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old;
1303
1304 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old;
1305 ops->ani_monitor = ath9k_hw_ani_monitor_old;
1306
1307 ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n");
1308}
1309
1310void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah)
1311{
1312 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1313 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1314
1315 priv_ops->ani_reset = ath9k_ani_reset_new;
1316 priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new;
1317
1318 ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new;
1319 ops->ani_monitor = ath9k_hw_ani_monitor_new;
1320
1321 ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n");
1322}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 3356762ea384..f4d0a4d48b37 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -23,23 +23,55 @@
23 23
24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) 24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
25 25
26#define ATH9K_ANI_OFDM_TRIG_HIGH 500 26/* units are errors per second */
27#define ATH9K_ANI_OFDM_TRIG_LOW 200 27#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
28#define ATH9K_ANI_CCK_TRIG_HIGH 200 28#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 1000
29#define ATH9K_ANI_CCK_TRIG_LOW 100 29
30/* units are errors per second */
31#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
32#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400
33
34/* units are errors per second */
35#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
36#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600
37
38/* units are errors per second */
39#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
40#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300
41
30#define ATH9K_ANI_NOISE_IMMUNE_LVL 4 42#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
31#define ATH9K_ANI_USE_OFDM_WEAK_SIG true 43#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
32#define ATH9K_ANI_CCK_WEAK_SIG_THR false 44#define ATH9K_ANI_CCK_WEAK_SIG_THR false
33#define ATH9K_ANI_SPUR_IMMUNE_LVL 7 45
34#define ATH9K_ANI_FIRSTEP_LVL 0 46#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD 7
47#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3
48
49#define ATH9K_ANI_FIRSTEP_LVL_OLD 0
50#define ATH9K_ANI_FIRSTEP_LVL_NEW 2
51
35#define ATH9K_ANI_RSSI_THR_HIGH 40 52#define ATH9K_ANI_RSSI_THR_HIGH 40
36#define ATH9K_ANI_RSSI_THR_LOW 7 53#define ATH9K_ANI_RSSI_THR_LOW 7
37#define ATH9K_ANI_PERIOD 100 54
55#define ATH9K_ANI_PERIOD_OLD 100
56#define ATH9K_ANI_PERIOD_NEW 1000
57
58/* in ms */
59#define ATH9K_ANI_POLLINTERVAL_OLD 100
60#define ATH9K_ANI_POLLINTERVAL_NEW 1000
38 61
39#define HAL_NOISE_IMMUNE_MAX 4 62#define HAL_NOISE_IMMUNE_MAX 4
40#define HAL_SPUR_IMMUNE_MAX 7 63#define HAL_SPUR_IMMUNE_MAX 7
41#define HAL_FIRST_STEP_MAX 2 64#define HAL_FIRST_STEP_MAX 2
42 65
66#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
67#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20
68#define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0
69#define ATH9K_SIG_SPUR_IMM_SETTING_MAX 22
70
71#define ATH9K_ANI_ENABLE_MRC_CCK true
72
73/* values here are relative to the INI */
74
43enum ath9k_ani_cmd { 75enum ath9k_ani_cmd {
44 ATH9K_ANI_PRESENT = 0x1, 76 ATH9K_ANI_PRESENT = 0x1,
45 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2, 77 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
@@ -49,7 +81,8 @@ enum ath9k_ani_cmd {
49 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20, 81 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
50 ATH9K_ANI_MODE = 0x40, 82 ATH9K_ANI_MODE = 0x40,
51 ATH9K_ANI_PHYERR_RESET = 0x80, 83 ATH9K_ANI_PHYERR_RESET = 0x80,
52 ATH9K_ANI_ALL = 0xff 84 ATH9K_ANI_MRC_CCK = 0x100,
85 ATH9K_ANI_ALL = 0xfff
53}; 86};
54 87
55struct ath9k_mib_stats { 88struct ath9k_mib_stats {
@@ -60,9 +93,31 @@ struct ath9k_mib_stats {
60 u32 beacons; 93 u32 beacons;
61}; 94};
62 95
96/* INI default values for ANI registers */
97struct ath9k_ani_default {
98 u16 m1ThreshLow;
99 u16 m2ThreshLow;
100 u16 m1Thresh;
101 u16 m2Thresh;
102 u16 m2CountThr;
103 u16 m2CountThrLow;
104 u16 m1ThreshLowExt;
105 u16 m2ThreshLowExt;
106 u16 m1ThreshExt;
107 u16 m2ThreshExt;
108 u16 firstep;
109 u16 firstepLow;
110 u16 cycpwrThr1;
111 u16 cycpwrThr1Ext;
112};
113
63struct ar5416AniState { 114struct ar5416AniState {
64 struct ath9k_channel *c; 115 struct ath9k_channel *c;
65 u8 noiseImmunityLevel; 116 u8 noiseImmunityLevel;
117 u8 ofdmNoiseImmunityLevel;
118 u8 cckNoiseImmunityLevel;
119 bool ofdmsTurn;
120 u8 mrcCCKOff;
66 u8 spurImmunityLevel; 121 u8 spurImmunityLevel;
67 u8 firstepLevel; 122 u8 firstepLevel;
68 u8 ofdmWeakSigDetectOff; 123 u8 ofdmWeakSigDetectOff;
@@ -85,6 +140,7 @@ struct ar5416AniState {
85 int16_t pktRssi[2]; 140 int16_t pktRssi[2];
86 int16_t ofdmErrRssi[2]; 141 int16_t ofdmErrRssi[2];
87 int16_t cckErrRssi[2]; 142 int16_t cckErrRssi[2];
143 struct ath9k_ani_default iniDef;
88}; 144};
89 145
90struct ar5416Stats { 146struct ar5416Stats {
@@ -108,15 +164,13 @@ struct ar5416Stats {
108}; 164};
109#define ah_mibStats stats.ast_mibstats 165#define ah_mibStats stats.ast_mibstats
110 166
111void ath9k_ani_reset(struct ath_hw *ah);
112void ath9k_hw_ani_monitor(struct ath_hw *ah,
113 struct ath9k_channel *chan);
114void ath9k_enable_mib_counters(struct ath_hw *ah); 167void ath9k_enable_mib_counters(struct ath_hw *ah);
115void ath9k_hw_disable_mib_counters(struct ath_hw *ah); 168void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
116u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, 169u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
117 u32 *rxf_pcnt, u32 *txf_pcnt); 170 u32 *rxf_pcnt, u32 *txf_pcnt);
118void ath9k_hw_procmibevent(struct ath_hw *ah);
119void ath9k_hw_ani_setup(struct ath_hw *ah); 171void ath9k_hw_ani_setup(struct ath_hw *ah);
120void ath9k_hw_ani_init(struct ath_hw *ah); 172void ath9k_hw_ani_init(struct ath_hw *ah);
173int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
174 struct ath9k_channel *chan);
121 175
122#endif /* ANI_H */ 176#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index b2c17c98bb38..ee34a495b0be 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -19,7 +19,30 @@
19#include "../regd.h" 19#include "../regd.h"
20#include "ar9002_phy.h" 20#include "ar9002_phy.h"
21 21
22/* All code below is for non single-chip solutions */ 22/* All code below is for AR5008, AR9001, AR9002 */
23
24static const int firstep_table[] =
25/* level: 0 1 2 3 4 5 6 7 8 */
26 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
27
28static const int cycpwrThr1_table[] =
29/* level: 0 1 2 3 4 5 6 7 8 */
30 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
31
32/*
33 * register values to turn OFDM weak signal detection OFF
34 */
35static const int m1ThreshLow_off = 127;
36static const int m2ThreshLow_off = 127;
37static const int m1Thresh_off = 127;
38static const int m2Thresh_off = 127;
39static const int m2CountThr_off = 31;
40static const int m2CountThrLow_off = 63;
41static const int m1ThreshLowExt_off = 127;
42static const int m2ThreshLowExt_off = 127;
43static const int m1ThreshExt_off = 127;
44static const int m2ThreshExt_off = 127;
45
23 46
24/** 47/**
25 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters 48 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
@@ -742,17 +765,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
742 return -EINVAL; 765 return -EINVAL;
743 } 766 }
744 767
745 if (AR_SREV_9287_12_OR_LATER(ah)) {
746 /* Enable ASYNC FIFO */
747 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
748 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
749 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
750 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
751 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
752 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
753 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
754 }
755
756 /* 768 /*
757 * Set correct baseband to analog shift setting to 769 * Set correct baseband to analog shift setting to
758 * access analog chips. 770 * access analog chips.
@@ -1037,8 +1049,9 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
1037 return pll; 1049 return pll;
1038} 1050}
1039 1051
1040static bool ar5008_hw_ani_control(struct ath_hw *ah, 1052static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
1041 enum ath9k_ani_cmd cmd, int param) 1053 enum ath9k_ani_cmd cmd,
1054 int param)
1042{ 1055{
1043 struct ar5416AniState *aniState = ah->curani; 1056 struct ar5416AniState *aniState = ah->curani;
1044 struct ath_common *common = ath9k_hw_common(ah); 1057 struct ath_common *common = ath9k_hw_common(ah);
@@ -1220,6 +1233,265 @@ static bool ar5008_hw_ani_control(struct ath_hw *ah,
1220 return true; 1233 return true;
1221} 1234}
1222 1235
1236static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
1237 enum ath9k_ani_cmd cmd,
1238 int param)
1239{
1240 struct ar5416AniState *aniState = ah->curani;
1241 struct ath_common *common = ath9k_hw_common(ah);
1242 struct ath9k_channel *chan = ah->curchan;
1243 s32 value, value2;
1244
1245 switch (cmd & ah->ani_function) {
1246 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
1247 /*
1248 * on == 1 means ofdm weak signal detection is ON
1249 * on == 1 is the default, for less noise immunity
1250 *
1251 * on == 0 means ofdm weak signal detection is OFF
1252 * on == 0 means more noise imm
1253 */
1254 u32 on = param ? 1 : 0;
1255 /*
1256 * make register setting for default
1257 * (weak sig detect ON) come from INI file
1258 */
1259 int m1ThreshLow = on ?
1260 aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
1261 int m2ThreshLow = on ?
1262 aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
1263 int m1Thresh = on ?
1264 aniState->iniDef.m1Thresh : m1Thresh_off;
1265 int m2Thresh = on ?
1266 aniState->iniDef.m2Thresh : m2Thresh_off;
1267 int m2CountThr = on ?
1268 aniState->iniDef.m2CountThr : m2CountThr_off;
1269 int m2CountThrLow = on ?
1270 aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
1271 int m1ThreshLowExt = on ?
1272 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
1273 int m2ThreshLowExt = on ?
1274 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
1275 int m1ThreshExt = on ?
1276 aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
1277 int m2ThreshExt = on ?
1278 aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
1279
1280 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1281 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
1282 m1ThreshLow);
1283 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1284 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
1285 m2ThreshLow);
1286 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1287 AR_PHY_SFCORR_M1_THRESH, m1Thresh);
1288 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1289 AR_PHY_SFCORR_M2_THRESH, m2Thresh);
1290 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
1291 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
1292 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
1293 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
1294 m2CountThrLow);
1295
1296 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1297 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
1298 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1299 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
1300 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1301 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
1302 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
1303 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
1304
1305 if (on)
1306 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
1307 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1308 else
1309 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
1310 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
1311
1312 if (!on != aniState->ofdmWeakSigDetectOff) {
1313 ath_print(common, ATH_DBG_ANI,
1314 "** ch %d: ofdm weak signal: %s=>%s\n",
1315 chan->channel,
1316 !aniState->ofdmWeakSigDetectOff ?
1317 "on" : "off",
1318 on ? "on" : "off");
1319 if (on)
1320 ah->stats.ast_ani_ofdmon++;
1321 else
1322 ah->stats.ast_ani_ofdmoff++;
1323 aniState->ofdmWeakSigDetectOff = !on;
1324 }
1325 break;
1326 }
1327 case ATH9K_ANI_FIRSTEP_LEVEL:{
1328 u32 level = param;
1329
1330 if (level >= ARRAY_SIZE(firstep_table)) {
1331 ath_print(common, ATH_DBG_ANI,
1332 "ATH9K_ANI_FIRSTEP_LEVEL: level "
1333 "out of range (%u > %u)\n",
1334 level,
1335 (unsigned) ARRAY_SIZE(firstep_table));
1336 return false;
1337 }
1338
1339 /*
1340 * make register setting relative to default
1341 * from INI file & cap value
1342 */
1343 value = firstep_table[level] -
1344 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
1345 aniState->iniDef.firstep;
1346 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
1347 value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
1348 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
1349 value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
1350 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
1351 AR_PHY_FIND_SIG_FIRSTEP,
1352 value);
1353 /*
1354 * we need to set first step low register too
1355 * make register setting relative to default
1356 * from INI file & cap value
1357 */
1358 value2 = firstep_table[level] -
1359 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
1360 aniState->iniDef.firstepLow;
1361 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
1362 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
1363 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
1364 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
1365
1366 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
1367 AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
1368
1369 if (level != aniState->firstepLevel) {
1370 ath_print(common, ATH_DBG_ANI,
1371 "** ch %d: level %d=>%d[def:%d] "
1372 "firstep[level]=%d ini=%d\n",
1373 chan->channel,
1374 aniState->firstepLevel,
1375 level,
1376 ATH9K_ANI_FIRSTEP_LVL_NEW,
1377 value,
1378 aniState->iniDef.firstep);
1379 ath_print(common, ATH_DBG_ANI,
1380 "** ch %d: level %d=>%d[def:%d] "
1381 "firstep_low[level]=%d ini=%d\n",
1382 chan->channel,
1383 aniState->firstepLevel,
1384 level,
1385 ATH9K_ANI_FIRSTEP_LVL_NEW,
1386 value2,
1387 aniState->iniDef.firstepLow);
1388 if (level > aniState->firstepLevel)
1389 ah->stats.ast_ani_stepup++;
1390 else if (level < aniState->firstepLevel)
1391 ah->stats.ast_ani_stepdown++;
1392 aniState->firstepLevel = level;
1393 }
1394 break;
1395 }
1396 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
1397 u32 level = param;
1398
1399 if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
1400 ath_print(common, ATH_DBG_ANI,
1401 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
1402 "out of range (%u > %u)\n",
1403 level,
1404 (unsigned) ARRAY_SIZE(cycpwrThr1_table));
1405 return false;
1406 }
1407 /*
1408 * make register setting relative to default
1409 * from INI file & cap value
1410 */
1411 value = cycpwrThr1_table[level] -
1412 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
1413 aniState->iniDef.cycpwrThr1;
1414 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
1415 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
1416 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
1417 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
1418 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
1419 AR_PHY_TIMING5_CYCPWR_THR1,
1420 value);
1421
1422 /*
1423 * set AR_PHY_EXT_CCA for extension channel
1424 * make register setting relative to default
1425 * from INI file & cap value
1426 */
1427 value2 = cycpwrThr1_table[level] -
1428 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
1429 aniState->iniDef.cycpwrThr1Ext;
1430 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
1431 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
1432 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
1433 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
1434 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
1435 AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
1436
1437 if (level != aniState->spurImmunityLevel) {
1438 ath_print(common, ATH_DBG_ANI,
1439 "** ch %d: level %d=>%d[def:%d] "
1440 "cycpwrThr1[level]=%d ini=%d\n",
1441 chan->channel,
1442 aniState->spurImmunityLevel,
1443 level,
1444 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
1445 value,
1446 aniState->iniDef.cycpwrThr1);
1447 ath_print(common, ATH_DBG_ANI,
1448 "** ch %d: level %d=>%d[def:%d] "
1449 "cycpwrThr1Ext[level]=%d ini=%d\n",
1450 chan->channel,
1451 aniState->spurImmunityLevel,
1452 level,
1453 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
1454 value2,
1455 aniState->iniDef.cycpwrThr1Ext);
1456 if (level > aniState->spurImmunityLevel)
1457 ah->stats.ast_ani_spurup++;
1458 else if (level < aniState->spurImmunityLevel)
1459 ah->stats.ast_ani_spurdown++;
1460 aniState->spurImmunityLevel = level;
1461 }
1462 break;
1463 }
1464 case ATH9K_ANI_MRC_CCK:
1465 /*
1466 * You should not see this as AR5008, AR9001, AR9002
1467 * does not have hardware support for MRC CCK.
1468 */
1469 WARN_ON(1);
1470 break;
1471 case ATH9K_ANI_PRESENT:
1472 break;
1473 default:
1474 ath_print(common, ATH_DBG_ANI,
1475 "invalid cmd %u\n", cmd);
1476 return false;
1477 }
1478
1479 ath_print(common, ATH_DBG_ANI,
1480 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
1481 "MRCcck=%s listenTime=%d CC=%d listen=%d "
1482 "ofdmErrs=%d cckErrs=%d\n",
1483 aniState->spurImmunityLevel,
1484 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
1485 aniState->firstepLevel,
1486 !aniState->mrcCCKOff ? "on" : "off",
1487 aniState->listenTime,
1488 aniState->cycleCount,
1489 aniState->listenTime,
1490 aniState->ofdmPhyErrCount,
1491 aniState->cckPhyErrCount);
1492 return true;
1493}
1494
1223static void ar5008_hw_do_getnf(struct ath_hw *ah, 1495static void ar5008_hw_do_getnf(struct ath_hw *ah,
1224 int16_t nfarray[NUM_NF_READINGS]) 1496 int16_t nfarray[NUM_NF_READINGS])
1225{ 1497{
@@ -1340,6 +1612,71 @@ static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1340 DISABLE_REGWRITE_BUFFER(ah); 1612 DISABLE_REGWRITE_BUFFER(ah);
1341} 1613}
1342 1614
1615/*
1616 * Initialize the ANI register values with default (ini) values.
1617 * This routine is called during a (full) hardware reset after
1618 * all the registers are initialised from the INI.
1619 */
1620static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1621{
1622 struct ar5416AniState *aniState;
1623 struct ath_common *common = ath9k_hw_common(ah);
1624 struct ath9k_channel *chan = ah->curchan;
1625 struct ath9k_ani_default *iniDef;
1626 int index;
1627 u32 val;
1628
1629 index = ath9k_hw_get_ani_channel_idx(ah, chan);
1630 aniState = &ah->ani[index];
1631 ah->curani = aniState;
1632 iniDef = &aniState->iniDef;
1633
1634 ath_print(common, ATH_DBG_ANI,
1635 "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
1636 ah->hw_version.macVersion,
1637 ah->hw_version.macRev,
1638 ah->opmode,
1639 chan->channel,
1640 chan->channelFlags);
1641
1642 val = REG_READ(ah, AR_PHY_SFCORR);
1643 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
1644 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
1645 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
1646
1647 val = REG_READ(ah, AR_PHY_SFCORR_LOW);
1648 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
1649 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
1650 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
1651
1652 val = REG_READ(ah, AR_PHY_SFCORR_EXT);
1653 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
1654 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
1655 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
1656 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
1657 iniDef->firstep = REG_READ_FIELD(ah,
1658 AR_PHY_FIND_SIG,
1659 AR_PHY_FIND_SIG_FIRSTEP);
1660 iniDef->firstepLow = REG_READ_FIELD(ah,
1661 AR_PHY_FIND_SIG_LOW,
1662 AR_PHY_FIND_SIG_FIRSTEP_LOW);
1663 iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
1664 AR_PHY_TIMING5,
1665 AR_PHY_TIMING5_CYCPWR_THR1);
1666 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
1667 AR_PHY_EXT_CCA,
1668 AR_PHY_EXT_TIMING5_CYCPWR_THR1);
1669
1670 /* these levels just got reset to defaults by the INI */
1671 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1672 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1673 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1674 aniState->mrcCCKOff = true; /* not available on pre AR9003 */
1675
1676 aniState->cycleCount = 0;
1677}
1678
1679
1343void ar5008_hw_attach_phy_ops(struct ath_hw *ah) 1680void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1344{ 1681{
1345 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1682 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1361,10 +1698,15 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1361 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; 1698 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
1362 priv_ops->restore_chainmask = ar5008_restore_chainmask; 1699 priv_ops->restore_chainmask = ar5008_restore_chainmask;
1363 priv_ops->set_diversity = ar5008_set_diversity; 1700 priv_ops->set_diversity = ar5008_set_diversity;
1364 priv_ops->ani_control = ar5008_hw_ani_control;
1365 priv_ops->do_getnf = ar5008_hw_do_getnf; 1701 priv_ops->do_getnf = ar5008_hw_do_getnf;
1366 priv_ops->loadnf = ar5008_hw_loadnf; 1702 priv_ops->loadnf = ar5008_hw_loadnf;
1367 1703
1704 if (modparam_force_new_ani) {
1705 priv_ops->ani_control = ar5008_hw_ani_control_new;
1706 priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
1707 } else
1708 priv_ops->ani_control = ar5008_hw_ani_control_old;
1709
1368 if (AR_SREV_9100(ah)) 1710 if (AR_SREV_9100(ah))
1369 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; 1711 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
1370 else if (AR_SREV_9160_10_OR_LATER(ah)) 1712 else if (AR_SREV_9160_10_OR_LATER(ah))
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index a8a8cdc04afa..0317ac9fc1b7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -18,6 +18,11 @@
18#include "ar5008_initvals.h" 18#include "ar5008_initvals.h"
19#include "ar9001_initvals.h" 19#include "ar9001_initvals.h"
20#include "ar9002_initvals.h" 20#include "ar9002_initvals.h"
21#include "ar9002_phy.h"
22
23int modparam_force_new_ani;
24module_param_named(force_new_ani, modparam_force_new_ani, int, 0444);
25MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002");
21 26
22/* General hardware code for the A5008/AR9001/AR9002 hadware families */ 27/* General hardware code for the A5008/AR9001/AR9002 hadware families */
23 28
@@ -436,55 +441,84 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
436 } 441 }
437 442
438 udelay(1000); 443 udelay(1000);
444 }
439 445
440 /* set bit 19 to allow forcing of pcie core into L1 state */ 446 if (power_off) {
441 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 447 /* clear bit 19 to disable L1 */
448 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
449
450 val = REG_READ(ah, AR_WA);
451
452 /*
453 * Set PCIe workaround bits
454 * In AR9280 and AR9285, bit 14 in WA register (disable L1)
455 * should only be set when device enters D3 and be
456 * cleared when device comes back to D0.
457 */
458 if (ah->config.pcie_waen) {
459 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
460 val |= AR_WA_D3_L1_DISABLE;
461 } else {
462 if (((AR_SREV_9285(ah) ||
463 AR_SREV_9271(ah) ||
464 AR_SREV_9287(ah)) &&
465 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
466 (AR_SREV_9280(ah) &&
467 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
468 val |= AR_WA_D3_L1_DISABLE;
469 }
470 }
471
472 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
473 /*
474 * Disable bit 6 and 7 before entering D3 to
475 * prevent system hang.
476 */
477 val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
478 }
442 479
443 /* Several PCIe massages to ensure proper behaviour */ 480 if (AR_SREV_9285E_20(ah))
481 val |= AR_WA_BIT23;
482
483 REG_WRITE(ah, AR_WA, val);
484 } else {
444 if (ah->config.pcie_waen) { 485 if (ah->config.pcie_waen) {
445 val = ah->config.pcie_waen; 486 val = ah->config.pcie_waen;
446 if (!power_off) 487 if (!power_off)
447 val &= (~AR_WA_D3_L1_DISABLE); 488 val &= (~AR_WA_D3_L1_DISABLE);
448 } else { 489 } else {
449 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || 490 if (AR_SREV_9285(ah) ||
491 AR_SREV_9271(ah) ||
450 AR_SREV_9287(ah)) { 492 AR_SREV_9287(ah)) {
451 val = AR9285_WA_DEFAULT; 493 val = AR9285_WA_DEFAULT;
452 if (!power_off) 494 if (!power_off)
453 val &= (~AR_WA_D3_L1_DISABLE); 495 val &= (~AR_WA_D3_L1_DISABLE);
454 } else if (AR_SREV_9280(ah)) { 496 }
497 else if (AR_SREV_9280(ah)) {
455 /* 498 /*
456 * On AR9280 chips bit 22 of 0x4004 needs to be 499 * For AR9280 chips, bit 22 of 0x4004
457 * set otherwise card may disappear. 500 * needs to be set.
458 */ 501 */
459 val = AR9280_WA_DEFAULT; 502 val = AR9280_WA_DEFAULT;
460 if (!power_off) 503 if (!power_off)
461 val &= (~AR_WA_D3_L1_DISABLE); 504 val &= (~AR_WA_D3_L1_DISABLE);
462 } else 505 } else {
463 val = AR_WA_DEFAULT; 506 val = AR_WA_DEFAULT;
507 }
508 }
509
510 /* WAR for ASPM system hang */
511 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
512 val |= (AR_WA_BIT6 | AR_WA_BIT7);
464 } 513 }
465 514
515 if (AR_SREV_9285E_20(ah))
516 val |= AR_WA_BIT23;
517
466 REG_WRITE(ah, AR_WA, val); 518 REG_WRITE(ah, AR_WA, val);
467 }
468 519
469 if (power_off) { 520 /* set bit 19 to allow forcing of pcie core into L1 state */
470 /* 521 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
471 * Set PCIe workaround bits
472 * bit 14 in WA register (disable L1) should only
473 * be set when device enters D3 and be cleared
474 * when device comes back to D0.
475 */
476 if (ah->config.pcie_waen) {
477 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
478 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
479 } else {
480 if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
481 AR_SREV_9287(ah)) &&
482 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
483 (AR_SREV_9280(ah) &&
484 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
485 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
486 }
487 }
488 } 522 }
489} 523}
490 524
@@ -536,18 +570,29 @@ int ar9002_hw_rf_claim(struct ath_hw *ah)
536 return 0; 570 return 0;
537} 571}
538 572
573void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
574{
575 if (AR_SREV_9287_13_OR_LATER(ah)) {
576 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
577 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
578 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
579 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
580 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
581 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
582 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
583 }
584}
585
539/* 586/*
540 * Enable ASYNC FIFO
541 *
542 * If Async FIFO is enabled, the following counters change as MAC now runs 587 * If Async FIFO is enabled, the following counters change as MAC now runs
543 * at 117 Mhz instead of 88/44MHz when async FIFO is disabled. 588 * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
544 * 589 *
545 * The values below tested for ht40 2 chain. 590 * The values below tested for ht40 2 chain.
546 * Overwrite the delay/timeouts initialized in process ini. 591 * Overwrite the delay/timeouts initialized in process ini.
547 */ 592 */
548void ar9002_hw_enable_async_fifo(struct ath_hw *ah) 593void ar9002_hw_update_async_fifo(struct ath_hw *ah)
549{ 594{
550 if (AR_SREV_9287_12_OR_LATER(ah)) { 595 if (AR_SREV_9287_13_OR_LATER(ah)) {
551 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 596 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
552 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); 597 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
553 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, 598 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
@@ -571,9 +616,9 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
571 */ 616 */
572void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) 617void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
573{ 618{
574 if (AR_SREV_9287_12_OR_LATER(ah)) { 619 if (AR_SREV_9287_13_OR_LATER(ah)) {
575 REG_SET_BIT(ah, AR_PCU_MISC_MODE2, 620 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
576 AR_PCU_MISC_MODE2_ENABLE_AGGWEP); 621 AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
577 } 622 }
578} 623}
579 624
@@ -595,4 +640,9 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
595 640
596 ar9002_hw_attach_calib_ops(ah); 641 ar9002_hw_attach_calib_ops(ah);
597 ar9002_hw_attach_mac_ops(ah); 642 ar9002_hw_attach_mac_ops(ah);
643
644 if (modparam_force_new_ani)
645 ath9k_hw_attach_ani_ops_new(ah);
646 else
647 ath9k_hw_attach_ani_ops_old(ah);
598} 648}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index dae7f3304eb8..8ab24ee8564b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -4492,7 +4492,7 @@ static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
4492}; 4492};
4493 4493
4494 4494
4495/* AR9271 initialization values automaticaly created: 06/04/09 */ 4495/* AR9271 initialization values automaticaly created: 03/31/10 */
4496static const u32 ar9271Modes_9271[][6] = { 4496static const u32 ar9271Modes_9271[][6] = {
4497 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 4497 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
4498 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 4498 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -5011,7 +5011,7 @@ static const u32 ar9271Common_9271[][2] = {
5011 { 0x0000783c, 0x72ee0a72 }, 5011 { 0x0000783c, 0x72ee0a72 },
5012 { 0x00007840, 0xbbfffffc }, 5012 { 0x00007840, 0xbbfffffc },
5013 { 0x00007844, 0x000c0db6 }, 5013 { 0x00007844, 0x000c0db6 },
5014 { 0x00007848, 0x6db61b6f }, 5014 { 0x00007848, 0x6db6246f },
5015 { 0x0000784c, 0x6d9b66db }, 5015 { 0x0000784c, 0x6d9b66db },
5016 { 0x00007850, 0x6d8c6dba }, 5016 { 0x00007850, 0x6d8c6dba },
5017 { 0x00007854, 0x00040000 }, 5017 { 0x00007854, 0x00040000 },
@@ -5218,7 +5218,7 @@ static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = {
5218 { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff }, 5218 { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff },
5219 { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 }, 5219 { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 },
5220 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, 5220 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
5221 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 }, 5221 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a214652, 0x0a214652, 0x0a22a652 },
5222 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, 5222 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
5223 { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 }, 5223 { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 },
5224 { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 }, 5224 { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index 81bf6e5840e1..ce8bb001c6d1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -114,6 +114,10 @@
114#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 114#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
115#define AR_PHY_FIND_SIG_FIRPWR_S 18 115#define AR_PHY_FIND_SIG_FIRPWR_S 18
116 116
117#define AR_PHY_FIND_SIG_LOW 0x9840
118#define AR_PHY_FIND_SIG_FIRSTEP_LOW 0x00000FC0L
119#define AR_PHY_FIND_SIG_FIRSTEP_LOW_S 6
120
117#define AR_PHY_AGC_CTL1 0x985C 121#define AR_PHY_AGC_CTL1 0x985C
118#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 122#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
119#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 123#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
@@ -325,6 +329,9 @@
325#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 329#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
326#define AR_PHY_EXT_CCA_THRESH62 0x007F0000 330#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
327#define AR_PHY_EXT_CCA_THRESH62_S 16 331#define AR_PHY_EXT_CCA_THRESH62_S 16
332#define AR_PHY_EXT_TIMING5_CYCPWR_THR1 0x0000FE00L
333#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9
334
328#define AR_PHY_EXT_MINCCA_PWR 0xFF800000 335#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
329#define AR_PHY_EXT_MINCCA_PWR_S 23 336#define AR_PHY_EXT_MINCCA_PWR_S 23
330#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 337#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
index db019dd220b7..d3375fc4ce8b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h
@@ -14,8 +14,8 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#ifndef INITVALS_9003_H 17#ifndef INITVALS_9003_2P0_H
18#define INITVALS_9003_H 18#define INITVALS_9003_2P0_H
19 19
20/* AR9003 2.0 */ 20/* AR9003 2.0 */
21 21
@@ -835,71 +835,71 @@ static const u32 ar9300_2p0_baseband_core[][2] = {
835 835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { 836static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 838 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
839 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 839 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
840 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 840 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
841 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, 841 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
842 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, 842 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
843 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, 843 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
844 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, 844 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
845 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, 845 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
846 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, 846 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
847 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, 847 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
848 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, 848 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
849 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, 849 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
850 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, 850 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
851 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, 851 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
852 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, 852 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
853 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, 853 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
854 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, 854 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
855 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, 855 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
856 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, 856 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
857 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, 857 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
858 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, 858 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
859 {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, 859 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
860 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, 860 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
861 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 861 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
862 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 862 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
863 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, 863 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
864 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 864 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
865 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 865 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
866 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 866 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
867 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 867 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
868 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 868 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
869 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 869 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
870 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 870 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
871 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, 871 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
872 {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, 872 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
873 {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, 873 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
874 {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, 874 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
875 {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, 875 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
876 {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, 876 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
877 {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, 877 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
878 {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, 878 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
879 {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, 879 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
880 {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, 880 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
881 {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, 881 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
882 {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, 882 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
883 {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, 883 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
884 {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, 884 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
885 {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, 885 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
886 {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, 886 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
887 {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, 887 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
888 {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, 888 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
889 {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, 889 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
890 {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, 890 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
891 {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, 891 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
892 {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, 892 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
893 {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, 893 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
894 {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, 894 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
895 {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, 895 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
896 {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 896 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
897 {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 897 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
898 {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 898 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
899 {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 899 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
900 {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 900 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
901 {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 901 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
902 {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 902 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
903 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, 903 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
904 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, 904 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
905 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, 905 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
@@ -913,71 +913,71 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
913 913
914static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { 914static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
915 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 915 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
916 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 916 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
917 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 917 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
918 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 918 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
919 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, 919 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
920 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, 920 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
921 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, 921 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
922 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, 922 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
923 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, 923 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
924 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, 924 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
925 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, 925 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
926 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, 926 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
927 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, 927 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
928 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, 928 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
929 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, 929 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
930 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, 930 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
931 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, 931 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
932 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, 932 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
933 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, 933 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
934 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, 934 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
935 {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, 935 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
936 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, 936 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
937 {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, 937 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
938 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, 938 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
939 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 939 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
940 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 940 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
941 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, 941 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
942 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 942 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
943 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 943 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
944 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 944 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
945 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 945 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
946 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 946 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
947 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 947 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
948 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 948 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
949 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, 949 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
950 {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, 950 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
951 {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, 951 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
952 {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, 952 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
953 {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, 953 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
954 {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, 954 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
955 {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, 955 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
956 {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, 956 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
957 {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, 957 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
958 {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, 958 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
959 {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, 959 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
960 {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, 960 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
961 {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, 961 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
962 {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, 962 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
963 {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, 963 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
964 {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, 964 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
965 {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, 965 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
966 {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, 966 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
967 {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, 967 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
968 {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, 968 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
969 {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, 969 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
970 {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, 970 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
971 {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, 971 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
972 {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, 972 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
973 {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, 973 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
974 {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 974 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
975 {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 975 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
976 {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 976 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
977 {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 977 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
978 {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 978 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
979 {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 979 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
980 {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, 980 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
981 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, 981 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
982 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, 982 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
983 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 983 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -1781,4 +1781,4 @@ static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = {
1781 {0x00004044, 0x00000000}, 1781 {0x00004044, 0x00000000},
1782}; 1782};
1783 1783
1784#endif /* INITVALS_9003_H */ 1784#endif /* INITVALS_9003_2P0_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
new file mode 100644
index 000000000000..ec98ab50748a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -0,0 +1,1785 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef INITVALS_9003_2P2_H
18#define INITVALS_9003_2P2_H
19
20/* AR9003 2.2 */
21
22static const u32 ar9300_2p2_radio_postamble[][5] = {
23 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
24 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
25 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
26 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
27 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
28 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
29 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
30 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
31 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
32 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
33};
34
35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
37 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
38 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
39 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
40 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
41 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
42 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
43 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
44 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
45 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
46 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
47 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
48 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
49 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
50 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
51 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
52 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
53 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
54 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
55 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
56 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
57 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
58 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
59 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
60 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
61 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
62 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
63 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
64 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
65 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
66 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
67 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
68 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
69 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
70 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
71 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
72 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
73 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
74 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
75 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
76 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
77 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
78 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
79 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
80 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
81 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
82 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
83 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
84 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
85 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
86 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
87 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
88 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
89 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
90 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
91 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
92 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
93 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
94 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
95 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
96 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
97 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
98 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
99 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
100 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
101 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
102 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
103 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
104 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
105 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
106 {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
107 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
108 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
109 {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
110 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
111};
112
113static const u32 ar9300Modes_fast_clock_2p2[][3] = {
114 /* Addr 5G_HT20 5G_HT40 */
115 {0x00001030, 0x00000268, 0x000004d0},
116 {0x00001070, 0x0000018c, 0x00000318},
117 {0x000010b0, 0x00000fd0, 0x00001fa0},
118 {0x00008014, 0x044c044c, 0x08980898},
119 {0x0000801c, 0x148ec02b, 0x148ec057},
120 {0x00008318, 0x000044c0, 0x00008980},
121 {0x00009e00, 0x03721821, 0x03721821},
122 {0x0000a230, 0x0000000b, 0x00000016},
123 {0x0000a254, 0x00000898, 0x00001130},
124};
125
126static const u32 ar9300_2p2_radio_core[][2] = {
127 /* Addr allmodes */
128 {0x00016000, 0x36db6db6},
129 {0x00016004, 0x6db6db40},
130 {0x00016008, 0x73f00000},
131 {0x0001600c, 0x00000000},
132 {0x00016040, 0x7f80fff8},
133 {0x0001604c, 0x76d005b5},
134 {0x00016050, 0x556cf031},
135 {0x00016054, 0x13449440},
136 {0x00016058, 0x0c51c92c},
137 {0x0001605c, 0x3db7fffc},
138 {0x00016060, 0xfffffffc},
139 {0x00016064, 0x000f0278},
140 {0x0001606c, 0x6db60000},
141 {0x00016080, 0x00000000},
142 {0x00016084, 0x0e48048c},
143 {0x00016088, 0x54214514},
144 {0x0001608c, 0x119f481e},
145 {0x00016090, 0x24926490},
146 {0x00016098, 0xd2888888},
147 {0x000160a0, 0x0a108ffe},
148 {0x000160a4, 0x812fc370},
149 {0x000160a8, 0x423c8000},
150 {0x000160b4, 0x92480080},
151 {0x000160c0, 0x00adb6d0},
152 {0x000160c4, 0x6db6db60},
153 {0x000160c8, 0x6db6db6c},
154 {0x000160cc, 0x01e6c000},
155 {0x00016100, 0x3fffbe01},
156 {0x00016104, 0xfff80000},
157 {0x00016108, 0x00080010},
158 {0x00016144, 0x02084080},
159 {0x00016148, 0x00000000},
160 {0x00016280, 0x058a0001},
161 {0x00016284, 0x3d840208},
162 {0x00016288, 0x05a20408},
163 {0x0001628c, 0x00038c07},
164 {0x00016290, 0x00000004},
165 {0x00016294, 0x458aa14f},
166 {0x00016380, 0x00000000},
167 {0x00016384, 0x00000000},
168 {0x00016388, 0x00800700},
169 {0x0001638c, 0x00800700},
170 {0x00016390, 0x00800700},
171 {0x00016394, 0x00000000},
172 {0x00016398, 0x00000000},
173 {0x0001639c, 0x00000000},
174 {0x000163a0, 0x00000001},
175 {0x000163a4, 0x00000001},
176 {0x000163a8, 0x00000000},
177 {0x000163ac, 0x00000000},
178 {0x000163b0, 0x00000000},
179 {0x000163b4, 0x00000000},
180 {0x000163b8, 0x00000000},
181 {0x000163bc, 0x00000000},
182 {0x000163c0, 0x000000a0},
183 {0x000163c4, 0x000c0000},
184 {0x000163c8, 0x14021402},
185 {0x000163cc, 0x00001402},
186 {0x000163d0, 0x00000000},
187 {0x000163d4, 0x00000000},
188 {0x00016400, 0x36db6db6},
189 {0x00016404, 0x6db6db40},
190 {0x00016408, 0x73f00000},
191 {0x0001640c, 0x00000000},
192 {0x00016440, 0x7f80fff8},
193 {0x0001644c, 0x76d005b5},
194 {0x00016450, 0x556cf031},
195 {0x00016454, 0x13449440},
196 {0x00016458, 0x0c51c92c},
197 {0x0001645c, 0x3db7fffc},
198 {0x00016460, 0xfffffffc},
199 {0x00016464, 0x000f0278},
200 {0x0001646c, 0x6db60000},
201 {0x00016500, 0x3fffbe01},
202 {0x00016504, 0xfff80000},
203 {0x00016508, 0x00080010},
204 {0x00016544, 0x02084080},
205 {0x00016548, 0x00000000},
206 {0x00016780, 0x00000000},
207 {0x00016784, 0x00000000},
208 {0x00016788, 0x00800700},
209 {0x0001678c, 0x00800700},
210 {0x00016790, 0x00800700},
211 {0x00016794, 0x00000000},
212 {0x00016798, 0x00000000},
213 {0x0001679c, 0x00000000},
214 {0x000167a0, 0x00000001},
215 {0x000167a4, 0x00000001},
216 {0x000167a8, 0x00000000},
217 {0x000167ac, 0x00000000},
218 {0x000167b0, 0x00000000},
219 {0x000167b4, 0x00000000},
220 {0x000167b8, 0x00000000},
221 {0x000167bc, 0x00000000},
222 {0x000167c0, 0x000000a0},
223 {0x000167c4, 0x000c0000},
224 {0x000167c8, 0x14021402},
225 {0x000167cc, 0x00001402},
226 {0x000167d0, 0x00000000},
227 {0x000167d4, 0x00000000},
228 {0x00016800, 0x36db6db6},
229 {0x00016804, 0x6db6db40},
230 {0x00016808, 0x73f00000},
231 {0x0001680c, 0x00000000},
232 {0x00016840, 0x7f80fff8},
233 {0x0001684c, 0x76d005b5},
234 {0x00016850, 0x556cf031},
235 {0x00016854, 0x13449440},
236 {0x00016858, 0x0c51c92c},
237 {0x0001685c, 0x3db7fffc},
238 {0x00016860, 0xfffffffc},
239 {0x00016864, 0x000f0278},
240 {0x0001686c, 0x6db60000},
241 {0x00016900, 0x3fffbe01},
242 {0x00016904, 0xfff80000},
243 {0x00016908, 0x00080010},
244 {0x00016944, 0x02084080},
245 {0x00016948, 0x00000000},
246 {0x00016b80, 0x00000000},
247 {0x00016b84, 0x00000000},
248 {0x00016b88, 0x00800700},
249 {0x00016b8c, 0x00800700},
250 {0x00016b90, 0x00800700},
251 {0x00016b94, 0x00000000},
252 {0x00016b98, 0x00000000},
253 {0x00016b9c, 0x00000000},
254 {0x00016ba0, 0x00000001},
255 {0x00016ba4, 0x00000001},
256 {0x00016ba8, 0x00000000},
257 {0x00016bac, 0x00000000},
258 {0x00016bb0, 0x00000000},
259 {0x00016bb4, 0x00000000},
260 {0x00016bb8, 0x00000000},
261 {0x00016bbc, 0x00000000},
262 {0x00016bc0, 0x000000a0},
263 {0x00016bc4, 0x000c0000},
264 {0x00016bc8, 0x14021402},
265 {0x00016bcc, 0x00001402},
266 {0x00016bd0, 0x00000000},
267 {0x00016bd4, 0x00000000},
268};
269
270static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = {
271 /* Addr allmodes */
272 {0x0000a000, 0x02000101},
273 {0x0000a004, 0x02000102},
274 {0x0000a008, 0x02000103},
275 {0x0000a00c, 0x02000104},
276 {0x0000a010, 0x02000200},
277 {0x0000a014, 0x02000201},
278 {0x0000a018, 0x02000202},
279 {0x0000a01c, 0x02000203},
280 {0x0000a020, 0x02000204},
281 {0x0000a024, 0x02000205},
282 {0x0000a028, 0x02000208},
283 {0x0000a02c, 0x02000302},
284 {0x0000a030, 0x02000303},
285 {0x0000a034, 0x02000304},
286 {0x0000a038, 0x02000400},
287 {0x0000a03c, 0x02010300},
288 {0x0000a040, 0x02010301},
289 {0x0000a044, 0x02010302},
290 {0x0000a048, 0x02000500},
291 {0x0000a04c, 0x02010400},
292 {0x0000a050, 0x02020300},
293 {0x0000a054, 0x02020301},
294 {0x0000a058, 0x02020302},
295 {0x0000a05c, 0x02020303},
296 {0x0000a060, 0x02020400},
297 {0x0000a064, 0x02030300},
298 {0x0000a068, 0x02030301},
299 {0x0000a06c, 0x02030302},
300 {0x0000a070, 0x02030303},
301 {0x0000a074, 0x02030400},
302 {0x0000a078, 0x02040300},
303 {0x0000a07c, 0x02040301},
304 {0x0000a080, 0x02040302},
305 {0x0000a084, 0x02040303},
306 {0x0000a088, 0x02030500},
307 {0x0000a08c, 0x02040400},
308 {0x0000a090, 0x02050203},
309 {0x0000a094, 0x02050204},
310 {0x0000a098, 0x02050205},
311 {0x0000a09c, 0x02040500},
312 {0x0000a0a0, 0x02050301},
313 {0x0000a0a4, 0x02050302},
314 {0x0000a0a8, 0x02050303},
315 {0x0000a0ac, 0x02050400},
316 {0x0000a0b0, 0x02050401},
317 {0x0000a0b4, 0x02050402},
318 {0x0000a0b8, 0x02050403},
319 {0x0000a0bc, 0x02050500},
320 {0x0000a0c0, 0x02050501},
321 {0x0000a0c4, 0x02050502},
322 {0x0000a0c8, 0x02050503},
323 {0x0000a0cc, 0x02050504},
324 {0x0000a0d0, 0x02050600},
325 {0x0000a0d4, 0x02050601},
326 {0x0000a0d8, 0x02050602},
327 {0x0000a0dc, 0x02050603},
328 {0x0000a0e0, 0x02050604},
329 {0x0000a0e4, 0x02050700},
330 {0x0000a0e8, 0x02050701},
331 {0x0000a0ec, 0x02050702},
332 {0x0000a0f0, 0x02050703},
333 {0x0000a0f4, 0x02050704},
334 {0x0000a0f8, 0x02050705},
335 {0x0000a0fc, 0x02050708},
336 {0x0000a100, 0x02050709},
337 {0x0000a104, 0x0205070a},
338 {0x0000a108, 0x0205070b},
339 {0x0000a10c, 0x0205070c},
340 {0x0000a110, 0x0205070d},
341 {0x0000a114, 0x02050710},
342 {0x0000a118, 0x02050711},
343 {0x0000a11c, 0x02050712},
344 {0x0000a120, 0x02050713},
345 {0x0000a124, 0x02050714},
346 {0x0000a128, 0x02050715},
347 {0x0000a12c, 0x02050730},
348 {0x0000a130, 0x02050731},
349 {0x0000a134, 0x02050732},
350 {0x0000a138, 0x02050733},
351 {0x0000a13c, 0x02050734},
352 {0x0000a140, 0x02050735},
353 {0x0000a144, 0x02050750},
354 {0x0000a148, 0x02050751},
355 {0x0000a14c, 0x02050752},
356 {0x0000a150, 0x02050753},
357 {0x0000a154, 0x02050754},
358 {0x0000a158, 0x02050755},
359 {0x0000a15c, 0x02050770},
360 {0x0000a160, 0x02050771},
361 {0x0000a164, 0x02050772},
362 {0x0000a168, 0x02050773},
363 {0x0000a16c, 0x02050774},
364 {0x0000a170, 0x02050775},
365 {0x0000a174, 0x00000776},
366 {0x0000a178, 0x00000776},
367 {0x0000a17c, 0x00000776},
368 {0x0000a180, 0x00000776},
369 {0x0000a184, 0x00000776},
370 {0x0000a188, 0x00000776},
371 {0x0000a18c, 0x00000776},
372 {0x0000a190, 0x00000776},
373 {0x0000a194, 0x00000776},
374 {0x0000a198, 0x00000776},
375 {0x0000a19c, 0x00000776},
376 {0x0000a1a0, 0x00000776},
377 {0x0000a1a4, 0x00000776},
378 {0x0000a1a8, 0x00000776},
379 {0x0000a1ac, 0x00000776},
380 {0x0000a1b0, 0x00000776},
381 {0x0000a1b4, 0x00000776},
382 {0x0000a1b8, 0x00000776},
383 {0x0000a1bc, 0x00000776},
384 {0x0000a1c0, 0x00000776},
385 {0x0000a1c4, 0x00000776},
386 {0x0000a1c8, 0x00000776},
387 {0x0000a1cc, 0x00000776},
388 {0x0000a1d0, 0x00000776},
389 {0x0000a1d4, 0x00000776},
390 {0x0000a1d8, 0x00000776},
391 {0x0000a1dc, 0x00000776},
392 {0x0000a1e0, 0x00000776},
393 {0x0000a1e4, 0x00000776},
394 {0x0000a1e8, 0x00000776},
395 {0x0000a1ec, 0x00000776},
396 {0x0000a1f0, 0x00000776},
397 {0x0000a1f4, 0x00000776},
398 {0x0000a1f8, 0x00000776},
399 {0x0000a1fc, 0x00000776},
400 {0x0000b000, 0x02000101},
401 {0x0000b004, 0x02000102},
402 {0x0000b008, 0x02000103},
403 {0x0000b00c, 0x02000104},
404 {0x0000b010, 0x02000200},
405 {0x0000b014, 0x02000201},
406 {0x0000b018, 0x02000202},
407 {0x0000b01c, 0x02000203},
408 {0x0000b020, 0x02000204},
409 {0x0000b024, 0x02000205},
410 {0x0000b028, 0x02000208},
411 {0x0000b02c, 0x02000302},
412 {0x0000b030, 0x02000303},
413 {0x0000b034, 0x02000304},
414 {0x0000b038, 0x02000400},
415 {0x0000b03c, 0x02010300},
416 {0x0000b040, 0x02010301},
417 {0x0000b044, 0x02010302},
418 {0x0000b048, 0x02000500},
419 {0x0000b04c, 0x02010400},
420 {0x0000b050, 0x02020300},
421 {0x0000b054, 0x02020301},
422 {0x0000b058, 0x02020302},
423 {0x0000b05c, 0x02020303},
424 {0x0000b060, 0x02020400},
425 {0x0000b064, 0x02030300},
426 {0x0000b068, 0x02030301},
427 {0x0000b06c, 0x02030302},
428 {0x0000b070, 0x02030303},
429 {0x0000b074, 0x02030400},
430 {0x0000b078, 0x02040300},
431 {0x0000b07c, 0x02040301},
432 {0x0000b080, 0x02040302},
433 {0x0000b084, 0x02040303},
434 {0x0000b088, 0x02030500},
435 {0x0000b08c, 0x02040400},
436 {0x0000b090, 0x02050203},
437 {0x0000b094, 0x02050204},
438 {0x0000b098, 0x02050205},
439 {0x0000b09c, 0x02040500},
440 {0x0000b0a0, 0x02050301},
441 {0x0000b0a4, 0x02050302},
442 {0x0000b0a8, 0x02050303},
443 {0x0000b0ac, 0x02050400},
444 {0x0000b0b0, 0x02050401},
445 {0x0000b0b4, 0x02050402},
446 {0x0000b0b8, 0x02050403},
447 {0x0000b0bc, 0x02050500},
448 {0x0000b0c0, 0x02050501},
449 {0x0000b0c4, 0x02050502},
450 {0x0000b0c8, 0x02050503},
451 {0x0000b0cc, 0x02050504},
452 {0x0000b0d0, 0x02050600},
453 {0x0000b0d4, 0x02050601},
454 {0x0000b0d8, 0x02050602},
455 {0x0000b0dc, 0x02050603},
456 {0x0000b0e0, 0x02050604},
457 {0x0000b0e4, 0x02050700},
458 {0x0000b0e8, 0x02050701},
459 {0x0000b0ec, 0x02050702},
460 {0x0000b0f0, 0x02050703},
461 {0x0000b0f4, 0x02050704},
462 {0x0000b0f8, 0x02050705},
463 {0x0000b0fc, 0x02050708},
464 {0x0000b100, 0x02050709},
465 {0x0000b104, 0x0205070a},
466 {0x0000b108, 0x0205070b},
467 {0x0000b10c, 0x0205070c},
468 {0x0000b110, 0x0205070d},
469 {0x0000b114, 0x02050710},
470 {0x0000b118, 0x02050711},
471 {0x0000b11c, 0x02050712},
472 {0x0000b120, 0x02050713},
473 {0x0000b124, 0x02050714},
474 {0x0000b128, 0x02050715},
475 {0x0000b12c, 0x02050730},
476 {0x0000b130, 0x02050731},
477 {0x0000b134, 0x02050732},
478 {0x0000b138, 0x02050733},
479 {0x0000b13c, 0x02050734},
480 {0x0000b140, 0x02050735},
481 {0x0000b144, 0x02050750},
482 {0x0000b148, 0x02050751},
483 {0x0000b14c, 0x02050752},
484 {0x0000b150, 0x02050753},
485 {0x0000b154, 0x02050754},
486 {0x0000b158, 0x02050755},
487 {0x0000b15c, 0x02050770},
488 {0x0000b160, 0x02050771},
489 {0x0000b164, 0x02050772},
490 {0x0000b168, 0x02050773},
491 {0x0000b16c, 0x02050774},
492 {0x0000b170, 0x02050775},
493 {0x0000b174, 0x00000776},
494 {0x0000b178, 0x00000776},
495 {0x0000b17c, 0x00000776},
496 {0x0000b180, 0x00000776},
497 {0x0000b184, 0x00000776},
498 {0x0000b188, 0x00000776},
499 {0x0000b18c, 0x00000776},
500 {0x0000b190, 0x00000776},
501 {0x0000b194, 0x00000776},
502 {0x0000b198, 0x00000776},
503 {0x0000b19c, 0x00000776},
504 {0x0000b1a0, 0x00000776},
505 {0x0000b1a4, 0x00000776},
506 {0x0000b1a8, 0x00000776},
507 {0x0000b1ac, 0x00000776},
508 {0x0000b1b0, 0x00000776},
509 {0x0000b1b4, 0x00000776},
510 {0x0000b1b8, 0x00000776},
511 {0x0000b1bc, 0x00000776},
512 {0x0000b1c0, 0x00000776},
513 {0x0000b1c4, 0x00000776},
514 {0x0000b1c8, 0x00000776},
515 {0x0000b1cc, 0x00000776},
516 {0x0000b1d0, 0x00000776},
517 {0x0000b1d4, 0x00000776},
518 {0x0000b1d8, 0x00000776},
519 {0x0000b1dc, 0x00000776},
520 {0x0000b1e0, 0x00000776},
521 {0x0000b1e4, 0x00000776},
522 {0x0000b1e8, 0x00000776},
523 {0x0000b1ec, 0x00000776},
524 {0x0000b1f0, 0x00000776},
525 {0x0000b1f4, 0x00000776},
526 {0x0000b1f8, 0x00000776},
527 {0x0000b1fc, 0x00000776},
528};
529
530static const u32 ar9300_2p2_mac_postamble[][5] = {
531 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
532 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
533 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
534 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
535 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
536 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
537 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
538 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
539 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
540};
541
542static const u32 ar9300_2p2_soc_postamble[][5] = {
543 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
544 {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
545};
546
547static const u32 ar9200_merlin_2p2_radio_core[][2] = {
548 /* Addr allmodes */
549 {0x00007800, 0x00040000},
550 {0x00007804, 0xdb005012},
551 {0x00007808, 0x04924914},
552 {0x0000780c, 0x21084210},
553 {0x00007810, 0x6d801300},
554 {0x00007814, 0x0019beff},
555 {0x00007818, 0x07e41000},
556 {0x0000781c, 0x00392000},
557 {0x00007820, 0x92592480},
558 {0x00007824, 0x00040000},
559 {0x00007828, 0xdb005012},
560 {0x0000782c, 0x04924914},
561 {0x00007830, 0x21084210},
562 {0x00007834, 0x6d801300},
563 {0x00007838, 0x0019beff},
564 {0x0000783c, 0x07e40000},
565 {0x00007840, 0x00392000},
566 {0x00007844, 0x92592480},
567 {0x00007848, 0x00100000},
568 {0x0000784c, 0x773f0567},
569 {0x00007850, 0x54214514},
570 {0x00007854, 0x12035828},
571 {0x00007858, 0x92592692},
572 {0x0000785c, 0x00000000},
573 {0x00007860, 0x56400000},
574 {0x00007864, 0x0a8e370e},
575 {0x00007868, 0xc0102850},
576 {0x0000786c, 0x812d4000},
577 {0x00007870, 0x807ec400},
578 {0x00007874, 0x001b6db0},
579 {0x00007878, 0x00376b63},
580 {0x0000787c, 0x06db6db6},
581 {0x00007880, 0x006d8000},
582 {0x00007884, 0xffeffffe},
583 {0x00007888, 0xffeffffe},
584 {0x0000788c, 0x00010000},
585 {0x00007890, 0x02060aeb},
586 {0x00007894, 0x5a108000},
587};
588
589static const u32 ar9300_2p2_baseband_postamble[][5] = {
590 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
591 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
592 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
593 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
594 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
595 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
596 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
597 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
598 {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
599 {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
600 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
601 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
602 {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
603 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
604 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
605 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
606 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
607 {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
608 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
609 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
610 {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
611 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
612 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
613 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
614 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
615 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
616 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
617 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
618 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
619 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
620 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
621 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
622 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
623 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
624 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
625 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
626 {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
627 {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
628 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
629 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
630 {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
631 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
632 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
633 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
634 {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
635 {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
636 {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
637 {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
638 {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
639 {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
640 {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
641};
642
643static const u32 ar9300_2p2_baseband_core[][2] = {
644 /* Addr allmodes */
645 {0x00009800, 0xafe68e30},
646 {0x00009804, 0xfd14e000},
647 {0x00009808, 0x9c0a9f6b},
648 {0x0000980c, 0x04900000},
649 {0x00009814, 0x9280c00a},
650 {0x00009818, 0x00000000},
651 {0x0000981c, 0x00020028},
652 {0x00009834, 0x5f3ca3de},
653 {0x00009838, 0x0108ecff},
654 {0x0000983c, 0x14750600},
655 {0x00009880, 0x201fff00},
656 {0x00009884, 0x00001042},
657 {0x000098a4, 0x00200400},
658 {0x000098b0, 0x52440bbe},
659 {0x000098d0, 0x004b6a8e},
660 {0x000098d4, 0x00000820},
661 {0x000098dc, 0x00000000},
662 {0x000098f0, 0x00000000},
663 {0x000098f4, 0x00000000},
664 {0x00009c04, 0xff55ff55},
665 {0x00009c08, 0x0320ff55},
666 {0x00009c0c, 0x00000000},
667 {0x00009c10, 0x00000000},
668 {0x00009c14, 0x00046384},
669 {0x00009c18, 0x05b6b440},
670 {0x00009c1c, 0x00b6b440},
671 {0x00009d00, 0xc080a333},
672 {0x00009d04, 0x40206c10},
673 {0x00009d08, 0x009c4060},
674 {0x00009d0c, 0x9883800a},
675 {0x00009d10, 0x01834061},
676 {0x00009d14, 0x00c0040b},
677 {0x00009d18, 0x00000000},
678 {0x00009e08, 0x0038230c},
679 {0x00009e24, 0x990bb515},
680 {0x00009e28, 0x0c6f0000},
681 {0x00009e30, 0x06336f77},
682 {0x00009e34, 0x6af6532f},
683 {0x00009e38, 0x0cc80c00},
684 {0x00009e3c, 0xcf946222},
685 {0x00009e40, 0x0d261820},
686 {0x00009e4c, 0x00001004},
687 {0x00009e50, 0x00ff03f1},
688 {0x00009e54, 0x00000000},
689 {0x00009fc0, 0x803e4788},
690 {0x00009fc4, 0x0001efb5},
691 {0x00009fcc, 0x40000014},
692 {0x00009fd0, 0x01193b93},
693 {0x0000a20c, 0x00000000},
694 {0x0000a220, 0x00000000},
695 {0x0000a224, 0x00000000},
696 {0x0000a228, 0x10002310},
697 {0x0000a22c, 0x01036a1e},
698 {0x0000a23c, 0x00000000},
699 {0x0000a244, 0x0c000000},
700 {0x0000a2a0, 0x00000001},
701 {0x0000a2c0, 0x00000001},
702 {0x0000a2c8, 0x00000000},
703 {0x0000a2cc, 0x18c43433},
704 {0x0000a2d4, 0x00000000},
705 {0x0000a2dc, 0x00000000},
706 {0x0000a2e0, 0x00000000},
707 {0x0000a2e4, 0x00000000},
708 {0x0000a2e8, 0x00000000},
709 {0x0000a2ec, 0x00000000},
710 {0x0000a2f0, 0x00000000},
711 {0x0000a2f4, 0x00000000},
712 {0x0000a2f8, 0x00000000},
713 {0x0000a344, 0x00000000},
714 {0x0000a34c, 0x00000000},
715 {0x0000a350, 0x0000a000},
716 {0x0000a364, 0x00000000},
717 {0x0000a370, 0x00000000},
718 {0x0000a390, 0x00000001},
719 {0x0000a394, 0x00000444},
720 {0x0000a398, 0x001f0e0f},
721 {0x0000a39c, 0x0075393f},
722 {0x0000a3a0, 0xb79f6427},
723 {0x0000a3a4, 0x00000000},
724 {0x0000a3a8, 0xaaaaaaaa},
725 {0x0000a3ac, 0x3c466478},
726 {0x0000a3c0, 0x20202020},
727 {0x0000a3c4, 0x22222220},
728 {0x0000a3c8, 0x20200020},
729 {0x0000a3cc, 0x20202020},
730 {0x0000a3d0, 0x20202020},
731 {0x0000a3d4, 0x20202020},
732 {0x0000a3d8, 0x20202020},
733 {0x0000a3dc, 0x20202020},
734 {0x0000a3e0, 0x20202020},
735 {0x0000a3e4, 0x20202020},
736 {0x0000a3e8, 0x20202020},
737 {0x0000a3ec, 0x20202020},
738 {0x0000a3f0, 0x00000000},
739 {0x0000a3f4, 0x00000246},
740 {0x0000a3f8, 0x0cdbd380},
741 {0x0000a3fc, 0x000f0f01},
742 {0x0000a400, 0x8fa91f01},
743 {0x0000a404, 0x00000000},
744 {0x0000a408, 0x0e79e5c6},
745 {0x0000a40c, 0x00820820},
746 {0x0000a414, 0x1ce739ce},
747 {0x0000a418, 0x2d001dce},
748 {0x0000a41c, 0x1ce739ce},
749 {0x0000a420, 0x000001ce},
750 {0x0000a424, 0x1ce739ce},
751 {0x0000a428, 0x000001ce},
752 {0x0000a42c, 0x1ce739ce},
753 {0x0000a430, 0x1ce739ce},
754 {0x0000a434, 0x00000000},
755 {0x0000a438, 0x00001801},
756 {0x0000a43c, 0x00000000},
757 {0x0000a440, 0x00000000},
758 {0x0000a444, 0x00000000},
759 {0x0000a448, 0x06000080},
760 {0x0000a44c, 0x00000001},
761 {0x0000a450, 0x00010000},
762 {0x0000a458, 0x00000000},
763 {0x0000a600, 0x00000000},
764 {0x0000a604, 0x00000000},
765 {0x0000a608, 0x00000000},
766 {0x0000a60c, 0x00000000},
767 {0x0000a610, 0x00000000},
768 {0x0000a614, 0x00000000},
769 {0x0000a618, 0x00000000},
770 {0x0000a61c, 0x00000000},
771 {0x0000a620, 0x00000000},
772 {0x0000a624, 0x00000000},
773 {0x0000a628, 0x00000000},
774 {0x0000a62c, 0x00000000},
775 {0x0000a630, 0x00000000},
776 {0x0000a634, 0x00000000},
777 {0x0000a638, 0x00000000},
778 {0x0000a63c, 0x00000000},
779 {0x0000a640, 0x00000000},
780 {0x0000a644, 0x3fad9d74},
781 {0x0000a648, 0x0048060a},
782 {0x0000a64c, 0x00000637},
783 {0x0000a670, 0x03020100},
784 {0x0000a674, 0x09080504},
785 {0x0000a678, 0x0d0c0b0a},
786 {0x0000a67c, 0x13121110},
787 {0x0000a680, 0x31301514},
788 {0x0000a684, 0x35343332},
789 {0x0000a688, 0x00000036},
790 {0x0000a690, 0x00000838},
791 {0x0000a7c0, 0x00000000},
792 {0x0000a7c4, 0xfffffffc},
793 {0x0000a7c8, 0x00000000},
794 {0x0000a7cc, 0x00000000},
795 {0x0000a7d0, 0x00000000},
796 {0x0000a7d4, 0x00000004},
797 {0x0000a7dc, 0x00000001},
798 {0x0000a8d0, 0x004b6a8e},
799 {0x0000a8d4, 0x00000820},
800 {0x0000a8dc, 0x00000000},
801 {0x0000a8f0, 0x00000000},
802 {0x0000a8f4, 0x00000000},
803 {0x0000b2d0, 0x00000080},
804 {0x0000b2d4, 0x00000000},
805 {0x0000b2dc, 0x00000000},
806 {0x0000b2e0, 0x00000000},
807 {0x0000b2e4, 0x00000000},
808 {0x0000b2e8, 0x00000000},
809 {0x0000b2ec, 0x00000000},
810 {0x0000b2f0, 0x00000000},
811 {0x0000b2f4, 0x00000000},
812 {0x0000b2f8, 0x00000000},
813 {0x0000b408, 0x0e79e5c0},
814 {0x0000b40c, 0x00820820},
815 {0x0000b420, 0x00000000},
816 {0x0000b8d0, 0x004b6a8e},
817 {0x0000b8d4, 0x00000820},
818 {0x0000b8dc, 0x00000000},
819 {0x0000b8f0, 0x00000000},
820 {0x0000b8f4, 0x00000000},
821 {0x0000c2d0, 0x00000080},
822 {0x0000c2d4, 0x00000000},
823 {0x0000c2dc, 0x00000000},
824 {0x0000c2e0, 0x00000000},
825 {0x0000c2e4, 0x00000000},
826 {0x0000c2e8, 0x00000000},
827 {0x0000c2ec, 0x00000000},
828 {0x0000c2f0, 0x00000000},
829 {0x0000c2f4, 0x00000000},
830 {0x0000c2f8, 0x00000000},
831 {0x0000c408, 0x0e79e5c0},
832 {0x0000c40c, 0x00820820},
833 {0x0000c420, 0x00000000},
834};
835
836static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
837 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
838 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
839 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
840 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
841 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
842 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
843 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
844 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
845 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
846 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
847 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
848 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
849 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
850 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
851 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
852 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
853 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
854 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
855 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
856 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
857 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
858 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
859 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
860 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
861 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
862 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
863 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
864 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
865 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
866 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
867 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
868 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
869 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
870 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
871 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
872 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
873 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
874 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
875 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
876 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
877 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
878 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
879 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
880 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
881 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
882 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
883 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
884 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
885 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
886 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
887 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
888 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
889 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
890 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
891 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
892 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
893 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
894 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
895 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
896 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
897 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
898 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
899 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
900 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
901 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
902 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
903 {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
904 {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
905 {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
906 {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
907 {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
908 {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
909 {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
910 {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
911 {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
912};
913
914static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
915 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
916 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
917 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
918 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
919 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
920 {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
921 {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
922 {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
923 {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
924 {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
925 {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
926 {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
927 {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
928 {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
929 {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
930 {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
931 {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
932 {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
933 {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
934 {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
935 {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
936 {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
937 {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
938 {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
939 {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
940 {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
941 {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
942 {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
943 {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
944 {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
945 {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
946 {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
947 {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
948 {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
949 {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
950 {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
951 {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
952 {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
953 {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
954 {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
955 {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
956 {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
957 {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
958 {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
959 {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
960 {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
961 {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
962 {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
963 {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
964 {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
965 {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
966 {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
967 {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
968 {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
969 {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
970 {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
971 {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
972 {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
973 {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
974 {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
975 {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
976 {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
977 {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
978 {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
979 {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
980 {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
981 {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
982 {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
983 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
984 {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
985 {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
986 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
987 {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
988 {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
989 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
990};
991
992static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
993 /* Addr allmodes */
994 {0x0000a000, 0x00010000},
995 {0x0000a004, 0x00030002},
996 {0x0000a008, 0x00050004},
997 {0x0000a00c, 0x00810080},
998 {0x0000a010, 0x00830082},
999 {0x0000a014, 0x01810180},
1000 {0x0000a018, 0x01830182},
1001 {0x0000a01c, 0x01850184},
1002 {0x0000a020, 0x01890188},
1003 {0x0000a024, 0x018b018a},
1004 {0x0000a028, 0x018d018c},
1005 {0x0000a02c, 0x01910190},
1006 {0x0000a030, 0x01930192},
1007 {0x0000a034, 0x01950194},
1008 {0x0000a038, 0x038a0196},
1009 {0x0000a03c, 0x038c038b},
1010 {0x0000a040, 0x0390038d},
1011 {0x0000a044, 0x03920391},
1012 {0x0000a048, 0x03940393},
1013 {0x0000a04c, 0x03960395},
1014 {0x0000a050, 0x00000000},
1015 {0x0000a054, 0x00000000},
1016 {0x0000a058, 0x00000000},
1017 {0x0000a05c, 0x00000000},
1018 {0x0000a060, 0x00000000},
1019 {0x0000a064, 0x00000000},
1020 {0x0000a068, 0x00000000},
1021 {0x0000a06c, 0x00000000},
1022 {0x0000a070, 0x00000000},
1023 {0x0000a074, 0x00000000},
1024 {0x0000a078, 0x00000000},
1025 {0x0000a07c, 0x00000000},
1026 {0x0000a080, 0x22222229},
1027 {0x0000a084, 0x1d1d1d1d},
1028 {0x0000a088, 0x1d1d1d1d},
1029 {0x0000a08c, 0x1d1d1d1d},
1030 {0x0000a090, 0x171d1d1d},
1031 {0x0000a094, 0x11111717},
1032 {0x0000a098, 0x00030311},
1033 {0x0000a09c, 0x00000000},
1034 {0x0000a0a0, 0x00000000},
1035 {0x0000a0a4, 0x00000000},
1036 {0x0000a0a8, 0x00000000},
1037 {0x0000a0ac, 0x00000000},
1038 {0x0000a0b0, 0x00000000},
1039 {0x0000a0b4, 0x00000000},
1040 {0x0000a0b8, 0x00000000},
1041 {0x0000a0bc, 0x00000000},
1042 {0x0000a0c0, 0x001f0000},
1043 {0x0000a0c4, 0x01000101},
1044 {0x0000a0c8, 0x011e011f},
1045 {0x0000a0cc, 0x011c011d},
1046 {0x0000a0d0, 0x02030204},
1047 {0x0000a0d4, 0x02010202},
1048 {0x0000a0d8, 0x021f0200},
1049 {0x0000a0dc, 0x0302021e},
1050 {0x0000a0e0, 0x03000301},
1051 {0x0000a0e4, 0x031e031f},
1052 {0x0000a0e8, 0x0402031d},
1053 {0x0000a0ec, 0x04000401},
1054 {0x0000a0f0, 0x041e041f},
1055 {0x0000a0f4, 0x0502041d},
1056 {0x0000a0f8, 0x05000501},
1057 {0x0000a0fc, 0x051e051f},
1058 {0x0000a100, 0x06010602},
1059 {0x0000a104, 0x061f0600},
1060 {0x0000a108, 0x061d061e},
1061 {0x0000a10c, 0x07020703},
1062 {0x0000a110, 0x07000701},
1063 {0x0000a114, 0x00000000},
1064 {0x0000a118, 0x00000000},
1065 {0x0000a11c, 0x00000000},
1066 {0x0000a120, 0x00000000},
1067 {0x0000a124, 0x00000000},
1068 {0x0000a128, 0x00000000},
1069 {0x0000a12c, 0x00000000},
1070 {0x0000a130, 0x00000000},
1071 {0x0000a134, 0x00000000},
1072 {0x0000a138, 0x00000000},
1073 {0x0000a13c, 0x00000000},
1074 {0x0000a140, 0x001f0000},
1075 {0x0000a144, 0x01000101},
1076 {0x0000a148, 0x011e011f},
1077 {0x0000a14c, 0x011c011d},
1078 {0x0000a150, 0x02030204},
1079 {0x0000a154, 0x02010202},
1080 {0x0000a158, 0x021f0200},
1081 {0x0000a15c, 0x0302021e},
1082 {0x0000a160, 0x03000301},
1083 {0x0000a164, 0x031e031f},
1084 {0x0000a168, 0x0402031d},
1085 {0x0000a16c, 0x04000401},
1086 {0x0000a170, 0x041e041f},
1087 {0x0000a174, 0x0502041d},
1088 {0x0000a178, 0x05000501},
1089 {0x0000a17c, 0x051e051f},
1090 {0x0000a180, 0x06010602},
1091 {0x0000a184, 0x061f0600},
1092 {0x0000a188, 0x061d061e},
1093 {0x0000a18c, 0x07020703},
1094 {0x0000a190, 0x07000701},
1095 {0x0000a194, 0x00000000},
1096 {0x0000a198, 0x00000000},
1097 {0x0000a19c, 0x00000000},
1098 {0x0000a1a0, 0x00000000},
1099 {0x0000a1a4, 0x00000000},
1100 {0x0000a1a8, 0x00000000},
1101 {0x0000a1ac, 0x00000000},
1102 {0x0000a1b0, 0x00000000},
1103 {0x0000a1b4, 0x00000000},
1104 {0x0000a1b8, 0x00000000},
1105 {0x0000a1bc, 0x00000000},
1106 {0x0000a1c0, 0x00000000},
1107 {0x0000a1c4, 0x00000000},
1108 {0x0000a1c8, 0x00000000},
1109 {0x0000a1cc, 0x00000000},
1110 {0x0000a1d0, 0x00000000},
1111 {0x0000a1d4, 0x00000000},
1112 {0x0000a1d8, 0x00000000},
1113 {0x0000a1dc, 0x00000000},
1114 {0x0000a1e0, 0x00000000},
1115 {0x0000a1e4, 0x00000000},
1116 {0x0000a1e8, 0x00000000},
1117 {0x0000a1ec, 0x00000000},
1118 {0x0000a1f0, 0x00000396},
1119 {0x0000a1f4, 0x00000396},
1120 {0x0000a1f8, 0x00000396},
1121 {0x0000a1fc, 0x00000196},
1122 {0x0000b000, 0x00010000},
1123 {0x0000b004, 0x00030002},
1124 {0x0000b008, 0x00050004},
1125 {0x0000b00c, 0x00810080},
1126 {0x0000b010, 0x00830082},
1127 {0x0000b014, 0x01810180},
1128 {0x0000b018, 0x01830182},
1129 {0x0000b01c, 0x01850184},
1130 {0x0000b020, 0x02810280},
1131 {0x0000b024, 0x02830282},
1132 {0x0000b028, 0x02850284},
1133 {0x0000b02c, 0x02890288},
1134 {0x0000b030, 0x028b028a},
1135 {0x0000b034, 0x0388028c},
1136 {0x0000b038, 0x038a0389},
1137 {0x0000b03c, 0x038c038b},
1138 {0x0000b040, 0x0390038d},
1139 {0x0000b044, 0x03920391},
1140 {0x0000b048, 0x03940393},
1141 {0x0000b04c, 0x03960395},
1142 {0x0000b050, 0x00000000},
1143 {0x0000b054, 0x00000000},
1144 {0x0000b058, 0x00000000},
1145 {0x0000b05c, 0x00000000},
1146 {0x0000b060, 0x00000000},
1147 {0x0000b064, 0x00000000},
1148 {0x0000b068, 0x00000000},
1149 {0x0000b06c, 0x00000000},
1150 {0x0000b070, 0x00000000},
1151 {0x0000b074, 0x00000000},
1152 {0x0000b078, 0x00000000},
1153 {0x0000b07c, 0x00000000},
1154 {0x0000b080, 0x32323232},
1155 {0x0000b084, 0x2f2f3232},
1156 {0x0000b088, 0x23282a2d},
1157 {0x0000b08c, 0x1c1e2123},
1158 {0x0000b090, 0x14171919},
1159 {0x0000b094, 0x0e0e1214},
1160 {0x0000b098, 0x03050707},
1161 {0x0000b09c, 0x00030303},
1162 {0x0000b0a0, 0x00000000},
1163 {0x0000b0a4, 0x00000000},
1164 {0x0000b0a8, 0x00000000},
1165 {0x0000b0ac, 0x00000000},
1166 {0x0000b0b0, 0x00000000},
1167 {0x0000b0b4, 0x00000000},
1168 {0x0000b0b8, 0x00000000},
1169 {0x0000b0bc, 0x00000000},
1170 {0x0000b0c0, 0x003f0020},
1171 {0x0000b0c4, 0x00400041},
1172 {0x0000b0c8, 0x0140005f},
1173 {0x0000b0cc, 0x0160015f},
1174 {0x0000b0d0, 0x017e017f},
1175 {0x0000b0d4, 0x02410242},
1176 {0x0000b0d8, 0x025f0240},
1177 {0x0000b0dc, 0x027f0260},
1178 {0x0000b0e0, 0x0341027e},
1179 {0x0000b0e4, 0x035f0340},
1180 {0x0000b0e8, 0x037f0360},
1181 {0x0000b0ec, 0x04400441},
1182 {0x0000b0f0, 0x0460045f},
1183 {0x0000b0f4, 0x0541047f},
1184 {0x0000b0f8, 0x055f0540},
1185 {0x0000b0fc, 0x057f0560},
1186 {0x0000b100, 0x06400641},
1187 {0x0000b104, 0x0660065f},
1188 {0x0000b108, 0x067e067f},
1189 {0x0000b10c, 0x07410742},
1190 {0x0000b110, 0x075f0740},
1191 {0x0000b114, 0x077f0760},
1192 {0x0000b118, 0x07800781},
1193 {0x0000b11c, 0x07a0079f},
1194 {0x0000b120, 0x07c107bf},
1195 {0x0000b124, 0x000007c0},
1196 {0x0000b128, 0x00000000},
1197 {0x0000b12c, 0x00000000},
1198 {0x0000b130, 0x00000000},
1199 {0x0000b134, 0x00000000},
1200 {0x0000b138, 0x00000000},
1201 {0x0000b13c, 0x00000000},
1202 {0x0000b140, 0x003f0020},
1203 {0x0000b144, 0x00400041},
1204 {0x0000b148, 0x0140005f},
1205 {0x0000b14c, 0x0160015f},
1206 {0x0000b150, 0x017e017f},
1207 {0x0000b154, 0x02410242},
1208 {0x0000b158, 0x025f0240},
1209 {0x0000b15c, 0x027f0260},
1210 {0x0000b160, 0x0341027e},
1211 {0x0000b164, 0x035f0340},
1212 {0x0000b168, 0x037f0360},
1213 {0x0000b16c, 0x04400441},
1214 {0x0000b170, 0x0460045f},
1215 {0x0000b174, 0x0541047f},
1216 {0x0000b178, 0x055f0540},
1217 {0x0000b17c, 0x057f0560},
1218 {0x0000b180, 0x06400641},
1219 {0x0000b184, 0x0660065f},
1220 {0x0000b188, 0x067e067f},
1221 {0x0000b18c, 0x07410742},
1222 {0x0000b190, 0x075f0740},
1223 {0x0000b194, 0x077f0760},
1224 {0x0000b198, 0x07800781},
1225 {0x0000b19c, 0x07a0079f},
1226 {0x0000b1a0, 0x07c107bf},
1227 {0x0000b1a4, 0x000007c0},
1228 {0x0000b1a8, 0x00000000},
1229 {0x0000b1ac, 0x00000000},
1230 {0x0000b1b0, 0x00000000},
1231 {0x0000b1b4, 0x00000000},
1232 {0x0000b1b8, 0x00000000},
1233 {0x0000b1bc, 0x00000000},
1234 {0x0000b1c0, 0x00000000},
1235 {0x0000b1c4, 0x00000000},
1236 {0x0000b1c8, 0x00000000},
1237 {0x0000b1cc, 0x00000000},
1238 {0x0000b1d0, 0x00000000},
1239 {0x0000b1d4, 0x00000000},
1240 {0x0000b1d8, 0x00000000},
1241 {0x0000b1dc, 0x00000000},
1242 {0x0000b1e0, 0x00000000},
1243 {0x0000b1e4, 0x00000000},
1244 {0x0000b1e8, 0x00000000},
1245 {0x0000b1ec, 0x00000000},
1246 {0x0000b1f0, 0x00000396},
1247 {0x0000b1f4, 0x00000396},
1248 {0x0000b1f8, 0x00000396},
1249 {0x0000b1fc, 0x00000196},
1250};
1251
1252static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
1253 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1254 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1255 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1256 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1257 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1258 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1259 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1260 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1261 {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
1262 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
1263 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1264 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1265 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1266 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1267 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1268 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1269 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1270 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1271 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1272 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1273 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1274 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
1275 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
1276 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
1277 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
1278 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
1279 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
1280 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1281 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1282 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1283 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1284 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1285 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1286 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
1287 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1288 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
1289 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
1290 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
1291 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
1292 {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
1293 {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
1294 {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
1295 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
1296 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
1297 {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
1298 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
1299 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
1300 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
1301 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
1302 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
1303 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
1304 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
1305 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
1306 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
1307 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
1308 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
1309 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
1310 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
1311 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
1312 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1313 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1314 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1315 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1316 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1317 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1318 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
1319 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1320 {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
1321 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1322 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1323 {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
1324 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1325 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
1326 {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
1327 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
1328};
1329
1330static const u32 ar9300_2p2_mac_core[][2] = {
1331 /* Addr allmodes */
1332 {0x00000008, 0x00000000},
1333 {0x00000030, 0x00020085},
1334 {0x00000034, 0x00000005},
1335 {0x00000040, 0x00000000},
1336 {0x00000044, 0x00000000},
1337 {0x00000048, 0x00000008},
1338 {0x0000004c, 0x00000010},
1339 {0x00000050, 0x00000000},
1340 {0x00001040, 0x002ffc0f},
1341 {0x00001044, 0x002ffc0f},
1342 {0x00001048, 0x002ffc0f},
1343 {0x0000104c, 0x002ffc0f},
1344 {0x00001050, 0x002ffc0f},
1345 {0x00001054, 0x002ffc0f},
1346 {0x00001058, 0x002ffc0f},
1347 {0x0000105c, 0x002ffc0f},
1348 {0x00001060, 0x002ffc0f},
1349 {0x00001064, 0x002ffc0f},
1350 {0x000010f0, 0x00000100},
1351 {0x00001270, 0x00000000},
1352 {0x000012b0, 0x00000000},
1353 {0x000012f0, 0x00000000},
1354 {0x0000143c, 0x00000000},
1355 {0x0000147c, 0x00000000},
1356 {0x00008000, 0x00000000},
1357 {0x00008004, 0x00000000},
1358 {0x00008008, 0x00000000},
1359 {0x0000800c, 0x00000000},
1360 {0x00008018, 0x00000000},
1361 {0x00008020, 0x00000000},
1362 {0x00008038, 0x00000000},
1363 {0x0000803c, 0x00000000},
1364 {0x00008040, 0x00000000},
1365 {0x00008044, 0x00000000},
1366 {0x00008048, 0x00000000},
1367 {0x0000804c, 0xffffffff},
1368 {0x00008054, 0x00000000},
1369 {0x00008058, 0x00000000},
1370 {0x0000805c, 0x000fc78f},
1371 {0x00008060, 0x0000000f},
1372 {0x00008064, 0x00000000},
1373 {0x00008070, 0x00000310},
1374 {0x00008074, 0x00000020},
1375 {0x00008078, 0x00000000},
1376 {0x0000809c, 0x0000000f},
1377 {0x000080a0, 0x00000000},
1378 {0x000080a4, 0x02ff0000},
1379 {0x000080a8, 0x0e070605},
1380 {0x000080ac, 0x0000000d},
1381 {0x000080b0, 0x00000000},
1382 {0x000080b4, 0x00000000},
1383 {0x000080b8, 0x00000000},
1384 {0x000080bc, 0x00000000},
1385 {0x000080c0, 0x2a800000},
1386 {0x000080c4, 0x06900168},
1387 {0x000080c8, 0x13881c20},
1388 {0x000080cc, 0x01f40000},
1389 {0x000080d0, 0x00252500},
1390 {0x000080d4, 0x00a00000},
1391 {0x000080d8, 0x00400000},
1392 {0x000080dc, 0x00000000},
1393 {0x000080e0, 0xffffffff},
1394 {0x000080e4, 0x0000ffff},
1395 {0x000080e8, 0x3f3f3f3f},
1396 {0x000080ec, 0x00000000},
1397 {0x000080f0, 0x00000000},
1398 {0x000080f4, 0x00000000},
1399 {0x000080fc, 0x00020000},
1400 {0x00008100, 0x00000000},
1401 {0x00008108, 0x00000052},
1402 {0x0000810c, 0x00000000},
1403 {0x00008110, 0x00000000},
1404 {0x00008114, 0x000007ff},
1405 {0x00008118, 0x000000aa},
1406 {0x0000811c, 0x00003210},
1407 {0x00008124, 0x00000000},
1408 {0x00008128, 0x00000000},
1409 {0x0000812c, 0x00000000},
1410 {0x00008130, 0x00000000},
1411 {0x00008134, 0x00000000},
1412 {0x00008138, 0x00000000},
1413 {0x0000813c, 0x0000ffff},
1414 {0x00008144, 0xffffffff},
1415 {0x00008168, 0x00000000},
1416 {0x0000816c, 0x00000000},
1417 {0x00008170, 0x18486200},
1418 {0x00008174, 0x33332210},
1419 {0x00008178, 0x00000000},
1420 {0x0000817c, 0x00020000},
1421 {0x000081c0, 0x00000000},
1422 {0x000081c4, 0x33332210},
1423 {0x000081c8, 0x00000000},
1424 {0x000081cc, 0x00000000},
1425 {0x000081d4, 0x00000000},
1426 {0x000081ec, 0x00000000},
1427 {0x000081f0, 0x00000000},
1428 {0x000081f4, 0x00000000},
1429 {0x000081f8, 0x00000000},
1430 {0x000081fc, 0x00000000},
1431 {0x00008240, 0x00100000},
1432 {0x00008244, 0x0010f424},
1433 {0x00008248, 0x00000800},
1434 {0x0000824c, 0x0001e848},
1435 {0x00008250, 0x00000000},
1436 {0x00008254, 0x00000000},
1437 {0x00008258, 0x00000000},
1438 {0x0000825c, 0x40000000},
1439 {0x00008260, 0x00080922},
1440 {0x00008264, 0x9bc00010},
1441 {0x00008268, 0xffffffff},
1442 {0x0000826c, 0x0000ffff},
1443 {0x00008270, 0x00000000},
1444 {0x00008274, 0x40000000},
1445 {0x00008278, 0x003e4180},
1446 {0x0000827c, 0x00000004},
1447 {0x00008284, 0x0000002c},
1448 {0x00008288, 0x0000002c},
1449 {0x0000828c, 0x000000ff},
1450 {0x00008294, 0x00000000},
1451 {0x00008298, 0x00000000},
1452 {0x0000829c, 0x00000000},
1453 {0x00008300, 0x00000140},
1454 {0x00008314, 0x00000000},
1455 {0x0000831c, 0x0000010d},
1456 {0x00008328, 0x00000000},
1457 {0x0000832c, 0x00000007},
1458 {0x00008330, 0x00000302},
1459 {0x00008334, 0x00000700},
1460 {0x00008338, 0x00ff0000},
1461 {0x0000833c, 0x02400000},
1462 {0x00008340, 0x000107ff},
1463 {0x00008344, 0xaa48105b},
1464 {0x00008348, 0x008f0000},
1465 {0x0000835c, 0x00000000},
1466 {0x00008360, 0xffffffff},
1467 {0x00008364, 0xffffffff},
1468 {0x00008368, 0x00000000},
1469 {0x00008370, 0x00000000},
1470 {0x00008374, 0x000000ff},
1471 {0x00008378, 0x00000000},
1472 {0x0000837c, 0x00000000},
1473 {0x00008380, 0xffffffff},
1474 {0x00008384, 0xffffffff},
1475 {0x00008390, 0xffffffff},
1476 {0x00008394, 0xffffffff},
1477 {0x00008398, 0x00000000},
1478 {0x0000839c, 0x00000000},
1479 {0x000083a0, 0x00000000},
1480 {0x000083a4, 0x0000fa14},
1481 {0x000083a8, 0x000f0c00},
1482 {0x000083ac, 0x33332210},
1483 {0x000083b0, 0x33332210},
1484 {0x000083b4, 0x33332210},
1485 {0x000083b8, 0x33332210},
1486 {0x000083bc, 0x00000000},
1487 {0x000083c0, 0x00000000},
1488 {0x000083c4, 0x00000000},
1489 {0x000083c8, 0x00000000},
1490 {0x000083cc, 0x00000200},
1491 {0x000083d0, 0x000301ff},
1492};
1493
1494static const u32 ar9300Common_wo_xlna_rx_gain_table_2p2[][2] = {
1495 /* Addr allmodes */
1496 {0x0000a000, 0x00010000},
1497 {0x0000a004, 0x00030002},
1498 {0x0000a008, 0x00050004},
1499 {0x0000a00c, 0x00810080},
1500 {0x0000a010, 0x00830082},
1501 {0x0000a014, 0x01810180},
1502 {0x0000a018, 0x01830182},
1503 {0x0000a01c, 0x01850184},
1504 {0x0000a020, 0x01890188},
1505 {0x0000a024, 0x018b018a},
1506 {0x0000a028, 0x018d018c},
1507 {0x0000a02c, 0x03820190},
1508 {0x0000a030, 0x03840383},
1509 {0x0000a034, 0x03880385},
1510 {0x0000a038, 0x038a0389},
1511 {0x0000a03c, 0x038c038b},
1512 {0x0000a040, 0x0390038d},
1513 {0x0000a044, 0x03920391},
1514 {0x0000a048, 0x03940393},
1515 {0x0000a04c, 0x03960395},
1516 {0x0000a050, 0x00000000},
1517 {0x0000a054, 0x00000000},
1518 {0x0000a058, 0x00000000},
1519 {0x0000a05c, 0x00000000},
1520 {0x0000a060, 0x00000000},
1521 {0x0000a064, 0x00000000},
1522 {0x0000a068, 0x00000000},
1523 {0x0000a06c, 0x00000000},
1524 {0x0000a070, 0x00000000},
1525 {0x0000a074, 0x00000000},
1526 {0x0000a078, 0x00000000},
1527 {0x0000a07c, 0x00000000},
1528 {0x0000a080, 0x29292929},
1529 {0x0000a084, 0x29292929},
1530 {0x0000a088, 0x29292929},
1531 {0x0000a08c, 0x29292929},
1532 {0x0000a090, 0x22292929},
1533 {0x0000a094, 0x1d1d2222},
1534 {0x0000a098, 0x0c111117},
1535 {0x0000a09c, 0x00030303},
1536 {0x0000a0a0, 0x00000000},
1537 {0x0000a0a4, 0x00000000},
1538 {0x0000a0a8, 0x00000000},
1539 {0x0000a0ac, 0x00000000},
1540 {0x0000a0b0, 0x00000000},
1541 {0x0000a0b4, 0x00000000},
1542 {0x0000a0b8, 0x00000000},
1543 {0x0000a0bc, 0x00000000},
1544 {0x0000a0c0, 0x001f0000},
1545 {0x0000a0c4, 0x01000101},
1546 {0x0000a0c8, 0x011e011f},
1547 {0x0000a0cc, 0x011c011d},
1548 {0x0000a0d0, 0x02030204},
1549 {0x0000a0d4, 0x02010202},
1550 {0x0000a0d8, 0x021f0200},
1551 {0x0000a0dc, 0x0302021e},
1552 {0x0000a0e0, 0x03000301},
1553 {0x0000a0e4, 0x031e031f},
1554 {0x0000a0e8, 0x0402031d},
1555 {0x0000a0ec, 0x04000401},
1556 {0x0000a0f0, 0x041e041f},
1557 {0x0000a0f4, 0x0502041d},
1558 {0x0000a0f8, 0x05000501},
1559 {0x0000a0fc, 0x051e051f},
1560 {0x0000a100, 0x06010602},
1561 {0x0000a104, 0x061f0600},
1562 {0x0000a108, 0x061d061e},
1563 {0x0000a10c, 0x07020703},
1564 {0x0000a110, 0x07000701},
1565 {0x0000a114, 0x00000000},
1566 {0x0000a118, 0x00000000},
1567 {0x0000a11c, 0x00000000},
1568 {0x0000a120, 0x00000000},
1569 {0x0000a124, 0x00000000},
1570 {0x0000a128, 0x00000000},
1571 {0x0000a12c, 0x00000000},
1572 {0x0000a130, 0x00000000},
1573 {0x0000a134, 0x00000000},
1574 {0x0000a138, 0x00000000},
1575 {0x0000a13c, 0x00000000},
1576 {0x0000a140, 0x001f0000},
1577 {0x0000a144, 0x01000101},
1578 {0x0000a148, 0x011e011f},
1579 {0x0000a14c, 0x011c011d},
1580 {0x0000a150, 0x02030204},
1581 {0x0000a154, 0x02010202},
1582 {0x0000a158, 0x021f0200},
1583 {0x0000a15c, 0x0302021e},
1584 {0x0000a160, 0x03000301},
1585 {0x0000a164, 0x031e031f},
1586 {0x0000a168, 0x0402031d},
1587 {0x0000a16c, 0x04000401},
1588 {0x0000a170, 0x041e041f},
1589 {0x0000a174, 0x0502041d},
1590 {0x0000a178, 0x05000501},
1591 {0x0000a17c, 0x051e051f},
1592 {0x0000a180, 0x06010602},
1593 {0x0000a184, 0x061f0600},
1594 {0x0000a188, 0x061d061e},
1595 {0x0000a18c, 0x07020703},
1596 {0x0000a190, 0x07000701},
1597 {0x0000a194, 0x00000000},
1598 {0x0000a198, 0x00000000},
1599 {0x0000a19c, 0x00000000},
1600 {0x0000a1a0, 0x00000000},
1601 {0x0000a1a4, 0x00000000},
1602 {0x0000a1a8, 0x00000000},
1603 {0x0000a1ac, 0x00000000},
1604 {0x0000a1b0, 0x00000000},
1605 {0x0000a1b4, 0x00000000},
1606 {0x0000a1b8, 0x00000000},
1607 {0x0000a1bc, 0x00000000},
1608 {0x0000a1c0, 0x00000000},
1609 {0x0000a1c4, 0x00000000},
1610 {0x0000a1c8, 0x00000000},
1611 {0x0000a1cc, 0x00000000},
1612 {0x0000a1d0, 0x00000000},
1613 {0x0000a1d4, 0x00000000},
1614 {0x0000a1d8, 0x00000000},
1615 {0x0000a1dc, 0x00000000},
1616 {0x0000a1e0, 0x00000000},
1617 {0x0000a1e4, 0x00000000},
1618 {0x0000a1e8, 0x00000000},
1619 {0x0000a1ec, 0x00000000},
1620 {0x0000a1f0, 0x00000396},
1621 {0x0000a1f4, 0x00000396},
1622 {0x0000a1f8, 0x00000396},
1623 {0x0000a1fc, 0x00000196},
1624 {0x0000b000, 0x00010000},
1625 {0x0000b004, 0x00030002},
1626 {0x0000b008, 0x00050004},
1627 {0x0000b00c, 0x00810080},
1628 {0x0000b010, 0x00830082},
1629 {0x0000b014, 0x01810180},
1630 {0x0000b018, 0x01830182},
1631 {0x0000b01c, 0x01850184},
1632 {0x0000b020, 0x02810280},
1633 {0x0000b024, 0x02830282},
1634 {0x0000b028, 0x02850284},
1635 {0x0000b02c, 0x02890288},
1636 {0x0000b030, 0x028b028a},
1637 {0x0000b034, 0x0388028c},
1638 {0x0000b038, 0x038a0389},
1639 {0x0000b03c, 0x038c038b},
1640 {0x0000b040, 0x0390038d},
1641 {0x0000b044, 0x03920391},
1642 {0x0000b048, 0x03940393},
1643 {0x0000b04c, 0x03960395},
1644 {0x0000b050, 0x00000000},
1645 {0x0000b054, 0x00000000},
1646 {0x0000b058, 0x00000000},
1647 {0x0000b05c, 0x00000000},
1648 {0x0000b060, 0x00000000},
1649 {0x0000b064, 0x00000000},
1650 {0x0000b068, 0x00000000},
1651 {0x0000b06c, 0x00000000},
1652 {0x0000b070, 0x00000000},
1653 {0x0000b074, 0x00000000},
1654 {0x0000b078, 0x00000000},
1655 {0x0000b07c, 0x00000000},
1656 {0x0000b080, 0x32323232},
1657 {0x0000b084, 0x2f2f3232},
1658 {0x0000b088, 0x23282a2d},
1659 {0x0000b08c, 0x1c1e2123},
1660 {0x0000b090, 0x14171919},
1661 {0x0000b094, 0x0e0e1214},
1662 {0x0000b098, 0x03050707},
1663 {0x0000b09c, 0x00030303},
1664 {0x0000b0a0, 0x00000000},
1665 {0x0000b0a4, 0x00000000},
1666 {0x0000b0a8, 0x00000000},
1667 {0x0000b0ac, 0x00000000},
1668 {0x0000b0b0, 0x00000000},
1669 {0x0000b0b4, 0x00000000},
1670 {0x0000b0b8, 0x00000000},
1671 {0x0000b0bc, 0x00000000},
1672 {0x0000b0c0, 0x003f0020},
1673 {0x0000b0c4, 0x00400041},
1674 {0x0000b0c8, 0x0140005f},
1675 {0x0000b0cc, 0x0160015f},
1676 {0x0000b0d0, 0x017e017f},
1677 {0x0000b0d4, 0x02410242},
1678 {0x0000b0d8, 0x025f0240},
1679 {0x0000b0dc, 0x027f0260},
1680 {0x0000b0e0, 0x0341027e},
1681 {0x0000b0e4, 0x035f0340},
1682 {0x0000b0e8, 0x037f0360},
1683 {0x0000b0ec, 0x04400441},
1684 {0x0000b0f0, 0x0460045f},
1685 {0x0000b0f4, 0x0541047f},
1686 {0x0000b0f8, 0x055f0540},
1687 {0x0000b0fc, 0x057f0560},
1688 {0x0000b100, 0x06400641},
1689 {0x0000b104, 0x0660065f},
1690 {0x0000b108, 0x067e067f},
1691 {0x0000b10c, 0x07410742},
1692 {0x0000b110, 0x075f0740},
1693 {0x0000b114, 0x077f0760},
1694 {0x0000b118, 0x07800781},
1695 {0x0000b11c, 0x07a0079f},
1696 {0x0000b120, 0x07c107bf},
1697 {0x0000b124, 0x000007c0},
1698 {0x0000b128, 0x00000000},
1699 {0x0000b12c, 0x00000000},
1700 {0x0000b130, 0x00000000},
1701 {0x0000b134, 0x00000000},
1702 {0x0000b138, 0x00000000},
1703 {0x0000b13c, 0x00000000},
1704 {0x0000b140, 0x003f0020},
1705 {0x0000b144, 0x00400041},
1706 {0x0000b148, 0x0140005f},
1707 {0x0000b14c, 0x0160015f},
1708 {0x0000b150, 0x017e017f},
1709 {0x0000b154, 0x02410242},
1710 {0x0000b158, 0x025f0240},
1711 {0x0000b15c, 0x027f0260},
1712 {0x0000b160, 0x0341027e},
1713 {0x0000b164, 0x035f0340},
1714 {0x0000b168, 0x037f0360},
1715 {0x0000b16c, 0x04400441},
1716 {0x0000b170, 0x0460045f},
1717 {0x0000b174, 0x0541047f},
1718 {0x0000b178, 0x055f0540},
1719 {0x0000b17c, 0x057f0560},
1720 {0x0000b180, 0x06400641},
1721 {0x0000b184, 0x0660065f},
1722 {0x0000b188, 0x067e067f},
1723 {0x0000b18c, 0x07410742},
1724 {0x0000b190, 0x075f0740},
1725 {0x0000b194, 0x077f0760},
1726 {0x0000b198, 0x07800781},
1727 {0x0000b19c, 0x07a0079f},
1728 {0x0000b1a0, 0x07c107bf},
1729 {0x0000b1a4, 0x000007c0},
1730 {0x0000b1a8, 0x00000000},
1731 {0x0000b1ac, 0x00000000},
1732 {0x0000b1b0, 0x00000000},
1733 {0x0000b1b4, 0x00000000},
1734 {0x0000b1b8, 0x00000000},
1735 {0x0000b1bc, 0x00000000},
1736 {0x0000b1c0, 0x00000000},
1737 {0x0000b1c4, 0x00000000},
1738 {0x0000b1c8, 0x00000000},
1739 {0x0000b1cc, 0x00000000},
1740 {0x0000b1d0, 0x00000000},
1741 {0x0000b1d4, 0x00000000},
1742 {0x0000b1d8, 0x00000000},
1743 {0x0000b1dc, 0x00000000},
1744 {0x0000b1e0, 0x00000000},
1745 {0x0000b1e4, 0x00000000},
1746 {0x0000b1e8, 0x00000000},
1747 {0x0000b1ec, 0x00000000},
1748 {0x0000b1f0, 0x00000396},
1749 {0x0000b1f4, 0x00000396},
1750 {0x0000b1f8, 0x00000396},
1751 {0x0000b1fc, 0x00000196},
1752};
1753
1754static const u32 ar9300_2p2_soc_preamble[][2] = {
1755 /* Addr allmodes */
1756 {0x000040a4, 0x00a0c1c9},
1757 {0x00007008, 0x00000000},
1758 {0x00007020, 0x00000000},
1759 {0x00007034, 0x00000002},
1760 {0x00007038, 0x000004c2},
1761 {0x00007048, 0x00000008},
1762};
1763
1764static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
1765 /* Addr allmodes */
1766 {0x00004040, 0x08212e5e},
1767 {0x00004040, 0x0008003b},
1768 {0x00004044, 0x00000000},
1769};
1770
1771static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
1772 /* Addr allmodes */
1773 {0x00004040, 0x08253e5e},
1774 {0x00004040, 0x0008003b},
1775 {0x00004044, 0x00000000},
1776};
1777
1778static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
1779 /* Addr allmodes */
1780 {0x00004040, 0x08213e5e},
1781 {0x00004040, 0x0008003b},
1782 {0x00004044, 0x00000000},
1783};
1784
1785#endif /* INITVALS_9003_2P2_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 56a9e5fa6d66..5a0650399136 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -739,6 +739,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
739 */ 739 */
740 ar9003_hw_set_chain_masks(ah, 0x7, 0x7); 740 ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
741 741
742 /* Do Tx IQ Calibration */
743 ar9003_hw_tx_iq_cal(ah);
744 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
745 udelay(5);
746 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
747
742 /* Calibrate the AGC */ 748 /* Calibrate the AGC */
743 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 749 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
744 REG_READ(ah, AR_PHY_AGC_CONTROL) | 750 REG_READ(ah, AR_PHY_AGC_CONTROL) |
@@ -753,10 +759,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
753 return false; 759 return false;
754 } 760 }
755 761
756 /* Do Tx IQ Calibration */
757 if (ah->config.tx_iq_calibration)
758 ar9003_hw_tx_iq_cal(ah);
759
760 /* Revert chainmasks to their original values before NF cal */ 762 /* Revert chainmasks to their original values before NF cal */
761 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 763 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
762 764
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 23eb60ea5455..343c9a427acb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -67,6 +67,7 @@ static const struct ar9300_eeprom ar9300_default = {
67 * bit2 - enable fastClock - enabled 67 * bit2 - enable fastClock - enabled
68 * bit3 - enable doubling - enabled 68 * bit3 - enable doubling - enabled
69 * bit4 - enable internal regulator - disabled 69 * bit4 - enable internal regulator - disabled
70 * bit5 - enable pa predistortion - disabled
70 */ 71 */
71 .miscConfiguration = 0, /* bit0 - turn down drivestrength */ 72 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
72 .eepromWriteEnableGpio = 3, 73 .eepromWriteEnableGpio = 3,
@@ -129,9 +130,11 @@ static const struct ar9300_eeprom ar9300_default = {
129 .txEndToRxOn = 0x2, 130 .txEndToRxOn = 0x2,
130 .txFrameToXpaOn = 0xe, 131 .txFrameToXpaOn = 0xe,
131 .thresh62 = 28, 132 .thresh62 = 28,
132 .futureModal = { /* [32] */ 133 .papdRateMaskHt20 = LE32(0x80c080),
134 .papdRateMaskHt40 = LE32(0x80c080),
135 .futureModal = {
133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 137 0, 0, 0, 0, 0, 0, 0, 0
135 }, 138 },
136 }, 139 },
137 .calFreqPier2G = { 140 .calFreqPier2G = {
@@ -326,9 +329,11 @@ static const struct ar9300_eeprom ar9300_default = {
326 .txEndToRxOn = 0x2, 329 .txEndToRxOn = 0x2,
327 .txFrameToXpaOn = 0xe, 330 .txFrameToXpaOn = 0xe,
328 .thresh62 = 28, 331 .thresh62 = 28,
332 .papdRateMaskHt20 = LE32(0xf0e0e0),
333 .papdRateMaskHt40 = LE32(0xf0e0e0),
329 .futureModal = { 334 .futureModal = {
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 336 0, 0, 0, 0, 0, 0, 0, 0
332 }, 337 },
333 }, 338 },
334 .calFreqPier5G = { 339 .calFreqPier5G = {
@@ -644,6 +649,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
644 return (pBase->featureEnable & 0x10) >> 4; 649 return (pBase->featureEnable & 0x10) >> 4;
645 case EEP_SWREG: 650 case EEP_SWREG:
646 return le32_to_cpu(pBase->swreg); 651 return le32_to_cpu(pBase->swreg);
652 case EEP_PAPRD:
653 return !!(pBase->featureEnable & BIT(5));
647 default: 654 default:
648 return 0; 655 return 0;
649 } 656 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 23fb353c3bba..3c533bb983c7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -234,7 +234,9 @@ struct ar9300_modal_eep_header {
234 u8 txEndToRxOn; 234 u8 txEndToRxOn;
235 u8 txFrameToXpaOn; 235 u8 txFrameToXpaOn;
236 u8 thresh62; 236 u8 thresh62;
237 u8 futureModal[32]; 237 __le32 papdRateMaskHt20;
238 __le32 papdRateMaskHt40;
239 u8 futureModal[24];
238} __packed; 240} __packed;
239 241
240struct ar9300_cal_data_per_freq_op_loop { 242struct ar9300_cal_data_per_freq_op_loop {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index b15309caf1da..064168909108 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -16,7 +16,8 @@
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_mac.h" 18#include "ar9003_mac.h"
19#include "ar9003_initvals.h" 19#include "ar9003_2p0_initvals.h"
20#include "ar9003_2p2_initvals.h"
20 21
21/* General hardware code for the AR9003 hadware family */ 22/* General hardware code for the AR9003 hadware family */
22 23
@@ -31,12 +32,8 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
31 return false; 32 return false;
32} 33}
33 34
34/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */ 35/* AR9003 2.0 */
35/* 36static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah)
36 * XXX: move TX/RX gain INI to its own init_mode_gain_regs after
37 * ensuring it does not affect hardware bring up
38 */
39static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
40{ 37{
41 /* mac */ 38 /* mac */
42 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); 39 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -106,27 +103,128 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
106 3); 103 3);
107} 104}
108 105
106/* AR9003 2.2 */
107static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
108{
109 /* mac */
110 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
111 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
112 ar9300_2p2_mac_core,
113 ARRAY_SIZE(ar9300_2p2_mac_core), 2);
114 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
115 ar9300_2p2_mac_postamble,
116 ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
117
118 /* bb */
119 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
120 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
121 ar9300_2p2_baseband_core,
122 ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
123 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
124 ar9300_2p2_baseband_postamble,
125 ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
126
127 /* radio */
128 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
129 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
130 ar9300_2p2_radio_core,
131 ARRAY_SIZE(ar9300_2p2_radio_core), 2);
132 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
133 ar9300_2p2_radio_postamble,
134 ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
135
136 /* soc */
137 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
138 ar9300_2p2_soc_preamble,
139 ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
140 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
141 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
142 ar9300_2p2_soc_postamble,
143 ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
144
145 /* rx/tx gain */
146 INIT_INI_ARRAY(&ah->iniModesRxGain,
147 ar9300Common_rx_gain_table_2p2,
148 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
149 INIT_INI_ARRAY(&ah->iniModesTxGain,
150 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
151 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
152 5);
153
154 /* Load PCIE SERDES settings from INI */
155
156 /* Awake Setting */
157
158 INIT_INI_ARRAY(&ah->iniPcieSerdes,
159 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
160 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
161 2);
162
163 /* Sleep Setting */
164
165 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
166 ar9300PciePhy_clkreq_enable_L1_2p2,
167 ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
168 2);
169
170 /* Fast clock modal settings */
171 INIT_INI_ARRAY(&ah->iniModesAdditional,
172 ar9300Modes_fast_clock_2p2,
173 ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
174 3);
175}
176
177/*
178 * The AR9003 family uses a new INI format (pre, core, post
179 * arrays per subsystem).
180 */
181static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
182{
183 if (AR_SREV_9300_20(ah))
184 ar9003_2p0_hw_init_mode_regs(ah);
185 else
186 ar9003_2p2_hw_init_mode_regs(ah);
187}
188
109static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 189static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
110{ 190{
111 switch (ar9003_hw_get_tx_gain_idx(ah)) { 191 switch (ar9003_hw_get_tx_gain_idx(ah)) {
112 case 0: 192 case 0:
113 default: 193 default:
114 INIT_INI_ARRAY(&ah->iniModesTxGain, 194 if (AR_SREV_9300_20(ah))
115 ar9300Modes_lowest_ob_db_tx_gain_table_2p0, 195 INIT_INI_ARRAY(&ah->iniModesTxGain,
116 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), 196 ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
117 5); 197 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
198 5);
199 else
200 INIT_INI_ARRAY(&ah->iniModesTxGain,
201 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
202 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
203 5);
118 break; 204 break;
119 case 1: 205 case 1:
120 INIT_INI_ARRAY(&ah->iniModesTxGain, 206 if (AR_SREV_9300_20(ah))
121 ar9300Modes_high_ob_db_tx_gain_table_2p0, 207 INIT_INI_ARRAY(&ah->iniModesTxGain,
122 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), 208 ar9300Modes_high_ob_db_tx_gain_table_2p0,
123 5); 209 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
210 5);
211 else
212 INIT_INI_ARRAY(&ah->iniModesTxGain,
213 ar9300Modes_high_ob_db_tx_gain_table_2p2,
214 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
215 5);
124 break; 216 break;
125 case 2: 217 case 2:
126 INIT_INI_ARRAY(&ah->iniModesTxGain, 218 if (AR_SREV_9300_20(ah))
127 ar9300Modes_low_ob_db_tx_gain_table_2p0, 219 INIT_INI_ARRAY(&ah->iniModesTxGain,
128 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), 220 ar9300Modes_low_ob_db_tx_gain_table_2p0,
129 5); 221 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
222 5);
223 else
224 INIT_INI_ARRAY(&ah->iniModesTxGain,
225 ar9300Modes_low_ob_db_tx_gain_table_2p2,
226 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
227 5);
130 break; 228 break;
131 } 229 }
132} 230}
@@ -136,15 +234,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
136 switch (ar9003_hw_get_rx_gain_idx(ah)) { 234 switch (ar9003_hw_get_rx_gain_idx(ah)) {
137 case 0: 235 case 0:
138 default: 236 default:
139 INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0, 237 if (AR_SREV_9300_20(ah))
140 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 238 INIT_INI_ARRAY(&ah->iniModesRxGain,
141 2); 239 ar9300Common_rx_gain_table_2p0,
240 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
241 2);
242 else
243 INIT_INI_ARRAY(&ah->iniModesRxGain,
244 ar9300Common_rx_gain_table_2p2,
245 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
246 2);
142 break; 247 break;
143 case 1: 248 case 1:
144 INIT_INI_ARRAY(&ah->iniModesRxGain, 249 if (AR_SREV_9300_20(ah))
145 ar9300Common_wo_xlna_rx_gain_table_2p0, 250 INIT_INI_ARRAY(&ah->iniModesRxGain,
146 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), 251 ar9300Common_wo_xlna_rx_gain_table_2p0,
147 2); 252 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
253 2);
254 else
255 INIT_INI_ARRAY(&ah->iniModesRxGain,
256 ar9300Common_wo_xlna_rx_gain_table_2p2,
257 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
258 2);
148 break; 259 break;
149 } 260 }
150} 261}
@@ -184,6 +295,26 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
184 /* Several PCIe massages to ensure proper behaviour */ 295 /* Several PCIe massages to ensure proper behaviour */
185 if (ah->config.pcie_waen) 296 if (ah->config.pcie_waen)
186 REG_WRITE(ah, AR_WA, ah->config.pcie_waen); 297 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
298 else
299 REG_WRITE(ah, AR_WA, ah->WARegVal);
300 }
301
302 /*
303 * Configire PCIE after Ini init. SERDES values now come from ini file
304 * This enables PCIe low power mode.
305 */
306 if (ah->config.pcieSerDesWrite) {
307 unsigned int i;
308 struct ar5416IniArray *array;
309
310 array = power_off ? &ah->iniPcieSerdes :
311 &ah->iniPcieSerdesLowPower;
312
313 for (i = 0; i < array->ia_rows; i++) {
314 REG_WRITE(ah,
315 INI_RA(array, i, 0),
316 INI_RA(array, i, 1));
317 }
187 } 318 }
188} 319}
189 320
@@ -202,4 +333,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
202 ar9003_hw_attach_phy_ops(ah); 333 ar9003_hw_attach_phy_ops(ah);
203 ar9003_hw_attach_calib_ops(ah); 334 ar9003_hw_attach_calib_ops(ah);
204 ar9003_hw_attach_mac_ops(ah); 335 ar9003_hw_attach_mac_ops(ah);
336
337 ath9k_hw_attach_ani_ops_new(ah);
205} 338}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 37ba37481a47..06ef71019c12 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -90,6 +90,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
90 MAP_ISR_S2_CST); 90 MAP_ISR_S2_CST);
91 mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> 91 mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
92 MAP_ISR_S2_TSFOOR); 92 MAP_ISR_S2_TSFOOR);
93 mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >>
94 MAP_ISR_S2_BB_WATCHDOG);
93 95
94 if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { 96 if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
95 REG_WRITE(ah, AR_ISR_S2, isr2); 97 REG_WRITE(ah, AR_ISR_S2, isr2);
@@ -167,6 +169,9 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
167 169
168 (void) REG_READ(ah, AR_ISR); 170 (void) REG_READ(ah, AR_ISR);
169 } 171 }
172
173 if (*masked & ATH9K_INT_BB_WATCHDOG)
174 ar9003_hw_bb_watchdog_read(ah);
170 } 175 }
171 176
172 if (sync_cause) { 177 if (sync_cause) {
@@ -465,6 +470,14 @@ static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
465 ads->ctl11 &= ~AR_VirtMoreFrag; 470 ads->ctl11 &= ~AR_VirtMoreFrag;
466} 471}
467 472
473void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
474{
475 struct ar9003_txc *ads = ds;
476
477 ads->ctl12 |= SM(chains, AR_PAPRDChainMask);
478}
479EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc);
480
468void ar9003_hw_attach_mac_ops(struct ath_hw *hw) 481void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
469{ 482{
470 struct ath_hw_ops *ops = ath9k_hw_ops(hw); 483 struct ath_hw_ops *ops = ath9k_hw_ops(hw);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index f17558b14539..f76f27d16f77 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -40,6 +40,10 @@
40 40
41#define AR_Not_Sounding 0x20000000 41#define AR_Not_Sounding 0x20000000
42 42
43/* ctl 12 */
44#define AR_PAPRDChainMask 0x00000e00
45#define AR_PAPRDChainMask_S 9
46
43#define MAP_ISR_S2_CST 6 47#define MAP_ISR_S2_CST 6
44#define MAP_ISR_S2_GTT 6 48#define MAP_ISR_S2_GTT 6
45#define MAP_ISR_S2_TIM 3 49#define MAP_ISR_S2_TIM 3
@@ -47,6 +51,7 @@
47#define MAP_ISR_S2_DTIMSYNC 7 51#define MAP_ISR_S2_DTIMSYNC 7
48#define MAP_ISR_S2_DTIM 7 52#define MAP_ISR_S2_DTIM 7
49#define MAP_ISR_S2_TSFOOR 4 53#define MAP_ISR_S2_TSFOOR 4
54#define MAP_ISR_S2_BB_WATCHDOG 6
50 55
51#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds) 56#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
52 57
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
new file mode 100644
index 000000000000..49e0c865ce5c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -0,0 +1,714 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "ar9003_phy.h"
19
20void ar9003_paprd_enable(struct ath_hw *ah, bool val)
21{
22 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
23 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
24 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
25 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
26 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
27 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
28}
29EXPORT_SYMBOL(ar9003_paprd_enable);
30
31static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
32{
33 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
34 struct ar9300_modal_eep_header *hdr;
35 const u32 ctrl0[3] = {
36 AR_PHY_PAPRD_CTRL0_B0,
37 AR_PHY_PAPRD_CTRL0_B1,
38 AR_PHY_PAPRD_CTRL0_B2
39 };
40 const u32 ctrl1[3] = {
41 AR_PHY_PAPRD_CTRL1_B0,
42 AR_PHY_PAPRD_CTRL1_B1,
43 AR_PHY_PAPRD_CTRL1_B2
44 };
45 u32 am_mask, ht40_mask;
46 int i;
47
48 if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
49 hdr = &eep->modalHeader5G;
50 else
51 hdr = &eep->modalHeader2G;
52
53 am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
54 ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
55
56 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
57 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
58 REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
59
60 for (i = 0; i < 3; i++) {
61 REG_RMW_FIELD(ah, ctrl0[i],
62 AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
63 REG_RMW_FIELD(ah, ctrl1[i],
64 AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1);
65 REG_RMW_FIELD(ah, ctrl1[i],
66 AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1);
67 REG_RMW_FIELD(ah, ctrl1[i],
68 AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0);
69 REG_RMW_FIELD(ah, ctrl1[i],
70 AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK, 181);
71 REG_RMW_FIELD(ah, ctrl1[i],
72 AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT, 361);
73 REG_RMW_FIELD(ah, ctrl1[i],
74 AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0);
75 REG_RMW_FIELD(ah, ctrl0[i],
76 AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH, 3);
77 }
78
79 ar9003_paprd_enable(ah, false);
80
81 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
82 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30);
83 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
84 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1);
85 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
86 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1);
87 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
88 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0);
89 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
90 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0);
91 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
92 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
93 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
94 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
95 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
96 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);
97 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
98 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
99 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
100 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4);
101 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
102 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
103 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
104 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
105 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
106 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
107 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
108 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
109 -15);
110 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
111 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
112 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
113 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0);
114 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
115 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400);
116 REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
117 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES,
118 100);
119 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0,
120 AR_PHY_PAPRD_PRE_POST_SCALING, 261376);
121 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0,
122 AR_PHY_PAPRD_PRE_POST_SCALING, 248079);
123 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0,
124 AR_PHY_PAPRD_PRE_POST_SCALING, 233759);
125 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0,
126 AR_PHY_PAPRD_PRE_POST_SCALING, 220464);
127 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0,
128 AR_PHY_PAPRD_PRE_POST_SCALING, 208194);
129 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0,
130 AR_PHY_PAPRD_PRE_POST_SCALING, 196949);
131 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0,
132 AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
133 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
134 AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
135}
136
137static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
138{
139 u32 *entry = ah->paprd_gain_table_entries;
140 u8 *index = ah->paprd_gain_table_index;
141 u32 reg = AR_PHY_TXGAIN_TABLE;
142 int i;
143
144 memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
145 memset(index, 0, sizeof(ah->paprd_gain_table_index));
146
147 for (i = 0; i < 32; i++) {
148 entry[i] = REG_READ(ah, reg);
149 index[i] = (entry[i] >> 24) & 0xff;
150 reg += 4;
151 }
152}
153
154static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
155 int target_power)
156{
157 int olpc_gain_delta = 0;
158 int alpha_therm, alpha_volt;
159 int therm_cal_value, volt_cal_value;
160 int therm_value, volt_value;
161 int thermal_gain_corr, voltage_gain_corr;
162 int desired_scale, desired_gain = 0;
163 u32 reg;
164
165 REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
166 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
167 desired_scale = REG_READ_FIELD(ah, AR_PHY_TPC_12,
168 AR_PHY_TPC_12_DESIRED_SCALE_HT40_5);
169 alpha_therm = REG_READ_FIELD(ah, AR_PHY_TPC_19,
170 AR_PHY_TPC_19_ALPHA_THERM);
171 alpha_volt = REG_READ_FIELD(ah, AR_PHY_TPC_19,
172 AR_PHY_TPC_19_ALPHA_VOLT);
173 therm_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18,
174 AR_PHY_TPC_18_THERM_CAL_VALUE);
175 volt_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18,
176 AR_PHY_TPC_18_VOLT_CAL_VALUE);
177 therm_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
178 AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE);
179 volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
180 AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE);
181
182 if (chain == 0)
183 reg = AR_PHY_TPC_11_B0;
184 else if (chain == 1)
185 reg = AR_PHY_TPC_11_B1;
186 else
187 reg = AR_PHY_TPC_11_B2;
188
189 olpc_gain_delta = REG_READ_FIELD(ah, reg,
190 AR_PHY_TPC_11_OLPC_GAIN_DELTA);
191
192 if (olpc_gain_delta >= 128)
193 olpc_gain_delta = olpc_gain_delta - 256;
194
195 thermal_gain_corr = (alpha_therm * (therm_value - therm_cal_value) +
196 (256 / 2)) / 256;
197 voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) +
198 (128 / 2)) / 128;
199 desired_gain = target_power - olpc_gain_delta - thermal_gain_corr -
200 voltage_gain_corr + desired_scale;
201
202 return desired_gain;
203}
204
205static void ar9003_tx_force_gain(struct ath_hw *ah, unsigned int gain_index)
206{
207 int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain;
208 int padrvgnA, padrvgnB, padrvgnC, padrvgnD;
209 u32 *gain_table_entries = ah->paprd_gain_table_entries;
210
211 selected_gain_entry = gain_table_entries[gain_index];
212 txbb1dbgain = selected_gain_entry & 0x7;
213 txbb6dbgain = (selected_gain_entry >> 3) & 0x3;
214 txmxrgain = (selected_gain_entry >> 5) & 0xf;
215 padrvgnA = (selected_gain_entry >> 9) & 0xf;
216 padrvgnB = (selected_gain_entry >> 13) & 0xf;
217 padrvgnC = (selected_gain_entry >> 17) & 0xf;
218 padrvgnD = (selected_gain_entry >> 21) & 0x3;
219
220 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
221 AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain);
222 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
223 AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain);
224 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
225 AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain);
226 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
227 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgnA);
228 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
229 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgnB);
230 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
231 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgnC);
232 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
233 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgnD);
234 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
235 AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0);
236 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
237 AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0);
238 REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0);
239 REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0);
240}
241
242static inline int find_expn(int num)
243{
244 return fls(num) - 1;
245}
246
247static inline int find_proper_scale(int expn, int N)
248{
249 return (expn > N) ? expn - 10 : 0;
250}
251
252#define NUM_BIN 23
253
254static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
255{
256 unsigned int thresh_accum_cnt;
257 int x_est[NUM_BIN + 1], Y[NUM_BIN + 1], theta[NUM_BIN + 1];
258 int PA_in[NUM_BIN + 1];
259 int B1_tmp[NUM_BIN + 1], B2_tmp[NUM_BIN + 1];
260 unsigned int B1_abs_max, B2_abs_max;
261 int max_index, scale_factor;
262 int y_est[NUM_BIN + 1];
263 int x_est_fxp1_nonlin, x_tilde[NUM_BIN + 1];
264 unsigned int x_tilde_abs;
265 int G_fxp, Y_intercept, order_x_by_y, M, I, L, sum_y_sqr, sum_y_quad;
266 int Q_x, Q_B1, Q_B2, beta_raw, alpha_raw, scale_B;
267 int Q_scale_B, Q_beta, Q_alpha, alpha, beta, order_1, order_2;
268 int order1_5x, order2_3x, order1_5x_rem, order2_3x_rem;
269 int y5, y3, tmp;
270 int theta_low_bin = 0;
271 int i;
272
273 /* disregard any bin that contains <= 16 samples */
274 thresh_accum_cnt = 16;
275 scale_factor = 5;
276 max_index = 0;
277 memset(theta, 0, sizeof(theta));
278 memset(x_est, 0, sizeof(x_est));
279 memset(Y, 0, sizeof(Y));
280 memset(y_est, 0, sizeof(y_est));
281 memset(x_tilde, 0, sizeof(x_tilde));
282
283 for (i = 0; i < NUM_BIN; i++) {
284 s32 accum_cnt, accum_tx, accum_rx, accum_ang;
285
286 /* number of samples */
287 accum_cnt = data_L[i] & 0xffff;
288
289 if (accum_cnt <= thresh_accum_cnt)
290 continue;
291
292 /* sum(tx amplitude) */
293 accum_tx = ((data_L[i] >> 16) & 0xffff) |
294 ((data_U[i] & 0x7ff) << 16);
295
296 /* sum(rx amplitude distance to lower bin edge) */
297 accum_rx = ((data_U[i] >> 11) & 0x1f) |
298 ((data_L[i + 23] & 0xffff) << 5);
299
300 /* sum(angles) */
301 accum_ang = ((data_L[i + 23] >> 16) & 0xffff) |
302 ((data_U[i + 23] & 0x7ff) << 16);
303
304 accum_tx <<= scale_factor;
305 accum_rx <<= scale_factor;
306 x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >>
307 scale_factor;
308
309 Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >>
310 scale_factor) +
311 (1 << scale_factor) * max_index + 16;
312
313 if (accum_ang >= (1 << 26))
314 accum_ang -= 1 << 27;
315
316 theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) /
317 accum_cnt;
318
319 max_index++;
320 }
321
322 /*
323 * Find average theta of first 5 bin and all of those to same value.
324 * Curve is linear at that range.
325 */
326 for (i = 1; i < 6; i++)
327 theta_low_bin += theta[i];
328
329 theta_low_bin = theta_low_bin / 5;
330 for (i = 1; i < 6; i++)
331 theta[i] = theta_low_bin;
332
333 /* Set values at origin */
334 theta[0] = theta_low_bin;
335 for (i = 0; i <= max_index; i++)
336 theta[i] -= theta_low_bin;
337
338 x_est[0] = 0;
339 Y[0] = 0;
340 scale_factor = 8;
341
342 /* low signal gain */
343 if (x_est[6] == x_est[3])
344 return false;
345
346 G_fxp =
347 (((Y[6] - Y[3]) * 1 << scale_factor) +
348 (x_est[6] - x_est[3])) / (x_est[6] - x_est[3]);
349
350 Y_intercept =
351 (G_fxp * (x_est[0] - x_est[3]) +
352 (1 << scale_factor)) / (1 << scale_factor) + Y[3];
353
354 for (i = 0; i <= max_index; i++)
355 y_est[i] = Y[i] - Y_intercept;
356
357 for (i = 0; i <= 3; i++) {
358 y_est[i] = i * 32;
359
360 /* prevent division by zero */
361 if (G_fxp == 0)
362 return false;
363
364 x_est[i] = ((y_est[i] * 1 << scale_factor) + G_fxp) / G_fxp;
365 }
366
367 x_est_fxp1_nonlin =
368 x_est[max_index] - ((1 << scale_factor) * y_est[max_index] +
369 G_fxp) / G_fxp;
370
371 order_x_by_y =
372 (x_est_fxp1_nonlin + y_est[max_index]) / y_est[max_index];
373
374 if (order_x_by_y == 0)
375 M = 10;
376 else if (order_x_by_y == 1)
377 M = 9;
378 else
379 M = 8;
380
381 I = (max_index > 15) ? 7 : max_index >> 1;
382 L = max_index - I;
383 scale_factor = 8;
384 sum_y_sqr = 0;
385 sum_y_quad = 0;
386 x_tilde_abs = 0;
387
388 for (i = 0; i <= L; i++) {
389 unsigned int y_sqr;
390 unsigned int y_quad;
391 unsigned int tmp_abs;
392
393 /* prevent division by zero */
394 if (y_est[i + I] == 0)
395 return false;
396
397 x_est_fxp1_nonlin =
398 x_est[i + I] - ((1 << scale_factor) * y_est[i + I] +
399 G_fxp) / G_fxp;
400
401 x_tilde[i] =
402 (x_est_fxp1_nonlin * (1 << M) + y_est[i + I]) / y_est[i +
403 I];
404 x_tilde[i] =
405 (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I];
406 x_tilde[i] =
407 (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I];
408 y_sqr =
409 (y_est[i + I] * y_est[i + I] +
410 (scale_factor * scale_factor)) / (scale_factor *
411 scale_factor);
412 tmp_abs = abs(x_tilde[i]);
413 if (tmp_abs > x_tilde_abs)
414 x_tilde_abs = tmp_abs;
415
416 y_quad = y_sqr * y_sqr;
417 sum_y_sqr = sum_y_sqr + y_sqr;
418 sum_y_quad = sum_y_quad + y_quad;
419 B1_tmp[i] = y_sqr * (L + 1);
420 B2_tmp[i] = y_sqr;
421 }
422
423 B1_abs_max = 0;
424 B2_abs_max = 0;
425 for (i = 0; i <= L; i++) {
426 int abs_val;
427
428 B1_tmp[i] -= sum_y_sqr;
429 B2_tmp[i] = sum_y_quad - sum_y_sqr * B2_tmp[i];
430
431 abs_val = abs(B1_tmp[i]);
432 if (abs_val > B1_abs_max)
433 B1_abs_max = abs_val;
434
435 abs_val = abs(B2_tmp[i]);
436 if (abs_val > B2_abs_max)
437 B2_abs_max = abs_val;
438 }
439
440 Q_x = find_proper_scale(find_expn(x_tilde_abs), 10);
441 Q_B1 = find_proper_scale(find_expn(B1_abs_max), 10);
442 Q_B2 = find_proper_scale(find_expn(B2_abs_max), 10);
443
444 beta_raw = 0;
445 alpha_raw = 0;
446 for (i = 0; i <= L; i++) {
447 x_tilde[i] = x_tilde[i] / (1 << Q_x);
448 B1_tmp[i] = B1_tmp[i] / (1 << Q_B1);
449 B2_tmp[i] = B2_tmp[i] / (1 << Q_B2);
450 beta_raw = beta_raw + B1_tmp[i] * x_tilde[i];
451 alpha_raw = alpha_raw + B2_tmp[i] * x_tilde[i];
452 }
453
454 scale_B =
455 ((sum_y_quad / scale_factor) * (L + 1) -
456 (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor;
457
458 Q_scale_B = find_proper_scale(find_expn(abs(scale_B)), 10);
459 scale_B = scale_B / (1 << Q_scale_B);
460 Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10);
461 Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10);
462 beta_raw = beta_raw / (1 << Q_beta);
463 alpha_raw = alpha_raw / (1 << Q_alpha);
464 alpha = (alpha_raw << 10) / scale_B;
465 beta = (beta_raw << 10) / scale_B;
466 order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B;
467 order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B;
468 order1_5x = order_1 / 5;
469 order2_3x = order_2 / 3;
470 order1_5x_rem = order_1 - 5 * order1_5x;
471 order2_3x_rem = order_2 - 3 * order2_3x;
472
473 for (i = 0; i < PAPRD_TABLE_SZ; i++) {
474 tmp = i * 32;
475 y5 = ((beta * tmp) >> 6) >> order1_5x;
476 y5 = (y5 * tmp) >> order1_5x;
477 y5 = (y5 * tmp) >> order1_5x;
478 y5 = (y5 * tmp) >> order1_5x;
479 y5 = (y5 * tmp) >> order1_5x;
480 y5 = y5 >> order1_5x_rem;
481 y3 = (alpha * tmp) >> order2_3x;
482 y3 = (y3 * tmp) >> order2_3x;
483 y3 = (y3 * tmp) >> order2_3x;
484 y3 = y3 >> order2_3x_rem;
485 PA_in[i] = y5 + y3 + (256 * tmp) / G_fxp;
486
487 if (i >= 2) {
488 tmp = PA_in[i] - PA_in[i - 1];
489 if (tmp < 0)
490 PA_in[i] =
491 PA_in[i - 1] + (PA_in[i - 1] -
492 PA_in[i - 2]);
493 }
494
495 PA_in[i] = (PA_in[i] < 1400) ? PA_in[i] : 1400;
496 }
497
498 beta_raw = 0;
499 alpha_raw = 0;
500
501 for (i = 0; i <= L; i++) {
502 int theta_tilde =
503 ((theta[i + I] << M) + y_est[i + I]) / y_est[i + I];
504 theta_tilde =
505 ((theta_tilde << M) + y_est[i + I]) / y_est[i + I];
506 theta_tilde =
507 ((theta_tilde << M) + y_est[i + I]) / y_est[i + I];
508 beta_raw = beta_raw + B1_tmp[i] * theta_tilde;
509 alpha_raw = alpha_raw + B2_tmp[i] * theta_tilde;
510 }
511
512 Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10);
513 Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10);
514 beta_raw = beta_raw / (1 << Q_beta);
515 alpha_raw = alpha_raw / (1 << Q_alpha);
516
517 alpha = (alpha_raw << 10) / scale_B;
518 beta = (beta_raw << 10) / scale_B;
519 order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B + 5;
520 order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B + 5;
521 order1_5x = order_1 / 5;
522 order2_3x = order_2 / 3;
523 order1_5x_rem = order_1 - 5 * order1_5x;
524 order2_3x_rem = order_2 - 3 * order2_3x;
525
526 for (i = 0; i < PAPRD_TABLE_SZ; i++) {
527 int PA_angle;
528
529 /* pa_table[4] is calculated from PA_angle for i=5 */
530 if (i == 4)
531 continue;
532
533 tmp = i * 32;
534 if (beta > 0)
535 y5 = (((beta * tmp - 64) >> 6) -
536 (1 << order1_5x)) / (1 << order1_5x);
537 else
538 y5 = ((((beta * tmp - 64) >> 6) +
539 (1 << order1_5x)) / (1 << order1_5x));
540
541 y5 = (y5 * tmp) / (1 << order1_5x);
542 y5 = (y5 * tmp) / (1 << order1_5x);
543 y5 = (y5 * tmp) / (1 << order1_5x);
544 y5 = (y5 * tmp) / (1 << order1_5x);
545 y5 = y5 / (1 << order1_5x_rem);
546
547 if (beta > 0)
548 y3 = (alpha * tmp -
549 (1 << order2_3x)) / (1 << order2_3x);
550 else
551 y3 = (alpha * tmp +
552 (1 << order2_3x)) / (1 << order2_3x);
553 y3 = (y3 * tmp) / (1 << order2_3x);
554 y3 = (y3 * tmp) / (1 << order2_3x);
555 y3 = y3 / (1 << order2_3x_rem);
556
557 if (i < 4) {
558 PA_angle = 0;
559 } else {
560 PA_angle = y5 + y3;
561 if (PA_angle < -150)
562 PA_angle = -150;
563 else if (PA_angle > 150)
564 PA_angle = 150;
565 }
566
567 pa_table[i] = ((PA_in[i] & 0x7ff) << 11) + (PA_angle & 0x7ff);
568 if (i == 5) {
569 PA_angle = (PA_angle + 2) >> 1;
570 pa_table[i - 1] = ((PA_in[i - 1] & 0x7ff) << 11) +
571 (PA_angle & 0x7ff);
572 }
573 }
574
575 *gain = G_fxp;
576 return true;
577}
578
579void ar9003_paprd_populate_single_table(struct ath_hw *ah,
580 struct ath9k_channel *chan, int chain)
581{
582 u32 *paprd_table_val = chan->pa_table[chain];
583 u32 small_signal_gain = chan->small_signal_gain[chain];
584 u32 training_power;
585 u32 reg = 0;
586 int i;
587
588 training_power =
589 REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
590 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
591 training_power -= 4;
592
593 if (chain == 0)
594 reg = AR_PHY_PAPRD_MEM_TAB_B0;
595 else if (chain == 1)
596 reg = AR_PHY_PAPRD_MEM_TAB_B1;
597 else if (chain == 2)
598 reg = AR_PHY_PAPRD_MEM_TAB_B2;
599
600 for (i = 0; i < PAPRD_TABLE_SZ; i++) {
601 REG_WRITE(ah, reg, paprd_table_val[i]);
602 reg = reg + 4;
603 }
604
605 if (chain == 0)
606 reg = AR_PHY_PA_GAIN123_B0;
607 else if (chain == 1)
608 reg = AR_PHY_PA_GAIN123_B1;
609 else
610 reg = AR_PHY_PA_GAIN123_B2;
611
612 REG_RMW_FIELD(ah, reg, AR_PHY_PA_GAIN123_PA_GAIN1, small_signal_gain);
613
614 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B0,
615 AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
616 training_power);
617
618 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1,
619 AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
620 training_power);
621
622 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
623 AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
624 training_power);
625}
626EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
627
628int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
629{
630
631 unsigned int i, desired_gain, gain_index;
632 unsigned int train_power;
633
634 train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
635 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
636
637 train_power = train_power - 4;
638
639 desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
640
641 gain_index = 0;
642 for (i = 0; i < 32; i++) {
643 if (ah->paprd_gain_table_index[i] >= desired_gain)
644 break;
645 gain_index++;
646 }
647
648 ar9003_tx_force_gain(ah, gain_index);
649
650 REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
651 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
652
653 return 0;
654}
655EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
656
657int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
658 int chain)
659{
660 u16 *small_signal_gain = &chan->small_signal_gain[chain];
661 u32 *pa_table = chan->pa_table[chain];
662 u32 *data_L, *data_U;
663 int i, status = 0;
664 u32 *buf;
665 u32 reg;
666
667 memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain]));
668
669 buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC);
670 if (!buf)
671 return -ENOMEM;
672
673 data_L = &buf[0];
674 data_U = &buf[48];
675
676 REG_CLR_BIT(ah, AR_PHY_CHAN_INFO_MEMORY,
677 AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ);
678
679 reg = AR_PHY_CHAN_INFO_TAB_0;
680 for (i = 0; i < 48; i++)
681 data_L[i] = REG_READ(ah, reg + (i << 2));
682
683 REG_SET_BIT(ah, AR_PHY_CHAN_INFO_MEMORY,
684 AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ);
685
686 for (i = 0; i < 48; i++)
687 data_U[i] = REG_READ(ah, reg + (i << 2));
688
689 if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))
690 status = -2;
691
692 REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
693 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
694
695 kfree(buf);
696
697 return status;
698}
699EXPORT_SYMBOL(ar9003_paprd_create_curve);
700
701int ar9003_paprd_init_table(struct ath_hw *ah)
702{
703 ar9003_paprd_setup_single_table(ah);
704 ar9003_paprd_get_gain_table(ah);
705 return 0;
706}
707EXPORT_SYMBOL(ar9003_paprd_init_table);
708
709bool ar9003_paprd_is_done(struct ath_hw *ah)
710{
711 return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1,
712 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
713}
714EXPORT_SYMBOL(ar9003_paprd_is_done);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 80431a2f6dc1..19bc05c41136 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -17,6 +17,28 @@
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_phy.h" 18#include "ar9003_phy.h"
19 19
20static const int firstep_table[] =
21/* level: 0 1 2 3 4 5 6 7 8 */
22 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
23
24static const int cycpwrThr1_table[] =
25/* level: 0 1 2 3 4 5 6 7 8 */
26 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
27
28/*
29 * register values to turn OFDM weak signal detection OFF
30 */
31static const int m1ThreshLow_off = 127;
32static const int m2ThreshLow_off = 127;
33static const int m1Thresh_off = 127;
34static const int m2Thresh_off = 127;
35static const int m2CountThr_off = 31;
36static const int m2CountThrLow_off = 63;
37static const int m1ThreshLowExt_off = 127;
38static const int m2ThreshLowExt_off = 127;
39static const int m1ThreshExt_off = 127;
40static const int m2ThreshExt_off = 127;
41
20/** 42/**
21 * ar9003_hw_set_channel - set channel on single-chip device 43 * ar9003_hw_set_channel - set channel on single-chip device
22 * @ah: atheros hardware structure 44 * @ah: atheros hardware structure
@@ -94,7 +116,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
94} 116}
95 117
96/** 118/**
97 * ar9003_hw_spur_mitigate - convert baseband spur frequency 119 * ar9003_hw_spur_mitigate_mrc_cck - convert baseband spur frequency
98 * @ah: atheros hardware structure 120 * @ah: atheros hardware structure
99 * @chan: 121 * @chan:
100 * 122 *
@@ -521,15 +543,6 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
521 u32 val = INI_RA(iniArr, i, column); 543 u32 val = INI_RA(iniArr, i, column);
522 544
523 REG_WRITE(ah, reg, val); 545 REG_WRITE(ah, reg, val);
524
525 /*
526 * Determine if this is a shift register value, and insert the
527 * configured delay if so.
528 */
529 if (reg >= 0x16000 && reg < 0x17000
530 && ah->config.analog_shiftreg)
531 udelay(100);
532
533 DO_DELAY(regWrites); 546 DO_DELAY(regWrites);
534 } 547 }
535} 548}
@@ -732,71 +745,68 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
732{ 745{
733 struct ar5416AniState *aniState = ah->curani; 746 struct ar5416AniState *aniState = ah->curani;
734 struct ath_common *common = ath9k_hw_common(ah); 747 struct ath_common *common = ath9k_hw_common(ah);
748 struct ath9k_channel *chan = ah->curchan;
749 s32 value, value2;
735 750
736 switch (cmd & ah->ani_function) { 751 switch (cmd & ah->ani_function) {
737 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
738 u32 level = param;
739
740 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
741 ath_print(common, ATH_DBG_ANI,
742 "level out of range (%u > %u)\n",
743 level,
744 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
745 return false;
746 }
747
748 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
749 AR_PHY_DESIRED_SZ_TOT_DES,
750 ah->totalSizeDesired[level]);
751 REG_RMW_FIELD(ah, AR_PHY_AGC,
752 AR_PHY_AGC_COARSE_LOW,
753 ah->coarse_low[level]);
754 REG_RMW_FIELD(ah, AR_PHY_AGC,
755 AR_PHY_AGC_COARSE_HIGH,
756 ah->coarse_high[level]);
757 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
758 AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
759
760 if (level > aniState->noiseImmunityLevel)
761 ah->stats.ast_ani_niup++;
762 else if (level < aniState->noiseImmunityLevel)
763 ah->stats.ast_ani_nidown++;
764 aniState->noiseImmunityLevel = level;
765 break;
766 }
767 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 752 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
768 const int m1ThreshLow[] = { 127, 50 }; 753 /*
769 const int m2ThreshLow[] = { 127, 40 }; 754 * on == 1 means ofdm weak signal detection is ON
770 const int m1Thresh[] = { 127, 0x4d }; 755 * on == 1 is the default, for less noise immunity
771 const int m2Thresh[] = { 127, 0x40 }; 756 *
772 const int m2CountThr[] = { 31, 16 }; 757 * on == 0 means ofdm weak signal detection is OFF
773 const int m2CountThrLow[] = { 63, 48 }; 758 * on == 0 means more noise imm
759 */
774 u32 on = param ? 1 : 0; 760 u32 on = param ? 1 : 0;
761 /*
762 * make register setting for default
763 * (weak sig detect ON) come from INI file
764 */
765 int m1ThreshLow = on ?
766 aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
767 int m2ThreshLow = on ?
768 aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
769 int m1Thresh = on ?
770 aniState->iniDef.m1Thresh : m1Thresh_off;
771 int m2Thresh = on ?
772 aniState->iniDef.m2Thresh : m2Thresh_off;
773 int m2CountThr = on ?
774 aniState->iniDef.m2CountThr : m2CountThr_off;
775 int m2CountThrLow = on ?
776 aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
777 int m1ThreshLowExt = on ?
778 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
779 int m2ThreshLowExt = on ?
780 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
781 int m1ThreshExt = on ?
782 aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
783 int m2ThreshExt = on ?
784 aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
775 785
776 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 786 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
777 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 787 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
778 m1ThreshLow[on]); 788 m1ThreshLow);
779 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 789 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
780 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 790 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
781 m2ThreshLow[on]); 791 m2ThreshLow);
782 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 792 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
783 AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); 793 AR_PHY_SFCORR_M1_THRESH, m1Thresh);
784 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 794 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
785 AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); 795 AR_PHY_SFCORR_M2_THRESH, m2Thresh);
786 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 796 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
787 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); 797 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
788 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
789 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 799 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
790 m2CountThrLow[on]); 800 m2CountThrLow);
791 801
792 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 802 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
793 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); 803 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
794 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 804 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
795 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]); 805 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
796 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 806 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
797 AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]); 807 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
798 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 808 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
799 AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]); 809 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
800 810
801 if (on) 811 if (on)
802 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 812 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
@@ -806,6 +816,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
806 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 816 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
807 817
808 if (!on != aniState->ofdmWeakSigDetectOff) { 818 if (!on != aniState->ofdmWeakSigDetectOff) {
819 ath_print(common, ATH_DBG_ANI,
820 "** ch %d: ofdm weak signal: %s=>%s\n",
821 chan->channel,
822 !aniState->ofdmWeakSigDetectOff ?
823 "on" : "off",
824 on ? "on" : "off");
809 if (on) 825 if (on)
810 ah->stats.ast_ani_ofdmon++; 826 ah->stats.ast_ani_ofdmon++;
811 else 827 else
@@ -814,64 +830,167 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
814 } 830 }
815 break; 831 break;
816 } 832 }
817 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
818 const int weakSigThrCck[] = { 8, 6 };
819 u32 high = param ? 1 : 0;
820
821 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
822 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
823 weakSigThrCck[high]);
824 if (high != aniState->cckWeakSigThreshold) {
825 if (high)
826 ah->stats.ast_ani_cckhigh++;
827 else
828 ah->stats.ast_ani_ccklow++;
829 aniState->cckWeakSigThreshold = high;
830 }
831 break;
832 }
833 case ATH9K_ANI_FIRSTEP_LEVEL:{ 833 case ATH9K_ANI_FIRSTEP_LEVEL:{
834 const int firstep[] = { 0, 4, 8 };
835 u32 level = param; 834 u32 level = param;
836 835
837 if (level >= ARRAY_SIZE(firstep)) { 836 if (level >= ARRAY_SIZE(firstep_table)) {
838 ath_print(common, ATH_DBG_ANI, 837 ath_print(common, ATH_DBG_ANI,
839 "level out of range (%u > %u)\n", 838 "ATH9K_ANI_FIRSTEP_LEVEL: level "
839 "out of range (%u > %u)\n",
840 level, 840 level,
841 (unsigned) ARRAY_SIZE(firstep)); 841 (unsigned) ARRAY_SIZE(firstep_table));
842 return false; 842 return false;
843 } 843 }
844
845 /*
846 * make register setting relative to default
847 * from INI file & cap value
848 */
849 value = firstep_table[level] -
850 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
851 aniState->iniDef.firstep;
852 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
853 value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
854 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
855 value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
844 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 856 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
845 AR_PHY_FIND_SIG_FIRSTEP, 857 AR_PHY_FIND_SIG_FIRSTEP,
846 firstep[level]); 858 value);
847 if (level > aniState->firstepLevel) 859 /*
848 ah->stats.ast_ani_stepup++; 860 * we need to set first step low register too
849 else if (level < aniState->firstepLevel) 861 * make register setting relative to default
850 ah->stats.ast_ani_stepdown++; 862 * from INI file & cap value
851 aniState->firstepLevel = level; 863 */
864 value2 = firstep_table[level] -
865 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
866 aniState->iniDef.firstepLow;
867 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
868 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
869 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
870 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
871
872 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
873 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
874
875 if (level != aniState->firstepLevel) {
876 ath_print(common, ATH_DBG_ANI,
877 "** ch %d: level %d=>%d[def:%d] "
878 "firstep[level]=%d ini=%d\n",
879 chan->channel,
880 aniState->firstepLevel,
881 level,
882 ATH9K_ANI_FIRSTEP_LVL_NEW,
883 value,
884 aniState->iniDef.firstep);
885 ath_print(common, ATH_DBG_ANI,
886 "** ch %d: level %d=>%d[def:%d] "
887 "firstep_low[level]=%d ini=%d\n",
888 chan->channel,
889 aniState->firstepLevel,
890 level,
891 ATH9K_ANI_FIRSTEP_LVL_NEW,
892 value2,
893 aniState->iniDef.firstepLow);
894 if (level > aniState->firstepLevel)
895 ah->stats.ast_ani_stepup++;
896 else if (level < aniState->firstepLevel)
897 ah->stats.ast_ani_stepdown++;
898 aniState->firstepLevel = level;
899 }
852 break; 900 break;
853 } 901 }
854 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ 902 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
855 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
856 u32 level = param; 903 u32 level = param;
857 904
858 if (level >= ARRAY_SIZE(cycpwrThr1)) { 905 if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
859 ath_print(common, ATH_DBG_ANI, 906 ath_print(common, ATH_DBG_ANI,
860 "level out of range (%u > %u)\n", 907 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
908 "out of range (%u > %u)\n",
861 level, 909 level,
862 (unsigned) ARRAY_SIZE(cycpwrThr1)); 910 (unsigned) ARRAY_SIZE(cycpwrThr1_table));
863 return false; 911 return false;
864 } 912 }
913 /*
914 * make register setting relative to default
915 * from INI file & cap value
916 */
917 value = cycpwrThr1_table[level] -
918 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
919 aniState->iniDef.cycpwrThr1;
920 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
921 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
922 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
923 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
865 REG_RMW_FIELD(ah, AR_PHY_TIMING5, 924 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
866 AR_PHY_TIMING5_CYCPWR_THR1, 925 AR_PHY_TIMING5_CYCPWR_THR1,
867 cycpwrThr1[level]); 926 value);
868 if (level > aniState->spurImmunityLevel) 927
869 ah->stats.ast_ani_spurup++; 928 /*
870 else if (level < aniState->spurImmunityLevel) 929 * set AR_PHY_EXT_CCA for extension channel
871 ah->stats.ast_ani_spurdown++; 930 * make register setting relative to default
872 aniState->spurImmunityLevel = level; 931 * from INI file & cap value
932 */
933 value2 = cycpwrThr1_table[level] -
934 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
935 aniState->iniDef.cycpwrThr1Ext;
936 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
937 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
938 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
939 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
940 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
941 AR_PHY_EXT_CYCPWR_THR1, value2);
942
943 if (level != aniState->spurImmunityLevel) {
944 ath_print(common, ATH_DBG_ANI,
945 "** ch %d: level %d=>%d[def:%d] "
946 "cycpwrThr1[level]=%d ini=%d\n",
947 chan->channel,
948 aniState->spurImmunityLevel,
949 level,
950 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
951 value,
952 aniState->iniDef.cycpwrThr1);
953 ath_print(common, ATH_DBG_ANI,
954 "** ch %d: level %d=>%d[def:%d] "
955 "cycpwrThr1Ext[level]=%d ini=%d\n",
956 chan->channel,
957 aniState->spurImmunityLevel,
958 level,
959 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
960 value2,
961 aniState->iniDef.cycpwrThr1Ext);
962 if (level > aniState->spurImmunityLevel)
963 ah->stats.ast_ani_spurup++;
964 else if (level < aniState->spurImmunityLevel)
965 ah->stats.ast_ani_spurdown++;
966 aniState->spurImmunityLevel = level;
967 }
873 break; 968 break;
874 } 969 }
970 case ATH9K_ANI_MRC_CCK:{
971 /*
972 * is_on == 1 means MRC CCK ON (default, less noise imm)
973 * is_on == 0 means MRC CCK is OFF (more noise imm)
974 */
975 bool is_on = param ? 1 : 0;
976 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
977 AR_PHY_MRC_CCK_ENABLE, is_on);
978 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
979 AR_PHY_MRC_CCK_MUX_REG, is_on);
980 if (!is_on != aniState->mrcCCKOff) {
981 ath_print(common, ATH_DBG_ANI,
982 "** ch %d: MRC CCK: %s=>%s\n",
983 chan->channel,
984 !aniState->mrcCCKOff ? "on" : "off",
985 is_on ? "on" : "off");
986 if (is_on)
987 ah->stats.ast_ani_ccklow++;
988 else
989 ah->stats.ast_ani_cckhigh++;
990 aniState->mrcCCKOff = !is_on;
991 }
992 break;
993 }
875 case ATH9K_ANI_PRESENT: 994 case ATH9K_ANI_PRESENT:
876 break; 995 break;
877 default: 996 default:
@@ -880,25 +999,19 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
880 return false; 999 return false;
881 } 1000 }
882 1001
883 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
884 ath_print(common, ATH_DBG_ANI, 1002 ath_print(common, ATH_DBG_ANI,
885 "noiseImmunityLevel=%d, spurImmunityLevel=%d, " 1003 "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
886 "ofdmWeakSigDetectOff=%d\n", 1004 "MRCcck=%s listenTime=%d CC=%d listen=%d "
887 aniState->noiseImmunityLevel, 1005 "ofdmErrs=%d cckErrs=%d\n",
888 aniState->spurImmunityLevel, 1006 aniState->spurImmunityLevel,
889 !aniState->ofdmWeakSigDetectOff); 1007 !aniState->ofdmWeakSigDetectOff ? "on" : "off",
890 ath_print(common, ATH_DBG_ANI,
891 "cckWeakSigThreshold=%d, "
892 "firstepLevel=%d, listenTime=%d\n",
893 aniState->cckWeakSigThreshold,
894 aniState->firstepLevel, 1008 aniState->firstepLevel,
895 aniState->listenTime); 1009 !aniState->mrcCCKOff ? "on" : "off",
896 ath_print(common, ATH_DBG_ANI, 1010 aniState->listenTime,
897 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", 1011 aniState->cycleCount,
898 aniState->cycleCount, 1012 aniState->listenTime,
899 aniState->ofdmPhyErrCount, 1013 aniState->ofdmPhyErrCount,
900 aniState->cckPhyErrCount); 1014 aniState->cckPhyErrCount);
901
902 return true; 1015 return true;
903} 1016}
904 1017
@@ -1111,6 +1224,70 @@ static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
1111 } 1224 }
1112} 1225}
1113 1226
1227/*
1228 * Initialize the ANI register values with default (ini) values.
1229 * This routine is called during a (full) hardware reset after
1230 * all the registers are initialised from the INI.
1231 */
1232static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1233{
1234 struct ar5416AniState *aniState;
1235 struct ath_common *common = ath9k_hw_common(ah);
1236 struct ath9k_channel *chan = ah->curchan;
1237 struct ath9k_ani_default *iniDef;
1238 int index;
1239 u32 val;
1240
1241 index = ath9k_hw_get_ani_channel_idx(ah, chan);
1242 aniState = &ah->ani[index];
1243 ah->curani = aniState;
1244 iniDef = &aniState->iniDef;
1245
1246 ath_print(common, ATH_DBG_ANI,
1247 "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
1248 ah->hw_version.macVersion,
1249 ah->hw_version.macRev,
1250 ah->opmode,
1251 chan->channel,
1252 chan->channelFlags);
1253
1254 val = REG_READ(ah, AR_PHY_SFCORR);
1255 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
1256 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
1257 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
1258
1259 val = REG_READ(ah, AR_PHY_SFCORR_LOW);
1260 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
1261 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
1262 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
1263
1264 val = REG_READ(ah, AR_PHY_SFCORR_EXT);
1265 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
1266 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
1267 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
1268 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
1269 iniDef->firstep = REG_READ_FIELD(ah,
1270 AR_PHY_FIND_SIG,
1271 AR_PHY_FIND_SIG_FIRSTEP);
1272 iniDef->firstepLow = REG_READ_FIELD(ah,
1273 AR_PHY_FIND_SIG_LOW,
1274 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW);
1275 iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
1276 AR_PHY_TIMING5,
1277 AR_PHY_TIMING5_CYCPWR_THR1);
1278 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
1279 AR_PHY_EXT_CCA,
1280 AR_PHY_EXT_CYCPWR_THR1);
1281
1282 /* these levels just got reset to defaults by the INI */
1283 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1284 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1285 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1286 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
1287
1288 aniState->cycleCount = 0;
1289}
1290
1114void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1291void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1115{ 1292{
1116 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1293 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1131,4 +1308,124 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1131 priv_ops->ani_control = ar9003_hw_ani_control; 1308 priv_ops->ani_control = ar9003_hw_ani_control;
1132 priv_ops->do_getnf = ar9003_hw_do_getnf; 1309 priv_ops->do_getnf = ar9003_hw_do_getnf;
1133 priv_ops->loadnf = ar9003_hw_loadnf; 1310 priv_ops->loadnf = ar9003_hw_loadnf;
1311 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1312}
1313
1314void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
1315{
1316 struct ath_common *common = ath9k_hw_common(ah);
1317 u32 idle_tmo_ms = ah->bb_watchdog_timeout_ms;
1318 u32 val, idle_count;
1319
1320 if (!idle_tmo_ms) {
1321 /* disable IRQ, disable chip-reset for BB panic */
1322 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2,
1323 REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) &
1324 ~(AR_PHY_WATCHDOG_RST_ENABLE |
1325 AR_PHY_WATCHDOG_IRQ_ENABLE));
1326
1327 /* disable watchdog in non-IDLE mode, disable in IDLE mode */
1328 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1,
1329 REG_READ(ah, AR_PHY_WATCHDOG_CTL_1) &
1330 ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
1331 AR_PHY_WATCHDOG_IDLE_ENABLE));
1332
1333 ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
1334 return;
1335 }
1336
1337 /* enable IRQ, disable chip-reset for BB watchdog */
1338 val = REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & AR_PHY_WATCHDOG_CNTL2_MASK;
1339 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2,
1340 (val | AR_PHY_WATCHDOG_IRQ_ENABLE) &
1341 ~AR_PHY_WATCHDOG_RST_ENABLE);
1342
1343 /* bound limit to 10 secs */
1344 if (idle_tmo_ms > 10000)
1345 idle_tmo_ms = 10000;
1346
1347 /*
1348 * The time unit for watchdog event is 2^15 44/88MHz cycles.
1349 *
1350 * For HT20 we have a time unit of 2^15/44 MHz = .74 ms per tick
1351 * For HT40 we have a time unit of 2^15/88 MHz = .37 ms per tick
1352 *
1353 * Given we use fast clock now in 5 GHz, these time units should
1354 * be common for both 2 GHz and 5 GHz.
1355 */
1356 idle_count = (100 * idle_tmo_ms) / 74;
1357 if (ah->curchan && IS_CHAN_HT40(ah->curchan))
1358 idle_count = (100 * idle_tmo_ms) / 37;
1359
1360 /*
1361 * enable watchdog in non-IDLE mode, disable in IDLE mode,
1362 * set idle time-out.
1363 */
1364 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1,
1365 AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
1366 AR_PHY_WATCHDOG_IDLE_MASK |
1367 (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2)));
1368
1369 ath_print(common, ATH_DBG_RESET,
1370 "Enabled BB Watchdog timeout (%u ms)\n",
1371 idle_tmo_ms);
1372}
1373
1374void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
1375{
1376 /*
1377 * we want to avoid printing in ISR context so we save the
1378 * watchdog status to be printed later in bottom half context.
1379 */
1380 ah->bb_watchdog_last_status = REG_READ(ah, AR_PHY_WATCHDOG_STATUS);
1381
1382 /*
1383 * the watchdog timer should reset on status read but to be sure
1384 * sure we write 0 to the watchdog status bit.
1385 */
1386 REG_WRITE(ah, AR_PHY_WATCHDOG_STATUS,
1387 ah->bb_watchdog_last_status & ~AR_PHY_WATCHDOG_STATUS_CLR);
1388}
1389
1390void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
1391{
1392 struct ath_common *common = ath9k_hw_common(ah);
1393 u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
1394
1395 if (likely(!(common->debug_mask & ATH_DBG_RESET)))
1396 return;
1397
1398 status = ah->bb_watchdog_last_status;
1399 ath_print(common, ATH_DBG_RESET,
1400 "\n==== BB update: BB status=0x%08x ====\n", status);
1401 ath_print(common, ATH_DBG_RESET,
1402 "** BB state: wd=%u det=%u rdar=%u rOFDM=%d "
1403 "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
1404 MS(status, AR_PHY_WATCHDOG_INFO),
1405 MS(status, AR_PHY_WATCHDOG_DET_HANG),
1406 MS(status, AR_PHY_WATCHDOG_RADAR_SM),
1407 MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
1408 MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
1409 MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
1410 MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
1411 MS(status, AR_PHY_WATCHDOG_AGC_SM),
1412 MS(status,AR_PHY_WATCHDOG_SRCH_SM));
1413
1414 ath_print(common, ATH_DBG_RESET,
1415 "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
1416 REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
1417 REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
1418 ath_print(common, ATH_DBG_RESET,
1419 "** BB mode: BB_gen_controls=0x%08x **\n",
1420 REG_READ(ah, AR_PHY_GEN_CTRL));
1421
1422 if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
1423 ath_print(common, ATH_DBG_RESET,
1424 "** BB busy times: rx_clear=%d%%, "
1425 "rx_frame=%d%%, tx_frame=%d%% **\n",
1426 rxc_pcnt, rxf_pcnt, txf_pcnt);
1427
1428 ath_print(common, ATH_DBG_RESET,
1429 "==== BB update: done ====\n\n");
1134} 1430}
1431EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index f08cc8bda005..3394dfe52b42 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -149,6 +149,8 @@
149#define AR_PHY_EXT_CCA_THRESH62_S 16 149#define AR_PHY_EXT_CCA_THRESH62_S 16
150#define AR_PHY_EXT_MINCCA_PWR 0x01FF0000 150#define AR_PHY_EXT_MINCCA_PWR 0x01FF0000
151#define AR_PHY_EXT_MINCCA_PWR_S 16 151#define AR_PHY_EXT_MINCCA_PWR_S 16
152#define AR_PHY_EXT_CYCPWR_THR1 0x0000FE00L
153#define AR_PHY_EXT_CYCPWR_THR1_S 9
152#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE 154#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
153#define AR_PHY_TIMING5_CYCPWR_THR1_S 1 155#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
154#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001 156#define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001
@@ -283,6 +285,12 @@
283#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ 0x1ffffe00 285#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ 0x1ffffe00
284#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9 286#define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9
285 287
288#define AR_PHY_MRC_CCK_CTRL (AR_AGC_BASE + 0x1d0)
289#define AR_PHY_MRC_CCK_ENABLE 0x00000001
290#define AR_PHY_MRC_CCK_ENABLE_S 0
291#define AR_PHY_MRC_CCK_MUX_REG 0x00000002
292#define AR_PHY_MRC_CCK_MUX_REG_S 1
293
286#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200) 294#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200)
287 295
288#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110 296#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110
@@ -451,7 +459,11 @@
451#define AR_PHY_TSTDAC (AR_SM_BASE + 0x168) 459#define AR_PHY_TSTDAC (AR_SM_BASE + 0x168)
452 460
453#define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c) 461#define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c)
454#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) 462
463#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170)
464#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008
465#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3
466
455#define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174) 467#define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174)
456#define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178) 468#define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178)
457#define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c) 469#define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c)
@@ -467,30 +479,86 @@
467#define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0) 479#define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0)
468#define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4) 480#define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4)
469 481
470#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) 482#define AR_PHY_TPC_1 (AR_SM_BASE + 0x1f8)
471#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) 483#define AR_PHY_TPC_1_FORCED_DAC_GAIN 0x0000003e
472#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) 484#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S 1
473#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) 485#define AR_PHY_TPC_1_FORCE_DAC_GAIN 0x00000001
474#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) 486#define AR_PHY_TPC_1_FORCE_DAC_GAIN_S 0
475#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) 487
488#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204)
489#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208)
490#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c)
491
492#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220)
493#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
494#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
495#define AR_PHY_TPC_11_OLPC_GAIN_DELTA 0x00ff0000
496#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S 16
497
498#define AR_PHY_TPC_12 (AR_SM_BASE + 0x224)
499#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5 0x3e000000
500#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S 25
501
502#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c)
503#define AR_PHY_TPC_18_THERM_CAL_VALUE 0x000000ff
504#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0
505#define AR_PHY_TPC_18_VOLT_CAL_VALUE 0x0000ff00
506#define AR_PHY_TPC_18_VOLT_CAL_VALUE_S 8
507
508#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240)
509#define AR_PHY_TPC_19_ALPHA_VOLT 0x001f0000
510#define AR_PHY_TPC_19_ALPHA_VOLT_S 16
511#define AR_PHY_TPC_19_ALPHA_THERM 0xff
512#define AR_PHY_TPC_19_ALPHA_THERM_S 0
513
514#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258)
515#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN 0x00000001
516#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN_S 0
517#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN 0x0000000e
518#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_S 1
519#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN 0x00000030
520#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_S 4
521#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN 0x000003c0
522#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN_S 6
523#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA 0x00003c00
524#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA_S 10
525#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB 0x0003c000
526#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB_S 14
527#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC 0x003c0000
528#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC_S 18
529#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND 0x00c00000
530#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND_S 22
531#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL 0x01000000
532#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL_S 24
476 533
477#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258)
478 534
479#define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280) 535#define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280)
480 536
537#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
538
481#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) 539#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
482#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) 540#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
483#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) 541#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
484#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450) 542#define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450)
485 543
486#define AR_PHY_PANIC_WD_STATUS (AR_SM_BASE + 0x5c0) 544#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
487#define AR_PHY_PANIC_WD_CTL_1 (AR_SM_BASE + 0x5c4) 545#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
488#define AR_PHY_PANIC_WD_CTL_2 (AR_SM_BASE + 0x5c8) 546#define AR_PHY_WATCHDOG_CTL_2 (AR_SM_BASE + 0x5c8)
489#define AR_PHY_BT_CTL (AR_SM_BASE + 0x5cc) 547#define AR_PHY_WATCHDOG_CTL (AR_SM_BASE + 0x5cc)
490#define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0) 548#define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0)
491#define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4) 549#define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4)
492#define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc) 550#define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc)
493#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) 551
552#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248)
553#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
554#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
555
556#define AR_PHY_BB_THERM_ADC_4 (AR_SM_BASE + 0x254)
557#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE 0x000000ff
558#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S 0
559#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00
560#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8
561
494 562
495#define AR_PHY_65NM_CH0_SYNTH4 0x1608c 563#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
496#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 564#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
@@ -660,17 +728,9 @@
660#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff 728#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff
661#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0 729#define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
662 730
663#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff
664#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0
665#define AR_PHY_TPC_19_ALPHA_THERM 0xff
666#define AR_PHY_TPC_19_ALPHA_THERM_S 0
667
668#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 731#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
669#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 732#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
670 733
671#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
672#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
673
674/* 734/*
675 * Channel 1 Register Map 735 * Channel 1 Register Map
676 */ 736 */
@@ -812,35 +872,173 @@
812#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) 872#define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
813#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) 873#define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i)))
814 874
815#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001 875#define AR_PHY_WATCHDOG_NON_IDLE_ENABLE 0x00000001
816#define AR_PHY_BB_PANIC_IDLE_ENABLE 0x00000002 876#define AR_PHY_WATCHDOG_IDLE_ENABLE 0x00000002
817#define AR_PHY_BB_PANIC_IDLE_MASK 0xFFFF0000 877#define AR_PHY_WATCHDOG_IDLE_MASK 0xFFFF0000
818#define AR_PHY_BB_PANIC_NON_IDLE_MASK 0x0000FFFC 878#define AR_PHY_WATCHDOG_NON_IDLE_MASK 0x0000FFFC
819 879
820#define AR_PHY_BB_PANIC_RST_ENABLE 0x00000002 880#define AR_PHY_WATCHDOG_RST_ENABLE 0x00000002
821#define AR_PHY_BB_PANIC_IRQ_ENABLE 0x00000004 881#define AR_PHY_WATCHDOG_IRQ_ENABLE 0x00000004
822#define AR_PHY_BB_PANIC_CNTL2_MASK 0xFFFFFFF9 882#define AR_PHY_WATCHDOG_CNTL2_MASK 0xFFFFFFF9
823 883
824#define AR_PHY_BB_WD_STATUS 0x00000007 884#define AR_PHY_WATCHDOG_INFO 0x00000007
825#define AR_PHY_BB_WD_STATUS_S 0 885#define AR_PHY_WATCHDOG_INFO_S 0
826#define AR_PHY_BB_WD_DET_HANG 0x00000008 886#define AR_PHY_WATCHDOG_DET_HANG 0x00000008
827#define AR_PHY_BB_WD_DET_HANG_S 3 887#define AR_PHY_WATCHDOG_DET_HANG_S 3
828#define AR_PHY_BB_WD_RADAR_SM 0x000000F0 888#define AR_PHY_WATCHDOG_RADAR_SM 0x000000F0
829#define AR_PHY_BB_WD_RADAR_SM_S 4 889#define AR_PHY_WATCHDOG_RADAR_SM_S 4
830#define AR_PHY_BB_WD_RX_OFDM_SM 0x00000F00 890#define AR_PHY_WATCHDOG_RX_OFDM_SM 0x00000F00
831#define AR_PHY_BB_WD_RX_OFDM_SM_S 8 891#define AR_PHY_WATCHDOG_RX_OFDM_SM_S 8
832#define AR_PHY_BB_WD_RX_CCK_SM 0x0000F000 892#define AR_PHY_WATCHDOG_RX_CCK_SM 0x0000F000
833#define AR_PHY_BB_WD_RX_CCK_SM_S 12 893#define AR_PHY_WATCHDOG_RX_CCK_SM_S 12
834#define AR_PHY_BB_WD_TX_OFDM_SM 0x000F0000 894#define AR_PHY_WATCHDOG_TX_OFDM_SM 0x000F0000
835#define AR_PHY_BB_WD_TX_OFDM_SM_S 16 895#define AR_PHY_WATCHDOG_TX_OFDM_SM_S 16
836#define AR_PHY_BB_WD_TX_CCK_SM 0x00F00000 896#define AR_PHY_WATCHDOG_TX_CCK_SM 0x00F00000
837#define AR_PHY_BB_WD_TX_CCK_SM_S 20 897#define AR_PHY_WATCHDOG_TX_CCK_SM_S 20
838#define AR_PHY_BB_WD_AGC_SM 0x0F000000 898#define AR_PHY_WATCHDOG_AGC_SM 0x0F000000
839#define AR_PHY_BB_WD_AGC_SM_S 24 899#define AR_PHY_WATCHDOG_AGC_SM_S 24
840#define AR_PHY_BB_WD_SRCH_SM 0xF0000000 900#define AR_PHY_WATCHDOG_SRCH_SM 0xF0000000
841#define AR_PHY_BB_WD_SRCH_SM_S 28 901#define AR_PHY_WATCHDOG_SRCH_SM_S 28
842 902
843#define AR_PHY_BB_WD_STATUS_CLR 0x00000008 903#define AR_PHY_WATCHDOG_STATUS_CLR 0x00000008
904
905/*
906 * PAPRD registers
907 */
908#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64)
909
910#define AR_PHY_PAPRD_AM2AM (AR_CHAN_BASE + 0xe4)
911#define AR_PHY_PAPRD_AM2AM_MASK 0x01ffffff
912#define AR_PHY_PAPRD_AM2AM_MASK_S 0
913
914#define AR_PHY_PAPRD_AM2PM (AR_CHAN_BASE + 0xe8)
915#define AR_PHY_PAPRD_AM2PM_MASK 0x01ffffff
916#define AR_PHY_PAPRD_AM2PM_MASK_S 0
917
918#define AR_PHY_PAPRD_HT40 (AR_CHAN_BASE + 0xec)
919#define AR_PHY_PAPRD_HT40_MASK 0x01ffffff
920#define AR_PHY_PAPRD_HT40_MASK_S 0
921
922#define AR_PHY_PAPRD_CTRL0_B0 (AR_CHAN_BASE + 0xf0)
923#define AR_PHY_PAPRD_CTRL0_B1 (AR_CHAN1_BASE + 0xf0)
924#define AR_PHY_PAPRD_CTRL0_B2 (AR_CHAN2_BASE + 0xf0)
925#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE 0x00000001
926#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE_S 0
927#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK 0x00000002
928#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK_S 1
929#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH 0xf8000000
930#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S 27
931
932#define AR_PHY_PAPRD_CTRL1_B0 (AR_CHAN_BASE + 0xf4)
933#define AR_PHY_PAPRD_CTRL1_B1 (AR_CHAN1_BASE + 0xf4)
934#define AR_PHY_PAPRD_CTRL1_B2 (AR_CHAN2_BASE + 0xf4)
935#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA 0x00000001
936#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA_S 0
937#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE 0x00000002
938#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE_S 1
939#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE 0x00000004
940#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE_S 2
941#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL 0x000001f8
942#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_S 3
943#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK 0x0001fe00
944#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK_S 9
945#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000
946#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17
947
948#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490)
949#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001
950#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0
951#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e
952#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_S 1
953#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE 0x00000100
954#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_S 8
955#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE 0x00000200
956#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_S 9
957#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE 0x00000400
958#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_S 10
959#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE 0x00000800
960#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_S 11
961#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000
962#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12
963
964#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494)
965#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF
966#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0
967
968#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498)
969#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f
970#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0
971#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0
972#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_S 6
973#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL 0x0001f000
974#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_S 12
975#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES 0x000e0000
976#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_S 17
977#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN 0x00f00000
978#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_S 20
979#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN 0x0f000000
980#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_S 24
981#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000
982#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29
983
984#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c)
985#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000
986#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16
987#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000
988#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_S 12
989#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR 0x00000fff
990#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_S 0
991
992#define AR_PHY_PAPRD_PRE_POST_SCALE_0_B0 (AR_CHAN_BASE + 0x100)
993#define AR_PHY_PAPRD_PRE_POST_SCALE_1_B0 (AR_CHAN_BASE + 0x104)
994#define AR_PHY_PAPRD_PRE_POST_SCALE_2_B0 (AR_CHAN_BASE + 0x108)
995#define AR_PHY_PAPRD_PRE_POST_SCALE_3_B0 (AR_CHAN_BASE + 0x10c)
996#define AR_PHY_PAPRD_PRE_POST_SCALE_4_B0 (AR_CHAN_BASE + 0x110)
997#define AR_PHY_PAPRD_PRE_POST_SCALE_5_B0 (AR_CHAN_BASE + 0x114)
998#define AR_PHY_PAPRD_PRE_POST_SCALE_6_B0 (AR_CHAN_BASE + 0x118)
999#define AR_PHY_PAPRD_PRE_POST_SCALE_7_B0 (AR_CHAN_BASE + 0x11c)
1000#define AR_PHY_PAPRD_PRE_POST_SCALING 0x3FFFF
1001#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0
1002
1003#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + 0x4a0)
1004#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE 0x00000001
1005#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S 0
1006#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE 0x00000002
1007#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_S 1
1008#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR 0x00000004
1009#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_S 2
1010#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE 0x00000008
1011#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_S 3
1012#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX 0x000001f0
1013#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_S 4
1014#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR 0x0001fe00
1015#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S 9
1016
1017#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + 0x4a4)
1018#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL 0x0000ffff
1019#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S 0
1020#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX 0x001f0000
1021#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_S 16
1022#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX 0x00600000
1023#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S 21
1024
1025#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + 0x4a8)
1026#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT 0x000fffff
1027#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S 0
1028
1029#define AR_PHY_PAPRD_MEM_TAB_B0 (AR_CHAN_BASE + 0x120)
1030#define AR_PHY_PAPRD_MEM_TAB_B1 (AR_CHAN1_BASE + 0x120)
1031#define AR_PHY_PAPRD_MEM_TAB_B2 (AR_CHAN2_BASE + 0x120)
1032
1033#define AR_PHY_PA_GAIN123_B0 (AR_CHAN_BASE + 0xf8)
1034#define AR_PHY_PA_GAIN123_B1 (AR_CHAN1_BASE + 0xf8)
1035#define AR_PHY_PA_GAIN123_B2 (AR_CHAN2_BASE + 0xf8)
1036#define AR_PHY_PA_GAIN123_PA_GAIN1 0x3FF
1037#define AR_PHY_PA_GAIN123_PA_GAIN1_S 0
1038
1039#define AR_PHY_POWERTX_RATE5 (AR_SM_BASE + 0x1d0)
1040#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F
1041#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0
844 1042
845void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); 1043void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
846 1044
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 5ea87736a6ae..72d5e52abb8f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -20,6 +20,7 @@
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/leds.h> 22#include <linux/leds.h>
23#include <linux/completion.h>
23 24
24#include "debug.h" 25#include "debug.h"
25#include "common.h" 26#include "common.h"
@@ -136,6 +137,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
136#define ATH_MAX_ANTENNA 3 137#define ATH_MAX_ANTENNA 3
137#define ATH_RXBUF 512 138#define ATH_RXBUF 512
138#define ATH_TXBUF 512 139#define ATH_TXBUF 512
140#define ATH_TXBUF_RESERVE 5
141#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
139#define ATH_TXMAXTRY 13 142#define ATH_TXMAXTRY 13
140#define ATH_MGT_TXMAXTRY 4 143#define ATH_MGT_TXMAXTRY 4
141 144
@@ -192,6 +195,7 @@ enum ATH_AGGR_STATUS {
192 195
193#define ATH_TXFIFO_DEPTH 8 196#define ATH_TXFIFO_DEPTH 8
194struct ath_txq { 197struct ath_txq {
198 int axq_class;
195 u32 axq_qnum; 199 u32 axq_qnum;
196 u32 *axq_link; 200 u32 *axq_link;
197 struct list_head axq_q; 201 struct list_head axq_q;
@@ -206,6 +210,71 @@ struct ath_txq {
206 u8 txq_tailidx; 210 u8 txq_tailidx;
207}; 211};
208 212
213struct ath_atx_ac {
214 int sched;
215 int qnum;
216 struct list_head list;
217 struct list_head tid_q;
218};
219
220struct ath_buf_state {
221 int bfs_nframes;
222 u16 bfs_al;
223 u16 bfs_frmlen;
224 int bfs_seqno;
225 int bfs_tidno;
226 int bfs_retries;
227 u8 bf_type;
228 u8 bfs_paprd;
229 unsigned long bfs_paprd_timestamp;
230 u32 bfs_keyix;
231 enum ath9k_key_type bfs_keytype;
232};
233
234struct ath_buf {
235 struct list_head list;
236 struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
237 an aggregate) */
238 struct ath_buf *bf_next; /* next subframe in the aggregate */
239 struct sk_buff *bf_mpdu; /* enclosing frame structure */
240 void *bf_desc; /* virtual addr of desc */
241 dma_addr_t bf_daddr; /* physical addr of desc */
242 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
243 bool bf_stale;
244 bool bf_isnullfunc;
245 bool bf_tx_aborted;
246 u16 bf_flags;
247 struct ath_buf_state bf_state;
248 dma_addr_t bf_dmacontext;
249 struct ath_wiphy *aphy;
250};
251
252struct ath_atx_tid {
253 struct list_head list;
254 struct list_head buf_q;
255 struct ath_node *an;
256 struct ath_atx_ac *ac;
257 struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
258 u16 seq_start;
259 u16 seq_next;
260 u16 baw_size;
261 int tidno;
262 int baw_head; /* first un-acked tx buffer */
263 int baw_tail; /* next unused tx buffer slot */
264 int sched;
265 int paused;
266 u8 state;
267};
268
269struct ath_node {
270 struct ath_common *common;
271 struct ath_atx_tid tid[WME_NUM_TID];
272 struct ath_atx_ac ac[WME_NUM_AC];
273 u16 maxampdu;
274 u8 mpdudensity;
275 int last_rssi;
276};
277
209#define AGGR_CLEANUP BIT(1) 278#define AGGR_CLEANUP BIT(1)
210#define AGGR_ADDBA_COMPLETE BIT(2) 279#define AGGR_ADDBA_COMPLETE BIT(2)
211#define AGGR_ADDBA_PROGRESS BIT(3) 280#define AGGR_ADDBA_PROGRESS BIT(3)
@@ -214,6 +283,7 @@ struct ath_tx_control {
214 struct ath_txq *txq; 283 struct ath_txq *txq;
215 int if_id; 284 int if_id;
216 enum ath9k_internal_frame_type frame_type; 285 enum ath9k_internal_frame_type frame_type;
286 u8 paprd;
217}; 287};
218 288
219#define ATH_TX_ERROR 0x01 289#define ATH_TX_ERROR 0x01
@@ -223,11 +293,12 @@ struct ath_tx_control {
223struct ath_tx { 293struct ath_tx {
224 u16 seq_no; 294 u16 seq_no;
225 u32 txqsetup; 295 u32 txqsetup;
226 int hwq_map[ATH9K_WME_AC_VO+1]; 296 int hwq_map[WME_NUM_AC];
227 spinlock_t txbuflock; 297 spinlock_t txbuflock;
228 struct list_head txbuf; 298 struct list_head txbuf;
229 struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; 299 struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
230 struct ath_descdma txdma; 300 struct ath_descdma txdma;
301 int pending_frames[WME_NUM_AC];
231}; 302};
232 303
233struct ath_rx_edma { 304struct ath_rx_edma {
@@ -267,7 +338,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
267void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); 338void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
268int ath_tx_init(struct ath_softc *sc, int nbufs); 339int ath_tx_init(struct ath_softc *sc, int nbufs);
269void ath_tx_cleanup(struct ath_softc *sc); 340void ath_tx_cleanup(struct ath_softc *sc);
270struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
271int ath_txq_update(struct ath_softc *sc, int qnum, 341int ath_txq_update(struct ath_softc *sc, int qnum,
272 struct ath9k_tx_queue_info *q); 342 struct ath9k_tx_queue_info *q);
273int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, 343int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -351,10 +421,14 @@ int ath_beaconq_config(struct ath_softc *sc);
351 421
352#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ 422#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
353#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ 423#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
354#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ 424#define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */
425#define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */
355#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 426#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
356#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 427#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
357 428
429#define ATH_PAPRD_TIMEOUT 100 /* msecs */
430
431void ath_paprd_calibrate(struct work_struct *work);
358void ath_ani_calibrate(unsigned long data); 432void ath_ani_calibrate(unsigned long data);
359 433
360/**********/ 434/**********/
@@ -487,6 +561,8 @@ struct ath_softc {
487 spinlock_t sc_serial_rw; 561 spinlock_t sc_serial_rw;
488 spinlock_t sc_pm_lock; 562 spinlock_t sc_pm_lock;
489 struct mutex mutex; 563 struct mutex mutex;
564 struct work_struct paprd_work;
565 struct completion paprd_complete;
490 566
491 u32 intrstatus; 567 u32 intrstatus;
492 u32 sc_flags; /* SC_OP_* */ 568 u32 sc_flags; /* SC_OP_* */
@@ -545,7 +621,6 @@ struct ath_wiphy {
545 621
546void ath9k_tasklet(unsigned long data); 622void ath9k_tasklet(unsigned long data);
547int ath_reset(struct ath_softc *sc, bool retry_tx); 623int ath_reset(struct ath_softc *sc, bool retry_tx);
548int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
549int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); 624int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
550int ath_cabq_update(struct ath_softc *); 625int ath_cabq_update(struct ath_softc *);
551 626
@@ -556,13 +631,12 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
556 631
557extern struct ieee80211_ops ath9k_ops; 632extern struct ieee80211_ops ath9k_ops;
558extern int modparam_nohwcrypt; 633extern int modparam_nohwcrypt;
634extern int led_blink;
559 635
560irqreturn_t ath_isr(int irq, void *dev); 636irqreturn_t ath_isr(int irq, void *dev);
561int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, 637int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
562 const struct ath_bus_ops *bus_ops); 638 const struct ath_bus_ops *bus_ops);
563void ath9k_deinit_device(struct ath_softc *sc); 639void ath9k_deinit_device(struct ath_softc *sc);
564const char *ath_mac_bb_name(u32 mac_bb_version);
565const char *ath_rf_name(u16 rf_version);
566void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); 640void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
567void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, 641void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
568 struct ath9k_channel *ichan); 642 struct ath9k_channel *ichan);
@@ -613,8 +687,6 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
613void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); 687void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
614void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); 688void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
615 689
616int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
617
618void ath_start_rfkill_poll(struct ath_softc *sc); 690void ath_start_rfkill_poll(struct ath_softc *sc);
619extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); 691extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
620 692
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index f43d85a302c4..4d4b22d52dfd 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -38,8 +38,7 @@ int ath_beaconq_config(struct ath_softc *sc)
38 qi.tqi_cwmax = 0; 38 qi.tqi_cwmax = 0;
39 } else { 39 } else {
40 /* Adhoc mode; important thing is to use 2x cwmin. */ 40 /* Adhoc mode; important thing is to use 2x cwmin. */
41 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, 41 qnum = sc->tx.hwq_map[WME_AC_BE];
42 ATH9K_WME_AC_BE);
43 ath9k_hw_get_txq_props(ah, qnum, &qi_be); 42 ath9k_hw_get_txq_props(ah, qnum, &qi_be);
44 qi.tqi_aifs = qi_be.tqi_aifs; 43 qi.tqi_aifs = qi_be.tqi_aifs;
45 qi.tqi_cwmin = 4*qi_be.tqi_cwmin; 44 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 7707341cd0d3..16e2849f644d 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -27,270 +27,6 @@ MODULE_AUTHOR("Atheros Communications");
27MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); 27MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
28MODULE_LICENSE("Dual BSD/GPL"); 28MODULE_LICENSE("Dual BSD/GPL");
29 29
30/* Common RX processing */
31
32/* Assumes you've already done the endian to CPU conversion */
33static bool ath9k_rx_accept(struct ath_common *common,
34 struct sk_buff *skb,
35 struct ieee80211_rx_status *rxs,
36 struct ath_rx_status *rx_stats,
37 bool *decrypt_error)
38{
39 struct ath_hw *ah = common->ah;
40 struct ieee80211_hdr *hdr;
41 __le16 fc;
42
43 hdr = (struct ieee80211_hdr *) skb->data;
44 fc = hdr->frame_control;
45
46 if (!rx_stats->rs_datalen)
47 return false;
48 /*
49 * rs_status follows rs_datalen so if rs_datalen is too large
50 * we can take a hint that hardware corrupted it, so ignore
51 * those frames.
52 */
53 if (rx_stats->rs_datalen > common->rx_bufsize)
54 return false;
55
56 /*
57 * rs_more indicates chained descriptors which can be used
58 * to link buffers together for a sort of scatter-gather
59 * operation.
60 * reject the frame, we don't support scatter-gather yet and
61 * the frame is probably corrupt anyway
62 */
63 if (rx_stats->rs_more)
64 return false;
65
66 /*
67 * The rx_stats->rs_status will not be set until the end of the
68 * chained descriptors so it can be ignored if rs_more is set. The
69 * rs_more will be false at the last element of the chained
70 * descriptors.
71 */
72 if (rx_stats->rs_status != 0) {
73 if (rx_stats->rs_status & ATH9K_RXERR_CRC)
74 rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
75 if (rx_stats->rs_status & ATH9K_RXERR_PHY)
76 return false;
77
78 if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
79 *decrypt_error = true;
80 } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
81 if (ieee80211_is_ctl(fc))
82 /*
83 * Sometimes, we get invalid
84 * MIC failures on valid control frames.
85 * Remove these mic errors.
86 */
87 rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
88 else
89 rxs->flag |= RX_FLAG_MMIC_ERROR;
90 }
91 /*
92 * Reject error frames with the exception of
93 * decryption and MIC failures. For monitor mode,
94 * we also ignore the CRC error.
95 */
96 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
97 if (rx_stats->rs_status &
98 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
99 ATH9K_RXERR_CRC))
100 return false;
101 } else {
102 if (rx_stats->rs_status &
103 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
104 return false;
105 }
106 }
107 }
108 return true;
109}
110
111static int ath9k_process_rate(struct ath_common *common,
112 struct ieee80211_hw *hw,
113 struct ath_rx_status *rx_stats,
114 struct ieee80211_rx_status *rxs,
115 struct sk_buff *skb)
116{
117 struct ieee80211_supported_band *sband;
118 enum ieee80211_band band;
119 unsigned int i = 0;
120
121 band = hw->conf.channel->band;
122 sband = hw->wiphy->bands[band];
123
124 if (rx_stats->rs_rate & 0x80) {
125 /* HT rate */
126 rxs->flag |= RX_FLAG_HT;
127 if (rx_stats->rs_flags & ATH9K_RX_2040)
128 rxs->flag |= RX_FLAG_40MHZ;
129 if (rx_stats->rs_flags & ATH9K_RX_GI)
130 rxs->flag |= RX_FLAG_SHORT_GI;
131 rxs->rate_idx = rx_stats->rs_rate & 0x7f;
132 return 0;
133 }
134
135 for (i = 0; i < sband->n_bitrates; i++) {
136 if (sband->bitrates[i].hw_value == rx_stats->rs_rate) {
137 rxs->rate_idx = i;
138 return 0;
139 }
140 if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
141 rxs->flag |= RX_FLAG_SHORTPRE;
142 rxs->rate_idx = i;
143 return 0;
144 }
145 }
146
147 /*
148 * No valid hardware bitrate found -- we should not get here
149 * because hardware has already validated this frame as OK.
150 */
151 ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
152 "0x%02x using 1 Mbit\n", rx_stats->rs_rate);
153 if ((common->debug_mask & ATH_DBG_XMIT))
154 print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len);
155
156 return -EINVAL;
157}
158
159static void ath9k_process_rssi(struct ath_common *common,
160 struct ieee80211_hw *hw,
161 struct sk_buff *skb,
162 struct ath_rx_status *rx_stats)
163{
164 struct ath_hw *ah = common->ah;
165 struct ieee80211_sta *sta;
166 struct ieee80211_hdr *hdr;
167 struct ath_node *an;
168 int last_rssi = ATH_RSSI_DUMMY_MARKER;
169 __le16 fc;
170
171 hdr = (struct ieee80211_hdr *)skb->data;
172 fc = hdr->frame_control;
173
174 rcu_read_lock();
175 /*
176 * XXX: use ieee80211_find_sta! This requires quite a bit of work
177 * under the current ath9k virtual wiphy implementation as we have
178 * no way of tying a vif to wiphy. Typically vifs are attached to
179 * at least one sdata of a wiphy on mac80211 but with ath9k virtual
180 * wiphy you'd have to iterate over every wiphy and each sdata.
181 */
182 sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
183 if (sta) {
184 an = (struct ath_node *) sta->drv_priv;
185 if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
186 !rx_stats->rs_moreaggr)
187 ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
188 last_rssi = an->last_rssi;
189 }
190 rcu_read_unlock();
191
192 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
193 rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
194 ATH_RSSI_EP_MULTIPLIER);
195 if (rx_stats->rs_rssi < 0)
196 rx_stats->rs_rssi = 0;
197
198 /* Update Beacon RSSI, this is used by ANI. */
199 if (ieee80211_is_beacon(fc))
200 ah->stats.avgbrssi = rx_stats->rs_rssi;
201}
202
203/*
204 * For Decrypt or Demic errors, we only mark packet status here and always push
205 * up the frame up to let mac80211 handle the actual error case, be it no
206 * decryption key or real decryption error. This let us keep statistics there.
207 */
208int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
209 struct ieee80211_hw *hw,
210 struct sk_buff *skb,
211 struct ath_rx_status *rx_stats,
212 struct ieee80211_rx_status *rx_status,
213 bool *decrypt_error)
214{
215 struct ath_hw *ah = common->ah;
216
217 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
218
219 /*
220 * everything but the rate is checked here, the rate check is done
221 * separately to avoid doing two lookups for a rate for each frame.
222 */
223 if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error))
224 return -EINVAL;
225
226 ath9k_process_rssi(common, hw, skb, rx_stats);
227
228 if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb))
229 return -EINVAL;
230
231 rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp);
232 rx_status->band = hw->conf.channel->band;
233 rx_status->freq = hw->conf.channel->center_freq;
234 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
235 rx_status->antenna = rx_stats->rs_antenna;
236 rx_status->flag |= RX_FLAG_TSFT;
237
238 return 0;
239}
240EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess);
241
242void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
243 struct sk_buff *skb,
244 struct ath_rx_status *rx_stats,
245 struct ieee80211_rx_status *rxs,
246 bool decrypt_error)
247{
248 struct ath_hw *ah = common->ah;
249 struct ieee80211_hdr *hdr;
250 int hdrlen, padpos, padsize;
251 u8 keyix;
252 __le16 fc;
253
254 /* see if any padding is done by the hw and remove it */
255 hdr = (struct ieee80211_hdr *) skb->data;
256 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
257 fc = hdr->frame_control;
258 padpos = ath9k_cmn_padpos(hdr->frame_control);
259
260 /* The MAC header is padded to have 32-bit boundary if the
261 * packet payload is non-zero. The general calculation for
262 * padsize would take into account odd header lengths:
263 * padsize = (4 - padpos % 4) % 4; However, since only
264 * even-length headers are used, padding can only be 0 or 2
265 * bytes and we can optimize this a bit. In addition, we must
266 * not try to remove padding from short control frames that do
267 * not have payload. */
268 padsize = padpos & 3;
269 if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
270 memmove(skb->data + padsize, skb->data, padpos);
271 skb_pull(skb, padsize);
272 }
273
274 keyix = rx_stats->rs_keyix;
275
276 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
277 ieee80211_has_protected(fc)) {
278 rxs->flag |= RX_FLAG_DECRYPTED;
279 } else if (ieee80211_has_protected(fc)
280 && !decrypt_error && skb->len >= hdrlen + 4) {
281 keyix = skb->data[hdrlen + 3] >> 6;
282
283 if (test_bit(keyix, common->keymap))
284 rxs->flag |= RX_FLAG_DECRYPTED;
285 }
286 if (ah->sw_mgmt_crypto &&
287 (rxs->flag & RX_FLAG_DECRYPTED) &&
288 ieee80211_is_mgmt(fc))
289 /* Use software decrypt for management frames. */
290 rxs->flag &= ~RX_FLAG_DECRYPTED;
291}
292EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
293
294int ath9k_cmn_padpos(__le16 frame_control) 30int ath9k_cmn_padpos(__le16 frame_control)
295{ 31{
296 int padpos = 24; 32 int padpos = 24;
@@ -475,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
475 return -1; 211 return -1;
476} 212}
477 213
478static int ath_reserve_key_cache_slot(struct ath_common *common) 214static int ath_reserve_key_cache_slot(struct ath_common *common,
215 enum ieee80211_key_alg alg)
479{ 216{
480 int i; 217 int i;
481 218
219 if (alg == ALG_TKIP)
220 return ath_reserve_key_cache_slot_tkip(common);
221
482 /* First, try to find slots that would not be available for TKIP. */ 222 /* First, try to find slots that would not be available for TKIP. */
483 if (common->splitmic) { 223 if (common->splitmic) {
484 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { 224 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
@@ -547,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common,
547 struct ath_hw *ah = common->ah; 287 struct ath_hw *ah = common->ah;
548 struct ath9k_keyval hk; 288 struct ath9k_keyval hk;
549 const u8 *mac = NULL; 289 const u8 *mac = NULL;
290 u8 gmac[ETH_ALEN];
550 int ret = 0; 291 int ret = 0;
551 int idx; 292 int idx;
552 293
@@ -570,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common,
570 memcpy(hk.kv_val, key->key, key->keylen); 311 memcpy(hk.kv_val, key->key, key->keylen);
571 312
572 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { 313 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
573 /* For now, use the default keys for broadcast keys. This may 314 switch (vif->type) {
574 * need to change with virtual interfaces. */ 315 case NL80211_IFTYPE_AP:
575 idx = key->keyidx; 316 memcpy(gmac, vif->addr, ETH_ALEN);
317 gmac[0] |= 0x01;
318 mac = gmac;
319 idx = ath_reserve_key_cache_slot(common, key->alg);
320 break;
321 case NL80211_IFTYPE_ADHOC:
322 memcpy(gmac, sta->addr, ETH_ALEN);
323 gmac[0] |= 0x01;
324 mac = gmac;
325 idx = ath_reserve_key_cache_slot(common, key->alg);
326 break;
327 default:
328 idx = key->keyidx;
329 break;
330 }
576 } else if (key->keyidx) { 331 } else if (key->keyidx) {
577 if (WARN_ON(!sta)) 332 if (WARN_ON(!sta))
578 return -EOPNOTSUPP; 333 return -EOPNOTSUPP;
@@ -589,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common,
589 return -EOPNOTSUPP; 344 return -EOPNOTSUPP;
590 mac = sta->addr; 345 mac = sta->addr;
591 346
592 if (key->alg == ALG_TKIP) 347 idx = ath_reserve_key_cache_slot(common, key->alg);
593 idx = ath_reserve_key_cache_slot_tkip(common);
594 else
595 idx = ath_reserve_key_cache_slot(common);
596 if (idx < 0)
597 return -ENOSPC; /* no free key cache entries */
598 } 348 }
599 349
350 if (idx < 0)
351 return -ENOSPC; /* no free key cache entries */
352
600 if (key->alg == ALG_TKIP) 353 if (key->alg == ALG_TKIP)
601 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, 354 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
602 vif->type == NL80211_IFTYPE_AP); 355 vif->type == NL80211_IFTYPE_AP);
@@ -644,6 +397,19 @@ void ath9k_cmn_key_delete(struct ath_common *common,
644} 397}
645EXPORT_SYMBOL(ath9k_cmn_key_delete); 398EXPORT_SYMBOL(ath9k_cmn_key_delete);
646 399
400int ath9k_cmn_count_streams(unsigned int chainmask, int max)
401{
402 int streams = 0;
403
404 do {
405 if (++streams == max)
406 break;
407 } while ((chainmask = chainmask & (chainmask - 1)));
408
409 return streams;
410}
411EXPORT_SYMBOL(ath9k_cmn_count_streams);
412
647static int __init ath9k_cmn_init(void) 413static int __init ath9k_cmn_init(void)
648{ 414{
649 return 0; 415 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index e08f7e5a26e0..97809d39c73f 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -52,82 +52,6 @@
52#define ATH_EP_RND(x, mul) \ 52#define ATH_EP_RND(x, mul) \
53 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) 53 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
54 54
55struct ath_atx_ac {
56 int sched;
57 int qnum;
58 struct list_head list;
59 struct list_head tid_q;
60};
61
62struct ath_buf_state {
63 int bfs_nframes;
64 u16 bfs_al;
65 u16 bfs_frmlen;
66 int bfs_seqno;
67 int bfs_tidno;
68 int bfs_retries;
69 u8 bf_type;
70 u32 bfs_keyix;
71 enum ath9k_key_type bfs_keytype;
72};
73
74struct ath_buf {
75 struct list_head list;
76 struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
77 an aggregate) */
78 struct ath_buf *bf_next; /* next subframe in the aggregate */
79 struct sk_buff *bf_mpdu; /* enclosing frame structure */
80 void *bf_desc; /* virtual addr of desc */
81 dma_addr_t bf_daddr; /* physical addr of desc */
82 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
83 bool bf_stale;
84 bool bf_isnullfunc;
85 bool bf_tx_aborted;
86 u16 bf_flags;
87 struct ath_buf_state bf_state;
88 dma_addr_t bf_dmacontext;
89 struct ath_wiphy *aphy;
90};
91
92struct ath_atx_tid {
93 struct list_head list;
94 struct list_head buf_q;
95 struct ath_node *an;
96 struct ath_atx_ac *ac;
97 struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
98 u16 seq_start;
99 u16 seq_next;
100 u16 baw_size;
101 int tidno;
102 int baw_head; /* first un-acked tx buffer */
103 int baw_tail; /* next unused tx buffer slot */
104 int sched;
105 int paused;
106 u8 state;
107};
108
109struct ath_node {
110 struct ath_common *common;
111 struct ath_atx_tid tid[WME_NUM_TID];
112 struct ath_atx_ac ac[WME_NUM_AC];
113 u16 maxampdu;
114 u8 mpdudensity;
115 int last_rssi;
116};
117
118int ath9k_cmn_rx_skb_preprocess(struct ath_common *common,
119 struct ieee80211_hw *hw,
120 struct sk_buff *skb,
121 struct ath_rx_status *rx_stats,
122 struct ieee80211_rx_status *rx_status,
123 bool *decrypt_error);
124
125void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
126 struct sk_buff *skb,
127 struct ath_rx_status *rx_stats,
128 struct ieee80211_rx_status *rxs,
129 bool decrypt_error);
130
131int ath9k_cmn_padpos(__le16 frame_control); 55int ath9k_cmn_padpos(__le16 frame_control);
132int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); 56int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
133void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, 57void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
@@ -140,3 +64,4 @@ int ath9k_cmn_key_config(struct ath_common *common,
140 struct ieee80211_key_conf *key); 64 struct ieee80211_key_conf *key);
141void ath9k_cmn_key_delete(struct ath_common *common, 65void ath9k_cmn_key_delete(struct ath_common *common,
142 struct ieee80211_key_conf *key); 66 struct ieee80211_key_conf *key);
67int ath9k_cmn_count_streams(unsigned int chainmask, int max);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 29898f8d1893..54aae931424e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -42,7 +42,7 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
42 char buf[32]; 42 char buf[32];
43 unsigned int len; 43 unsigned int len;
44 44
45 len = snprintf(buf, sizeof(buf), "0x%08x\n", common->debug_mask); 45 len = sprintf(buf, "0x%08x\n", common->debug_mask);
46 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 46 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
47} 47}
48 48
@@ -57,7 +57,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
57 57
58 len = min(count, sizeof(buf) - 1); 58 len = min(count, sizeof(buf) - 1);
59 if (copy_from_user(buf, user_buf, len)) 59 if (copy_from_user(buf, user_buf, len))
60 return -EINVAL; 60 return -EFAULT;
61 61
62 buf[len] = '\0'; 62 buf[len] = '\0';
63 if (strict_strtoul(buf, 0, &mask)) 63 if (strict_strtoul(buf, 0, &mask))
@@ -86,7 +86,7 @@ static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf,
86 char buf[32]; 86 char buf[32];
87 unsigned int len; 87 unsigned int len;
88 88
89 len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask); 89 len = sprintf(buf, "0x%08x\n", common->tx_chainmask);
90 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 90 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
91} 91}
92 92
@@ -101,7 +101,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use
101 101
102 len = min(count, sizeof(buf) - 1); 102 len = min(count, sizeof(buf) - 1);
103 if (copy_from_user(buf, user_buf, len)) 103 if (copy_from_user(buf, user_buf, len))
104 return -EINVAL; 104 return -EFAULT;
105 105
106 buf[len] = '\0'; 106 buf[len] = '\0';
107 if (strict_strtoul(buf, 0, &mask)) 107 if (strict_strtoul(buf, 0, &mask))
@@ -128,7 +128,7 @@ static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
128 char buf[32]; 128 char buf[32];
129 unsigned int len; 129 unsigned int len;
130 130
131 len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask); 131 len = sprintf(buf, "0x%08x\n", common->rx_chainmask);
132 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 132 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
133} 133}
134 134
@@ -143,7 +143,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use
143 143
144 len = min(count, sizeof(buf) - 1); 144 len = min(count, sizeof(buf) - 1);
145 if (copy_from_user(buf, user_buf, len)) 145 if (copy_from_user(buf, user_buf, len))
146 return -EINVAL; 146 return -EFAULT;
147 147
148 buf[len] = '\0'; 148 buf[len] = '\0';
149 if (strict_strtoul(buf, 0, &mask)) 149 if (strict_strtoul(buf, 0, &mask))
@@ -176,7 +176,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
176 176
177 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL); 177 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
178 if (!buf) 178 if (!buf)
179 return 0; 179 return -ENOMEM;
180 180
181 ath9k_ps_wakeup(sc); 181 ath9k_ps_wakeup(sc);
182 182
@@ -248,6 +248,9 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
248 248
249 ath9k_ps_restore(sc); 249 ath9k_ps_restore(sc);
250 250
251 if (len > DMA_BUF_LEN)
252 len = DMA_BUF_LEN;
253
251 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 254 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
252 kfree(buf); 255 kfree(buf);
253 return retval; 256 return retval;
@@ -269,6 +272,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
269 sc->debug.stats.istats.rxlp++; 272 sc->debug.stats.istats.rxlp++;
270 if (status & ATH9K_INT_RXHP) 273 if (status & ATH9K_INT_RXHP)
271 sc->debug.stats.istats.rxhp++; 274 sc->debug.stats.istats.rxhp++;
275 if (status & ATH9K_INT_BB_WATCHDOG)
276 sc->debug.stats.istats.bb_watchdog++;
272 } else { 277 } else {
273 if (status & ATH9K_INT_RX) 278 if (status & ATH9K_INT_RX)
274 sc->debug.stats.istats.rxok++; 279 sc->debug.stats.istats.rxok++;
@@ -319,6 +324,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
319 "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); 324 "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
320 len += snprintf(buf + len, sizeof(buf) - len, 325 len += snprintf(buf + len, sizeof(buf) - len,
321 "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp); 326 "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
327 len += snprintf(buf + len, sizeof(buf) - len,
328 "%8s: %10u\n", "WATCHDOG",
329 sc->debug.stats.istats.bb_watchdog);
322 } else { 330 } else {
323 len += snprintf(buf + len, sizeof(buf) - len, 331 len += snprintf(buf + len, sizeof(buf) - len,
324 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); 332 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
@@ -358,6 +366,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
358 len += snprintf(buf + len, sizeof(buf) - len, 366 len += snprintf(buf + len, sizeof(buf) - len,
359 "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); 367 "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
360 368
369 if (len > sizeof(buf))
370 len = sizeof(buf);
371
361 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 372 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
362} 373}
363 374
@@ -397,11 +408,10 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
397 if (sc->cur_rate_table == NULL) 408 if (sc->cur_rate_table == NULL)
398 return 0; 409 return 0;
399 410
400 max = 80 + sc->cur_rate_table->rate_cnt * 1024; 411 max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
401 buf = kmalloc(max + 1, GFP_KERNEL); 412 buf = kmalloc(max, GFP_KERNEL);
402 if (buf == NULL) 413 if (buf == NULL)
403 return 0; 414 return -ENOMEM;
404 buf[max] = 0;
405 415
406 len += sprintf(buf, "%6s %6s %6s " 416 len += sprintf(buf, "%6s %6s %6s "
407 "%10s %10s %10s %10s\n", 417 "%10s %10s %10s %10s\n",
@@ -443,6 +453,9 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
443 stats->per); 453 stats->per);
444 } 454 }
445 455
456 if (len > max)
457 len = max;
458
446 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 459 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
447 kfree(buf); 460 kfree(buf);
448 return retval; 461 return retval;
@@ -505,6 +518,9 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
505 len += snprintf(buf + len, sizeof(buf) - len, 518 len += snprintf(buf + len, sizeof(buf) - len,
506 "addrmask: %pM\n", addr); 519 "addrmask: %pM\n", addr);
507 520
521 if (len > sizeof(buf))
522 len = sizeof(buf);
523
508 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 524 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
509} 525}
510 526
@@ -614,10 +630,10 @@ static const struct file_operations fops_wiphy = {
614 do { \ 630 do { \
615 len += snprintf(buf + len, size - len, \ 631 len += snprintf(buf + len, size - len, \
616 "%s%13u%11u%10u%10u\n", str, \ 632 "%s%13u%11u%10u%10u\n", str, \
617 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \ 633 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \
618 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \ 634 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \
619 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \ 635 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \
620 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \ 636 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \
621} while(0) 637} while(0)
622 638
623static ssize_t read_file_xmit(struct file *file, char __user *user_buf, 639static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
@@ -630,7 +646,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
630 646
631 buf = kzalloc(size, GFP_KERNEL); 647 buf = kzalloc(size, GFP_KERNEL);
632 if (buf == NULL) 648 if (buf == NULL)
633 return 0; 649 return -ENOMEM;
634 650
635 len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO"); 651 len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO");
636 652
@@ -648,6 +664,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
648 PR("DATA Underrun: ", data_underrun); 664 PR("DATA Underrun: ", data_underrun);
649 PR("DELIM Underrun: ", delim_underrun); 665 PR("DELIM Underrun: ", delim_underrun);
650 666
667 if (len > size)
668 len = size;
669
651 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 670 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
652 kfree(buf); 671 kfree(buf);
653 672
@@ -700,7 +719,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
700 719
701 buf = kzalloc(size, GFP_KERNEL); 720 buf = kzalloc(size, GFP_KERNEL);
702 if (buf == NULL) 721 if (buf == NULL)
703 return 0; 722 return -ENOMEM;
704 723
705 len += snprintf(buf + len, size - len, 724 len += snprintf(buf + len, size - len,
706 "%18s : %10u\n", "CRC ERR", 725 "%18s : %10u\n", "CRC ERR",
@@ -751,6 +770,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
751 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); 770 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
752 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); 771 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
753 772
773 if (len > size)
774 len = size;
775
754 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 776 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
755 kfree(buf); 777 kfree(buf);
756 778
@@ -802,7 +824,7 @@ static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
802 char buf[32]; 824 char buf[32];
803 unsigned int len; 825 unsigned int len;
804 826
805 len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx); 827 len = sprintf(buf, "0x%08x\n", sc->debug.regidx);
806 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 828 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
807} 829}
808 830
@@ -816,7 +838,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
816 838
817 len = min(count, sizeof(buf) - 1); 839 len = min(count, sizeof(buf) - 1);
818 if (copy_from_user(buf, user_buf, len)) 840 if (copy_from_user(buf, user_buf, len))
819 return -EINVAL; 841 return -EFAULT;
820 842
821 buf[len] = '\0'; 843 buf[len] = '\0';
822 if (strict_strtoul(buf, 0, &regidx)) 844 if (strict_strtoul(buf, 0, &regidx))
@@ -843,7 +865,7 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf,
843 u32 regval; 865 u32 regval;
844 866
845 regval = REG_READ_D(ah, sc->debug.regidx); 867 regval = REG_READ_D(ah, sc->debug.regidx);
846 len = snprintf(buf, sizeof(buf), "0x%08x\n", regval); 868 len = sprintf(buf, "0x%08x\n", regval);
847 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 869 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
848} 870}
849 871
@@ -858,7 +880,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
858 880
859 len = min(count, sizeof(buf) - 1); 881 len = min(count, sizeof(buf) - 1);
860 if (copy_from_user(buf, user_buf, len)) 882 if (copy_from_user(buf, user_buf, len))
861 return -EINVAL; 883 return -EFAULT;
862 884
863 buf[len] = '\0'; 885 buf[len] = '\0';
864 if (strict_strtoul(buf, 0, &regval)) 886 if (strict_strtoul(buf, 0, &regval))
@@ -934,6 +956,10 @@ int ath9k_init_debug(struct ath_hw *ah)
934 sc->debug.debugfs_phy, sc, &fops_regval)) 956 sc->debug.debugfs_phy, sc, &fops_regval))
935 goto err; 957 goto err;
936 958
959 if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
960 sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
961 goto err;
962
937 sc->debug.regidx = 0; 963 sc->debug.regidx = 0;
938 return 0; 964 return 0;
939err: 965err:
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 5147b8709e10..5d21704e87ff 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -53,6 +53,7 @@ struct ath_buf;
53 * @cabend: RX End of CAB traffic 53 * @cabend: RX End of CAB traffic
54 * @dtimsync: DTIM sync lossage 54 * @dtimsync: DTIM sync lossage
55 * @dtim: RX Beacon with DTIM 55 * @dtim: RX Beacon with DTIM
56 * @bb_watchdog: Baseband watchdog
56 */ 57 */
57struct ath_interrupt_stats { 58struct ath_interrupt_stats {
58 u32 total; 59 u32 total;
@@ -76,6 +77,7 @@ struct ath_interrupt_stats {
76 u32 cabend; 77 u32 cabend;
77 u32 dtimsync; 78 u32 dtimsync;
78 u32 dtim; 79 u32 dtim;
80 u32 bb_watchdog;
79}; 81};
80 82
81struct ath_rc_stats { 83struct ath_rc_stats {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index ca8704a9d7ac..1266333f586d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -24,6 +24,14 @@ static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
24 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 24 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
25} 25}
26 26
27void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
28{
29 REG_WRITE(ah, reg, val);
30
31 if (ah->config.analog_shiftreg)
32 udelay(100);
33}
34
27void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, 35void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
28 u32 shift, u32 val) 36 u32 shift, u32 val)
29{ 37{
@@ -250,6 +258,27 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
250 return twiceMaxEdgePower; 258 return twiceMaxEdgePower;
251} 259}
252 260
261void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
262{
263 struct ath_common *common = ath9k_hw_common(ah);
264 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
265
266 switch (ar5416_get_ntxchains(ah->txchainmask)) {
267 case 1:
268 break;
269 case 2:
270 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
271 break;
272 case 3:
273 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
274 break;
275 default:
276 ath_print(common, ATH_DBG_EEPROM,
277 "Invalid chainmask configuration\n");
278 break;
279 }
280}
281
253int ath9k_hw_eeprom_init(struct ath_hw *ah) 282int ath9k_hw_eeprom_init(struct ath_hw *ah)
254{ 283{
255 int status; 284 int status;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 21354c15a9a9..bdd8aa054b80 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -263,7 +263,8 @@ enum eeprom_param {
263 EEP_PWR_TABLE_OFFSET, 263 EEP_PWR_TABLE_OFFSET,
264 EEP_DRIVE_STRENGTH, 264 EEP_DRIVE_STRENGTH,
265 EEP_INTERNAL_REGULATOR, 265 EEP_INTERNAL_REGULATOR,
266 EEP_SWREG 266 EEP_SWREG,
267 EEP_PAPRD,
267}; 268};
268 269
269enum ar5416_rates { 270enum ar5416_rates {
@@ -679,6 +680,7 @@ struct eeprom_ops {
679 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); 680 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
680}; 681};
681 682
683void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val);
682void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, 684void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
683 u32 shift, u32 val); 685 u32 shift, u32 val);
684int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, 686int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
@@ -704,6 +706,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah,
704 u16 numRates, bool isHt40Target); 706 u16 numRates, bool isHt40Target);
705u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, 707u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
706 bool is2GHz, int num_band_edges); 708 bool is2GHz, int num_band_edges);
709void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
707int ath9k_hw_eeprom_init(struct ath_hw *ah); 710int ath9k_hw_eeprom_init(struct ath_hw *ah);
708 711
709#define ar5416_get_ntxchains(_txchainmask) \ 712#define ar5416_get_ntxchains(_txchainmask) \
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 41a77d1bd439..e25a2abbf561 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -249,6 +249,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
249 struct chan_centers centers; 249 struct chan_centers centers;
250#define PD_GAIN_BOUNDARY_DEFAULT 58; 250#define PD_GAIN_BOUNDARY_DEFAULT 58;
251 251
252 memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
252 ath9k_hw_get_channel_centers(ah, chan, &centers); 253 ath9k_hw_get_channel_centers(ah, chan, &centers);
253 254
254 for (numPiers = 0; numPiers < availPiers; numPiers++) { 255 for (numPiers = 0; numPiers < availPiers; numPiers++) {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index b471db5fb82d..39a41053705f 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -17,17 +17,19 @@
17#include "hw.h" 17#include "hw.h"
18#include "ar9002_phy.h" 18#include "ar9002_phy.h"
19 19
20static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) 20#define NUM_EEP_WORDS (sizeof(struct ar9287_eeprom) / sizeof(u16))
21
22static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah)
21{ 23{
22 return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; 24 return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
23} 25}
24 26
25static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah) 27static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah)
26{ 28{
27 return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; 29 return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
28} 30}
29 31
30static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) 32static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
31{ 33{
32 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 34 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
33 struct ath_common *common = ath9k_hw_common(ah); 35 struct ath_common *common = ath9k_hw_common(ah);
@@ -40,20 +42,20 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
40 "Reading from EEPROM, not flash\n"); 42 "Reading from EEPROM, not flash\n");
41 } 43 }
42 44
43 for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16); 45 for (addr = 0; addr < NUM_EEP_WORDS; addr++) {
44 addr++) { 46 if (!ath9k_hw_nvram_read(common, addr + eep_start_loc,
45 if (!ath9k_hw_nvram_read(common, 47 eep_data)) {
46 addr + eep_start_loc, eep_data)) {
47 ath_print(common, ATH_DBG_EEPROM, 48 ath_print(common, ATH_DBG_EEPROM,
48 "Unable to read eeprom region\n"); 49 "Unable to read eeprom region\n");
49 return false; 50 return false;
50 } 51 }
51 eep_data++; 52 eep_data++;
52 } 53 }
54
53 return true; 55 return true;
54} 56}
55 57
56static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) 58static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
57{ 59{
58 u32 sum = 0, el, integer; 60 u32 sum = 0, el, integer;
59 u16 temp, word, magic, magic2, *eepdata; 61 u16 temp, word, magic, magic2, *eepdata;
@@ -63,8 +65,8 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
63 struct ath_common *common = ath9k_hw_common(ah); 65 struct ath_common *common = ath9k_hw_common(ah);
64 66
65 if (!ath9k_hw_use_flash(ah)) { 67 if (!ath9k_hw_use_flash(ah)) {
66 if (!ath9k_hw_nvram_read(common, 68 if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET,
67 AR5416_EEPROM_MAGIC_OFFSET, &magic)) { 69 &magic)) {
68 ath_print(common, ATH_DBG_FATAL, 70 ath_print(common, ATH_DBG_FATAL,
69 "Reading Magic # failed\n"); 71 "Reading Magic # failed\n");
70 return false; 72 return false;
@@ -72,6 +74,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
72 74
73 ath_print(common, ATH_DBG_EEPROM, 75 ath_print(common, ATH_DBG_EEPROM,
74 "Read Magic = 0x%04X\n", magic); 76 "Read Magic = 0x%04X\n", magic);
77
75 if (magic != AR5416_EEPROM_MAGIC) { 78 if (magic != AR5416_EEPROM_MAGIC) {
76 magic2 = swab16(magic); 79 magic2 = swab16(magic);
77 80
@@ -79,9 +82,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
79 need_swap = true; 82 need_swap = true;
80 eepdata = (u16 *)(&ah->eeprom); 83 eepdata = (u16 *)(&ah->eeprom);
81 84
82 for (addr = 0; 85 for (addr = 0; addr < NUM_EEP_WORDS; addr++) {
83 addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
84 addr++) {
85 temp = swab16(*eepdata); 86 temp = swab16(*eepdata);
86 *eepdata = temp; 87 *eepdata = temp;
87 eepdata++; 88 eepdata++;
@@ -89,13 +90,14 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
89 } else { 90 } else {
90 ath_print(common, ATH_DBG_FATAL, 91 ath_print(common, ATH_DBG_FATAL,
91 "Invalid EEPROM Magic. " 92 "Invalid EEPROM Magic. "
92 "endianness mismatch.\n"); 93 "Endianness mismatch.\n");
93 return -EINVAL; 94 return -EINVAL;
94 } 95 }
95 } 96 }
96 } 97 }
97 ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ? 98
98 "True" : "False"); 99 ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n",
100 need_swap ? "True" : "False");
99 101
100 if (need_swap) 102 if (need_swap)
101 el = swab16(ah->eeprom.map9287.baseEepHeader.length); 103 el = swab16(ah->eeprom.map9287.baseEepHeader.length);
@@ -108,6 +110,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
108 el = el / sizeof(u16); 110 el = el / sizeof(u16);
109 111
110 eepdata = (u16 *)(&ah->eeprom); 112 eepdata = (u16 *)(&ah->eeprom);
113
111 for (i = 0; i < el; i++) 114 for (i = 0; i < el; i++)
112 sum ^= *eepdata++; 115 sum ^= *eepdata++;
113 116
@@ -161,7 +164,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
161 return 0; 164 return 0;
162} 165}
163 166
164static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, 167static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
165 enum eeprom_param param) 168 enum eeprom_param param)
166{ 169{
167 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 170 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
@@ -170,6 +173,7 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
170 u16 ver_minor; 173 u16 ver_minor;
171 174
172 ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK; 175 ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
176
173 switch (param) { 177 switch (param) {
174 case EEP_NFTHRESH_2: 178 case EEP_NFTHRESH_2:
175 return pModal->noiseFloorThreshCh[0]; 179 return pModal->noiseFloorThreshCh[0];
@@ -214,29 +218,30 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
214 } 218 }
215} 219}
216 220
217 221static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah,
218static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, 222 struct ath9k_channel *chan,
219 struct ath9k_channel *chan, 223 struct cal_data_per_freq_ar9287 *pRawDataSet,
220 struct cal_data_per_freq_ar9287 *pRawDataSet, 224 u8 *bChans, u16 availPiers,
221 u8 *bChans, u16 availPiers, 225 u16 tPdGainOverlap,
222 u16 tPdGainOverlap, int16_t *pMinCalPower, 226 int16_t *pMinCalPower,
223 u16 *pPdGainBoundaries, u8 *pPDADCValues, 227 u16 *pPdGainBoundaries,
224 u16 numXpdGains) 228 u8 *pPDADCValues,
229 u16 numXpdGains)
225{ 230{
226#define TMP_VAL_VPD_TABLE \ 231#define TMP_VAL_VPD_TABLE \
227 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); 232 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
228 233
229 int i, j, k; 234 int i, j, k;
230 int16_t ss; 235 int16_t ss;
231 u16 idxL = 0, idxR = 0, numPiers; 236 u16 idxL = 0, idxR = 0, numPiers;
232 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; 237 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
233 u8 minPwrT4[AR9287_NUM_PD_GAINS]; 238 u8 minPwrT4[AR9287_NUM_PD_GAINS];
234 u8 maxPwrT4[AR9287_NUM_PD_GAINS]; 239 u8 maxPwrT4[AR9287_NUM_PD_GAINS];
235 int16_t vpdStep; 240 int16_t vpdStep;
236 int16_t tmpVal; 241 int16_t tmpVal;
237 u16 sizeCurrVpdTable, maxIndex, tgtIndex; 242 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
238 bool match; 243 bool match;
239 int16_t minDelta = 0; 244 int16_t minDelta = 0;
240 struct chan_centers centers; 245 struct chan_centers centers;
241 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] 246 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
242 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 247 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
@@ -245,6 +250,7 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
245 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] 250 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
246 [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 251 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
247 252
253 memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
248 ath9k_hw_get_channel_centers(ah, chan, &centers); 254 ath9k_hw_get_channel_centers(ah, chan, &centers);
249 255
250 for (numPiers = 0; numPiers < availPiers; numPiers++) { 256 for (numPiers = 0; numPiers < availPiers; numPiers++) {
@@ -253,18 +259,18 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
253 } 259 }
254 260
255 match = ath9k_hw_get_lower_upper_index( 261 match = ath9k_hw_get_lower_upper_index(
256 (u8)FREQ2FBIN(centers.synth_center, 262 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
257 IS_CHAN_2GHZ(chan)), bChans, numPiers, 263 bChans, numPiers, &idxL, &idxR);
258 &idxL, &idxR);
259 264
260 if (match) { 265 if (match) {
261 for (i = 0; i < numXpdGains; i++) { 266 for (i = 0; i < numXpdGains; i++) {
262 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 267 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
263 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 268 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
264 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 269 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
265 pRawDataSet[idxL].pwrPdg[i], 270 pRawDataSet[idxL].pwrPdg[i],
266 pRawDataSet[idxL].vpdPdg[i], 271 pRawDataSet[idxL].vpdPdg[i],
267 AR9287_PD_GAIN_ICEPTS, vpdTableI[i]); 272 AR9287_PD_GAIN_ICEPTS,
273 vpdTableI[i]);
268 } 274 }
269 } else { 275 } else {
270 for (i = 0; i < numXpdGains; i++) { 276 for (i = 0; i < numXpdGains; i++) {
@@ -275,61 +281,59 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
275 281
276 minPwrT4[i] = max(pPwrL[0], pPwrR[0]); 282 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
277 283
278 maxPwrT4[i] = 284 maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
279 min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], 285 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
280 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
281 286
282 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 287 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
283 pPwrL, pVpdL, 288 pPwrL, pVpdL,
284 AR9287_PD_GAIN_ICEPTS, 289 AR9287_PD_GAIN_ICEPTS,
285 vpdTableL[i]); 290 vpdTableL[i]);
286 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], 291 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
287 pPwrR, pVpdR, 292 pPwrR, pVpdR,
288 AR9287_PD_GAIN_ICEPTS, 293 AR9287_PD_GAIN_ICEPTS,
289 vpdTableR[i]); 294 vpdTableR[i]);
290 295
291 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 296 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
292 vpdTableI[i][j] = 297 vpdTableI[i][j] = (u8)(ath9k_hw_interpolate(
293 (u8)(ath9k_hw_interpolate((u16) 298 (u16)FREQ2FBIN(centers. synth_center,
294 FREQ2FBIN(centers. synth_center, 299 IS_CHAN_2GHZ(chan)),
295 IS_CHAN_2GHZ(chan)), 300 bChans[idxL], bChans[idxR],
296 bChans[idxL], bChans[idxR], 301 vpdTableL[i][j], vpdTableR[i][j]));
297 vpdTableL[i][j], vpdTableR[i][j]));
298 } 302 }
299 } 303 }
300 } 304 }
301 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
302 305
306 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
303 k = 0; 307 k = 0;
308
304 for (i = 0; i < numXpdGains; i++) { 309 for (i = 0; i < numXpdGains; i++) {
305 if (i == (numXpdGains - 1)) 310 if (i == (numXpdGains - 1))
306 pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2); 311 pPdGainBoundaries[i] =
312 (u16)(maxPwrT4[i] / 2);
307 else 313 else
308 pPdGainBoundaries[i] = (u16)((maxPwrT4[i] + 314 pPdGainBoundaries[i] =
309 minPwrT4[i+1]) / 4); 315 (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
310 316
311 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER, 317 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
312 pPdGainBoundaries[i]); 318 pPdGainBoundaries[i]);
313 319
314 320
315 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { 321 minDelta = 0;
316 minDelta = pPdGainBoundaries[0] - 23;
317 pPdGainBoundaries[0] = 23;
318 } else
319 minDelta = 0;
320 322
321 if (i == 0) { 323 if (i == 0) {
322 if (AR_SREV_9280_10_OR_LATER(ah)) 324 if (AR_SREV_9280_10_OR_LATER(ah))
323 ss = (int16_t)(0 - (minPwrT4[i] / 2)); 325 ss = (int16_t)(0 - (minPwrT4[i] / 2));
324 else 326 else
325 ss = 0; 327 ss = 0;
326 } else 328 } else {
327 ss = (int16_t)((pPdGainBoundaries[i-1] - 329 ss = (int16_t)((pPdGainBoundaries[i-1] -
328 (minPwrT4[i] / 2)) - 330 (minPwrT4[i] / 2)) -
329 tPdGainOverlap + 1 + minDelta); 331 tPdGainOverlap + 1 + minDelta);
332 }
330 333
331 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 334 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
332 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 335 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
336
333 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { 337 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
334 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 338 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
335 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); 339 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
@@ -348,12 +352,13 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
348 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - 352 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
349 vpdTableI[i][sizeCurrVpdTable - 2]); 353 vpdTableI[i][sizeCurrVpdTable - 2]);
350 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 354 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
355
351 if (tgtIndex > maxIndex) { 356 if (tgtIndex > maxIndex) {
352 while ((ss <= tgtIndex) && 357 while ((ss <= tgtIndex) &&
353 (k < (AR9287_NUM_PDADC_VALUES - 1))) { 358 (k < (AR9287_NUM_PDADC_VALUES - 1))) {
354 tmpVal = (int16_t) TMP_VAL_VPD_TABLE; 359 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
355 pPDADCValues[k++] = (u8)((tmpVal > 255) ? 360 pPDADCValues[k++] =
356 255 : tmpVal); 361 (u8)((tmpVal > 255) ? 255 : tmpVal);
357 ss++; 362 ss++;
358 } 363 }
359 } 364 }
@@ -375,10 +380,9 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
375static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, 380static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
376 struct ath9k_channel *chan, 381 struct ath9k_channel *chan,
377 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, 382 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
378 u8 *pCalChans, u16 availPiers, 383 u8 *pCalChans, u16 availPiers, int8_t *pPwr)
379 int8_t *pPwr)
380{ 384{
381 u16 idxL = 0, idxR = 0, numPiers; 385 u16 idxL = 0, idxR = 0, numPiers;
382 bool match; 386 bool match;
383 struct chan_centers centers; 387 struct chan_centers centers;
384 388
@@ -390,15 +394,14 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
390 } 394 }
391 395
392 match = ath9k_hw_get_lower_upper_index( 396 match = ath9k_hw_get_lower_upper_index(
393 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), 397 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
394 pCalChans, numPiers, 398 pCalChans, numPiers, &idxL, &idxR);
395 &idxL, &idxR);
396 399
397 if (match) { 400 if (match) {
398 *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0]; 401 *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
399 } else { 402 } else {
400 *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] + 403 *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
401 (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; 404 (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
402 } 405 }
403 406
404} 407}
@@ -409,16 +412,22 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
409 u32 tmpVal; 412 u32 tmpVal;
410 u32 a; 413 u32 a;
411 414
415 /* Enable OLPC for chain 0 */
416
412 tmpVal = REG_READ(ah, 0xa270); 417 tmpVal = REG_READ(ah, 0xa270);
413 tmpVal = tmpVal & 0xFCFFFFFF; 418 tmpVal = tmpVal & 0xFCFFFFFF;
414 tmpVal = tmpVal | (0x3 << 24); 419 tmpVal = tmpVal | (0x3 << 24);
415 REG_WRITE(ah, 0xa270, tmpVal); 420 REG_WRITE(ah, 0xa270, tmpVal);
416 421
422 /* Enable OLPC for chain 1 */
423
417 tmpVal = REG_READ(ah, 0xb270); 424 tmpVal = REG_READ(ah, 0xb270);
418 tmpVal = tmpVal & 0xFCFFFFFF; 425 tmpVal = tmpVal & 0xFCFFFFFF;
419 tmpVal = tmpVal | (0x3 << 24); 426 tmpVal = tmpVal | (0x3 << 24);
420 REG_WRITE(ah, 0xb270, tmpVal); 427 REG_WRITE(ah, 0xb270, tmpVal);
421 428
429 /* Write the OLPC ref power for chain 0 */
430
422 if (chain == 0) { 431 if (chain == 0) {
423 tmpVal = REG_READ(ah, 0xa398); 432 tmpVal = REG_READ(ah, 0xa398);
424 tmpVal = tmpVal & 0xff00ffff; 433 tmpVal = tmpVal & 0xff00ffff;
@@ -427,6 +436,8 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
427 REG_WRITE(ah, 0xa398, tmpVal); 436 REG_WRITE(ah, 0xa398, tmpVal);
428 } 437 }
429 438
439 /* Write the OLPC ref power for chain 1 */
440
430 if (chain == 1) { 441 if (chain == 1) {
431 tmpVal = REG_READ(ah, 0xb398); 442 tmpVal = REG_READ(ah, 0xb398);
432 tmpVal = tmpVal & 0xff00ffff; 443 tmpVal = tmpVal & 0xff00ffff;
@@ -436,28 +447,29 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
436 } 447 }
437} 448}
438 449
439static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, 450static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
440 struct ath9k_channel *chan, 451 struct ath9k_channel *chan,
441 int16_t *pTxPowerIndexOffset) 452 int16_t *pTxPowerIndexOffset)
442{ 453{
443 struct ath_common *common = ath9k_hw_common(ah);
444 struct cal_data_per_freq_ar9287 *pRawDataset; 454 struct cal_data_per_freq_ar9287 *pRawDataset;
445 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; 455 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
446 u8 *pCalBChans = NULL; 456 u8 *pCalBChans = NULL;
447 u16 pdGainOverlap_t2; 457 u16 pdGainOverlap_t2;
448 u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; 458 u8 pdadcValues[AR9287_NUM_PDADC_VALUES];
449 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; 459 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
450 u16 numPiers = 0, i, j; 460 u16 numPiers = 0, i, j;
451 int16_t tMinCalPower; 461 int16_t tMinCalPower;
452 u16 numXpdGain, xpdMask; 462 u16 numXpdGain, xpdMask;
453 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; 463 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
454 u32 reg32, regOffset, regChainOffset; 464 u32 reg32, regOffset, regChainOffset, regval;
455 int16_t modalIdx, diff = 0; 465 int16_t modalIdx, diff = 0;
456 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 466 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
467
457 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; 468 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
458 xpdMask = pEepData->modalHeader.xpdGain; 469 xpdMask = pEepData->modalHeader.xpdGain;
470
459 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= 471 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
460 AR9287_EEP_MINOR_VER_2) 472 AR9287_EEP_MINOR_VER_2)
461 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; 473 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
462 else 474 else
463 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), 475 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
@@ -466,15 +478,16 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
466 if (IS_CHAN_2GHZ(chan)) { 478 if (IS_CHAN_2GHZ(chan)) {
467 pCalBChans = pEepData->calFreqPier2G; 479 pCalBChans = pEepData->calFreqPier2G;
468 numPiers = AR9287_NUM_2G_CAL_PIERS; 480 numPiers = AR9287_NUM_2G_CAL_PIERS;
469 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 481 if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
470 pRawDatasetOpenLoop = 482 pRawDatasetOpenLoop =
471 (struct cal_data_op_loop_ar9287 *) 483 (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0];
472 pEepData->calPierData2G[0];
473 ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0]; 484 ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
474 } 485 }
475 } 486 }
476 487
477 numXpdGain = 0; 488 numXpdGain = 0;
489
490 /* Calculate the value of xpdgains from the xpdGain Mask */
478 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { 491 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
479 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { 492 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
480 if (numXpdGain >= AR9287_NUM_PD_GAINS) 493 if (numXpdGain >= AR9287_NUM_PD_GAINS)
@@ -496,99 +509,80 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
496 509
497 for (i = 0; i < AR9287_MAX_CHAINS; i++) { 510 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
498 regChainOffset = i * 0x1000; 511 regChainOffset = i * 0x1000;
512
499 if (pEepData->baseEepHeader.txMask & (1 << i)) { 513 if (pEepData->baseEepHeader.txMask & (1 << i)) {
500 pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *) 514 pRawDatasetOpenLoop =
501 pEepData->calPierData2G[i]; 515 (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i];
502 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 516
517 if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
503 int8_t txPower; 518 int8_t txPower;
504 ar9287_eeprom_get_tx_gain_index(ah, chan, 519 ar9287_eeprom_get_tx_gain_index(ah, chan,
505 pRawDatasetOpenLoop, 520 pRawDatasetOpenLoop,
506 pCalBChans, numPiers, 521 pCalBChans, numPiers,
507 &txPower); 522 &txPower);
508 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i); 523 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
509 } else { 524 } else {
510 pRawDataset = 525 pRawDataset =
511 (struct cal_data_per_freq_ar9287 *) 526 (struct cal_data_per_freq_ar9287 *)
512 pEepData->calPierData2G[i]; 527 pEepData->calPierData2G[i];
513 ath9k_hw_get_AR9287_gain_boundaries_pdadcs( 528
514 ah, chan, pRawDataset, 529 ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan,
515 pCalBChans, numPiers, 530 pRawDataset,
516 pdGainOverlap_t2, 531 pCalBChans, numPiers,
517 &tMinCalPower, gainBoundaries, 532 pdGainOverlap_t2,
518 pdadcValues, numXpdGain); 533 &tMinCalPower,
534 gainBoundaries,
535 pdadcValues,
536 numXpdGain);
519 } 537 }
520 538
521 if (i == 0) { 539 if (i == 0) {
522 if (!ath9k_hw_AR9287_get_eeprom( 540 if (!ath9k_hw_ar9287_get_eeprom(ah,
523 ah, EEP_OL_PWRCTRL)) { 541 EEP_OL_PWRCTRL)) {
524 REG_WRITE(ah, AR_PHY_TPCRG5 + 542
525 regChainOffset, 543 regval = SM(pdGainOverlap_t2,
526 SM(pdGainOverlap_t2, 544 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
527 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 545 | SM(gainBoundaries[0],
528 SM(gainBoundaries[0], 546 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
529 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) 547 | SM(gainBoundaries[1],
530 | SM(gainBoundaries[1], 548 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
531 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) 549 | SM(gainBoundaries[2],
532 | SM(gainBoundaries[2], 550 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
533 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) 551 | SM(gainBoundaries[3],
534 | SM(gainBoundaries[3], 552 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4);
535 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 553
554 REG_WRITE(ah,
555 AR_PHY_TPCRG5 + regChainOffset,
556 regval);
536 } 557 }
537 } 558 }
538 559
539 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB != 560 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB !=
540 pEepData->baseEepHeader.pwrTableOffset) { 561 pEepData->baseEepHeader.pwrTableOffset) {
541 diff = (u16) 562 diff = (u16)(pEepData->baseEepHeader.pwrTableOffset -
542 (pEepData->baseEepHeader.pwrTableOffset 563 (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
543 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
544 diff *= 2; 564 diff *= 2;
545 565
546 for (j = 0; 566 for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++)
547 j < ((u16)AR9287_NUM_PDADC_VALUES-diff);
548 j++)
549 pdadcValues[j] = pdadcValues[j+diff]; 567 pdadcValues[j] = pdadcValues[j+diff];
550 568
551 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); 569 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
552 j < AR9287_NUM_PDADC_VALUES; j++) 570 j < AR9287_NUM_PDADC_VALUES; j++)
553 pdadcValues[j] = 571 pdadcValues[j] =
554 pdadcValues[ 572 pdadcValues[AR9287_NUM_PDADC_VALUES-diff];
555 AR9287_NUM_PDADC_VALUES-diff];
556 } 573 }
557 574
558 if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 575 if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
559 regOffset = AR_PHY_BASE + (672 << 2) + 576 regOffset = AR_PHY_BASE +
560 regChainOffset; 577 (672 << 2) + regChainOffset;
561 for (j = 0; j < 32; j++) {
562 reg32 = ((pdadcValues[4*j + 0]
563 & 0xFF) << 0) |
564 ((pdadcValues[4*j + 1]
565 & 0xFF) << 8) |
566 ((pdadcValues[4*j + 2]
567 & 0xFF) << 16) |
568 ((pdadcValues[4*j + 3]
569 & 0xFF) << 24) ;
570 REG_WRITE(ah, regOffset, reg32);
571 578
572 ath_print(common, ATH_DBG_EEPROM, 579 for (j = 0; j < 32; j++) {
573 "PDADC (%d,%4x): %4.4x " 580 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)
574 "%8.8x\n", 581 | ((pdadcValues[4*j + 1] & 0xFF) << 8)
575 i, regChainOffset, regOffset, 582 | ((pdadcValues[4*j + 2] & 0xFF) << 16)
576 reg32); 583 | ((pdadcValues[4*j + 3] & 0xFF) << 24);
577
578 ath_print(common, ATH_DBG_EEPROM,
579 "PDADC: Chain %d | "
580 "PDADC %3d Value %3d | "
581 "PDADC %3d Value %3d | "
582 "PDADC %3d Value %3d | "
583 "PDADC %3d Value %3d |\n",
584 i, 4 * j, pdadcValues[4 * j],
585 4 * j + 1,
586 pdadcValues[4 * j + 1],
587 4 * j + 2,
588 pdadcValues[4 * j + 2],
589 4 * j + 3,
590 pdadcValues[4 * j + 3]);
591 584
585 REG_WRITE(ah, regOffset, reg32);
592 regOffset += 4; 586 regOffset += 4;
593 } 587 }
594 } 588 }
@@ -598,30 +592,45 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
598 *pTxPowerIndexOffset = 0; 592 *pTxPowerIndexOffset = 0;
599} 593}
600 594
601static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, 595static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
602 struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl, 596 struct ath9k_channel *chan,
603 u16 AntennaReduction, u16 twiceMaxRegulatoryPower, 597 int16_t *ratesArray,
604 u16 powerLimit) 598 u16 cfgCtl,
599 u16 AntennaReduction,
600 u16 twiceMaxRegulatoryPower,
601 u16 powerLimit)
605{ 602{
603#define CMP_CTL \
604 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
605 pEepData->ctlIndex[i])
606
607#define CMP_NO_CTL \
608 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
609 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
610
606#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 611#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
607#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 612#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
613
608 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 614 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
609 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 615 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
610 static const u16 tpScaleReductionTable[5] = 616 static const u16 tpScaleReductionTable[5] =
611 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 617 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
612 int i; 618 int i;
613 int16_t twiceLargestAntenna; 619 int16_t twiceLargestAntenna;
614 struct cal_ctl_data_ar9287 *rep; 620 struct cal_ctl_data_ar9287 *rep;
615 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, 621 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
616 targetPowerCck = {0, {0, 0, 0, 0} }; 622 targetPowerCck = {0, {0, 0, 0, 0} };
617 struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} }, 623 struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} },
618 targetPowerCckExt = {0, {0, 0, 0, 0} }; 624 targetPowerCckExt = {0, {0, 0, 0, 0} };
619 struct cal_target_power_ht targetPowerHt20, 625 struct cal_target_power_ht targetPowerHt20,
620 targetPowerHt40 = {0, {0, 0, 0, 0} }; 626 targetPowerHt40 = {0, {0, 0, 0, 0} };
621 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 627 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
622 u16 ctlModesFor11g[] = 628 u16 ctlModesFor11g[] = {CTL_11B,
623 {CTL_11B, CTL_11G, CTL_2GHT20, 629 CTL_11G,
624 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40}; 630 CTL_2GHT20,
631 CTL_11B_EXT,
632 CTL_11G_EXT,
633 CTL_2GHT40};
625 u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq; 634 u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
626 struct chan_centers centers; 635 struct chan_centers centers;
627 int tx_chainmask; 636 int tx_chainmask;
@@ -631,19 +640,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
631 640
632 ath9k_hw_get_channel_centers(ah, chan, &centers); 641 ath9k_hw_get_channel_centers(ah, chan, &centers);
633 642
643 /* Compute TxPower reduction due to Antenna Gain */
634 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0], 644 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
635 pEepData->modalHeader.antennaGainCh[1]); 645 pEepData->modalHeader.antennaGainCh[1]);
646 twiceLargestAntenna = (int16_t)min((AntennaReduction) -
647 twiceLargestAntenna, 0);
636 648
637 twiceLargestAntenna = (int16_t)min((AntennaReduction) - 649 /*
638 twiceLargestAntenna, 0); 650 * scaledPower is the minimum of the user input power level
639 651 * and the regulatory allowed power level.
652 */
640 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 653 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
654
641 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) 655 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
642 maxRegAllowedPower -= 656 maxRegAllowedPower -=
643 (tpScaleReductionTable[(regulatory->tp_scale)] * 2); 657 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
644 658
645 scaledPower = min(powerLimit, maxRegAllowedPower); 659 scaledPower = min(powerLimit, maxRegAllowedPower);
646 660
661 /*
662 * Reduce scaled Power by number of chains active
663 * to get the per chain tx power level.
664 */
647 switch (ar5416_get_ntxchains(tx_chainmask)) { 665 switch (ar5416_get_ntxchains(tx_chainmask)) {
648 case 1: 666 case 1:
649 break; 667 break;
@@ -656,9 +674,14 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
656 } 674 }
657 scaledPower = max((u16)0, scaledPower); 675 scaledPower = max((u16)0, scaledPower);
658 676
677 /*
678 * Get TX power from EEPROM.
679 */
659 if (IS_CHAN_2GHZ(chan)) { 680 if (IS_CHAN_2GHZ(chan)) {
681 /* CTL_11B, CTL_11G, CTL_2GHT20 */
660 numCtlModes = 682 numCtlModes =
661 ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 683 ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
684
662 pCtlMode = ctlModesFor11g; 685 pCtlMode = ctlModesFor11g;
663 686
664 ath9k_hw_get_legacy_target_powers(ah, chan, 687 ath9k_hw_get_legacy_target_powers(ah, chan,
@@ -675,6 +698,7 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
675 &targetPowerHt20, 8, false); 698 &targetPowerHt20, 8, false);
676 699
677 if (IS_CHAN_HT40(chan)) { 700 if (IS_CHAN_HT40(chan)) {
701 /* All 2G CTLs */
678 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 702 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
679 ath9k_hw_get_target_powers(ah, chan, 703 ath9k_hw_get_target_powers(ah, chan,
680 pEepData->calTargetPower2GHT40, 704 pEepData->calTargetPower2GHT40,
@@ -692,8 +716,9 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
692 } 716 }
693 717
694 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 718 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
695 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 719 bool isHt40CtlMode =
696 (pCtlMode[ctlMode] == CTL_2GHT40); 720 (pCtlMode[ctlMode] == CTL_2GHT40) ? true : false;
721
697 if (isHt40CtlMode) 722 if (isHt40CtlMode)
698 freq = centers.synth_center; 723 freq = centers.synth_center;
699 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 724 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
@@ -701,31 +726,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
701 else 726 else
702 freq = centers.ctl_center; 727 freq = centers.ctl_center;
703 728
704 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 729 /* Walk through the CTL indices stored in EEPROM */
705 ah->eep_ops->get_eeprom_rev(ah) <= 2)
706 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
707
708 for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 730 for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
709 if ((((cfgCtl & ~CTL_MODE_M) | 731 struct cal_ctl_edges *pRdEdgesPower;
710 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
711 pEepData->ctlIndex[i]) ||
712 (((cfgCtl & ~CTL_MODE_M) |
713 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
714 ((pEepData->ctlIndex[i] &
715 CTL_MODE_M) | SD_NO_CTL))) {
716 732
733 /*
734 * Compare test group from regulatory channel list
735 * with test mode from pCtlMode list
736 */
737 if (CMP_CTL || CMP_NO_CTL) {
717 rep = &(pEepData->ctlData[i]); 738 rep = &(pEepData->ctlData[i]);
718 twiceMinEdgePower = ath9k_hw_get_max_edge_power( 739 pRdEdgesPower =
719 freq, 740 rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1];
720 rep->ctlEdges[ar5416_get_ntxchains( 741
721 tx_chainmask) - 1], 742 twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
722 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); 743 pRdEdgesPower,
723 744 IS_CHAN_2GHZ(chan),
724 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) 745 AR5416_NUM_BAND_EDGES);
725 twiceMaxEdgePower = min( 746
726 twiceMaxEdgePower, 747 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
727 twiceMinEdgePower); 748 twiceMaxEdgePower = min(twiceMaxEdgePower,
728 else { 749 twiceMinEdgePower);
750 } else {
729 twiceMaxEdgePower = twiceMinEdgePower; 751 twiceMaxEdgePower = twiceMinEdgePower;
730 break; 752 break;
731 } 753 }
@@ -734,55 +756,48 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
734 756
735 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 757 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
736 758
759 /* Apply ctl mode to correct target power set */
737 switch (pCtlMode[ctlMode]) { 760 switch (pCtlMode[ctlMode]) {
738 case CTL_11B: 761 case CTL_11B:
739 for (i = 0; 762 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
740 i < ARRAY_SIZE(targetPowerCck.tPow2x); 763 targetPowerCck.tPow2x[i] =
741 i++) { 764 (u8)min((u16)targetPowerCck.tPow2x[i],
742 targetPowerCck.tPow2x[i] = (u8)min( 765 minCtlPower);
743 (u16)targetPowerCck.tPow2x[i],
744 minCtlPower);
745 } 766 }
746 break; 767 break;
747 case CTL_11A: 768 case CTL_11A:
748 case CTL_11G: 769 case CTL_11G:
749 for (i = 0; 770 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
750 i < ARRAY_SIZE(targetPowerOfdm.tPow2x); 771 targetPowerOfdm.tPow2x[i] =
751 i++) { 772 (u8)min((u16)targetPowerOfdm.tPow2x[i],
752 targetPowerOfdm.tPow2x[i] = (u8)min( 773 minCtlPower);
753 (u16)targetPowerOfdm.tPow2x[i],
754 minCtlPower);
755 } 774 }
756 break; 775 break;
757 case CTL_5GHT20: 776 case CTL_5GHT20:
758 case CTL_2GHT20: 777 case CTL_2GHT20:
759 for (i = 0; 778 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
760 i < ARRAY_SIZE(targetPowerHt20.tPow2x); 779 targetPowerHt20.tPow2x[i] =
761 i++) { 780 (u8)min((u16)targetPowerHt20.tPow2x[i],
762 targetPowerHt20.tPow2x[i] = (u8)min( 781 minCtlPower);
763 (u16)targetPowerHt20.tPow2x[i],
764 minCtlPower);
765 } 782 }
766 break; 783 break;
767 case CTL_11B_EXT: 784 case CTL_11B_EXT:
768 targetPowerCckExt.tPow2x[0] = (u8)min( 785 targetPowerCckExt.tPow2x[0] =
769 (u16)targetPowerCckExt.tPow2x[0], 786 (u8)min((u16)targetPowerCckExt.tPow2x[0],
770 minCtlPower); 787 minCtlPower);
771 break; 788 break;
772 case CTL_11A_EXT: 789 case CTL_11A_EXT:
773 case CTL_11G_EXT: 790 case CTL_11G_EXT:
774 targetPowerOfdmExt.tPow2x[0] = (u8)min( 791 targetPowerOfdmExt.tPow2x[0] =
775 (u16)targetPowerOfdmExt.tPow2x[0], 792 (u8)min((u16)targetPowerOfdmExt.tPow2x[0],
776 minCtlPower); 793 minCtlPower);
777 break; 794 break;
778 case CTL_5GHT40: 795 case CTL_5GHT40:
779 case CTL_2GHT40: 796 case CTL_2GHT40:
780 for (i = 0; 797 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
781 i < ARRAY_SIZE(targetPowerHt40.tPow2x); 798 targetPowerHt40.tPow2x[i] =
782 i++) { 799 (u8)min((u16)targetPowerHt40.tPow2x[i],
783 targetPowerHt40.tPow2x[i] = (u8)min( 800 minCtlPower);
784 (u16)targetPowerHt40.tPow2x[i],
785 minCtlPower);
786 } 801 }
787 break; 802 break;
788 default: 803 default:
@@ -790,12 +805,13 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
790 } 805 }
791 } 806 }
792 807
808 /* Now set the rates array */
809
793 ratesArray[rate6mb] = 810 ratesArray[rate6mb] =
794 ratesArray[rate9mb] = 811 ratesArray[rate9mb] =
795 ratesArray[rate12mb] = 812 ratesArray[rate12mb] =
796 ratesArray[rate18mb] = 813 ratesArray[rate18mb] =
797 ratesArray[rate24mb] = 814 ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0];
798 targetPowerOfdm.tPow2x[0];
799 815
800 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 816 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
801 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 817 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
@@ -807,12 +823,12 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
807 823
808 if (IS_CHAN_2GHZ(chan)) { 824 if (IS_CHAN_2GHZ(chan)) {
809 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 825 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
810 ratesArray[rate2s] = ratesArray[rate2l] = 826 ratesArray[rate2s] =
811 targetPowerCck.tPow2x[1]; 827 ratesArray[rate2l] = targetPowerCck.tPow2x[1];
812 ratesArray[rate5_5s] = ratesArray[rate5_5l] = 828 ratesArray[rate5_5s] =
813 targetPowerCck.tPow2x[2]; 829 ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
814 ratesArray[rate11s] = ratesArray[rate11l] = 830 ratesArray[rate11s] =
815 targetPowerCck.tPow2x[3]; 831 ratesArray[rate11l] = targetPowerCck.tPow2x[3];
816 } 832 }
817 if (IS_CHAN_HT40(chan)) { 833 if (IS_CHAN_HT40(chan)) {
818 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) 834 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++)
@@ -821,28 +837,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
821 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 837 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
822 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 838 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
823 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 839 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
840
824 if (IS_CHAN_2GHZ(chan)) 841 if (IS_CHAN_2GHZ(chan))
825 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 842 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
826 } 843 }
827 844
845#undef CMP_CTL
846#undef CMP_NO_CTL
828#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN 847#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
829#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN 848#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
830} 849}
831 850
832static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, 851static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
833 struct ath9k_channel *chan, u16 cfgCtl, 852 struct ath9k_channel *chan, u16 cfgCtl,
834 u8 twiceAntennaReduction, 853 u8 twiceAntennaReduction,
835 u8 twiceMaxRegulatoryPower, 854 u8 twiceMaxRegulatoryPower,
836 u8 powerLimit) 855 u8 powerLimit)
837{ 856{
838#define INCREASE_MAXPOW_BY_TWO_CHAIN 6
839#define INCREASE_MAXPOW_BY_THREE_CHAIN 10
840 struct ath_common *common = ath9k_hw_common(ah);
841 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 857 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
842 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 858 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
843 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; 859 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
844 int16_t ratesArray[Ar5416RateSize]; 860 int16_t ratesArray[Ar5416RateSize];
845 int16_t txPowerIndexOffset = 0; 861 int16_t txPowerIndexOffset = 0;
846 u8 ht40PowerIncForPdadc = 2; 862 u8 ht40PowerIncForPdadc = 2;
847 int i; 863 int i;
848 864
@@ -852,13 +868,13 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
852 AR9287_EEP_MINOR_VER_2) 868 AR9287_EEP_MINOR_VER_2)
853 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 869 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
854 870
855 ath9k_hw_set_AR9287_power_per_rate_table(ah, chan, 871 ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
856 &ratesArray[0], cfgCtl, 872 &ratesArray[0], cfgCtl,
857 twiceAntennaReduction, 873 twiceAntennaReduction,
858 twiceMaxRegulatoryPower, 874 twiceMaxRegulatoryPower,
859 powerLimit); 875 powerLimit);
860 876
861 ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset); 877 ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
862 878
863 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 879 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
864 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 880 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -871,6 +887,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
871 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; 887 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
872 } 888 }
873 889
890 /* OFDM power per rate */
874 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 891 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
875 ATH9K_POW_SM(ratesArray[rate18mb], 24) 892 ATH9K_POW_SM(ratesArray[rate18mb], 24)
876 | ATH9K_POW_SM(ratesArray[rate12mb], 16) 893 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
@@ -883,6 +900,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
883 | ATH9K_POW_SM(ratesArray[rate36mb], 8) 900 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
884 | ATH9K_POW_SM(ratesArray[rate24mb], 0)); 901 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
885 902
903 /* CCK power per rate */
886 if (IS_CHAN_2GHZ(chan)) { 904 if (IS_CHAN_2GHZ(chan)) {
887 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 905 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
888 ATH9K_POW_SM(ratesArray[rate2s], 24) 906 ATH9K_POW_SM(ratesArray[rate2s], 24)
@@ -896,6 +914,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
896 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); 914 | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
897 } 915 }
898 916
917 /* HT20 power per rate */
899 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 918 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
900 ATH9K_POW_SM(ratesArray[rateHt20_3], 24) 919 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
901 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) 920 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
@@ -908,8 +927,9 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
908 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) 927 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
909 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); 928 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
910 929
930 /* HT40 power per rate */
911 if (IS_CHAN_HT40(chan)) { 931 if (IS_CHAN_HT40(chan)) {
912 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 932 if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
913 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 933 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
914 ATH9K_POW_SM(ratesArray[rateHt40_3], 24) 934 ATH9K_POW_SM(ratesArray[rateHt40_3], 24)
915 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16) 935 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16)
@@ -943,6 +963,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
943 ht40PowerIncForPdadc, 0)); 963 ht40PowerIncForPdadc, 0));
944 } 964 }
945 965
966 /* Dup/Ext power per rate */
946 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 967 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
947 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) 968 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
948 | ATH9K_POW_SM(ratesArray[rateExtCck], 16) 969 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
@@ -960,37 +981,20 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
960 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; 981 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
961 else 982 else
962 regulatory->max_power_level = ratesArray[i]; 983 regulatory->max_power_level = ratesArray[i];
963
964 switch (ar5416_get_ntxchains(ah->txchainmask)) {
965 case 1:
966 break;
967 case 2:
968 regulatory->max_power_level +=
969 INCREASE_MAXPOW_BY_TWO_CHAIN;
970 break;
971 case 3:
972 regulatory->max_power_level +=
973 INCREASE_MAXPOW_BY_THREE_CHAIN;
974 break;
975 default:
976 ath_print(common, ATH_DBG_EEPROM,
977 "Invalid chainmask configuration\n");
978 break;
979 }
980} 984}
981 985
982static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah, 986static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
983 struct ath9k_channel *chan) 987 struct ath9k_channel *chan)
984{ 988{
985} 989}
986 990
987static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, 991static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
988 struct ath9k_channel *chan) 992 struct ath9k_channel *chan)
989{ 993{
990 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 994 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
991 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 995 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
992 u16 antWrites[AR9287_ANT_16S]; 996 u16 antWrites[AR9287_ANT_16S];
993 u32 regChainOffset; 997 u32 regChainOffset, regval;
994 u8 txRxAttenLocal; 998 u8 txRxAttenLocal;
995 int i, j, offset_num; 999 int i, j, offset_num;
996 1000
@@ -1077,42 +1081,37 @@ static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
1077 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, 1081 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
1078 AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); 1082 AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
1079 1083
1080 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1, 1084 regval = REG_READ(ah, AR9287_AN_RF2G3_CH0);
1081 AR9287_AN_RF2G3_DB1_S, pModal->db1); 1085 regval &= ~(AR9287_AN_RF2G3_DB1 |
1082 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2, 1086 AR9287_AN_RF2G3_DB2 |
1083 AR9287_AN_RF2G3_DB2_S, pModal->db2); 1087 AR9287_AN_RF2G3_OB_CCK |
1084 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1088 AR9287_AN_RF2G3_OB_PSK |
1085 AR9287_AN_RF2G3_OB_CCK, 1089 AR9287_AN_RF2G3_OB_QAM |
1086 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); 1090 AR9287_AN_RF2G3_OB_PAL_OFF);
1087 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1091 regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
1088 AR9287_AN_RF2G3_OB_PSK, 1092 SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
1089 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); 1093 SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
1090 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1094 SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
1091 AR9287_AN_RF2G3_OB_QAM, 1095 SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
1092 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); 1096 SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
1093 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, 1097
1094 AR9287_AN_RF2G3_OB_PAL_OFF, 1098 ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH0, regval);
1095 AR9287_AN_RF2G3_OB_PAL_OFF_S, 1099
1096 pModal->ob_pal_off); 1100 regval = REG_READ(ah, AR9287_AN_RF2G3_CH1);
1097 1101 regval &= ~(AR9287_AN_RF2G3_DB1 |
1098 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1102 AR9287_AN_RF2G3_DB2 |
1099 AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S, 1103 AR9287_AN_RF2G3_OB_CCK |
1100 pModal->db1); 1104 AR9287_AN_RF2G3_OB_PSK |
1101 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2, 1105 AR9287_AN_RF2G3_OB_QAM |
1102 AR9287_AN_RF2G3_DB2_S, pModal->db2); 1106 AR9287_AN_RF2G3_OB_PAL_OFF);
1103 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1107 regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) |
1104 AR9287_AN_RF2G3_OB_CCK, 1108 SM(pModal->db2, AR9287_AN_RF2G3_DB2) |
1105 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); 1109 SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) |
1106 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1110 SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) |
1107 AR9287_AN_RF2G3_OB_PSK, 1111 SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) |
1108 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); 1112 SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF));
1109 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, 1113
1110 AR9287_AN_RF2G3_OB_QAM, 1114 ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH1, regval);
1111 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
1112 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
1113 AR9287_AN_RF2G3_OB_PAL_OFF,
1114 AR9287_AN_RF2G3_OB_PAL_OFF_S,
1115 pModal->ob_pal_off);
1116 1115
1117 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, 1116 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
1118 AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart); 1117 AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart);
@@ -1125,13 +1124,13 @@ static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
1125 pModal->xpaBiasLvl); 1124 pModal->xpaBiasLvl);
1126} 1125}
1127 1126
1128static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah, 1127static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah,
1129 enum ieee80211_band freq_band) 1128 enum ieee80211_band freq_band)
1130{ 1129{
1131 return 1; 1130 return 1;
1132} 1131}
1133 1132
1134static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, 1133static u16 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
1135 struct ath9k_channel *chan) 1134 struct ath9k_channel *chan)
1136{ 1135{
1137 struct ar9287_eeprom *eep = &ah->eeprom.map9287; 1136 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
@@ -1140,11 +1139,12 @@ static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
1140 return pModal->antCtrlCommon & 0xFFFF; 1139 return pModal->antCtrlCommon & 0xFFFF;
1141} 1140}
1142 1141
1143static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, 1142static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
1144 u16 i, bool is2GHz) 1143 u16 i, bool is2GHz)
1145{ 1144{
1146#define EEP_MAP9287_SPURCHAN \ 1145#define EEP_MAP9287_SPURCHAN \
1147 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan) 1146 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
1147
1148 struct ath_common *common = ath9k_hw_common(ah); 1148 struct ath_common *common = ath9k_hw_common(ah);
1149 u16 spur_val = AR_NO_SPUR; 1149 u16 spur_val = AR_NO_SPUR;
1150 1150
@@ -1171,15 +1171,15 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
1171} 1171}
1172 1172
1173const struct eeprom_ops eep_ar9287_ops = { 1173const struct eeprom_ops eep_ar9287_ops = {
1174 .check_eeprom = ath9k_hw_AR9287_check_eeprom, 1174 .check_eeprom = ath9k_hw_ar9287_check_eeprom,
1175 .get_eeprom = ath9k_hw_AR9287_get_eeprom, 1175 .get_eeprom = ath9k_hw_ar9287_get_eeprom,
1176 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, 1176 .fill_eeprom = ath9k_hw_ar9287_fill_eeprom,
1177 .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver, 1177 .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
1178 .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev, 1178 .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
1179 .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config, 1179 .get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config,
1180 .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg, 1180 .get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg,
1181 .set_board_values = ath9k_hw_AR9287_set_board_values, 1181 .set_board_values = ath9k_hw_ar9287_set_board_values,
1182 .set_addac = ath9k_hw_AR9287_set_addac, 1182 .set_addac = ath9k_hw_ar9287_set_addac,
1183 .set_txpower = ath9k_hw_AR9287_set_txpower, 1183 .set_txpower = ath9k_hw_ar9287_set_txpower,
1184 .get_spur_channel = ath9k_hw_AR9287_get_spur_channel 1184 .get_spur_channel = ath9k_hw_ar9287_get_spur_channel
1185}; 1185};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 7e1ed78d0e64..77b1433312cc 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -617,6 +617,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
617 int16_t minDelta = 0; 617 int16_t minDelta = 0;
618 struct chan_centers centers; 618 struct chan_centers centers;
619 619
620 memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
620 ath9k_hw_get_channel_centers(ah, chan, &centers); 621 ath9k_hw_get_channel_centers(ah, chan, &centers);
621 622
622 for (numPiers = 0; numPiers < availPiers; numPiers++) { 623 for (numPiers = 0; numPiers < availPiers; numPiers++) {
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 0ee75e79fe35..3a8ee999da5d 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -76,7 +76,8 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
76 case LED_FULL: 76 case LED_FULL:
77 if (led->led_type == ATH_LED_ASSOC) { 77 if (led->led_type == ATH_LED_ASSOC) {
78 sc->sc_flags |= SC_OP_LED_ASSOCIATED; 78 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
79 ieee80211_queue_delayed_work(sc->hw, 79 if (led_blink)
80 ieee80211_queue_delayed_work(sc->hw,
80 &sc->ath_led_blink_work, 0); 81 &sc->ath_led_blink_work, 0);
81 } else if (led->led_type == ATH_LED_RADIO) { 82 } else if (led->led_type == ATH_LED_RADIO) {
82 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); 83 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
@@ -143,7 +144,8 @@ void ath_init_leds(struct ath_softc *sc)
143 /* LED off, active low */ 144 /* LED off, active low */
144 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); 145 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
145 146
146 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); 147 if (led_blink)
148 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
147 149
148 trigger = ieee80211_get_radio_led_name(sc->hw); 150 trigger = ieee80211_get_radio_led_name(sc->hw);
149 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), 151 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
@@ -180,7 +182,8 @@ void ath_init_leds(struct ath_softc *sc)
180 return; 182 return;
181 183
182fail: 184fail:
183 cancel_delayed_work_sync(&sc->ath_led_blink_work); 185 if (led_blink)
186 cancel_delayed_work_sync(&sc->ath_led_blink_work);
184 ath_deinit_leds(sc); 187 ath_deinit_leds(sc);
185} 188}
186 189
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 77b359162d6c..ad9134bddd1e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -16,12 +16,27 @@
16 16
17#include "htc.h" 17#include "htc.h"
18 18
19#define ATH9K_FW_USB_DEV(devid, fw) \ 19/* identify firmware images */
20 { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw } 20#define FIRMWARE_AR7010 "ar7010.fw"
21#define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw"
22#define FIRMWARE_AR9271 "ar9271.fw"
23
24MODULE_FIRMWARE(FIRMWARE_AR7010);
25MODULE_FIRMWARE(FIRMWARE_AR7010_1_1);
26MODULE_FIRMWARE(FIRMWARE_AR9271);
21 27
22static struct usb_device_id ath9k_hif_usb_ids[] = { 28static struct usb_device_id ath9k_hif_usb_ids[] = {
23 ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"), 29 { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
24 ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"), 30 { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
31 { USB_DEVICE(0x0cf3, 0x7010) }, /* Atheros */
32 { USB_DEVICE(0x0cf3, 0x7015) }, /* Atheros */
33 { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
34 { USB_DEVICE(0x0846, 0x9018) }, /* Netgear WNDA3200 */
35 { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
36 { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
37 { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
38 { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
39 { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
25 { }, 40 { },
26}; 41};
27 42
@@ -756,6 +771,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
756 size_t len = hif_dev->firmware->size; 771 size_t len = hif_dev->firmware->size;
757 u32 addr = AR9271_FIRMWARE; 772 u32 addr = AR9271_FIRMWARE;
758 u8 *buf = kzalloc(4096, GFP_KERNEL); 773 u8 *buf = kzalloc(4096, GFP_KERNEL);
774 u32 firm_offset;
759 775
760 if (!buf) 776 if (!buf)
761 return -ENOMEM; 777 return -ENOMEM;
@@ -779,32 +795,37 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
779 } 795 }
780 kfree(buf); 796 kfree(buf);
781 797
798 if (hif_dev->device_id == 0x7010)
799 firm_offset = AR7010_FIRMWARE_TEXT;
800 else
801 firm_offset = AR9271_FIRMWARE_TEXT;
802
782 /* 803 /*
783 * Issue FW download complete command to firmware. 804 * Issue FW download complete command to firmware.
784 */ 805 */
785 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0), 806 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
786 FIRMWARE_DOWNLOAD_COMP, 807 FIRMWARE_DOWNLOAD_COMP,
787 0x40 | USB_DIR_OUT, 808 0x40 | USB_DIR_OUT,
788 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ); 809 firm_offset >> 8, 0, NULL, 0, HZ);
789 if (err) 810 if (err)
790 return -EIO; 811 return -EIO;
791 812
792 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n", 813 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
793 "ar9271.fw", (unsigned long) hif_dev->firmware->size); 814 hif_dev->fw_name, (unsigned long) hif_dev->firmware->size);
794 815
795 return 0; 816 return 0;
796} 817}
797 818
798static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, 819static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
799 const char *fw_name)
800{ 820{
801 int ret; 821 int ret;
802 822
803 /* Request firmware */ 823 /* Request firmware */
804 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev); 824 ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
825 &hif_dev->udev->dev);
805 if (ret) { 826 if (ret) {
806 dev_err(&hif_dev->udev->dev, 827 dev_err(&hif_dev->udev->dev,
807 "ath9k_htc: Firmware - %s not found\n", fw_name); 828 "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name);
808 goto err_fw_req; 829 goto err_fw_req;
809 } 830 }
810 831
@@ -820,7 +841,8 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
820 ret = ath9k_hif_usb_download_fw(hif_dev); 841 ret = ath9k_hif_usb_download_fw(hif_dev);
821 if (ret) { 842 if (ret) {
822 dev_err(&hif_dev->udev->dev, 843 dev_err(&hif_dev->udev->dev,
823 "ath9k_htc: Firmware - %s download failed\n", fw_name); 844 "ath9k_htc: Firmware - %s download failed\n",
845 hif_dev->fw_name);
824 goto err_fw_download; 846 goto err_fw_download;
825 } 847 }
826 848
@@ -847,7 +869,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
847{ 869{
848 struct usb_device *udev = interface_to_usbdev(interface); 870 struct usb_device *udev = interface_to_usbdev(interface);
849 struct hif_device_usb *hif_dev; 871 struct hif_device_usb *hif_dev;
850 const char *fw_name = (const char *) id->driver_info;
851 int ret = 0; 872 int ret = 0;
852 873
853 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); 874 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
@@ -872,7 +893,27 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
872 goto err_htc_hw_alloc; 893 goto err_htc_hw_alloc;
873 } 894 }
874 895
875 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name); 896 /* Find out which firmware to load */
897
898 switch(hif_dev->device_id) {
899 case 0x7010:
900 case 0x9018:
901 if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
902 hif_dev->fw_name = FIRMWARE_AR7010_1_1;
903 else
904 hif_dev->fw_name = FIRMWARE_AR7010;
905 break;
906 default:
907 hif_dev->fw_name = FIRMWARE_AR9271;
908 break;
909 }
910
911 if (!hif_dev->fw_name) {
912 dev_err(&udev->dev, "Can't determine firmware !\n");
913 goto err_htc_hw_alloc;
914 }
915
916 ret = ath9k_hif_usb_dev_init(hif_dev);
876 if (ret) { 917 if (ret) {
877 ret = -EINVAL; 918 ret = -EINVAL;
878 goto err_hif_init_usb; 919 goto err_hif_init_usb;
@@ -907,12 +948,10 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
907 void *buf; 948 void *buf;
908 int ret; 949 int ret;
909 950
910 buf = kmalloc(4, GFP_KERNEL); 951 buf = kmemdup(&reboot_cmd, 4, GFP_KERNEL);
911 if (!buf) 952 if (!buf)
912 return; 953 return;
913 954
914 memcpy(buf, &reboot_cmd, 4);
915
916 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), 955 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE),
917 buf, 4, NULL, HZ); 956 buf, 4, NULL, HZ);
918 if (ret) 957 if (ret)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 0aca49b6fcb6..2daf97b11c08 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -19,6 +19,7 @@
19 19
20#define AR9271_FIRMWARE 0x501000 20#define AR9271_FIRMWARE 0x501000
21#define AR9271_FIRMWARE_TEXT 0x903000 21#define AR9271_FIRMWARE_TEXT 0x903000
22#define AR7010_FIRMWARE_TEXT 0x906000
22 23
23#define FIRMWARE_DOWNLOAD 0x30 24#define FIRMWARE_DOWNLOAD 0x30
24#define FIRMWARE_DOWNLOAD_COMP 0x31 25#define FIRMWARE_DOWNLOAD_COMP 0x31
@@ -90,6 +91,7 @@ struct hif_device_usb {
90 struct usb_anchor regout_submitted; 91 struct usb_anchor regout_submitted;
91 struct usb_anchor rx_submitted; 92 struct usb_anchor rx_submitted;
92 struct sk_buff *remain_skb; 93 struct sk_buff *remain_skb;
94 const char *fw_name;
93 int rx_remain_len; 95 int rx_remain_len;
94 int rx_pkt_len; 96 int rx_pkt_len;
95 int rx_transfer_len; 97 int rx_transfer_len;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index c251603ab032..58f52a1dc7ea 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -223,15 +223,6 @@ struct ath9k_htc_sta {
223 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; 223 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
224}; 224};
225 225
226struct ath9k_htc_aggr_work {
227 u16 tid;
228 u8 sta_addr[ETH_ALEN];
229 struct ieee80211_hw *hw;
230 struct ieee80211_vif *vif;
231 enum ieee80211_ampdu_mlme_action action;
232 struct mutex mutex;
233};
234
235#define ATH9K_HTC_RXBUF 256 226#define ATH9K_HTC_RXBUF 256
236#define HTC_RX_FRAME_HEADER_SIZE 40 227#define HTC_RX_FRAME_HEADER_SIZE 40
237 228
@@ -257,12 +248,15 @@ struct ath9k_htc_tx_ctl {
257#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) 248#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
258#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) 249#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
259 250
251#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
252
260struct ath_tx_stats { 253struct ath_tx_stats {
261 u32 buf_queued; 254 u32 buf_queued;
262 u32 buf_completed; 255 u32 buf_completed;
263 u32 skb_queued; 256 u32 skb_queued;
264 u32 skb_completed; 257 u32 skb_completed;
265 u32 skb_dropped; 258 u32 skb_dropped;
259 u32 queue_stats[WME_NUM_AC];
266}; 260};
267 261
268struct ath_rx_stats { 262struct ath_rx_stats {
@@ -286,6 +280,8 @@ struct ath9k_debug {
286#define TX_STAT_INC(c) do { } while (0) 280#define TX_STAT_INC(c) do { } while (0)
287#define RX_STAT_INC(c) do { } while (0) 281#define RX_STAT_INC(c) do { } while (0)
288 282
283#define TX_QSTAT_INC(c) do { } while (0)
284
289#endif /* CONFIG_ATH9K_HTC_DEBUGFS */ 285#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
290 286
291#define ATH_LED_PIN_DEF 1 287#define ATH_LED_PIN_DEF 1
@@ -326,11 +322,10 @@ struct htc_beacon_config {
326#define OP_LED_ON BIT(4) 322#define OP_LED_ON BIT(4)
327#define OP_PREAMBLE_SHORT BIT(5) 323#define OP_PREAMBLE_SHORT BIT(5)
328#define OP_PROTECT_ENABLE BIT(6) 324#define OP_PROTECT_ENABLE BIT(6)
329#define OP_TXAGGR BIT(7) 325#define OP_ASSOCIATED BIT(7)
330#define OP_ASSOCIATED BIT(8) 326#define OP_ENABLE_BEACON BIT(8)
331#define OP_ENABLE_BEACON BIT(9) 327#define OP_LED_DEINIT BIT(9)
332#define OP_LED_DEINIT BIT(10) 328#define OP_UNPLUGGED BIT(10)
333#define OP_UNPLUGGED BIT(11)
334 329
335struct ath9k_htc_priv { 330struct ath9k_htc_priv {
336 struct device *dev; 331 struct device *dev;
@@ -371,8 +366,6 @@ struct ath9k_htc_priv {
371 struct ath9k_htc_rx rx; 366 struct ath9k_htc_rx rx;
372 struct tasklet_struct tx_tasklet; 367 struct tasklet_struct tx_tasklet;
373 struct sk_buff_head tx_queue; 368 struct sk_buff_head tx_queue;
374 struct ath9k_htc_aggr_work aggr_work;
375 struct delayed_work ath9k_aggr_work;
376 struct delayed_work ath9k_ani_work; 369 struct delayed_work ath9k_ani_work;
377 struct work_struct ps_work; 370 struct work_struct ps_work;
378 371
@@ -390,13 +383,14 @@ struct ath9k_htc_priv {
390 int led_off_duration; 383 int led_off_duration;
391 int led_on_cnt; 384 int led_on_cnt;
392 int led_off_cnt; 385 int led_off_cnt;
393 int hwq_map[ATH9K_WME_AC_VO+1]; 386
387 int beaconq;
388 int cabq;
389 int hwq_map[WME_NUM_AC];
394 390
395#ifdef CONFIG_ATH9K_HTC_DEBUGFS 391#ifdef CONFIG_ATH9K_HTC_DEBUGFS
396 struct ath9k_debug debug; 392 struct ath9k_debug debug;
397#endif 393#endif
398 struct ath9k_htc_target_rate tgt_rate;
399
400 struct mutex mutex; 394 struct mutex mutex;
401}; 395};
402 396
@@ -405,6 +399,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
405 common->bus_ops->read_cachesize(common, csz); 399 common->bus_ops->read_cachesize(common, csz);
406} 400}
407 401
402void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
408void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, 403void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
409 struct ieee80211_vif *vif); 404 struct ieee80211_vif *vif);
410void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); 405void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
@@ -424,8 +419,8 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv);
424void ath9k_tx_tasklet(unsigned long data); 419void ath9k_tx_tasklet(unsigned long data);
425int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); 420int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
426void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); 421void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
427bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, 422bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype);
428 enum ath9k_tx_queue_subtype qtype); 423int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
429int get_hw_qnum(u16 queue, int *hwq_map); 424int get_hw_qnum(u16 queue, int *hwq_map);
430int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, 425int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
431 struct ath9k_tx_queue_info *qinfo); 426 struct ath9k_tx_queue_info *qinfo);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index c10c7d002eb7..bd1506e69105 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -222,6 +222,29 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
222 spin_unlock_bh(&priv->beacon_lock); 222 spin_unlock_bh(&priv->beacon_lock);
223} 223}
224 224
225/* Currently, only for IBSS */
226void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
227{
228 struct ath_hw *ah = priv->ah;
229 struct ath9k_tx_queue_info qi, qi_be;
230 int qnum = priv->hwq_map[WME_AC_BE];
231
232 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
233 memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
234
235 ath9k_hw_get_txq_props(ah, qnum, &qi_be);
236
237 qi.tqi_aifs = qi_be.tqi_aifs;
238 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
239 qi.tqi_cwmax = qi_be.tqi_cwmax;
240
241 if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
242 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
243 "Unable to update beacon queue %u!\n", qnum);
244 } else {
245 ath9k_hw_resettxqueue(ah, priv->beaconq);
246 }
247}
225 248
226void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, 249void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
227 struct ieee80211_vif *vif) 250 struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index dc015077a8d9..148b43317fdb 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -34,6 +34,13 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
34 .max_power = 20, \ 34 .max_power = 20, \
35} 35}
36 36
37#define CHAN5G(_freq, _idx) { \
38 .band = IEEE80211_BAND_5GHZ, \
39 .center_freq = (_freq), \
40 .hw_value = (_idx), \
41 .max_power = 20, \
42}
43
37static struct ieee80211_channel ath9k_2ghz_channels[] = { 44static struct ieee80211_channel ath9k_2ghz_channels[] = {
38 CHAN2G(2412, 0), /* Channel 1 */ 45 CHAN2G(2412, 0), /* Channel 1 */
39 CHAN2G(2417, 1), /* Channel 2 */ 46 CHAN2G(2417, 1), /* Channel 2 */
@@ -51,6 +58,37 @@ static struct ieee80211_channel ath9k_2ghz_channels[] = {
51 CHAN2G(2484, 13), /* Channel 14 */ 58 CHAN2G(2484, 13), /* Channel 14 */
52}; 59};
53 60
61static struct ieee80211_channel ath9k_5ghz_channels[] = {
62 /* _We_ call this UNII 1 */
63 CHAN5G(5180, 14), /* Channel 36 */
64 CHAN5G(5200, 15), /* Channel 40 */
65 CHAN5G(5220, 16), /* Channel 44 */
66 CHAN5G(5240, 17), /* Channel 48 */
67 /* _We_ call this UNII 2 */
68 CHAN5G(5260, 18), /* Channel 52 */
69 CHAN5G(5280, 19), /* Channel 56 */
70 CHAN5G(5300, 20), /* Channel 60 */
71 CHAN5G(5320, 21), /* Channel 64 */
72 /* _We_ call this "Middle band" */
73 CHAN5G(5500, 22), /* Channel 100 */
74 CHAN5G(5520, 23), /* Channel 104 */
75 CHAN5G(5540, 24), /* Channel 108 */
76 CHAN5G(5560, 25), /* Channel 112 */
77 CHAN5G(5580, 26), /* Channel 116 */
78 CHAN5G(5600, 27), /* Channel 120 */
79 CHAN5G(5620, 28), /* Channel 124 */
80 CHAN5G(5640, 29), /* Channel 128 */
81 CHAN5G(5660, 30), /* Channel 132 */
82 CHAN5G(5680, 31), /* Channel 136 */
83 CHAN5G(5700, 32), /* Channel 140 */
84 /* _We_ call this UNII 3 */
85 CHAN5G(5745, 33), /* Channel 149 */
86 CHAN5G(5765, 34), /* Channel 153 */
87 CHAN5G(5785, 35), /* Channel 157 */
88 CHAN5G(5805, 36), /* Channel 161 */
89 CHAN5G(5825, 37), /* Channel 165 */
90};
91
54/* Atheros hardware rate code addition for short premble */ 92/* Atheros hardware rate code addition for short premble */
55#define SHPCHECK(__hw_rate, __flags) \ 93#define SHPCHECK(__hw_rate, __flags) \
56 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0) 94 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
@@ -141,7 +179,7 @@ static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
141 return htc_connect_service(priv->htc, &req, ep_id); 179 return htc_connect_service(priv->htc, &req, ep_id);
142} 180}
143 181
144static int ath9k_init_htc_services(struct ath9k_htc_priv *priv) 182static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
145{ 183{
146 int ret; 184 int ret;
147 185
@@ -199,10 +237,28 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv)
199 if (ret) 237 if (ret)
200 goto err; 238 goto err;
201 239
240 /*
241 * Setup required credits before initializing HTC.
242 * This is a bit hacky, but, since queuing is done in
243 * the HIF layer, shouldn't matter much.
244 */
245
246 switch(devid) {
247 case 0x7010:
248 case 0x9018:
249 priv->htc->credits = 45;
250 break;
251 default:
252 priv->htc->credits = 33;
253 }
254
202 ret = htc_init(priv->htc); 255 ret = htc_init(priv->htc);
203 if (ret) 256 if (ret)
204 goto err; 257 goto err;
205 258
259 dev_info(priv->dev, "ath9k_htc: HTC initialized with %d credits\n",
260 priv->htc->credits);
261
206 return 0; 262 return 0;
207 263
208err: 264err:
@@ -398,17 +454,43 @@ static const struct ath_bus_ops ath9k_usb_bus_ops = {
398static void setup_ht_cap(struct ath9k_htc_priv *priv, 454static void setup_ht_cap(struct ath9k_htc_priv *priv,
399 struct ieee80211_sta_ht_cap *ht_info) 455 struct ieee80211_sta_ht_cap *ht_info)
400{ 456{
457 struct ath_common *common = ath9k_hw_common(priv->ah);
458 u8 tx_streams, rx_streams;
459 int i;
460
401 ht_info->ht_supported = true; 461 ht_info->ht_supported = true;
402 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 462 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
403 IEEE80211_HT_CAP_SM_PS | 463 IEEE80211_HT_CAP_SM_PS |
404 IEEE80211_HT_CAP_SGI_40 | 464 IEEE80211_HT_CAP_SGI_40 |
405 IEEE80211_HT_CAP_DSSSCCK40; 465 IEEE80211_HT_CAP_DSSSCCK40;
406 466
467 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
468 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
469
470 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
471
407 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 472 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
408 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; 473 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
409 474
410 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 475 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
411 ht_info->mcs.rx_mask[0] = 0xff; 476
477 /* ath9k_htc supports only 1 or 2 stream devices */
478 tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2);
479 rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2);
480
481 ath_print(common, ATH_DBG_CONFIG,
482 "TX streams %d, RX streams: %d\n",
483 tx_streams, rx_streams);
484
485 if (tx_streams != rx_streams) {
486 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
487 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
488 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
489 }
490
491 for (i = 0; i < rx_streams; i++)
492 ht_info->mcs.rx_mask[i] = 0xff;
493
412 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; 494 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
413} 495}
414 496
@@ -420,23 +502,37 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv)
420 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++) 502 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
421 priv->hwq_map[i] = -1; 503 priv->hwq_map[i] = -1;
422 504
423 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) { 505 priv->beaconq = ath9k_hw_beaconq_setup(priv->ah);
506 if (priv->beaconq == -1) {
507 ath_print(common, ATH_DBG_FATAL,
508 "Unable to setup BEACON xmit queue\n");
509 goto err;
510 }
511
512 priv->cabq = ath9k_htc_cabq_setup(priv);
513 if (priv->cabq == -1) {
514 ath_print(common, ATH_DBG_FATAL,
515 "Unable to setup CAB xmit queue\n");
516 goto err;
517 }
518
519 if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) {
424 ath_print(common, ATH_DBG_FATAL, 520 ath_print(common, ATH_DBG_FATAL,
425 "Unable to setup xmit queue for BE traffic\n"); 521 "Unable to setup xmit queue for BE traffic\n");
426 goto err; 522 goto err;
427 } 523 }
428 524
429 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) { 525 if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) {
430 ath_print(common, ATH_DBG_FATAL, 526 ath_print(common, ATH_DBG_FATAL,
431 "Unable to setup xmit queue for BK traffic\n"); 527 "Unable to setup xmit queue for BK traffic\n");
432 goto err; 528 goto err;
433 } 529 }
434 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) { 530 if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) {
435 ath_print(common, ATH_DBG_FATAL, 531 ath_print(common, ATH_DBG_FATAL,
436 "Unable to setup xmit queue for VI traffic\n"); 532 "Unable to setup xmit queue for VI traffic\n");
437 goto err; 533 goto err;
438 } 534 }
439 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) { 535 if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) {
440 ath_print(common, ATH_DBG_FATAL, 536 ath_print(common, ATH_DBG_FATAL,
441 "Unable to setup xmit queue for VO traffic\n"); 537 "Unable to setup xmit queue for VO traffic\n");
442 goto err; 538 goto err;
@@ -468,36 +564,6 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
468 */ 564 */
469 for (i = 0; i < common->keymax; i++) 565 for (i = 0; i < common->keymax; i++)
470 ath9k_hw_keyreset(priv->ah, (u16) i); 566 ath9k_hw_keyreset(priv->ah, (u16) i);
471
472 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
473 ATH9K_CIPHER_TKIP, NULL)) {
474 /*
475 * Whether we should enable h/w TKIP MIC.
476 * XXX: if we don't support WME TKIP MIC, then we wouldn't
477 * report WMM capable, so it's always safe to turn on
478 * TKIP MIC in this case.
479 */
480 ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
481 }
482
483 /*
484 * Check whether the separate key cache entries
485 * are required to handle both tx+rx MIC keys.
486 * With split mic keys the number of stations is limited
487 * to 27 otherwise 59.
488 */
489 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
490 ATH9K_CIPHER_TKIP, NULL)
491 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
492 ATH9K_CIPHER_MIC, NULL)
493 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
494 0, NULL))
495 common->splitmic = 1;
496
497 /* turn on mcast key search if possible */
498 if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
499 (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
500 1, 1, NULL);
501} 567}
502 568
503static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) 569static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
@@ -512,6 +578,17 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
512 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates = 578 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
513 ARRAY_SIZE(ath9k_legacy_rates); 579 ARRAY_SIZE(ath9k_legacy_rates);
514 } 580 }
581
582 if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) {
583 priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
584 priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
585 priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
586 ARRAY_SIZE(ath9k_5ghz_channels);
587 priv->sbands[IEEE80211_BAND_5GHZ].bitrates =
588 ath9k_legacy_rates + 4;
589 priv->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
590 ARRAY_SIZE(ath9k_legacy_rates) - 4;
591 }
515} 592}
516 593
517static void ath9k_init_misc(struct ath9k_htc_priv *priv) 594static void ath9k_init_misc(struct ath9k_htc_priv *priv)
@@ -524,7 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
524 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) 601 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
525 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); 602 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
526 603
527 priv->op_flags |= OP_TXAGGR;
528 priv->ah->opmode = NL80211_IFTYPE_STATION; 604 priv->ah->opmode = NL80211_IFTYPE_STATION;
529} 605}
530 606
@@ -556,14 +632,12 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
556 spin_lock_init(&priv->beacon_lock); 632 spin_lock_init(&priv->beacon_lock);
557 spin_lock_init(&priv->tx_lock); 633 spin_lock_init(&priv->tx_lock);
558 mutex_init(&priv->mutex); 634 mutex_init(&priv->mutex);
559 mutex_init(&priv->aggr_work.mutex);
560 mutex_init(&priv->htc_pm_lock); 635 mutex_init(&priv->htc_pm_lock);
561 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet, 636 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
562 (unsigned long)priv); 637 (unsigned long)priv);
563 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, 638 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
564 (unsigned long)priv); 639 (unsigned long)priv);
565 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv); 640 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
566 INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
567 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); 641 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
568 INIT_WORK(&priv->ps_work, ath9k_ps_work); 642 INIT_WORK(&priv->ps_work, ath9k_ps_work);
569 643
@@ -643,11 +717,17 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
643 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) 717 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
644 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 718 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
645 &priv->sbands[IEEE80211_BAND_2GHZ]; 719 &priv->sbands[IEEE80211_BAND_2GHZ];
720 if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
721 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
722 &priv->sbands[IEEE80211_BAND_5GHZ];
646 723
647 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { 724 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
648 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) 725 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
649 setup_ht_cap(priv, 726 setup_ht_cap(priv,
650 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); 727 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
728 if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
729 setup_ht_cap(priv,
730 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
651 } 731 }
652 732
653 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 733 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
@@ -747,7 +827,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
747 goto err_free; 827 goto err_free;
748 } 828 }
749 829
750 ret = ath9k_init_htc_services(priv); 830 ret = ath9k_init_htc_services(priv, devid);
751 if (ret) 831 if (ret)
752 goto err_init; 832 goto err_init;
753 833
@@ -790,7 +870,8 @@ int ath9k_htc_resume(struct htc_target *htc_handle)
790 if (ret) 870 if (ret)
791 return ret; 871 return ret;
792 872
793 ret = ath9k_init_htc_services(htc_handle->drv_priv); 873 ret = ath9k_init_htc_services(htc_handle->drv_priv,
874 htc_handle->drv_priv->ah->hw_version.devid);
794 return ret; 875 return ret;
795} 876}
796#endif 877#endif
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9d371c18eb41..05445d8a9818 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -27,13 +27,11 @@ static struct dentry *ath9k_debugfs_root;
27static void ath_update_txpow(struct ath9k_htc_priv *priv) 27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{ 28{
29 struct ath_hw *ah = priv->ah; 29 struct ath_hw *ah = priv->ah;
30 u32 txpow;
31 30
32 if (priv->curtxpow != priv->txpowlimit) { 31 if (priv->curtxpow != priv->txpowlimit) {
33 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit); 32 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
34 /* read back in case value is clamped */ 33 /* read back in case value is clamped */
35 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); 34 priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
36 priv->curtxpow = txpow;
37 } 35 }
38} 36}
39 37
@@ -325,142 +323,128 @@ static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
325 tcap.flags_ext = 0x80601000; 323 tcap.flags_ext = 0x80601000;
326 tcap.ampdu_limit = 0xffff0000; 324 tcap.ampdu_limit = 0xffff0000;
327 tcap.ampdu_subframes = 20; 325 tcap.ampdu_subframes = 20;
328 tcap.tx_chainmask_legacy = 1; 326 tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
329 tcap.protmode = 1; 327 tcap.protmode = 1;
330 tcap.tx_chainmask = 1; 328 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
331 329
332 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); 330 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
333 331
334 return ret; 332 return ret;
335} 333}
336 334
337static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv, 335static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
338 struct ieee80211_vif *vif, 336 struct ieee80211_sta *sta,
339 struct ieee80211_sta *sta) 337 struct ath9k_htc_target_rate *trate)
340{ 338{
341 struct ath_common *common = ath9k_hw_common(priv->ah);
342 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; 339 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
343 struct ieee80211_supported_band *sband; 340 struct ieee80211_supported_band *sband;
344 struct ath9k_htc_target_rate trate;
345 u32 caps = 0; 341 u32 caps = 0;
346 u8 cmd_rsp; 342 int i, j;
347 int i, j, ret;
348
349 memset(&trate, 0, sizeof(trate));
350 343
351 /* Only 2GHz is supported */ 344 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
352 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
353 345
354 for (i = 0, j = 0; i < sband->n_bitrates; i++) { 346 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
355 if (sta->supp_rates[sband->band] & BIT(i)) { 347 if (sta->supp_rates[sband->band] & BIT(i)) {
356 priv->tgt_rate.rates.legacy_rates.rs_rates[j] 348 trate->rates.legacy_rates.rs_rates[j]
357 = (sband->bitrates[i].bitrate * 2) / 10; 349 = (sband->bitrates[i].bitrate * 2) / 10;
358 j++; 350 j++;
359 } 351 }
360 } 352 }
361 priv->tgt_rate.rates.legacy_rates.rs_nrates = j; 353 trate->rates.legacy_rates.rs_nrates = j;
362 354
363 if (sta->ht_cap.ht_supported) { 355 if (sta->ht_cap.ht_supported) {
364 for (i = 0, j = 0; i < 77; i++) { 356 for (i = 0, j = 0; i < 77; i++) {
365 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) 357 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
366 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i; 358 trate->rates.ht_rates.rs_rates[j++] = i;
367 if (j == ATH_HTC_RATE_MAX) 359 if (j == ATH_HTC_RATE_MAX)
368 break; 360 break;
369 } 361 }
370 priv->tgt_rate.rates.ht_rates.rs_nrates = j; 362 trate->rates.ht_rates.rs_nrates = j;
371 363
372 caps = WLAN_RC_HT_FLAG; 364 caps = WLAN_RC_HT_FLAG;
365 if (sta->ht_cap.mcs.rx_mask[1])
366 caps |= WLAN_RC_DS_FLAG;
373 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 367 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
374 caps |= WLAN_RC_40_FLAG; 368 caps |= WLAN_RC_40_FLAG;
375 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) 369 if (conf_is_ht40(&priv->hw->conf) &&
370 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
371 caps |= WLAN_RC_SGI_FLAG;
372 else if (conf_is_ht20(&priv->hw->conf) &&
373 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
376 caps |= WLAN_RC_SGI_FLAG; 374 caps |= WLAN_RC_SGI_FLAG;
377
378 } 375 }
379 376
380 priv->tgt_rate.sta_index = ista->index; 377 trate->sta_index = ista->index;
381 priv->tgt_rate.isnew = 1; 378 trate->isnew = 1;
382 trate = priv->tgt_rate; 379 trate->capflags = cpu_to_be32(caps);
383 priv->tgt_rate.capflags = cpu_to_be32(caps); 380}
384 trate.capflags = cpu_to_be32(caps); 381
382static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
383 struct ath9k_htc_target_rate *trate)
384{
385 struct ath_common *common = ath9k_hw_common(priv->ah);
386 int ret;
387 u8 cmd_rsp;
385 388
386 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); 389 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
387 if (ret) { 390 if (ret) {
388 ath_print(common, ATH_DBG_FATAL, 391 ath_print(common, ATH_DBG_FATAL,
389 "Unable to initialize Rate information on target\n"); 392 "Unable to initialize Rate information on target\n");
390 return ret;
391 } 393 }
392 394
393 ath_print(common, ATH_DBG_CONFIG, 395 return ret;
394 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
395 return 0;
396} 396}
397 397
398static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40) 398static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
399 struct ieee80211_sta *sta)
399{ 400{
400 struct ath9k_htc_priv *priv = hw->priv; 401 struct ath_common *common = ath9k_hw_common(priv->ah);
401 struct ieee80211_conf *conf = &hw->conf; 402 struct ath9k_htc_target_rate trate;
402 403 int ret;
403 if (!conf_is_ht(conf))
404 return false;
405
406 if (!(priv->op_flags & OP_ASSOCIATED) ||
407 (priv->op_flags & OP_SCANNING))
408 return false;
409 404
410 if (conf_is_ht40(conf)) { 405 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
411 if (priv->ah->curchan->chanmode & 406 ath9k_htc_setup_rate(priv, sta, &trate);
412 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) { 407 ret = ath9k_htc_send_rate_cmd(priv, &trate);
413 return false; 408 if (!ret)
414 } else { 409 ath_print(common, ATH_DBG_CONFIG,
415 *cw40 = true; 410 "Updated target sta: %pM, rate caps: 0x%X\n",
416 return true; 411 sta->addr, be32_to_cpu(trate.capflags));
417 }
418 } else { /* ht20 */
419 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
420 return false;
421 else
422 return true;
423 }
424} 412}
425 413
426static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40) 414static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
415 struct ieee80211_vif *vif,
416 struct ieee80211_bss_conf *bss_conf)
427{ 417{
428 struct ath9k_htc_target_rate trate;
429 struct ath_common *common = ath9k_hw_common(priv->ah); 418 struct ath_common *common = ath9k_hw_common(priv->ah);
419 struct ath9k_htc_target_rate trate;
420 struct ieee80211_sta *sta;
430 int ret; 421 int ret;
431 u32 caps = be32_to_cpu(priv->tgt_rate.capflags);
432 u8 cmd_rsp;
433
434 memset(&trate, 0, sizeof(trate));
435
436 trate = priv->tgt_rate;
437 422
438 if (is_cw40) 423 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
439 caps |= WLAN_RC_40_FLAG;
440 else
441 caps &= ~WLAN_RC_40_FLAG;
442
443 priv->tgt_rate.capflags = cpu_to_be32(caps);
444 trate.capflags = cpu_to_be32(caps);
445 424
446 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); 425 rcu_read_lock();
447 if (ret) { 426 sta = ieee80211_find_sta(vif, bss_conf->bssid);
448 ath_print(common, ATH_DBG_FATAL, 427 if (!sta) {
449 "Unable to update Rate information on target\n"); 428 rcu_read_unlock();
450 return; 429 return;
451 } 430 }
431 ath9k_htc_setup_rate(priv, sta, &trate);
432 rcu_read_unlock();
452 433
453 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with " 434 ret = ath9k_htc_send_rate_cmd(priv, &trate);
454 "caps:0x%x on target\n", priv->tgt_rate.capflags); 435 if (!ret)
436 ath_print(common, ATH_DBG_CONFIG,
437 "Updated target sta: %pM, rate caps: 0x%X\n",
438 bss_conf->bssid, be32_to_cpu(trate.capflags));
455} 439}
456 440
457static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, 441int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
458 struct ieee80211_vif *vif, 442 struct ieee80211_vif *vif,
459 u8 *sta_addr, u8 tid, bool oper) 443 struct ieee80211_sta *sta,
444 enum ieee80211_ampdu_mlme_action action, u16 tid)
460{ 445{
461 struct ath_common *common = ath9k_hw_common(priv->ah); 446 struct ath_common *common = ath9k_hw_common(priv->ah);
462 struct ath9k_htc_target_aggr aggr; 447 struct ath9k_htc_target_aggr aggr;
463 struct ieee80211_sta *sta = NULL;
464 struct ath9k_htc_sta *ista; 448 struct ath9k_htc_sta *ista;
465 int ret = 0; 449 int ret = 0;
466 u8 cmd_rsp; 450 u8 cmd_rsp;
@@ -469,72 +453,28 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
469 return -EINVAL; 453 return -EINVAL;
470 454
471 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); 455 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
472
473 rcu_read_lock();
474
475 /* Check if we are able to retrieve the station */
476 sta = ieee80211_find_sta(vif, sta_addr);
477 if (!sta) {
478 rcu_read_unlock();
479 return -EINVAL;
480 }
481
482 ista = (struct ath9k_htc_sta *) sta->drv_priv; 456 ista = (struct ath9k_htc_sta *) sta->drv_priv;
483 457
484 if (oper)
485 ista->tid_state[tid] = AGGR_START;
486 else
487 ista->tid_state[tid] = AGGR_STOP;
488
489 aggr.sta_index = ista->index; 458 aggr.sta_index = ista->index;
490 459 aggr.tidno = tid & 0xf;
491 rcu_read_unlock(); 460 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
492
493 aggr.tidno = tid;
494 aggr.aggr_enable = oper;
495 461
496 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); 462 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
497 if (ret) 463 if (ret)
498 ath_print(common, ATH_DBG_CONFIG, 464 ath_print(common, ATH_DBG_CONFIG,
499 "Unable to %s TX aggregation for (%pM, %d)\n", 465 "Unable to %s TX aggregation for (%pM, %d)\n",
500 (oper) ? "start" : "stop", sta->addr, tid); 466 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
501 else 467 else
502 ath_print(common, ATH_DBG_CONFIG, 468 ath_print(common, ATH_DBG_CONFIG,
503 "%s aggregation for (%pM, %d)\n", 469 "%s TX aggregation for (%pM, %d)\n",
504 (oper) ? "Starting" : "Stopping", sta->addr, tid); 470 (aggr.aggr_enable) ? "Starting" : "Stopping",
505 471 sta->addr, tid);
506 return ret;
507}
508 472
509void ath9k_htc_aggr_work(struct work_struct *work) 473 spin_lock_bh(&priv->tx_lock);
510{ 474 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
511 int ret = 0; 475 spin_unlock_bh(&priv->tx_lock);
512 struct ath9k_htc_priv *priv =
513 container_of(work, struct ath9k_htc_priv,
514 ath9k_aggr_work.work);
515 struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
516
517 mutex_lock(&wk->mutex);
518
519 switch (wk->action) {
520 case IEEE80211_AMPDU_TX_START:
521 ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
522 wk->tid, true);
523 if (!ret)
524 ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr,
525 wk->tid);
526 break;
527 case IEEE80211_AMPDU_TX_STOP:
528 ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
529 wk->tid, false);
530 ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid);
531 break;
532 default:
533 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
534 "Unknown AMPDU action\n");
535 }
536 476
537 mutex_unlock(&wk->mutex); 477 return ret;
538} 478}
539 479
540/*********/ 480/*********/
@@ -617,6 +557,19 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
617 "%20s : %10u\n", "SKBs dropped", 557 "%20s : %10u\n", "SKBs dropped",
618 priv->debug.tx_stats.skb_dropped); 558 priv->debug.tx_stats.skb_dropped);
619 559
560 len += snprintf(buf + len, sizeof(buf) - len,
561 "%20s : %10u\n", "BE queued",
562 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
563 len += snprintf(buf + len, sizeof(buf) - len,
564 "%20s : %10u\n", "BK queued",
565 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
566 len += snprintf(buf + len, sizeof(buf) - len,
567 "%20s : %10u\n", "VI queued",
568 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
569 len += snprintf(buf + len, sizeof(buf) - len,
570 "%20s : %10u\n", "VO queued",
571 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
572
620 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 573 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
621} 574}
622 575
@@ -1054,6 +1007,95 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1054 wiphy_rfkill_start_polling(priv->hw->wiphy); 1007 wiphy_rfkill_start_polling(priv->hw->wiphy);
1055} 1008}
1056 1009
1010static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1011{
1012 struct ath9k_htc_priv *priv = hw->priv;
1013 struct ath_hw *ah = priv->ah;
1014 struct ath_common *common = ath9k_hw_common(ah);
1015 int ret;
1016 u8 cmd_rsp;
1017
1018 if (!ah->curchan)
1019 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1020
1021 /* Reset the HW */
1022 ret = ath9k_hw_reset(ah, ah->curchan, false);
1023 if (ret) {
1024 ath_print(common, ATH_DBG_FATAL,
1025 "Unable to reset hardware; reset status %d "
1026 "(freq %u MHz)\n", ret, ah->curchan->channel);
1027 }
1028
1029 ath_update_txpow(priv);
1030
1031 /* Start RX */
1032 WMI_CMD(WMI_START_RECV_CMDID);
1033 ath9k_host_rx_init(priv);
1034
1035 /* Start TX */
1036 htc_start(priv->htc);
1037 spin_lock_bh(&priv->tx_lock);
1038 priv->tx_queues_stop = false;
1039 spin_unlock_bh(&priv->tx_lock);
1040 ieee80211_wake_queues(hw);
1041
1042 WMI_CMD(WMI_ENABLE_INTR_CMDID);
1043
1044 /* Enable LED */
1045 ath9k_hw_cfg_output(ah, ah->led_pin,
1046 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1047 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1048}
1049
1050static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1051{
1052 struct ath9k_htc_priv *priv = hw->priv;
1053 struct ath_hw *ah = priv->ah;
1054 struct ath_common *common = ath9k_hw_common(ah);
1055 int ret;
1056 u8 cmd_rsp;
1057
1058 ath9k_htc_ps_wakeup(priv);
1059
1060 /* Disable LED */
1061 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1062 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1063
1064 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1065
1066 /* Stop TX */
1067 ieee80211_stop_queues(hw);
1068 htc_stop(priv->htc);
1069 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1070 skb_queue_purge(&priv->tx_queue);
1071
1072 /* Stop RX */
1073 WMI_CMD(WMI_STOP_RECV_CMDID);
1074
1075 /*
1076 * The MIB counters have to be disabled here,
1077 * since the target doesn't do it.
1078 */
1079 ath9k_hw_disable_mib_counters(ah);
1080
1081 if (!ah->curchan)
1082 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1083
1084 /* Reset the HW */
1085 ret = ath9k_hw_reset(ah, ah->curchan, false);
1086 if (ret) {
1087 ath_print(common, ATH_DBG_FATAL,
1088 "Unable to reset hardware; reset status %d "
1089 "(freq %u MHz)\n", ret, ah->curchan->channel);
1090 }
1091
1092 /* Disable the PHY */
1093 ath9k_hw_phy_disable(ah);
1094
1095 ath9k_htc_ps_restore(priv);
1096 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1097}
1098
1057/**********************/ 1099/**********************/
1058/* mac80211 Callbacks */ 1100/* mac80211 Callbacks */
1059/**********************/ 1101/**********************/
@@ -1099,7 +1141,7 @@ fail_tx:
1099 return 0; 1141 return 0;
1100} 1142}
1101 1143
1102static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) 1144static int ath9k_htc_start(struct ieee80211_hw *hw)
1103{ 1145{
1104 struct ath9k_htc_priv *priv = hw->priv; 1146 struct ath9k_htc_priv *priv = hw->priv;
1105 struct ath_hw *ah = priv->ah; 1147 struct ath_hw *ah = priv->ah;
@@ -1111,10 +1153,16 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1111 __be16 htc_mode; 1153 __be16 htc_mode;
1112 u8 cmd_rsp; 1154 u8 cmd_rsp;
1113 1155
1156 mutex_lock(&priv->mutex);
1157
1114 ath_print(common, ATH_DBG_CONFIG, 1158 ath_print(common, ATH_DBG_CONFIG,
1115 "Starting driver with initial channel: %d MHz\n", 1159 "Starting driver with initial channel: %d MHz\n",
1116 curchan->center_freq); 1160 curchan->center_freq);
1117 1161
1162 /* Ensure that HW is awake before flushing RX */
1163 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1164 WMI_CMD(WMI_FLUSH_RECV_CMDID);
1165
1118 /* setup initial channel */ 1166 /* setup initial channel */
1119 init_channel = ath9k_cmn_get_curchannel(hw, ah); 1167 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1120 1168
@@ -1127,6 +1175,7 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1127 ath_print(common, ATH_DBG_FATAL, 1175 ath_print(common, ATH_DBG_FATAL,
1128 "Unable to reset hardware; reset status %d " 1176 "Unable to reset hardware; reset status %d "
1129 "(freq %u MHz)\n", ret, curchan->center_freq); 1177 "(freq %u MHz)\n", ret, curchan->center_freq);
1178 mutex_unlock(&priv->mutex);
1130 return ret; 1179 return ret;
1131 } 1180 }
1132 1181
@@ -1147,31 +1196,14 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led)
1147 priv->tx_queues_stop = false; 1196 priv->tx_queues_stop = false;
1148 spin_unlock_bh(&priv->tx_lock); 1197 spin_unlock_bh(&priv->tx_lock);
1149 1198
1150 if (led) {
1151 /* Enable LED */
1152 ath9k_hw_cfg_output(ah, ah->led_pin,
1153 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1154 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1155 }
1156
1157 ieee80211_wake_queues(hw); 1199 ieee80211_wake_queues(hw);
1158 1200
1159 return ret;
1160}
1161
1162static int ath9k_htc_start(struct ieee80211_hw *hw)
1163{
1164 struct ath9k_htc_priv *priv = hw->priv;
1165 int ret = 0;
1166
1167 mutex_lock(&priv->mutex);
1168 ret = ath9k_htc_radio_enable(hw, false);
1169 mutex_unlock(&priv->mutex); 1201 mutex_unlock(&priv->mutex);
1170 1202
1171 return ret; 1203 return ret;
1172} 1204}
1173 1205
1174static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) 1206static void ath9k_htc_stop(struct ieee80211_hw *hw)
1175{ 1207{
1176 struct ath9k_htc_priv *priv = hw->priv; 1208 struct ath9k_htc_priv *priv = hw->priv;
1177 struct ath_hw *ah = priv->ah; 1209 struct ath_hw *ah = priv->ah;
@@ -1179,21 +1211,17 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1179 int ret = 0; 1211 int ret = 0;
1180 u8 cmd_rsp; 1212 u8 cmd_rsp;
1181 1213
1214 mutex_lock(&priv->mutex);
1215
1182 if (priv->op_flags & OP_INVALID) { 1216 if (priv->op_flags & OP_INVALID) {
1183 ath_print(common, ATH_DBG_ANY, "Device not present\n"); 1217 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1218 mutex_unlock(&priv->mutex);
1184 return; 1219 return;
1185 } 1220 }
1186 1221
1187 if (led) {
1188 /* Disable LED */
1189 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1190 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1191 }
1192
1193 /* Cancel all the running timers/work .. */ 1222 /* Cancel all the running timers/work .. */
1194 cancel_work_sync(&priv->ps_work); 1223 cancel_work_sync(&priv->ps_work);
1195 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1224 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1196 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1197 cancel_delayed_work_sync(&priv->ath9k_led_blink_work); 1225 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1198 ath9k_led_stop_brightness(priv); 1226 ath9k_led_stop_brightness(priv);
1199 1227
@@ -1202,12 +1230,6 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1202 WMI_CMD(WMI_DISABLE_INTR_CMDID); 1230 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1203 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); 1231 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1204 WMI_CMD(WMI_STOP_RECV_CMDID); 1232 WMI_CMD(WMI_STOP_RECV_CMDID);
1205 ath9k_hw_phy_disable(ah);
1206 ath9k_hw_disable(ah);
1207 ath9k_hw_configpcipowersave(ah, 1, 1);
1208 ath9k_htc_ps_restore(priv);
1209 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1210
1211 skb_queue_purge(&priv->tx_queue); 1233 skb_queue_purge(&priv->tx_queue);
1212 1234
1213 /* Remove monitor interface here */ 1235 /* Remove monitor interface here */
@@ -1220,21 +1242,18 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led)
1220 "Monitor interface removed\n"); 1242 "Monitor interface removed\n");
1221 } 1243 }
1222 1244
1245 ath9k_hw_phy_disable(ah);
1246 ath9k_hw_disable(ah);
1247 ath9k_hw_configpcipowersave(ah, 1, 1);
1248 ath9k_htc_ps_restore(priv);
1249 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1250
1223 priv->op_flags |= OP_INVALID; 1251 priv->op_flags |= OP_INVALID;
1224 1252
1225 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); 1253 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1226}
1227
1228static void ath9k_htc_stop(struct ieee80211_hw *hw)
1229{
1230 struct ath9k_htc_priv *priv = hw->priv;
1231
1232 mutex_lock(&priv->mutex);
1233 ath9k_htc_radio_disable(hw, false);
1234 mutex_unlock(&priv->mutex); 1254 mutex_unlock(&priv->mutex);
1235} 1255}
1236 1256
1237
1238static int ath9k_htc_add_interface(struct ieee80211_hw *hw, 1257static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1239 struct ieee80211_vif *vif) 1258 struct ieee80211_vif *vif)
1240{ 1259{
@@ -1302,6 +1321,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1302out: 1321out:
1303 ath9k_htc_ps_restore(priv); 1322 ath9k_htc_ps_restore(priv);
1304 mutex_unlock(&priv->mutex); 1323 mutex_unlock(&priv->mutex);
1324
1305 return ret; 1325 return ret;
1306} 1326}
1307 1327
@@ -1318,6 +1338,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1318 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); 1338 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1319 1339
1320 mutex_lock(&priv->mutex); 1340 mutex_lock(&priv->mutex);
1341 ath9k_htc_ps_wakeup(priv);
1321 1342
1322 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 1343 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1323 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); 1344 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
@@ -1328,6 +1349,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1328 ath9k_htc_remove_station(priv, vif, NULL); 1349 ath9k_htc_remove_station(priv, vif, NULL);
1329 priv->vif = NULL; 1350 priv->vif = NULL;
1330 1351
1352 ath9k_htc_ps_restore(priv);
1331 mutex_unlock(&priv->mutex); 1353 mutex_unlock(&priv->mutex);
1332} 1354}
1333 1355
@@ -1343,30 +1365,27 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1343 bool enable_radio = false; 1365 bool enable_radio = false;
1344 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); 1366 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1345 1367
1368 mutex_lock(&priv->htc_pm_lock);
1346 if (!idle && priv->ps_idle) 1369 if (!idle && priv->ps_idle)
1347 enable_radio = true; 1370 enable_radio = true;
1348
1349 priv->ps_idle = idle; 1371 priv->ps_idle = idle;
1372 mutex_unlock(&priv->htc_pm_lock);
1350 1373
1351 if (enable_radio) { 1374 if (enable_radio) {
1352 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1353 ath9k_htc_radio_enable(hw, true);
1354 ath_print(common, ATH_DBG_CONFIG, 1375 ath_print(common, ATH_DBG_CONFIG,
1355 "not-idle: enabling radio\n"); 1376 "not-idle: enabling radio\n");
1377 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1378 ath9k_htc_radio_enable(hw);
1356 } 1379 }
1357 } 1380 }
1358 1381
1359 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1382 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1360 struct ieee80211_channel *curchan = hw->conf.channel; 1383 struct ieee80211_channel *curchan = hw->conf.channel;
1361 int pos = curchan->hw_value; 1384 int pos = curchan->hw_value;
1362 bool is_cw40 = false;
1363 1385
1364 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", 1386 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1365 curchan->center_freq); 1387 curchan->center_freq);
1366 1388
1367 if (check_rc_update(hw, &is_cw40))
1368 ath9k_htc_rc_update(priv, is_cw40);
1369
1370 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]); 1389 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1371 1390
1372 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { 1391 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
@@ -1399,14 +1418,21 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1399 } 1418 }
1400 } 1419 }
1401 1420
1402 if (priv->ps_idle) { 1421 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1422 mutex_lock(&priv->htc_pm_lock);
1423 if (!priv->ps_idle) {
1424 mutex_unlock(&priv->htc_pm_lock);
1425 goto out;
1426 }
1427 mutex_unlock(&priv->htc_pm_lock);
1428
1403 ath_print(common, ATH_DBG_CONFIG, 1429 ath_print(common, ATH_DBG_CONFIG,
1404 "idle: disabling radio\n"); 1430 "idle: disabling radio\n");
1405 ath9k_htc_radio_disable(hw, true); 1431 ath9k_htc_radio_disable(hw);
1406 } 1432 }
1407 1433
1434out:
1408 mutex_unlock(&priv->mutex); 1435 mutex_unlock(&priv->mutex);
1409
1410 return 0; 1436 return 0;
1411} 1437}
1412 1438
@@ -1428,8 +1454,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1428 u32 rfilt; 1454 u32 rfilt;
1429 1455
1430 mutex_lock(&priv->mutex); 1456 mutex_lock(&priv->mutex);
1431
1432 ath9k_htc_ps_wakeup(priv); 1457 ath9k_htc_ps_wakeup(priv);
1458
1433 changed_flags &= SUPPORTED_FILTERS; 1459 changed_flags &= SUPPORTED_FILTERS;
1434 *total_flags &= SUPPORTED_FILTERS; 1460 *total_flags &= SUPPORTED_FILTERS;
1435 1461
@@ -1444,30 +1470,38 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1444 mutex_unlock(&priv->mutex); 1470 mutex_unlock(&priv->mutex);
1445} 1471}
1446 1472
1447static void ath9k_htc_sta_notify(struct ieee80211_hw *hw, 1473static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1448 struct ieee80211_vif *vif, 1474 struct ieee80211_vif *vif,
1449 enum sta_notify_cmd cmd, 1475 struct ieee80211_sta *sta)
1450 struct ieee80211_sta *sta)
1451{ 1476{
1452 struct ath9k_htc_priv *priv = hw->priv; 1477 struct ath9k_htc_priv *priv = hw->priv;
1453 int ret; 1478 int ret;
1454 1479
1455 mutex_lock(&priv->mutex); 1480 mutex_lock(&priv->mutex);
1481 ath9k_htc_ps_wakeup(priv);
1482 ret = ath9k_htc_add_station(priv, vif, sta);
1483 if (!ret)
1484 ath9k_htc_init_rate(priv, sta);
1485 ath9k_htc_ps_restore(priv);
1486 mutex_unlock(&priv->mutex);
1456 1487
1457 switch (cmd) { 1488 return ret;
1458 case STA_NOTIFY_ADD: 1489}
1459 ret = ath9k_htc_add_station(priv, vif, sta); 1490
1460 if (!ret) 1491static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1461 ath9k_htc_init_rate(priv, vif, sta); 1492 struct ieee80211_vif *vif,
1462 break; 1493 struct ieee80211_sta *sta)
1463 case STA_NOTIFY_REMOVE: 1494{
1464 ath9k_htc_remove_station(priv, vif, sta); 1495 struct ath9k_htc_priv *priv = hw->priv;
1465 break; 1496 int ret;
1466 default:
1467 break;
1468 }
1469 1497
1498 mutex_lock(&priv->mutex);
1499 ath9k_htc_ps_wakeup(priv);
1500 ret = ath9k_htc_remove_station(priv, vif, sta);
1501 ath9k_htc_ps_restore(priv);
1470 mutex_unlock(&priv->mutex); 1502 mutex_unlock(&priv->mutex);
1503
1504 return ret;
1471} 1505}
1472 1506
1473static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, 1507static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -1482,6 +1516,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1482 return 0; 1516 return 0;
1483 1517
1484 mutex_lock(&priv->mutex); 1518 mutex_lock(&priv->mutex);
1519 ath9k_htc_ps_wakeup(priv);
1485 1520
1486 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); 1521 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1487 1522
@@ -1499,9 +1534,16 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1499 params->cw_max, params->txop); 1534 params->cw_max, params->txop);
1500 1535
1501 ret = ath_htc_txq_update(priv, qnum, &qi); 1536 ret = ath_htc_txq_update(priv, qnum, &qi);
1502 if (ret) 1537 if (ret) {
1503 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); 1538 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1539 goto out;
1540 }
1504 1541
1542 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1543 (qnum == priv->hwq_map[WME_AC_BE]))
1544 ath9k_htc_beaconq_config(priv);
1545out:
1546 ath9k_htc_ps_restore(priv);
1505 mutex_unlock(&priv->mutex); 1547 mutex_unlock(&priv->mutex);
1506 1548
1507 return ret; 1549 return ret;
@@ -1574,7 +1616,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1574 ath_start_ani(priv); 1616 ath_start_ani(priv);
1575 } else { 1617 } else {
1576 priv->op_flags &= ~OP_ASSOCIATED; 1618 priv->op_flags &= ~OP_ASSOCIATED;
1577 cancel_work_sync(&priv->ps_work);
1578 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1619 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1579 } 1620 }
1580 } 1621 }
@@ -1631,6 +1672,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1631 ath9k_hw_init_global_settings(ah); 1672 ath9k_hw_init_global_settings(ah);
1632 } 1673 }
1633 1674
1675 if (changed & BSS_CHANGED_HT)
1676 ath9k_htc_update_rate(priv, vif, bss_conf);
1677
1634 ath9k_htc_ps_restore(priv); 1678 ath9k_htc_ps_restore(priv);
1635 mutex_unlock(&priv->mutex); 1679 mutex_unlock(&priv->mutex);
1636} 1680}
@@ -1641,7 +1685,9 @@ static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1641 u64 tsf; 1685 u64 tsf;
1642 1686
1643 mutex_lock(&priv->mutex); 1687 mutex_lock(&priv->mutex);
1688 ath9k_htc_ps_wakeup(priv);
1644 tsf = ath9k_hw_gettsf64(priv->ah); 1689 tsf = ath9k_hw_gettsf64(priv->ah);
1690 ath9k_htc_ps_restore(priv);
1645 mutex_unlock(&priv->mutex); 1691 mutex_unlock(&priv->mutex);
1646 1692
1647 return tsf; 1693 return tsf;
@@ -1652,7 +1698,9 @@ static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1652 struct ath9k_htc_priv *priv = hw->priv; 1698 struct ath9k_htc_priv *priv = hw->priv;
1653 1699
1654 mutex_lock(&priv->mutex); 1700 mutex_lock(&priv->mutex);
1701 ath9k_htc_ps_wakeup(priv);
1655 ath9k_hw_settsf64(priv->ah, tsf); 1702 ath9k_hw_settsf64(priv->ah, tsf);
1703 ath9k_htc_ps_restore(priv);
1656 mutex_unlock(&priv->mutex); 1704 mutex_unlock(&priv->mutex);
1657} 1705}
1658 1706
@@ -1660,11 +1708,11 @@ static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1660{ 1708{
1661 struct ath9k_htc_priv *priv = hw->priv; 1709 struct ath9k_htc_priv *priv = hw->priv;
1662 1710
1663 ath9k_htc_ps_wakeup(priv);
1664 mutex_lock(&priv->mutex); 1711 mutex_lock(&priv->mutex);
1712 ath9k_htc_ps_wakeup(priv);
1665 ath9k_hw_reset_tsf(priv->ah); 1713 ath9k_hw_reset_tsf(priv->ah);
1666 mutex_unlock(&priv->mutex);
1667 ath9k_htc_ps_restore(priv); 1714 ath9k_htc_ps_restore(priv);
1715 mutex_unlock(&priv->mutex);
1668} 1716}
1669 1717
1670static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, 1718static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
@@ -1674,8 +1722,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1674 u16 tid, u16 *ssn) 1722 u16 tid, u16 *ssn)
1675{ 1723{
1676 struct ath9k_htc_priv *priv = hw->priv; 1724 struct ath9k_htc_priv *priv = hw->priv;
1677 struct ath9k_htc_aggr_work *work = &priv->aggr_work;
1678 struct ath9k_htc_sta *ista; 1725 struct ath9k_htc_sta *ista;
1726 int ret = 0;
1679 1727
1680 switch (action) { 1728 switch (action) {
1681 case IEEE80211_AMPDU_RX_START: 1729 case IEEE80211_AMPDU_RX_START:
@@ -1683,26 +1731,26 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1683 case IEEE80211_AMPDU_RX_STOP: 1731 case IEEE80211_AMPDU_RX_STOP:
1684 break; 1732 break;
1685 case IEEE80211_AMPDU_TX_START: 1733 case IEEE80211_AMPDU_TX_START:
1734 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1735 if (!ret)
1736 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1737 break;
1686 case IEEE80211_AMPDU_TX_STOP: 1738 case IEEE80211_AMPDU_TX_STOP:
1687 if (!(priv->op_flags & OP_TXAGGR)) 1739 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1688 return -ENOTSUPP; 1740 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1689 memcpy(work->sta_addr, sta->addr, ETH_ALEN);
1690 work->hw = hw;
1691 work->vif = vif;
1692 work->action = action;
1693 work->tid = tid;
1694 ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
1695 break; 1741 break;
1696 case IEEE80211_AMPDU_TX_OPERATIONAL: 1742 case IEEE80211_AMPDU_TX_OPERATIONAL:
1697 ista = (struct ath9k_htc_sta *) sta->drv_priv; 1743 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1744 spin_lock_bh(&priv->tx_lock);
1698 ista->tid_state[tid] = AGGR_OPERATIONAL; 1745 ista->tid_state[tid] = AGGR_OPERATIONAL;
1746 spin_unlock_bh(&priv->tx_lock);
1699 break; 1747 break;
1700 default: 1748 default:
1701 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, 1749 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1702 "Unknown AMPDU action\n"); 1750 "Unknown AMPDU action\n");
1703 } 1751 }
1704 1752
1705 return 0; 1753 return ret;
1706} 1754}
1707 1755
1708static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) 1756static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
@@ -1722,8 +1770,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1722{ 1770{
1723 struct ath9k_htc_priv *priv = hw->priv; 1771 struct ath9k_htc_priv *priv = hw->priv;
1724 1772
1725 ath9k_htc_ps_wakeup(priv);
1726 mutex_lock(&priv->mutex); 1773 mutex_lock(&priv->mutex);
1774 ath9k_htc_ps_wakeup(priv);
1727 spin_lock_bh(&priv->beacon_lock); 1775 spin_lock_bh(&priv->beacon_lock);
1728 priv->op_flags &= ~OP_SCANNING; 1776 priv->op_flags &= ~OP_SCANNING;
1729 spin_unlock_bh(&priv->beacon_lock); 1777 spin_unlock_bh(&priv->beacon_lock);
@@ -1731,8 +1779,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1731 if (priv->op_flags & OP_ASSOCIATED) 1779 if (priv->op_flags & OP_ASSOCIATED)
1732 ath9k_htc_beacon_config(priv, priv->vif); 1780 ath9k_htc_beacon_config(priv, priv->vif);
1733 ath_start_ani(priv); 1781 ath_start_ani(priv);
1734 mutex_unlock(&priv->mutex);
1735 ath9k_htc_ps_restore(priv); 1782 ath9k_htc_ps_restore(priv);
1783 mutex_unlock(&priv->mutex);
1736} 1784}
1737 1785
1738static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 1786static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
@@ -1746,8 +1794,10 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1746 struct ath9k_htc_priv *priv = hw->priv; 1794 struct ath9k_htc_priv *priv = hw->priv;
1747 1795
1748 mutex_lock(&priv->mutex); 1796 mutex_lock(&priv->mutex);
1797 ath9k_htc_ps_wakeup(priv);
1749 priv->ah->coverage_class = coverage_class; 1798 priv->ah->coverage_class = coverage_class;
1750 ath9k_hw_init_global_settings(priv->ah); 1799 ath9k_hw_init_global_settings(priv->ah);
1800 ath9k_htc_ps_restore(priv);
1751 mutex_unlock(&priv->mutex); 1801 mutex_unlock(&priv->mutex);
1752} 1802}
1753 1803
@@ -1759,7 +1809,8 @@ struct ieee80211_ops ath9k_htc_ops = {
1759 .remove_interface = ath9k_htc_remove_interface, 1809 .remove_interface = ath9k_htc_remove_interface,
1760 .config = ath9k_htc_config, 1810 .config = ath9k_htc_config,
1761 .configure_filter = ath9k_htc_configure_filter, 1811 .configure_filter = ath9k_htc_configure_filter,
1762 .sta_notify = ath9k_htc_sta_notify, 1812 .sta_add = ath9k_htc_sta_add,
1813 .sta_remove = ath9k_htc_sta_remove,
1763 .conf_tx = ath9k_htc_conf_tx, 1814 .conf_tx = ath9k_htc_conf_tx,
1764 .bss_info_changed = ath9k_htc_bss_info_changed, 1815 .bss_info_changed = ath9k_htc_bss_info_changed,
1765 .set_key = ath9k_htc_set_key, 1816 .set_key = ath9k_htc_set_key,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 2571b443ac82..bd0b4acc3ece 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -20,19 +20,29 @@
20/* TX */ 20/* TX */
21/******/ 21/******/
22 22
23#define ATH9K_HTC_INIT_TXQ(subtype) do { \
24 qi.tqi_subtype = subtype; \
25 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \
26 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \
27 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \
28 qi.tqi_physCompBuf = 0; \
29 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | \
30 TXQ_FLAG_TXDESCINT_ENABLE; \
31 } while (0)
32
23int get_hw_qnum(u16 queue, int *hwq_map) 33int get_hw_qnum(u16 queue, int *hwq_map)
24{ 34{
25 switch (queue) { 35 switch (queue) {
26 case 0: 36 case 0:
27 return hwq_map[ATH9K_WME_AC_VO]; 37 return hwq_map[WME_AC_VO];
28 case 1: 38 case 1:
29 return hwq_map[ATH9K_WME_AC_VI]; 39 return hwq_map[WME_AC_VI];
30 case 2: 40 case 2:
31 return hwq_map[ATH9K_WME_AC_BE]; 41 return hwq_map[WME_AC_BE];
32 case 3: 42 case 3:
33 return hwq_map[ATH9K_WME_AC_BK]; 43 return hwq_map[WME_AC_BK];
34 default: 44 default:
35 return hwq_map[ATH9K_WME_AC_BE]; 45 return hwq_map[WME_AC_BE];
36 } 46 }
37} 47}
38 48
@@ -71,7 +81,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
71 struct ath9k_htc_vif *avp; 81 struct ath9k_htc_vif *avp;
72 struct ath9k_htc_tx_ctl tx_ctl; 82 struct ath9k_htc_tx_ctl tx_ctl;
73 enum htc_endpoint_id epid; 83 enum htc_endpoint_id epid;
74 u16 qnum, hw_qnum; 84 u16 qnum;
75 __le16 fc; 85 __le16 fc;
76 u8 *tx_fhdr; 86 u8 *tx_fhdr;
77 u8 sta_idx; 87 u8 sta_idx;
@@ -131,20 +141,23 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
131 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); 141 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
132 142
133 qnum = skb_get_queue_mapping(skb); 143 qnum = skb_get_queue_mapping(skb);
134 hw_qnum = get_hw_qnum(qnum, priv->hwq_map);
135 144
136 switch (hw_qnum) { 145 switch (qnum) {
137 case 0: 146 case 0:
138 epid = priv->data_be_ep; 147 TX_QSTAT_INC(WME_AC_VO);
148 epid = priv->data_vo_ep;
139 break; 149 break;
140 case 2: 150 case 1:
151 TX_QSTAT_INC(WME_AC_VI);
141 epid = priv->data_vi_ep; 152 epid = priv->data_vi_ep;
142 break; 153 break;
143 case 3: 154 case 2:
144 epid = priv->data_vo_ep; 155 TX_QSTAT_INC(WME_AC_BE);
156 epid = priv->data_be_ep;
145 break; 157 break;
146 case 1: 158 case 3:
147 default: 159 default:
160 TX_QSTAT_INC(WME_AC_BK);
148 epid = priv->data_bk_ep; 161 epid = priv->data_bk_ep;
149 break; 162 break;
150 } 163 }
@@ -174,6 +187,19 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
174 return htc_send(priv->htc, skb, epid, &tx_ctl); 187 return htc_send(priv->htc, skb, epid, &tx_ctl);
175} 188}
176 189
190static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
191 struct ath9k_htc_sta *ista, u8 tid)
192{
193 bool ret = false;
194
195 spin_lock_bh(&priv->tx_lock);
196 if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
197 ret = true;
198 spin_unlock_bh(&priv->tx_lock);
199
200 return ret;
201}
202
177void ath9k_tx_tasklet(unsigned long data) 203void ath9k_tx_tasklet(unsigned long data)
178{ 204{
179 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; 205 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
@@ -203,8 +229,7 @@ void ath9k_tx_tasklet(unsigned long data)
203 /* Check if we need to start aggregation */ 229 /* Check if we need to start aggregation */
204 230
205 if (sta && conf_is_ht(&priv->hw->conf) && 231 if (sta && conf_is_ht(&priv->hw->conf) &&
206 (priv->op_flags & OP_TXAGGR) 232 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
207 && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
208 if (ieee80211_is_data_qos(fc)) { 233 if (ieee80211_is_data_qos(fc)) {
209 u8 *qc, tid; 234 u8 *qc, tid;
210 struct ath9k_htc_sta *ista; 235 struct ath9k_htc_sta *ista;
@@ -213,10 +238,11 @@ void ath9k_tx_tasklet(unsigned long data)
213 tid = qc[0] & 0xf; 238 tid = qc[0] & 0xf;
214 ista = (struct ath9k_htc_sta *)sta->drv_priv; 239 ista = (struct ath9k_htc_sta *)sta->drv_priv;
215 240
216 if ((tid < ATH9K_HTC_MAX_TID) && 241 if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
217 ista->tid_state[tid] == AGGR_STOP) {
218 ieee80211_start_tx_ba_session(sta, tid); 242 ieee80211_start_tx_ba_session(sta, tid);
243 spin_lock_bh(&priv->tx_lock);
219 ista->tid_state[tid] = AGGR_PROGRESS; 244 ista->tid_state[tid] = AGGR_PROGRESS;
245 spin_unlock_bh(&priv->tx_lock);
220 } 246 }
221 } 247 }
222 } 248 }
@@ -284,8 +310,7 @@ void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
284 310
285} 311}
286 312
287bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, 313bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype)
288 enum ath9k_tx_queue_subtype subtype)
289{ 314{
290 struct ath_hw *ah = priv->ah; 315 struct ath_hw *ah = priv->ah;
291 struct ath_common *common = ath9k_hw_common(ah); 316 struct ath_common *common = ath9k_hw_common(ah);
@@ -293,13 +318,7 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
293 int qnum; 318 int qnum;
294 319
295 memset(&qi, 0, sizeof(qi)); 320 memset(&qi, 0, sizeof(qi));
296 321 ATH9K_HTC_INIT_TXQ(subtype);
297 qi.tqi_subtype = subtype;
298 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
299 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
300 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
301 qi.tqi_physCompBuf = 0;
302 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
303 322
304 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi); 323 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
305 if (qnum == -1) 324 if (qnum == -1)
@@ -317,6 +336,16 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
317 return true; 336 return true;
318} 337}
319 338
339int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv)
340{
341 struct ath9k_tx_queue_info qi;
342
343 memset(&qi, 0, sizeof(qi));
344 ATH9K_HTC_INIT_TXQ(0);
345
346 return ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_CAB, &qi);
347}
348
320/******/ 349/******/
321/* RX */ 350/* RX */
322/******/ 351/******/
@@ -387,9 +416,6 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
387 /* configure operational mode */ 416 /* configure operational mode */
388 ath9k_hw_setopmode(ah); 417 ath9k_hw_setopmode(ah);
389 418
390 /* Handle any link-level address change. */
391 ath9k_hw_setmac(ah, common->macaddr);
392
393 /* calculate and install multicast filter */ 419 /* calculate and install multicast filter */
394 mfilt[0] = mfilt[1] = ~0; 420 mfilt[0] = mfilt[1] = ~0;
395 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); 421 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
@@ -399,7 +425,7 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
399{ 425{
400 ath9k_hw_rxena(priv->ah); 426 ath9k_hw_rxena(priv->ah);
401 ath9k_htc_opmode_init(priv); 427 ath9k_htc_opmode_init(priv);
402 ath9k_hw_startpcureceive(priv->ah); 428 ath9k_hw_startpcureceive(priv->ah, (priv->op_flags & OP_SCANNING));
403 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER; 429 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
404} 430}
405 431
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 064397fd738e..705c0f342e1c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -89,7 +89,6 @@ static void htc_process_target_rdy(struct htc_target *target,
89 struct htc_endpoint *endpoint; 89 struct htc_endpoint *endpoint;
90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf; 90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
91 91
92 target->credits = be16_to_cpu(htc_ready_msg->credits);
93 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size); 92 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
94 93
95 endpoint = &target->endpoint[ENDPOINT0]; 94 endpoint = &target->endpoint[ENDPOINT0];
@@ -159,7 +158,7 @@ static int htc_config_pipe_credits(struct htc_target *target)
159 158
160 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID); 159 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
161 cp_msg->pipe_id = USB_WLAN_TX_PIPE; 160 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
162 cp_msg->credits = 28; 161 cp_msg->credits = target->credits;
163 162
164 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; 163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
165 164
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 624422a8169e..381da6c93b14 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -128,6 +128,17 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
128 ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); 128 ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
129} 129}
130 130
131static inline void ath9k_hw_procmibevent(struct ath_hw *ah)
132{
133 ath9k_hw_ops(ah)->ani_proc_mib_event(ah);
134}
135
136static inline void ath9k_hw_ani_monitor(struct ath_hw *ah,
137 struct ath9k_channel *chan)
138{
139 ath9k_hw_ops(ah)->ani_monitor(ah, chan);
140}
141
131/* Private hardware call ops */ 142/* Private hardware call ops */
132 143
133/* PHY ops */ 144/* PHY ops */
@@ -277,4 +288,9 @@ static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
277 return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType); 288 return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
278} 289}
279 290
291static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
292{
293 ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning);
294}
295
280#endif /* ATH9K_HW_OPS_H */ 296#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c33f17dbe6f1..1ed144038c36 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -23,11 +23,6 @@
23#include "rc.h" 23#include "rc.h"
24#include "ar9003_mac.h" 24#include "ar9003_mac.h"
25 25
26#define ATH9K_CLOCK_RATE_CCK 22
27#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
28#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
29#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44
30
31static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 26static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
32 27
33MODULE_AUTHOR("Atheros Communications"); 28MODULE_AUTHOR("Atheros Communications");
@@ -80,6 +75,15 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
80 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); 75 ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah);
81} 76}
82 77
78static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
79{
80 /* You will not have this callback if using the old ANI */
81 if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs)
82 return;
83
84 ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah);
85}
86
83/********************/ 87/********************/
84/* Helper Functions */ 88/* Helper Functions */
85/********************/ 89/********************/
@@ -371,13 +375,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
371 ah->config.ofdm_trig_high = 500; 375 ah->config.ofdm_trig_high = 500;
372 ah->config.cck_trig_high = 200; 376 ah->config.cck_trig_high = 200;
373 ah->config.cck_trig_low = 100; 377 ah->config.cck_trig_low = 100;
374 378 ah->config.enable_ani = true;
375 /*
376 * For now ANI is disabled for AR9003, it is still
377 * being tested.
378 */
379 if (!AR_SREV_9300_20_OR_LATER(ah))
380 ah->config.enable_ani = 1;
381 379
382 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 380 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
383 ah->config.spurchans[i][0] = AR_NO_SPUR; 381 ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -390,12 +388,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
390 ah->config.ht_enable = 0; 388 ah->config.ht_enable = 0;
391 389
392 ah->config.rx_intr_mitigation = true; 390 ah->config.rx_intr_mitigation = true;
393 391 ah->config.pcieSerDesWrite = true;
394 /*
395 * Tx IQ Calibration (ah->config.tx_iq_calibration) is only
396 * used by AR9003, but it is showing reliability issues.
397 * It will take a while to fix so this is currently disabled.
398 */
399 392
400 /* 393 /*
401 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 394 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -433,7 +426,9 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
433 ah->ah_flags = AH_USE_EEPROM; 426 ah->ah_flags = AH_USE_EEPROM;
434 427
435 ah->atim_window = 0; 428 ah->atim_window = 0;
436 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; 429 ah->sta_id1_defaults =
430 AR_STA_ID1_CRPT_MIC_ENABLE |
431 AR_STA_ID1_MCAST_KSRCH;
437 ah->beacon_interval = 100; 432 ah->beacon_interval = 100;
438 ah->enable_32kHz_clock = DONT_USE_32KHZ; 433 ah->enable_32kHz_clock = DONT_USE_32KHZ;
439 ah->slottime = (u32) -1; 434 ah->slottime = (u32) -1;
@@ -571,28 +566,19 @@ static int __ath9k_hw_init(struct ath_hw *ah)
571 ah->ani_function = ATH9K_ANI_ALL; 566 ah->ani_function = ATH9K_ANI_ALL;
572 if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 567 if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah))
573 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; 568 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
569 if (!AR_SREV_9300_20_OR_LATER(ah))
570 ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
574 571
575 ath9k_hw_init_mode_regs(ah); 572 ath9k_hw_init_mode_regs(ah);
576 573
577 /* 574 /*
578 * Configire PCIE after Ini init. SERDES values now come from ini file 575 * Read back AR_WA into a permanent copy and set bits 14 and 17.
579 * This enables PCIe low power mode. 576 * We need to do this to avoid RMW of this register. We cannot
577 * read the reg when chip is asleep.
580 */ 578 */
581 if (AR_SREV_9300_20_OR_LATER(ah)) { 579 ah->WARegVal = REG_READ(ah, AR_WA);
582 u32 regval; 580 ah->WARegVal |= (AR_WA_D3_L1_DISABLE |
583 unsigned int i; 581 AR_WA_ASPM_TIMER_BASED_DISABLE);
584
585 /* Set Bits 16 and 17 in the AR_WA register. */
586 regval = REG_READ(ah, AR_WA);
587 regval |= 0x00030000;
588 REG_WRITE(ah, AR_WA, regval);
589
590 for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) {
591 REG_WRITE(ah,
592 INI_RA(&ah->iniPcieSerdesLowPower, i, 0),
593 INI_RA(&ah->iniPcieSerdesLowPower, i, 1));
594 }
595 }
596 582
597 if (ah->is_pciexpress) 583 if (ah->is_pciexpress)
598 ath9k_hw_configpcipowersave(ah, 0, 0); 584 ath9k_hw_configpcipowersave(ah, 0, 0);
@@ -627,6 +613,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
627 ar9003_hw_set_nf_limits(ah); 613 ar9003_hw_set_nf_limits(ah);
628 614
629 ath9k_init_nfcal_hist_buffer(ah); 615 ath9k_init_nfcal_hist_buffer(ah);
616 ah->bb_watchdog_timeout_ms = 25;
630 617
631 common->state = ATH_HW_INITIALIZED; 618 common->state = ATH_HW_INITIALIZED;
632 619
@@ -1012,6 +999,11 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1012 999
1013 ENABLE_REGWRITE_BUFFER(ah); 1000 ENABLE_REGWRITE_BUFFER(ah);
1014 1001
1002 if (AR_SREV_9300_20_OR_LATER(ah)) {
1003 REG_WRITE(ah, AR_WA, ah->WARegVal);
1004 udelay(10);
1005 }
1006
1015 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1007 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1016 AR_RTC_FORCE_WAKE_ON_INT); 1008 AR_RTC_FORCE_WAKE_ON_INT);
1017 1009
@@ -1066,6 +1058,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1066{ 1058{
1067 ENABLE_REGWRITE_BUFFER(ah); 1059 ENABLE_REGWRITE_BUFFER(ah);
1068 1060
1061 if (AR_SREV_9300_20_OR_LATER(ah)) {
1062 REG_WRITE(ah, AR_WA, ah->WARegVal);
1063 udelay(10);
1064 }
1065
1069 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1066 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1070 AR_RTC_FORCE_WAKE_ON_INT); 1067 AR_RTC_FORCE_WAKE_ON_INT);
1071 1068
@@ -1073,6 +1070,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1073 REG_WRITE(ah, AR_RC, AR_RC_AHB); 1070 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1074 1071
1075 REG_WRITE(ah, AR_RTC_RESET, 0); 1072 REG_WRITE(ah, AR_RTC_RESET, 0);
1073 udelay(2);
1076 1074
1077 REGWRITE_BUFFER_FLUSH(ah); 1075 REGWRITE_BUFFER_FLUSH(ah);
1078 DISABLE_REGWRITE_BUFFER(ah); 1076 DISABLE_REGWRITE_BUFFER(ah);
@@ -1102,6 +1100,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1102 1100
1103static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) 1101static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
1104{ 1102{
1103 if (AR_SREV_9300_20_OR_LATER(ah)) {
1104 REG_WRITE(ah, AR_WA, ah->WARegVal);
1105 udelay(10);
1106 }
1107
1105 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1108 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1106 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1109 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1107 1110
@@ -1303,6 +1306,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1303 if (AR_SREV_9280_10_OR_LATER(ah)) 1306 if (AR_SREV_9280_10_OR_LATER(ah))
1304 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1307 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
1305 1308
1309 if (!AR_SREV_9300_20_OR_LATER(ah))
1310 ar9002_hw_enable_async_fifo(ah);
1311
1306 r = ath9k_hw_process_ini(ah, chan); 1312 r = ath9k_hw_process_ini(ah, chan);
1307 if (r) 1313 if (r)
1308 return r; 1314 return r;
@@ -1367,6 +1373,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1367 ath9k_hw_resettxqueue(ah, i); 1373 ath9k_hw_resettxqueue(ah, i);
1368 1374
1369 ath9k_hw_init_interrupt_masks(ah, ah->opmode); 1375 ath9k_hw_init_interrupt_masks(ah, ah->opmode);
1376 ath9k_hw_ani_cache_ini_regs(ah);
1370 ath9k_hw_init_qos(ah); 1377 ath9k_hw_init_qos(ah);
1371 1378
1372 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 1379 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
@@ -1375,7 +1382,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1375 ath9k_hw_init_global_settings(ah); 1382 ath9k_hw_init_global_settings(ah);
1376 1383
1377 if (!AR_SREV_9300_20_OR_LATER(ah)) { 1384 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1378 ar9002_hw_enable_async_fifo(ah); 1385 ar9002_hw_update_async_fifo(ah);
1379 ar9002_hw_enable_wep_aggregation(ah); 1386 ar9002_hw_enable_wep_aggregation(ah);
1380 } 1387 }
1381 1388
@@ -1426,9 +1433,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1426 "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); 1433 "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
1427 } 1434 }
1428 } else { 1435 } else {
1429 /* Configure AR9271 target WLAN */ 1436 if (common->bus_ops->ath_bus_type == ATH_USB) {
1430 if (AR_SREV_9271(ah)) 1437 /* Configure AR9271 target WLAN */
1431 REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); 1438 if (AR_SREV_9271(ah))
1439 REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
1440 else
1441 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
1442 }
1432#ifdef __BIG_ENDIAN 1443#ifdef __BIG_ENDIAN
1433 else 1444 else
1434 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 1445 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
@@ -1441,6 +1452,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1441 if (AR_SREV_9300_20_OR_LATER(ah)) { 1452 if (AR_SREV_9300_20_OR_LATER(ah)) {
1442 ath9k_hw_loadnf(ah, curchan); 1453 ath9k_hw_loadnf(ah, curchan);
1443 ath9k_hw_start_nfcal(ah); 1454 ath9k_hw_start_nfcal(ah);
1455 ar9003_hw_bb_watchdog_config(ah);
1444 } 1456 }
1445 1457
1446 return 0; 1458 return 0;
@@ -1489,6 +1501,7 @@ EXPORT_SYMBOL(ath9k_hw_keyreset);
1489bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) 1501bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
1490{ 1502{
1491 u32 macHi, macLo; 1503 u32 macHi, macLo;
1504 u32 unicast_flag = AR_KEYTABLE_VALID;
1492 1505
1493 if (entry >= ah->caps.keycache_size) { 1506 if (entry >= ah->caps.keycache_size) {
1494 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 1507 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
@@ -1497,6 +1510,16 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
1497 } 1510 }
1498 1511
1499 if (mac != NULL) { 1512 if (mac != NULL) {
1513 /*
1514 * AR_KEYTABLE_VALID indicates that the address is a unicast
1515 * address, which must match the transmitter address for
1516 * decrypting frames.
1517 * Not setting this bit allows the hardware to use the key
1518 * for multicast frame decryption.
1519 */
1520 if (mac[0] & 0x01)
1521 unicast_flag = 0;
1522
1500 macHi = (mac[5] << 8) | mac[4]; 1523 macHi = (mac[5] << 8) | mac[4];
1501 macLo = (mac[3] << 24) | 1524 macLo = (mac[3] << 24) |
1502 (mac[2] << 16) | 1525 (mac[2] << 16) |
@@ -1509,7 +1532,7 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
1509 macLo = macHi = 0; 1532 macLo = macHi = 0;
1510 } 1533 }
1511 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); 1534 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
1512 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID); 1535 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
1513 1536
1514 return true; 1537 return true;
1515} 1538}
@@ -1751,6 +1774,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
1751 REG_CLR_BIT(ah, (AR_RTC_RESET), 1774 REG_CLR_BIT(ah, (AR_RTC_RESET),
1752 AR_RTC_RESET_EN); 1775 AR_RTC_RESET_EN);
1753 } 1776 }
1777
1778 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
1779 if (AR_SREV_9300_20_OR_LATER(ah))
1780 REG_WRITE(ah, AR_WA,
1781 ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1754} 1782}
1755 1783
1756/* 1784/*
@@ -1777,6 +1805,10 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
1777 AR_RTC_FORCE_WAKE_EN); 1805 AR_RTC_FORCE_WAKE_EN);
1778 } 1806 }
1779 } 1807 }
1808
1809 /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */
1810 if (AR_SREV_9300_20_OR_LATER(ah))
1811 REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1780} 1812}
1781 1813
1782static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) 1814static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
@@ -1784,6 +1816,12 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
1784 u32 val; 1816 u32 val;
1785 int i; 1817 int i;
1786 1818
1819 /* Set Bits 14 and 17 of AR_WA before powering on the chip. */
1820 if (AR_SREV_9300_20_OR_LATER(ah)) {
1821 REG_WRITE(ah, AR_WA, ah->WARegVal);
1822 udelay(10);
1823 }
1824
1787 if (setChip) { 1825 if (setChip) {
1788 if ((REG_READ(ah, AR_RTC_STATUS) & 1826 if ((REG_READ(ah, AR_RTC_STATUS) &
1789 AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { 1827 AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
@@ -2165,7 +2203,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2165 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; 2203 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
2166 } 2204 }
2167#endif 2205#endif
2168 if (AR_SREV_9271(ah)) 2206 if (AR_SREV_9271(ah) || AR_SREV_9300_20_OR_LATER(ah))
2169 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; 2207 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
2170 else 2208 else
2171 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; 2209 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
@@ -2220,6 +2258,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2220 pCap->rx_status_len = sizeof(struct ar9003_rxs); 2258 pCap->rx_status_len = sizeof(struct ar9003_rxs);
2221 pCap->tx_desc_len = sizeof(struct ar9003_txc); 2259 pCap->tx_desc_len = sizeof(struct ar9003_txc);
2222 pCap->txs_len = sizeof(struct ar9003_txs); 2260 pCap->txs_len = sizeof(struct ar9003_txs);
2261 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
2262 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
2223 } else { 2263 } else {
2224 pCap->tx_desc_len = sizeof(struct ath_desc); 2264 pCap->tx_desc_len = sizeof(struct ath_desc);
2225 if (AR_SREV_9280_20(ah) && 2265 if (AR_SREV_9280_20(ah) &&
@@ -2232,100 +2272,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2232 if (AR_SREV_9300_20_OR_LATER(ah)) 2272 if (AR_SREV_9300_20_OR_LATER(ah))
2233 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; 2273 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
2234 2274
2235 return 0; 2275 if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah))
2236} 2276 pCap->hw_caps |= ATH9K_HW_CAP_SGI_20;
2237 2277
2238bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, 2278 return 0;
2239 u32 capability, u32 *result)
2240{
2241 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
2242 switch (type) {
2243 case ATH9K_CAP_CIPHER:
2244 switch (capability) {
2245 case ATH9K_CIPHER_AES_CCM:
2246 case ATH9K_CIPHER_AES_OCB:
2247 case ATH9K_CIPHER_TKIP:
2248 case ATH9K_CIPHER_WEP:
2249 case ATH9K_CIPHER_MIC:
2250 case ATH9K_CIPHER_CLR:
2251 return true;
2252 default:
2253 return false;
2254 }
2255 case ATH9K_CAP_TKIP_MIC:
2256 switch (capability) {
2257 case 0:
2258 return true;
2259 case 1:
2260 return (ah->sta_id1_defaults &
2261 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
2262 false;
2263 }
2264 case ATH9K_CAP_TKIP_SPLIT:
2265 return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
2266 false : true;
2267 case ATH9K_CAP_MCAST_KEYSRCH:
2268 switch (capability) {
2269 case 0:
2270 return true;
2271 case 1:
2272 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
2273 return false;
2274 } else {
2275 return (ah->sta_id1_defaults &
2276 AR_STA_ID1_MCAST_KSRCH) ? true :
2277 false;
2278 }
2279 }
2280 return false;
2281 case ATH9K_CAP_TXPOW:
2282 switch (capability) {
2283 case 0:
2284 return 0;
2285 case 1:
2286 *result = regulatory->power_limit;
2287 return 0;
2288 case 2:
2289 *result = regulatory->max_power_level;
2290 return 0;
2291 case 3:
2292 *result = regulatory->tp_scale;
2293 return 0;
2294 }
2295 return false;
2296 case ATH9K_CAP_DS:
2297 return (AR_SREV_9280_20_OR_LATER(ah) &&
2298 (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
2299 ? false : true;
2300 default:
2301 return false;
2302 }
2303}
2304EXPORT_SYMBOL(ath9k_hw_getcapability);
2305
2306bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
2307 u32 capability, u32 setting, int *status)
2308{
2309 switch (type) {
2310 case ATH9K_CAP_TKIP_MIC:
2311 if (setting)
2312 ah->sta_id1_defaults |=
2313 AR_STA_ID1_CRPT_MIC_ENABLE;
2314 else
2315 ah->sta_id1_defaults &=
2316 ~AR_STA_ID1_CRPT_MIC_ENABLE;
2317 return true;
2318 case ATH9K_CAP_MCAST_KEYSRCH:
2319 if (setting)
2320 ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
2321 else
2322 ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
2323 return true;
2324 default:
2325 return false;
2326 }
2327} 2279}
2328EXPORT_SYMBOL(ath9k_hw_setcapability);
2329 2280
2330/****************************/ 2281/****************************/
2331/* GPIO / RFKILL / Antennae */ 2282/* GPIO / RFKILL / Antennae */
@@ -2520,12 +2471,6 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
2520} 2471}
2521EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); 2472EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
2522 2473
2523void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
2524{
2525 memcpy(ath9k_hw_common(ah)->macaddr, mac, ETH_ALEN);
2526}
2527EXPORT_SYMBOL(ath9k_hw_setmac);
2528
2529void ath9k_hw_setopmode(struct ath_hw *ah) 2474void ath9k_hw_setopmode(struct ath_hw *ah)
2530{ 2475{
2531 ath9k_hw_set_operating_mode(ah, ah->opmode); 2476 ath9k_hw_set_operating_mode(ah, ah->opmode);
@@ -2598,21 +2543,6 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
2598} 2543}
2599EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); 2544EXPORT_SYMBOL(ath9k_hw_set_tsfadjust);
2600 2545
2601/*
2602 * Extend 15-bit time stamp from rx descriptor to
2603 * a full 64-bit TSF using the current h/w TSF.
2604*/
2605u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
2606{
2607 u64 tsf;
2608
2609 tsf = ath9k_hw_gettsf64(ah);
2610 if ((tsf & 0x7fff) < rstamp)
2611 tsf -= 0x8000;
2612 return (tsf & ~0x7fff) | rstamp;
2613}
2614EXPORT_SYMBOL(ath9k_hw_extend_tsf);
2615
2616void ath9k_hw_set11nmac2040(struct ath_hw *ah) 2546void ath9k_hw_set11nmac2040(struct ath_hw *ah)
2617{ 2547{
2618 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 2548 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 77245dff5993..e9578a4c912f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -158,6 +158,9 @@
158#define ATH9K_HW_RX_HP_QDEPTH 16 158#define ATH9K_HW_RX_HP_QDEPTH 16
159#define ATH9K_HW_RX_LP_QDEPTH 128 159#define ATH9K_HW_RX_LP_QDEPTH 128
160 160
161#define PAPRD_GAIN_TABLE_ENTRIES 32
162#define PAPRD_TABLE_SZ 24
163
161enum ath_ini_subsys { 164enum ath_ini_subsys {
162 ATH_INI_PRE = 0, 165 ATH_INI_PRE = 0,
163 ATH_INI_CORE, 166 ATH_INI_CORE,
@@ -199,15 +202,8 @@ enum ath9k_hw_caps {
199 ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), 202 ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18),
200 ATH9K_HW_CAP_LDPC = BIT(19), 203 ATH9K_HW_CAP_LDPC = BIT(19),
201 ATH9K_HW_CAP_FASTCLOCK = BIT(20), 204 ATH9K_HW_CAP_FASTCLOCK = BIT(20),
202}; 205 ATH9K_HW_CAP_SGI_20 = BIT(21),
203 206 ATH9K_HW_CAP_PAPRD = BIT(22),
204enum ath9k_capability_type {
205 ATH9K_CAP_CIPHER = 0,
206 ATH9K_CAP_TKIP_MIC,
207 ATH9K_CAP_TKIP_SPLIT,
208 ATH9K_CAP_TXPOW,
209 ATH9K_CAP_MCAST_KEYSRCH,
210 ATH9K_CAP_DS
211}; 207};
212 208
213struct ath9k_hw_capabilities { 209struct ath9k_hw_capabilities {
@@ -237,8 +233,9 @@ struct ath9k_ops_config {
237 int sw_beacon_response_time; 233 int sw_beacon_response_time;
238 int additional_swba_backoff; 234 int additional_swba_backoff;
239 int ack_6mb; 235 int ack_6mb;
240 int cwm_ignore_extcca; 236 u32 cwm_ignore_extcca;
241 u8 pcie_powersave_enable; 237 u8 pcie_powersave_enable;
238 bool pcieSerDesWrite;
242 u8 pcie_clock_req; 239 u8 pcie_clock_req;
243 u32 pcie_waen; 240 u32 pcie_waen;
244 u8 analog_shiftreg; 241 u8 analog_shiftreg;
@@ -262,10 +259,10 @@ struct ath9k_ops_config {
262#define AR_BASE_FREQ_5GHZ 4900 259#define AR_BASE_FREQ_5GHZ 4900
263#define AR_SPUR_FEEQ_BOUND_HT40 19 260#define AR_SPUR_FEEQ_BOUND_HT40 19
264#define AR_SPUR_FEEQ_BOUND_HT20 10 261#define AR_SPUR_FEEQ_BOUND_HT20 10
265 bool tx_iq_calibration; /* Only available for >= AR9003 */
266 int spurmode; 262 int spurmode;
267 u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; 263 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
268 u8 max_txtrig_level; 264 u8 max_txtrig_level;
265 u16 ani_poll_interval; /* ANI poll interval in ms */
269}; 266};
270 267
271enum ath9k_int { 268enum ath9k_int {
@@ -279,6 +276,7 @@ enum ath9k_int {
279 ATH9K_INT_TX = 0x00000040, 276 ATH9K_INT_TX = 0x00000040,
280 ATH9K_INT_TXDESC = 0x00000080, 277 ATH9K_INT_TXDESC = 0x00000080,
281 ATH9K_INT_TIM_TIMER = 0x00000100, 278 ATH9K_INT_TIM_TIMER = 0x00000100,
279 ATH9K_INT_BB_WATCHDOG = 0x00000400,
282 ATH9K_INT_TXURN = 0x00000800, 280 ATH9K_INT_TXURN = 0x00000800,
283 ATH9K_INT_MIB = 0x00001000, 281 ATH9K_INT_MIB = 0x00001000,
284 ATH9K_INT_RXPHY = 0x00004000, 282 ATH9K_INT_RXPHY = 0x00004000,
@@ -358,6 +356,9 @@ struct ath9k_channel {
358 int8_t iCoff; 356 int8_t iCoff;
359 int8_t qCoff; 357 int8_t qCoff;
360 int16_t rawNoiseFloor; 358 int16_t rawNoiseFloor;
359 bool paprd_done;
360 u16 small_signal_gain[AR9300_MAX_CHAINS];
361 u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
361}; 362};
362 363
363#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ 364#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
@@ -459,7 +460,7 @@ struct ath9k_hw_version {
459#define AR_GENTMR_BIT(_index) (1 << (_index)) 460#define AR_GENTMR_BIT(_index) (1 << (_index))
460 461
461/* 462/*
462 * Using de Bruijin sequence to to look up 1's index in a 32 bit number 463 * Using de Bruijin sequence to look up 1's index in a 32 bit number
463 * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001 464 * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
464 */ 465 */
465#define debruijn32 0x077CB531U 466#define debruijn32 0x077CB531U
@@ -510,6 +511,17 @@ struct ath_gen_timer_table {
510 * @setup_calibration: set up calibration 511 * @setup_calibration: set up calibration
511 * @iscal_supported: used to query if a type of calibration is supported 512 * @iscal_supported: used to query if a type of calibration is supported
512 * @loadnf: load noise floor read from each chain on the CCA registers 513 * @loadnf: load noise floor read from each chain on the CCA registers
514 *
515 * @ani_reset: reset ANI parameters to default values
516 * @ani_lower_immunity: lower the noise immunity level. The level controls
517 * the power-based packet detection on hardware. If a power jump is
518 * detected the adapter takes it as an indication that a packet has
519 * arrived. The level ranges from 0-5. Each level corresponds to a
520 * few dB more of noise immunity. If you have a strong time-varying
521 * interference that is causing false detections (OFDM timing errors or
522 * CCK timing errors) the level can be increased.
523 * @ani_cache_ini_regs: cache the values for ANI from the initial
524 * register settings through the register initialization.
513 */ 525 */
514struct ath_hw_private_ops { 526struct ath_hw_private_ops {
515 /* Calibration ops */ 527 /* Calibration ops */
@@ -553,6 +565,11 @@ struct ath_hw_private_ops {
553 int param); 565 int param);
554 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); 566 void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
555 void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan); 567 void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
568
569 /* ANI */
570 void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
571 void (*ani_lower_immunity)(struct ath_hw *ah);
572 void (*ani_cache_ini_regs)(struct ath_hw *ah);
556}; 573};
557 574
558/** 575/**
@@ -563,6 +580,11 @@ struct ath_hw_private_ops {
563 * 580 *
564 * @config_pci_powersave: 581 * @config_pci_powersave:
565 * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC 582 * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
583 *
584 * @ani_proc_mib_event: process MIB events, this would happen upon specific ANI
585 * thresholds being reached or having overflowed.
586 * @ani_monitor: called periodically by the core driver to collect
587 * MIB stats and adjust ANI if specific thresholds have been reached.
566 */ 588 */
567struct ath_hw_ops { 589struct ath_hw_ops {
568 void (*config_pci_powersave)(struct ath_hw *ah, 590 void (*config_pci_powersave)(struct ath_hw *ah,
@@ -603,6 +625,9 @@ struct ath_hw_ops {
603 u32 burstDuration); 625 u32 burstDuration);
604 void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, 626 void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
605 u32 vmf); 627 u32 vmf);
628
629 void (*ani_proc_mib_event)(struct ath_hw *ah);
630 void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan);
606}; 631};
607 632
608struct ath_hw { 633struct ath_hw {
@@ -789,6 +814,18 @@ struct ath_hw {
789 u32 ts_paddr_end; 814 u32 ts_paddr_end;
790 u16 ts_tail; 815 u16 ts_tail;
791 u8 ts_size; 816 u8 ts_size;
817
818 u32 bb_watchdog_last_status;
819 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
820
821 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
822 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
823 /*
824 * Store the permanent value of Reg 0x4004in WARegVal
825 * so we dont have to R/M/W. We should not be reading
826 * this register when in sleep states.
827 */
828 u32 WARegVal;
792}; 829};
793 830
794static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) 831static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -818,10 +855,6 @@ int ath9k_hw_init(struct ath_hw *ah);
818int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 855int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
819 bool bChannelChange); 856 bool bChannelChange);
820int ath9k_hw_fill_cap_info(struct ath_hw *ah); 857int ath9k_hw_fill_cap_info(struct ath_hw *ah);
821bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
822 u32 capability, u32 *result);
823bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
824 u32 capability, u32 setting, int *status);
825u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); 858u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
826 859
827/* Key Cache Management */ 860/* Key Cache Management */
@@ -856,7 +889,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
856bool ath9k_hw_phy_disable(struct ath_hw *ah); 889bool ath9k_hw_phy_disable(struct ath_hw *ah);
857bool ath9k_hw_disable(struct ath_hw *ah); 890bool ath9k_hw_disable(struct ath_hw *ah);
858void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); 891void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
859void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
860void ath9k_hw_setopmode(struct ath_hw *ah); 892void ath9k_hw_setopmode(struct ath_hw *ah);
861void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); 893void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
862void ath9k_hw_setbssidmask(struct ath_hw *ah); 894void ath9k_hw_setbssidmask(struct ath_hw *ah);
@@ -865,7 +897,6 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah);
865void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); 897void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
866void ath9k_hw_reset_tsf(struct ath_hw *ah); 898void ath9k_hw_reset_tsf(struct ath_hw *ah);
867void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); 899void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
868u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
869void ath9k_hw_init_global_settings(struct ath_hw *ah); 900void ath9k_hw_init_global_settings(struct ath_hw *ah);
870void ath9k_hw_set11nmac2040(struct ath_hw *ah); 901void ath9k_hw_set11nmac2040(struct ath_hw *ah);
871void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 902void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
@@ -907,13 +938,26 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
907void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); 938void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
908int ar9002_hw_rf_claim(struct ath_hw *ah); 939int ar9002_hw_rf_claim(struct ath_hw *ah);
909void ar9002_hw_enable_async_fifo(struct ath_hw *ah); 940void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
941void ar9002_hw_update_async_fifo(struct ath_hw *ah);
910void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah); 942void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
911 943
912/* 944/*
913 * Code specifric to AR9003, we stuff these here to avoid callbacks 945 * Code specific to AR9003, we stuff these here to avoid callbacks
914 * for older families 946 * for older families
915 */ 947 */
916void ar9003_hw_set_nf_limits(struct ath_hw *ah); 948void ar9003_hw_set_nf_limits(struct ath_hw *ah);
949void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
950void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
951void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
952void ar9003_paprd_enable(struct ath_hw *ah, bool val);
953void ar9003_paprd_populate_single_table(struct ath_hw *ah,
954 struct ath9k_channel *chan, int chain);
955int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
956 int chain);
957int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
958int ar9003_paprd_init_table(struct ath_hw *ah);
959bool ar9003_paprd_is_done(struct ath_hw *ah);
960void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains);
917 961
918/* Hardware family op attach helpers */ 962/* Hardware family op attach helpers */
919void ar5008_hw_attach_phy_ops(struct ath_hw *ah); 963void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
@@ -926,8 +970,24 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
926void ar9002_hw_attach_ops(struct ath_hw *ah); 970void ar9002_hw_attach_ops(struct ath_hw *ah);
927void ar9003_hw_attach_ops(struct ath_hw *ah); 971void ar9003_hw_attach_ops(struct ath_hw *ah);
928 972
973/*
974 * ANI work can be shared between all families but a next
975 * generation implementation of ANI will be used only for AR9003 only
976 * for now as the other families still need to be tested with the same
977 * next generation ANI. Feel free to start testing it though for the
978 * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
979 */
980extern int modparam_force_new_ani;
981void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah);
982void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah);
983
929#define ATH_PCIE_CAP_LINK_CTRL 0x70 984#define ATH_PCIE_CAP_LINK_CTRL 0x70
930#define ATH_PCIE_CAP_LINK_L0S 1 985#define ATH_PCIE_CAP_LINK_L0S 1
931#define ATH_PCIE_CAP_LINK_L1 2 986#define ATH_PCIE_CAP_LINK_L1 2
932 987
988#define ATH9K_CLOCK_RATE_CCK 22
989#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
990#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
991#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44
992
933#endif 993#endif
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index d457cb3bd772..8700e3dc53cf 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -33,6 +33,10 @@ int modparam_nohwcrypt;
33module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); 33module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
34MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); 34MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
35 35
36int led_blink = 1;
37module_param_named(blink, led_blink, int, 0444);
38MODULE_PARM_DESC(blink, "Enable LED blink on activity");
39
36/* We use the hw_value as an index into our private channel structure */ 40/* We use the hw_value as an index into our private channel structure */
37 41
38#define CHAN2G(_freq, _idx) { \ 42#define CHAN2G(_freq, _idx) { \
@@ -175,18 +179,6 @@ static const struct ath_ops ath9k_common_ops = {
175 .write = ath9k_iowrite32, 179 .write = ath9k_iowrite32,
176}; 180};
177 181
178static int count_streams(unsigned int chainmask, int max)
179{
180 int streams = 0;
181
182 do {
183 if (++streams == max)
184 break;
185 } while ((chainmask = chainmask & (chainmask - 1)));
186
187 return streams;
188}
189
190/**************************/ 182/**************************/
191/* Initialization */ 183/* Initialization */
192/**************************/ 184/**************************/
@@ -208,6 +200,9 @@ static void setup_ht_cap(struct ath_softc *sc,
208 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC) 200 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
209 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; 201 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
210 202
203 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
204 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
205
211 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 206 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
212 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; 207 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
213 208
@@ -224,8 +219,8 @@ static void setup_ht_cap(struct ath_softc *sc,
224 219
225 /* set up supported mcs set */ 220 /* set up supported mcs set */
226 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 221 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
227 tx_streams = count_streams(common->tx_chainmask, max_streams); 222 tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
228 rx_streams = count_streams(common->rx_chainmask, max_streams); 223 rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
229 224
230 ath_print(common, ATH_DBG_CONFIG, 225 ath_print(common, ATH_DBG_CONFIG,
231 "TX streams %d, RX streams: %d\n", 226 "TX streams %d, RX streams: %d\n",
@@ -388,36 +383,14 @@ static void ath9k_init_crypto(struct ath_softc *sc)
388 for (i = 0; i < common->keymax; i++) 383 for (i = 0; i < common->keymax; i++)
389 ath9k_hw_keyreset(sc->sc_ah, (u16) i); 384 ath9k_hw_keyreset(sc->sc_ah, (u16) i);
390 385
391 if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
392 ATH9K_CIPHER_TKIP, NULL)) {
393 /*
394 * Whether we should enable h/w TKIP MIC.
395 * XXX: if we don't support WME TKIP MIC, then we wouldn't
396 * report WMM capable, so it's always safe to turn on
397 * TKIP MIC in this case.
398 */
399 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
400 }
401
402 /* 386 /*
403 * Check whether the separate key cache entries 387 * Check whether the separate key cache entries
404 * are required to handle both tx+rx MIC keys. 388 * are required to handle both tx+rx MIC keys.
405 * With split mic keys the number of stations is limited 389 * With split mic keys the number of stations is limited
406 * to 27 otherwise 59. 390 * to 27 otherwise 59.
407 */ 391 */
408 if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, 392 if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA))
409 ATH9K_CIPHER_TKIP, NULL)
410 && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
411 ATH9K_CIPHER_MIC, NULL)
412 && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT,
413 0, NULL))
414 common->splitmic = 1; 393 common->splitmic = 1;
415
416 /* turn on mcast key search if possible */
417 if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
418 (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH,
419 1, 1, NULL);
420
421} 394}
422 395
423static int ath9k_init_btcoex(struct ath_softc *sc) 396static int ath9k_init_btcoex(struct ath_softc *sc)
@@ -435,7 +408,7 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
435 r = ath_init_btcoex_timer(sc); 408 r = ath_init_btcoex_timer(sc);
436 if (r) 409 if (r)
437 return -1; 410 return -1;
438 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); 411 qnum = sc->tx.hwq_map[WME_AC_BE];
439 ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); 412 ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
440 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 413 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
441 break; 414 break;
@@ -472,23 +445,23 @@ static int ath9k_init_queues(struct ath_softc *sc)
472 sc->config.cabqReadytime = ATH_CABQ_READY_TIME; 445 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
473 ath_cabq_update(sc); 446 ath_cabq_update(sc);
474 447
475 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { 448 if (!ath_tx_setup(sc, WME_AC_BK)) {
476 ath_print(common, ATH_DBG_FATAL, 449 ath_print(common, ATH_DBG_FATAL,
477 "Unable to setup xmit queue for BK traffic\n"); 450 "Unable to setup xmit queue for BK traffic\n");
478 goto err; 451 goto err;
479 } 452 }
480 453
481 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { 454 if (!ath_tx_setup(sc, WME_AC_BE)) {
482 ath_print(common, ATH_DBG_FATAL, 455 ath_print(common, ATH_DBG_FATAL,
483 "Unable to setup xmit queue for BE traffic\n"); 456 "Unable to setup xmit queue for BE traffic\n");
484 goto err; 457 goto err;
485 } 458 }
486 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { 459 if (!ath_tx_setup(sc, WME_AC_VI)) {
487 ath_print(common, ATH_DBG_FATAL, 460 ath_print(common, ATH_DBG_FATAL,
488 "Unable to setup xmit queue for VI traffic\n"); 461 "Unable to setup xmit queue for VI traffic\n");
489 goto err; 462 goto err;
490 } 463 }
491 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { 464 if (!ath_tx_setup(sc, WME_AC_VO)) {
492 ath_print(common, ATH_DBG_FATAL, 465 ath_print(common, ATH_DBG_FATAL,
493 "Unable to setup xmit queue for VO traffic\n"); 466 "Unable to setup xmit queue for VO traffic\n");
494 goto err; 467 goto err;
@@ -745,6 +718,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
745 goto error_world; 718 goto error_world;
746 } 719 }
747 720
721 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
748 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); 722 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
749 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); 723 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
750 sc->wiphy_scheduler_int = msecs_to_jiffies(500); 724 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 0e425cb4bbb1..e955bb9d98cb 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "hw.h" 17#include "hw.h"
18#include "hw-ops.h"
18 19
19static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, 20static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
20 struct ath9k_tx_queue_info *qi) 21 struct ath9k_tx_queue_info *qi)
@@ -554,8 +555,13 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
554 REGWRITE_BUFFER_FLUSH(ah); 555 REGWRITE_BUFFER_FLUSH(ah);
555 DISABLE_REGWRITE_BUFFER(ah); 556 DISABLE_REGWRITE_BUFFER(ah);
556 557
557 /* cwmin and cwmax should be 0 for beacon queue */ 558 /*
558 if (AR_SREV_9300_20_OR_LATER(ah)) { 559 * cwmin and cwmax should be 0 for beacon queue
560 * but not for IBSS as we would create an imbalance
561 * on beaconing fairness for participating nodes.
562 */
563 if (AR_SREV_9300_20_OR_LATER(ah) &&
564 ah->opmode != NL80211_IFTYPE_ADHOC) {
559 REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN) 565 REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
560 | SM(0, AR_D_LCL_IFS_CWMAX) 566 | SM(0, AR_D_LCL_IFS_CWMAX)
561 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); 567 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
@@ -756,11 +762,11 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
756} 762}
757EXPORT_SYMBOL(ath9k_hw_putrxbuf); 763EXPORT_SYMBOL(ath9k_hw_putrxbuf);
758 764
759void ath9k_hw_startpcureceive(struct ath_hw *ah) 765void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning)
760{ 766{
761 ath9k_enable_mib_counters(ah); 767 ath9k_enable_mib_counters(ah);
762 768
763 ath9k_ani_reset(ah); 769 ath9k_ani_reset(ah, is_scanning);
764 770
765 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 771 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
766} 772}
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 00f3e0c7528a..7559fb2b28a5 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -577,13 +577,8 @@ enum ath9k_tx_queue {
577 577
578#define ATH9K_NUM_TX_QUEUES 10 578#define ATH9K_NUM_TX_QUEUES 10
579 579
580enum ath9k_tx_queue_subtype { 580/* Used as a queue subtype instead of a WMM AC */
581 ATH9K_WME_AC_BK = 0, 581#define ATH9K_WME_UPSD 4
582 ATH9K_WME_AC_BE,
583 ATH9K_WME_AC_VI,
584 ATH9K_WME_AC_VO,
585 ATH9K_WME_UPSD
586};
587 582
588enum ath9k_tx_queue_flags { 583enum ath9k_tx_queue_flags {
589 TXQ_FLAG_TXOKINT_ENABLE = 0x0001, 584 TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
@@ -617,7 +612,7 @@ enum ath9k_pkt_type {
617struct ath9k_tx_queue_info { 612struct ath9k_tx_queue_info {
618 u32 tqi_ver; 613 u32 tqi_ver;
619 enum ath9k_tx_queue tqi_type; 614 enum ath9k_tx_queue tqi_type;
620 enum ath9k_tx_queue_subtype tqi_subtype; 615 int tqi_subtype;
621 enum ath9k_tx_queue_flags tqi_qflags; 616 enum ath9k_tx_queue_flags tqi_qflags;
622 u32 tqi_priority; 617 u32 tqi_priority;
623 u32 tqi_aifs; 618 u32 tqi_aifs;
@@ -715,7 +710,7 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
715 u32 size, u32 flags); 710 u32 size, u32 flags);
716bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); 711bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
717void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); 712void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
718void ath9k_hw_startpcureceive(struct ath_hw *ah); 713void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning);
719void ath9k_hw_stoppcurecv(struct ath_hw *ah); 714void ath9k_hw_stoppcurecv(struct ath_hw *ah);
720void ath9k_hw_abortpcurecv(struct ath_hw *ah); 715void ath9k_hw_abortpcurecv(struct ath_hw *ah);
721bool ath9k_hw_stopdmarecv(struct ath_hw *ah); 716bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 1e2a68ea9355..efbf53534ade 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -51,13 +51,11 @@ static void ath_cache_conf_rate(struct ath_softc *sc,
51static void ath_update_txpow(struct ath_softc *sc) 51static void ath_update_txpow(struct ath_softc *sc)
52{ 52{
53 struct ath_hw *ah = sc->sc_ah; 53 struct ath_hw *ah = sc->sc_ah;
54 u32 txpow;
55 54
56 if (sc->curtxpow != sc->config.txpowlimit) { 55 if (sc->curtxpow != sc->config.txpowlimit) {
57 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); 56 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
58 /* read back in case value is clamped */ 57 /* read back in case value is clamped */
59 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); 58 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
60 sc->curtxpow = txpow;
61 } 59 }
62} 60}
63 61
@@ -232,6 +230,114 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
232 return r; 230 return r;
233} 231}
234 232
233static void ath_paprd_activate(struct ath_softc *sc)
234{
235 struct ath_hw *ah = sc->sc_ah;
236 int chain;
237
238 if (!ah->curchan->paprd_done)
239 return;
240
241 ath9k_ps_wakeup(sc);
242 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
243 if (!(ah->caps.tx_chainmask & BIT(chain)))
244 continue;
245
246 ar9003_paprd_populate_single_table(ah, ah->curchan, chain);
247 }
248
249 ar9003_paprd_enable(ah, true);
250 ath9k_ps_restore(sc);
251}
252
253void ath_paprd_calibrate(struct work_struct *work)
254{
255 struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
256 struct ieee80211_hw *hw = sc->hw;
257 struct ath_hw *ah = sc->sc_ah;
258 struct ieee80211_hdr *hdr;
259 struct sk_buff *skb = NULL;
260 struct ieee80211_tx_info *tx_info;
261 int band = hw->conf.channel->band;
262 struct ieee80211_supported_band *sband = &sc->sbands[band];
263 struct ath_tx_control txctl;
264 int qnum, ftype;
265 int chain_ok = 0;
266 int chain;
267 int len = 1800;
268 int time_left;
269 int i;
270
271 skb = alloc_skb(len, GFP_KERNEL);
272 if (!skb)
273 return;
274
275 tx_info = IEEE80211_SKB_CB(skb);
276
277 skb_put(skb, len);
278 memset(skb->data, 0, len);
279 hdr = (struct ieee80211_hdr *)skb->data;
280 ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC;
281 hdr->frame_control = cpu_to_le16(ftype);
282 hdr->duration_id = 10;
283 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
284 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
285 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
286
287 memset(&txctl, 0, sizeof(txctl));
288 qnum = sc->tx.hwq_map[WME_AC_BE];
289 txctl.txq = &sc->tx.txq[qnum];
290
291 ath9k_ps_wakeup(sc);
292 ar9003_paprd_init_table(ah);
293 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
294 if (!(ah->caps.tx_chainmask & BIT(chain)))
295 continue;
296
297 chain_ok = 0;
298 memset(tx_info, 0, sizeof(*tx_info));
299 tx_info->band = band;
300
301 for (i = 0; i < 4; i++) {
302 tx_info->control.rates[i].idx = sband->n_bitrates - 1;
303 tx_info->control.rates[i].count = 6;
304 }
305
306 init_completion(&sc->paprd_complete);
307 ar9003_paprd_setup_gain_table(ah, chain);
308 txctl.paprd = BIT(chain);
309 if (ath_tx_start(hw, skb, &txctl) != 0)
310 break;
311
312 time_left = wait_for_completion_timeout(&sc->paprd_complete,
313 msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
314 if (!time_left) {
315 ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
316 "Timeout waiting for paprd training on "
317 "TX chain %d\n",
318 chain);
319 goto fail_paprd;
320 }
321
322 if (!ar9003_paprd_is_done(ah))
323 break;
324
325 if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0)
326 break;
327
328 chain_ok = 1;
329 }
330 kfree_skb(skb);
331
332 if (chain_ok) {
333 ah->curchan->paprd_done = true;
334 ath_paprd_activate(sc);
335 }
336
337fail_paprd:
338 ath9k_ps_restore(sc);
339}
340
235/* 341/*
236 * This routine performs the periodic noise floor calibration function 342 * This routine performs the periodic noise floor calibration function
237 * that is used to adjust and optimize the chip performance. This 343 * that is used to adjust and optimize the chip performance. This
@@ -285,7 +391,8 @@ void ath_ani_calibrate(unsigned long data)
285 } 391 }
286 392
287 /* Verify whether we must check ANI */ 393 /* Verify whether we must check ANI */
288 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { 394 if ((timestamp - common->ani.checkani_timer) >=
395 ah->config.ani_poll_interval) {
289 aniflag = true; 396 aniflag = true;
290 common->ani.checkani_timer = timestamp; 397 common->ani.checkani_timer = timestamp;
291 } 398 }
@@ -326,15 +433,24 @@ set_timer:
326 */ 433 */
327 cal_interval = ATH_LONG_CALINTERVAL; 434 cal_interval = ATH_LONG_CALINTERVAL;
328 if (sc->sc_ah->config.enable_ani) 435 if (sc->sc_ah->config.enable_ani)
329 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); 436 cal_interval = min(cal_interval,
437 (u32)ah->config.ani_poll_interval);
330 if (!common->ani.caldone) 438 if (!common->ani.caldone)
331 cal_interval = min(cal_interval, (u32)short_cal_interval); 439 cal_interval = min(cal_interval, (u32)short_cal_interval);
332 440
333 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); 441 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
442 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
443 !(sc->sc_flags & SC_OP_SCANNING)) {
444 if (!sc->sc_ah->curchan->paprd_done)
445 ieee80211_queue_work(sc->hw, &sc->paprd_work);
446 else
447 ath_paprd_activate(sc);
448 }
334} 449}
335 450
336static void ath_start_ani(struct ath_common *common) 451static void ath_start_ani(struct ath_common *common)
337{ 452{
453 struct ath_hw *ah = common->ah;
338 unsigned long timestamp = jiffies_to_msecs(jiffies); 454 unsigned long timestamp = jiffies_to_msecs(jiffies);
339 struct ath_softc *sc = (struct ath_softc *) common->priv; 455 struct ath_softc *sc = (struct ath_softc *) common->priv;
340 456
@@ -346,7 +462,8 @@ static void ath_start_ani(struct ath_common *common)
346 common->ani.checkani_timer = timestamp; 462 common->ani.checkani_timer = timestamp;
347 463
348 mod_timer(&common->ani.timer, 464 mod_timer(&common->ani.timer,
349 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 465 jiffies +
466 msecs_to_jiffies((u32)ah->config.ani_poll_interval));
350} 467}
351 468
352/* 469/*
@@ -524,6 +641,12 @@ irqreturn_t ath_isr(int irq, void *dev)
524 !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) 641 !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
525 goto chip_reset; 642 goto chip_reset;
526 643
644 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
645 (status & ATH9K_INT_BB_WATCHDOG)) {
646 ar9003_hw_bb_watchdog_dbg_info(ah);
647 goto chip_reset;
648 }
649
527 if (status & ATH9K_INT_SWBA) 650 if (status & ATH9K_INT_SWBA)
528 tasklet_schedule(&sc->bcon_tasklet); 651 tasklet_schedule(&sc->bcon_tasklet);
529 652
@@ -619,234 +742,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
619 return chanmode; 742 return chanmode;
620} 743}
621 744
622static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
623 struct ath9k_keyval *hk, const u8 *addr,
624 bool authenticator)
625{
626 struct ath_hw *ah = common->ah;
627 const u8 *key_rxmic;
628 const u8 *key_txmic;
629
630 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
631 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
632
633 if (addr == NULL) {
634 /*
635 * Group key installation - only two key cache entries are used
636 * regardless of splitmic capability since group key is only
637 * used either for TX or RX.
638 */
639 if (authenticator) {
640 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
641 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
642 } else {
643 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
644 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
645 }
646 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
647 }
648 if (!common->splitmic) {
649 /* TX and RX keys share the same key cache entry. */
650 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
651 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
652 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
653 }
654
655 /* Separate key cache entries for TX and RX */
656
657 /* TX key goes at first index, RX key at +32. */
658 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
659 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
660 /* TX MIC entry failed. No need to proceed further */
661 ath_print(common, ATH_DBG_FATAL,
662 "Setting TX MIC Key Failed\n");
663 return 0;
664 }
665
666 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
667 /* XXX delete tx key on failure? */
668 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
669}
670
671static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
672{
673 int i;
674
675 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
676 if (test_bit(i, common->keymap) ||
677 test_bit(i + 64, common->keymap))
678 continue; /* At least one part of TKIP key allocated */
679 if (common->splitmic &&
680 (test_bit(i + 32, common->keymap) ||
681 test_bit(i + 64 + 32, common->keymap)))
682 continue; /* At least one part of TKIP key allocated */
683
684 /* Found a free slot for a TKIP key */
685 return i;
686 }
687 return -1;
688}
689
690static int ath_reserve_key_cache_slot(struct ath_common *common)
691{
692 int i;
693
694 /* First, try to find slots that would not be available for TKIP. */
695 if (common->splitmic) {
696 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
697 if (!test_bit(i, common->keymap) &&
698 (test_bit(i + 32, common->keymap) ||
699 test_bit(i + 64, common->keymap) ||
700 test_bit(i + 64 + 32, common->keymap)))
701 return i;
702 if (!test_bit(i + 32, common->keymap) &&
703 (test_bit(i, common->keymap) ||
704 test_bit(i + 64, common->keymap) ||
705 test_bit(i + 64 + 32, common->keymap)))
706 return i + 32;
707 if (!test_bit(i + 64, common->keymap) &&
708 (test_bit(i , common->keymap) ||
709 test_bit(i + 32, common->keymap) ||
710 test_bit(i + 64 + 32, common->keymap)))
711 return i + 64;
712 if (!test_bit(i + 64 + 32, common->keymap) &&
713 (test_bit(i, common->keymap) ||
714 test_bit(i + 32, common->keymap) ||
715 test_bit(i + 64, common->keymap)))
716 return i + 64 + 32;
717 }
718 } else {
719 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
720 if (!test_bit(i, common->keymap) &&
721 test_bit(i + 64, common->keymap))
722 return i;
723 if (test_bit(i, common->keymap) &&
724 !test_bit(i + 64, common->keymap))
725 return i + 64;
726 }
727 }
728
729 /* No partially used TKIP slots, pick any available slot */
730 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
731 /* Do not allow slots that could be needed for TKIP group keys
732 * to be used. This limitation could be removed if we know that
733 * TKIP will not be used. */
734 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
735 continue;
736 if (common->splitmic) {
737 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
738 continue;
739 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
740 continue;
741 }
742
743 if (!test_bit(i, common->keymap))
744 return i; /* Found a free slot for a key */
745 }
746
747 /* No free slot found */
748 return -1;
749}
750
751static int ath_key_config(struct ath_common *common,
752 struct ieee80211_vif *vif,
753 struct ieee80211_sta *sta,
754 struct ieee80211_key_conf *key)
755{
756 struct ath_hw *ah = common->ah;
757 struct ath9k_keyval hk;
758 const u8 *mac = NULL;
759 int ret = 0;
760 int idx;
761
762 memset(&hk, 0, sizeof(hk));
763
764 switch (key->alg) {
765 case ALG_WEP:
766 hk.kv_type = ATH9K_CIPHER_WEP;
767 break;
768 case ALG_TKIP:
769 hk.kv_type = ATH9K_CIPHER_TKIP;
770 break;
771 case ALG_CCMP:
772 hk.kv_type = ATH9K_CIPHER_AES_CCM;
773 break;
774 default:
775 return -EOPNOTSUPP;
776 }
777
778 hk.kv_len = key->keylen;
779 memcpy(hk.kv_val, key->key, key->keylen);
780
781 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
782 /* For now, use the default keys for broadcast keys. This may
783 * need to change with virtual interfaces. */
784 idx = key->keyidx;
785 } else if (key->keyidx) {
786 if (WARN_ON(!sta))
787 return -EOPNOTSUPP;
788 mac = sta->addr;
789
790 if (vif->type != NL80211_IFTYPE_AP) {
791 /* Only keyidx 0 should be used with unicast key, but
792 * allow this for client mode for now. */
793 idx = key->keyidx;
794 } else
795 return -EIO;
796 } else {
797 if (WARN_ON(!sta))
798 return -EOPNOTSUPP;
799 mac = sta->addr;
800
801 if (key->alg == ALG_TKIP)
802 idx = ath_reserve_key_cache_slot_tkip(common);
803 else
804 idx = ath_reserve_key_cache_slot(common);
805 if (idx < 0)
806 return -ENOSPC; /* no free key cache entries */
807 }
808
809 if (key->alg == ALG_TKIP)
810 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
811 vif->type == NL80211_IFTYPE_AP);
812 else
813 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
814
815 if (!ret)
816 return -EIO;
817
818 set_bit(idx, common->keymap);
819 if (key->alg == ALG_TKIP) {
820 set_bit(idx + 64, common->keymap);
821 if (common->splitmic) {
822 set_bit(idx + 32, common->keymap);
823 set_bit(idx + 64 + 32, common->keymap);
824 }
825 }
826
827 return idx;
828}
829
830static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
831{
832 struct ath_hw *ah = common->ah;
833
834 ath9k_hw_keyreset(ah, key->hw_key_idx);
835 if (key->hw_key_idx < IEEE80211_WEP_NKID)
836 return;
837
838 clear_bit(key->hw_key_idx, common->keymap);
839 if (key->alg != ALG_TKIP)
840 return;
841
842 clear_bit(key->hw_key_idx + 64, common->keymap);
843 if (common->splitmic) {
844 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
845 clear_bit(key->hw_key_idx + 32, common->keymap);
846 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
847 }
848}
849
850static void ath9k_bss_assoc_info(struct ath_softc *sc, 745static void ath9k_bss_assoc_info(struct ath_softc *sc,
851 struct ieee80211_vif *vif, 746 struct ieee80211_vif *vif,
852 struct ieee80211_bss_conf *bss_conf) 747 struct ieee80211_bss_conf *bss_conf)
@@ -1032,25 +927,25 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1032 return r; 927 return r;
1033} 928}
1034 929
1035int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) 930static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1036{ 931{
1037 int qnum; 932 int qnum;
1038 933
1039 switch (queue) { 934 switch (queue) {
1040 case 0: 935 case 0:
1041 qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; 936 qnum = sc->tx.hwq_map[WME_AC_VO];
1042 break; 937 break;
1043 case 1: 938 case 1:
1044 qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; 939 qnum = sc->tx.hwq_map[WME_AC_VI];
1045 break; 940 break;
1046 case 2: 941 case 2:
1047 qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; 942 qnum = sc->tx.hwq_map[WME_AC_BE];
1048 break; 943 break;
1049 case 3: 944 case 3:
1050 qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; 945 qnum = sc->tx.hwq_map[WME_AC_BK];
1051 break; 946 break;
1052 default: 947 default:
1053 qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; 948 qnum = sc->tx.hwq_map[WME_AC_BE];
1054 break; 949 break;
1055 } 950 }
1056 951
@@ -1062,16 +957,16 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
1062 int qnum; 957 int qnum;
1063 958
1064 switch (queue) { 959 switch (queue) {
1065 case ATH9K_WME_AC_VO: 960 case WME_AC_VO:
1066 qnum = 0; 961 qnum = 0;
1067 break; 962 break;
1068 case ATH9K_WME_AC_VI: 963 case WME_AC_VI:
1069 qnum = 1; 964 qnum = 1;
1070 break; 965 break;
1071 case ATH9K_WME_AC_BE: 966 case WME_AC_BE:
1072 qnum = 2; 967 qnum = 2;
1073 break; 968 break;
1074 case ATH9K_WME_AC_BK: 969 case WME_AC_BK:
1075 qnum = 3; 970 qnum = 3;
1076 break; 971 break;
1077 default: 972 default:
@@ -1201,7 +1096,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
1201 ATH9K_INT_GLOBAL; 1096 ATH9K_INT_GLOBAL;
1202 1097
1203 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 1098 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
1204 ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP; 1099 ah->imask |= ATH9K_INT_RXHP |
1100 ATH9K_INT_RXLP |
1101 ATH9K_INT_BB_WATCHDOG;
1205 else 1102 else
1206 ah->imask |= ATH9K_INT_RX; 1103 ah->imask |= ATH9K_INT_RX;
1207 1104
@@ -1251,6 +1148,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1251 struct ath_tx_control txctl; 1148 struct ath_tx_control txctl;
1252 int padpos, padsize; 1149 int padpos, padsize;
1253 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1150 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1151 int qnum;
1254 1152
1255 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { 1153 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
1256 ath_print(common, ATH_DBG_XMIT, 1154 ath_print(common, ATH_DBG_XMIT,
@@ -1280,7 +1178,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1280 * completed and if needed, also for RX of buffered frames. 1178 * completed and if needed, also for RX of buffered frames.
1281 */ 1179 */
1282 ath9k_ps_wakeup(sc); 1180 ath9k_ps_wakeup(sc);
1283 ath9k_hw_setrxabort(sc->sc_ah, 0); 1181 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
1182 ath9k_hw_setrxabort(sc->sc_ah, 0);
1284 if (ieee80211_is_pspoll(hdr->frame_control)) { 1183 if (ieee80211_is_pspoll(hdr->frame_control)) {
1285 ath_print(common, ATH_DBG_PS, 1184 ath_print(common, ATH_DBG_PS,
1286 "Sending PS-Poll to pick a buffered frame\n"); 1185 "Sending PS-Poll to pick a buffered frame\n");
@@ -1322,11 +1221,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1322 memmove(skb->data, skb->data + padsize, padpos); 1221 memmove(skb->data, skb->data + padsize, padpos);
1323 } 1222 }
1324 1223
1325 /* Check if a tx queue is available */ 1224 qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
1326 1225 txctl.txq = &sc->tx.txq[qnum];
1327 txctl.txq = ath_test_get_txq(sc, skb);
1328 if (!txctl.txq)
1329 goto exit;
1330 1226
1331 ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); 1227 ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
1332 1228
@@ -1352,8 +1248,11 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1352 1248
1353 aphy->state = ATH_WIPHY_INACTIVE; 1249 aphy->state = ATH_WIPHY_INACTIVE;
1354 1250
1355 cancel_delayed_work_sync(&sc->ath_led_blink_work); 1251 if (led_blink)
1252 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1253
1356 cancel_delayed_work_sync(&sc->tx_complete_work); 1254 cancel_delayed_work_sync(&sc->tx_complete_work);
1255 cancel_work_sync(&sc->paprd_work);
1357 1256
1358 if (!sc->num_sec_wiphy) { 1257 if (!sc->num_sec_wiphy) {
1359 cancel_delayed_work_sync(&sc->wiphy_work); 1258 cancel_delayed_work_sync(&sc->wiphy_work);
@@ -1547,8 +1446,8 @@ void ath9k_enable_ps(struct ath_softc *sc)
1547 ah->imask |= ATH9K_INT_TIM_TIMER; 1446 ah->imask |= ATH9K_INT_TIM_TIMER;
1548 ath9k_hw_set_interrupts(ah, ah->imask); 1447 ath9k_hw_set_interrupts(ah, ah->imask);
1549 } 1448 }
1449 ath9k_hw_setrxabort(ah, 1);
1550 } 1450 }
1551 ath9k_hw_setrxabort(ah, 1);
1552} 1451}
1553 1452
1554static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1453static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -1785,7 +1684,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1785 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); 1684 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1786 1685
1787 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) 1686 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1788 if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret) 1687 if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
1789 ath_beaconq_config(sc); 1688 ath_beaconq_config(sc);
1790 1689
1791 mutex_unlock(&sc->mutex); 1690 mutex_unlock(&sc->mutex);
@@ -1813,7 +1712,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1813 1712
1814 switch (cmd) { 1713 switch (cmd) {
1815 case SET_KEY: 1714 case SET_KEY:
1816 ret = ath_key_config(common, vif, sta, key); 1715 ret = ath9k_cmn_key_config(common, vif, sta, key);
1817 if (ret >= 0) { 1716 if (ret >= 0) {
1818 key->hw_key_idx = ret; 1717 key->hw_key_idx = ret;
1819 /* push IV and Michael MIC generation to stack */ 1718 /* push IV and Michael MIC generation to stack */
@@ -1826,7 +1725,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1826 } 1725 }
1827 break; 1726 break;
1828 case DISABLE_KEY: 1727 case DISABLE_KEY:
1829 ath_key_delete(common, key); 1728 ath9k_cmn_key_delete(common, key);
1830 break; 1729 break;
1831 default: 1730 default:
1832 ret = -EINVAL; 1731 ret = -EINVAL;
@@ -1999,6 +1898,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1999 struct ath_softc *sc = aphy->sc; 1898 struct ath_softc *sc = aphy->sc;
2000 int ret = 0; 1899 int ret = 0;
2001 1900
1901 local_bh_disable();
1902
2002 switch (action) { 1903 switch (action) {
2003 case IEEE80211_AMPDU_RX_START: 1904 case IEEE80211_AMPDU_RX_START:
2004 if (!(sc->sc_flags & SC_OP_RXAGGR)) 1905 if (!(sc->sc_flags & SC_OP_RXAGGR))
@@ -2028,6 +1929,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2028 "Unknown AMPDU action\n"); 1929 "Unknown AMPDU action\n");
2029 } 1930 }
2030 1931
1932 local_bh_enable();
1933
2031 return ret; 1934 return ret;
2032} 1935}
2033 1936
@@ -2072,6 +1975,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2072 ath9k_wiphy_pause_all_forced(sc, aphy); 1975 ath9k_wiphy_pause_all_forced(sc, aphy);
2073 sc->sc_flags |= SC_OP_SCANNING; 1976 sc->sc_flags |= SC_OP_SCANNING;
2074 del_timer_sync(&common->ani.timer); 1977 del_timer_sync(&common->ani.timer);
1978 cancel_work_sync(&sc->paprd_work);
2075 cancel_delayed_work_sync(&sc->tx_complete_work); 1979 cancel_delayed_work_sync(&sc->tx_complete_work);
2076 mutex_unlock(&sc->mutex); 1980 mutex_unlock(&sc->mutex);
2077} 1981}
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 1ec836cf1c0d..257b10ba6f57 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
28 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 28 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
29 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 29 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
30 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 30 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
31 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
31 { 0 } 32 { 0 }
32}; 33};
33 34
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 8519452c95f1..600ee0ba2880 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -20,7 +20,7 @@
20#include "ath9k.h" 20#include "ath9k.h"
21 21
22static const struct ath_rate_table ar5416_11na_ratetable = { 22static const struct ath_rate_table ar5416_11na_ratetable = {
23 42, 23 43,
24 8, /* MCS start */ 24 8, /* MCS start */
25 { 25 {
26 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 26 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
@@ -40,73 +40,75 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
40 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 40 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
41 29300, 7, 108, 4, 7, 7, 7, 7 }, 41 29300, 7, 108, 4, 7, 7, 7, 7 },
42 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 42 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
43 6400, 0, 0, 0, 8, 24, 8, 24 }, 43 6400, 0, 0, 0, 8, 25, 8, 25 },
44 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 44 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
45 12700, 1, 1, 2, 9, 25, 9, 25 }, 45 12700, 1, 1, 2, 9, 26, 9, 26 },
46 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 46 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
47 18800, 2, 2, 2, 10, 26, 10, 26 }, 47 18800, 2, 2, 2, 10, 27, 10, 27 },
48 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 48 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
49 25000, 3, 3, 4, 11, 27, 11, 27 }, 49 25000, 3, 3, 4, 11, 28, 11, 28 },
50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
51 36700, 4, 4, 4, 12, 28, 12, 28 }, 51 36700, 4, 4, 4, 12, 29, 12, 29 },
52 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 52 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
53 48100, 5, 5, 4, 13, 29, 13, 29 }, 53 48100, 5, 5, 4, 13, 30, 13, 30 },
54 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 54 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
55 53500, 6, 6, 4, 14, 30, 14, 30 }, 55 53500, 6, 6, 4, 14, 31, 14, 31 },
56 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 56 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
57 59000, 7, 7, 4, 15, 31, 15, 32 }, 57 59000, 7, 7, 4, 15, 32, 15, 33 },
58 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 58 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
59 12700, 8, 8, 3, 16, 33, 16, 33 }, 59 12700, 8, 8, 3, 16, 34, 16, 34 },
60 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 60 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
61 24800, 9, 9, 2, 17, 34, 17, 34 }, 61 24800, 9, 9, 2, 17, 35, 17, 35 },
62 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 62 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
63 36600, 10, 10, 2, 18, 35, 18, 35 }, 63 36600, 10, 10, 2, 18, 36, 18, 36 },
64 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 64 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
65 48100, 11, 11, 4, 19, 36, 19, 36 }, 65 48100, 11, 11, 4, 19, 37, 19, 37 },
66 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 66 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
67 69500, 12, 12, 4, 20, 37, 20, 37 }, 67 69500, 12, 12, 4, 20, 38, 20, 38 },
68 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 68 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
69 89500, 13, 13, 4, 21, 38, 21, 38 }, 69 89500, 13, 13, 4, 21, 39, 21, 39 },
70 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 70 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
71 98900, 14, 14, 4, 22, 39, 22, 39 }, 71 98900, 14, 14, 4, 22, 40, 22, 40 },
72 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 72 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
73 108300, 15, 15, 4, 23, 40, 23, 41 }, 73 108300, 15, 15, 4, 23, 41, 24, 42 },
74 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */
75 12000, 15, 15, 4, 23, 41, 24, 42 },
74 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 76 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
75 13200, 0, 0, 0, 8, 24, 24, 24 }, 77 13200, 0, 0, 0, 8, 25, 25, 25 },
76 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 78 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
77 25900, 1, 1, 2, 9, 25, 25, 25 }, 79 25900, 1, 1, 2, 9, 26, 26, 26 },
78 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 80 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
79 38600, 2, 2, 2, 10, 26, 26, 26 }, 81 38600, 2, 2, 2, 10, 27, 27, 27 },
80 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 82 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
81 49800, 3, 3, 4, 11, 27, 27, 27 }, 83 49800, 3, 3, 4, 11, 28, 28, 28 },
82 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 84 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
83 72200, 4, 4, 4, 12, 28, 28, 28 }, 85 72200, 4, 4, 4, 12, 29, 29, 29 },
84 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 86 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
85 92900, 5, 5, 4, 13, 29, 29, 29 }, 87 92900, 5, 5, 4, 13, 30, 30, 30 },
86 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 88 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
87 102700, 6, 6, 4, 14, 30, 30, 30 }, 89 102700, 6, 6, 4, 14, 31, 31, 31 },
88 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 90 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
89 112000, 7, 7, 4, 15, 31, 32, 32 }, 91 112000, 7, 7, 4, 15, 32, 33, 33 },
90 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 92 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
91 122000, 7, 7, 4, 15, 31, 32, 32 }, 93 122000, 7, 7, 4, 15, 32, 33, 33 },
92 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 94 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
93 25800, 8, 8, 0, 16, 33, 33, 33 }, 95 25800, 8, 8, 0, 16, 34, 34, 34 },
94 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 96 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
95 49800, 9, 9, 2, 17, 34, 34, 34 }, 97 49800, 9, 9, 2, 17, 35, 35, 35 },
96 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 98 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
97 71900, 10, 10, 2, 18, 35, 35, 35 }, 99 71900, 10, 10, 2, 18, 36, 36, 36 },
98 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 100 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
99 92500, 11, 11, 4, 19, 36, 36, 36 }, 101 92500, 11, 11, 4, 19, 37, 37, 37 },
100 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 102 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
101 130300, 12, 12, 4, 20, 37, 37, 37 }, 103 130300, 12, 12, 4, 20, 38, 38, 38 },
102 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 104 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
103 162800, 13, 13, 4, 21, 38, 38, 38 }, 105 162800, 13, 13, 4, 21, 39, 39, 39 },
104 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 106 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
105 178200, 14, 14, 4, 22, 39, 39, 39 }, 107 178200, 14, 14, 4, 22, 40, 40, 40 },
106 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 108 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
107 192100, 15, 15, 4, 23, 40, 41, 41 }, 109 192100, 15, 15, 4, 23, 41, 42, 42 },
108 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 110 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
109 207000, 15, 15, 4, 23, 40, 41, 41 }, 111 207000, 15, 15, 4, 23, 41, 42, 42 },
110 }, 112 },
111 50, /* probe interval */ 113 50, /* probe interval */
112 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 114 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
@@ -116,7 +118,7 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
116 * for HT are the 64K max aggregate limit */ 118 * for HT are the 64K max aggregate limit */
117 119
118static const struct ath_rate_table ar5416_11ng_ratetable = { 120static const struct ath_rate_table ar5416_11ng_ratetable = {
119 46, 121 47,
120 12, /* MCS start */ 122 12, /* MCS start */
121 { 123 {
122 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 124 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
@@ -144,73 +146,75 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
144 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 146 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
145 30900, 11, 108, 8, 11, 11, 11, 11 }, 147 30900, 11, 108, 8, 11, 11, 11, 11 },
146 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 148 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
147 6400, 0, 0, 4, 12, 28, 12, 28 }, 149 6400, 0, 0, 4, 12, 29, 12, 29 },
148 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 150 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
149 12700, 1, 1, 6, 13, 29, 13, 29 }, 151 12700, 1, 1, 6, 13, 30, 13, 30 },
150 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 152 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
151 18800, 2, 2, 6, 14, 30, 14, 30 }, 153 18800, 2, 2, 6, 14, 31, 14, 31 },
152 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 154 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
153 25000, 3, 3, 8, 15, 31, 15, 31 }, 155 25000, 3, 3, 8, 15, 32, 15, 32 },
154 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 156 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
155 36700, 4, 4, 8, 16, 32, 16, 32 }, 157 36700, 4, 4, 8, 16, 33, 16, 33 },
156 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 158 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
157 48100, 5, 5, 8, 17, 33, 17, 33 }, 159 48100, 5, 5, 8, 17, 34, 17, 34 },
158 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 160 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
159 53500, 6, 6, 8, 18, 34, 18, 34 }, 161 53500, 6, 6, 8, 18, 35, 18, 35 },
160 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 162 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
161 59000, 7, 7, 8, 19, 35, 19, 36 }, 163 59000, 7, 7, 8, 19, 36, 19, 37 },
162 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 164 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
163 12700, 8, 8, 4, 20, 37, 20, 37 }, 165 12700, 8, 8, 4, 20, 38, 20, 38 },
164 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 166 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
165 24800, 9, 9, 6, 21, 38, 21, 38 }, 167 24800, 9, 9, 6, 21, 39, 21, 39 },
166 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 168 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
167 36600, 10, 10, 6, 22, 39, 22, 39 }, 169 36600, 10, 10, 6, 22, 40, 22, 40 },
168 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 170 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
169 48100, 11, 11, 8, 23, 40, 23, 40 }, 171 48100, 11, 11, 8, 23, 41, 23, 41 },
170 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 172 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
171 69500, 12, 12, 8, 24, 41, 24, 41 }, 173 69500, 12, 12, 8, 24, 42, 24, 42 },
172 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 174 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
173 89500, 13, 13, 8, 25, 42, 25, 42 }, 175 89500, 13, 13, 8, 25, 43, 25, 43 },
174 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 176 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
175 98900, 14, 14, 8, 26, 43, 26, 44 }, 177 98900, 14, 14, 8, 26, 44, 26, 44 },
176 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 178 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
177 108300, 15, 15, 8, 27, 44, 27, 45 }, 179 108300, 15, 15, 8, 27, 45, 28, 46 },
180 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */
181 120000, 15, 15, 8, 27, 45, 28, 46 },
178 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 182 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
179 13200, 0, 0, 8, 12, 28, 28, 28 }, 183 13200, 0, 0, 8, 12, 29, 29, 29 },
180 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 184 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
181 25900, 1, 1, 8, 13, 29, 29, 29 }, 185 25900, 1, 1, 8, 13, 30, 30, 30 },
182 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 186 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
183 38600, 2, 2, 8, 14, 30, 30, 30 }, 187 38600, 2, 2, 8, 14, 31, 31, 31 },
184 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 188 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
185 49800, 3, 3, 8, 15, 31, 31, 31 }, 189 49800, 3, 3, 8, 15, 32, 32, 32 },
186 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 190 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
187 72200, 4, 4, 8, 16, 32, 32, 32 }, 191 72200, 4, 4, 8, 16, 33, 33, 33 },
188 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 192 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
189 92900, 5, 5, 8, 17, 33, 33, 33 }, 193 92900, 5, 5, 8, 17, 34, 34, 34 },
190 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 194 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
191 102700, 6, 6, 8, 18, 34, 34, 34 }, 195 102700, 6, 6, 8, 18, 35, 35, 35 },
192 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 196 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
193 112000, 7, 7, 8, 19, 35, 36, 36 }, 197 112000, 7, 7, 8, 19, 36, 37, 37 },
194 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 198 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
195 122000, 7, 7, 8, 19, 35, 36, 36 }, 199 122000, 7, 7, 8, 19, 36, 37, 37 },
196 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 200 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
197 25800, 8, 8, 8, 20, 37, 37, 37 }, 201 25800, 8, 8, 8, 20, 38, 38, 38 },
198 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 202 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
199 49800, 9, 9, 8, 21, 38, 38, 38 }, 203 49800, 9, 9, 8, 21, 39, 39, 39 },
200 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 204 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
201 71900, 10, 10, 8, 22, 39, 39, 39 }, 205 71900, 10, 10, 8, 22, 40, 40, 40 },
202 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 206 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
203 92500, 11, 11, 8, 23, 40, 40, 40 }, 207 92500, 11, 11, 8, 23, 41, 41, 41 },
204 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 208 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
205 130300, 12, 12, 8, 24, 41, 41, 41 }, 209 130300, 12, 12, 8, 24, 42, 42, 42 },
206 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 210 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
207 162800, 13, 13, 8, 25, 42, 42, 42 }, 211 162800, 13, 13, 8, 25, 43, 43, 43 },
208 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 212 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
209 178200, 14, 14, 8, 26, 43, 43, 43 }, 213 178200, 14, 14, 8, 26, 44, 44, 44 },
210 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 214 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
211 192100, 15, 15, 8, 27, 44, 45, 45 }, 215 192100, 15, 15, 8, 27, 45, 46, 46 },
212 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 216 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
213 207000, 15, 15, 8, 27, 44, 45, 45 }, 217 207000, 15, 15, 8, 27, 45, 46, 46 },
214 }, 218 },
215 50, /* probe interval */ 219 50, /* probe interval */
216 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 220 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
@@ -1193,21 +1197,19 @@ static void ath_rc_init(struct ath_softc *sc,
1193} 1197}
1194 1198
1195static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, 1199static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
1196 bool is_cw40, bool is_sgi40) 1200 bool is_cw40, bool is_sgi)
1197{ 1201{
1198 u8 caps = 0; 1202 u8 caps = 0;
1199 1203
1200 if (sta->ht_cap.ht_supported) { 1204 if (sta->ht_cap.ht_supported) {
1201 caps = WLAN_RC_HT_FLAG; 1205 caps = WLAN_RC_HT_FLAG;
1202 if (sc->sc_ah->caps.tx_chainmask != 1 && 1206 if (sta->ht_cap.mcs.rx_mask[1])
1203 ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) { 1207 caps |= WLAN_RC_DS_FLAG;
1204 if (sta->ht_cap.mcs.rx_mask[1])
1205 caps |= WLAN_RC_DS_FLAG;
1206 }
1207 if (is_cw40) 1208 if (is_cw40)
1208 caps |= WLAN_RC_40_FLAG; 1209 caps |= WLAN_RC_40_FLAG;
1209 if (is_sgi40) 1210 if (is_sgi)
1210 caps |= WLAN_RC_SGI_FLAG; 1211 caps |= WLAN_RC_SGI_FLAG;
1212
1211 } 1213 }
1212 1214
1213 return caps; 1215 return caps;
@@ -1300,7 +1302,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1300 struct ath_softc *sc = priv; 1302 struct ath_softc *sc = priv;
1301 struct ath_rate_priv *ath_rc_priv = priv_sta; 1303 struct ath_rate_priv *ath_rc_priv = priv_sta;
1302 const struct ath_rate_table *rate_table; 1304 const struct ath_rate_table *rate_table;
1303 bool is_cw40, is_sgi40; 1305 bool is_cw40, is_sgi = false;
1304 int i, j = 0; 1306 int i, j = 0;
1305 1307
1306 for (i = 0; i < sband->n_bitrates; i++) { 1308 for (i = 0; i < sband->n_bitrates; i++) {
@@ -1323,7 +1325,11 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1323 } 1325 }
1324 1326
1325 is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1327 is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1326 is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; 1328
1329 if (is_cw40)
1330 is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
1331 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
1332 is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
1327 1333
1328 /* Choose rate table first */ 1334 /* Choose rate table first */
1329 1335
@@ -1336,7 +1342,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1336 rate_table = hw_rate_table[sc->cur_rate_mode]; 1342 rate_table = hw_rate_table[sc->cur_rate_mode];
1337 } 1343 }
1338 1344
1339 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40); 1345 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
1340 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1346 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1341} 1347}
1342 1348
@@ -1347,10 +1353,10 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1347 struct ath_softc *sc = priv; 1353 struct ath_softc *sc = priv;
1348 struct ath_rate_priv *ath_rc_priv = priv_sta; 1354 struct ath_rate_priv *ath_rc_priv = priv_sta;
1349 const struct ath_rate_table *rate_table = NULL; 1355 const struct ath_rate_table *rate_table = NULL;
1350 bool oper_cw40 = false, oper_sgi40; 1356 bool oper_cw40 = false, oper_sgi;
1351 bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? 1357 bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
1352 true : false; 1358 true : false;
1353 bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ? 1359 bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
1354 true : false; 1360 true : false;
1355 1361
1356 /* FIXME: Handle AP mode later when we support CWM */ 1362 /* FIXME: Handle AP mode later when we support CWM */
@@ -1363,15 +1369,21 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1363 oper_chan_type == NL80211_CHAN_HT40PLUS) 1369 oper_chan_type == NL80211_CHAN_HT40PLUS)
1364 oper_cw40 = true; 1370 oper_cw40 = true;
1365 1371
1366 oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1372 if (oper_cw40)
1367 true : false; 1373 oper_sgi = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1374 true : false;
1375 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
1376 oper_sgi = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1377 true : false;
1378 else
1379 oper_sgi = false;
1368 1380
1369 if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) { 1381 if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
1370 rate_table = ath_choose_rate_table(sc, sband->band, 1382 rate_table = ath_choose_rate_table(sc, sband->band,
1371 sta->ht_cap.ht_supported, 1383 sta->ht_cap.ht_supported,
1372 oper_cw40); 1384 oper_cw40);
1373 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, 1385 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
1374 oper_cw40, oper_sgi40); 1386 oper_cw40, oper_sgi);
1375 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1387 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1376 1388
1377 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, 1389 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ca6065b71b46..da0cfe90c38a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -116,9 +116,6 @@ static void ath_opmode_init(struct ath_softc *sc)
116 /* configure operational mode */ 116 /* configure operational mode */
117 ath9k_hw_setopmode(ah); 117 ath9k_hw_setopmode(ah);
118 118
119 /* Handle any link-level address change. */
120 ath9k_hw_setmac(ah, common->macaddr);
121
122 /* calculate and install multicast filter */ 119 /* calculate and install multicast filter */
123 mfilt[0] = mfilt[1] = ~0; 120 mfilt[0] = mfilt[1] = ~0;
124 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); 121 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
@@ -295,7 +292,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
295 292
296 ath_opmode_init(sc); 293 ath_opmode_init(sc);
297 294
298 ath9k_hw_startpcureceive(sc->sc_ah); 295 ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING));
299} 296}
300 297
301static void ath_edma_stop_recv(struct ath_softc *sc) 298static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -501,7 +498,7 @@ int ath_startrecv(struct ath_softc *sc)
501start_recv: 498start_recv:
502 spin_unlock_bh(&sc->rx.rxbuflock); 499 spin_unlock_bh(&sc->rx.rxbuflock);
503 ath_opmode_init(sc); 500 ath_opmode_init(sc);
504 ath9k_hw_startpcureceive(ah); 501 ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING));
505 502
506 return 0; 503 return 0;
507} 504}
@@ -700,12 +697,16 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
700 bf = SKB_CB_ATHBUF(skb); 697 bf = SKB_CB_ATHBUF(skb);
701 BUG_ON(!bf); 698 BUG_ON(!bf);
702 699
703 dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, 700 dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
704 common->rx_bufsize, DMA_FROM_DEVICE); 701 common->rx_bufsize, DMA_FROM_DEVICE);
705 702
706 ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); 703 ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
707 if (ret == -EINPROGRESS) 704 if (ret == -EINPROGRESS) {
705 /*let device gain the buffer again*/
706 dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
707 common->rx_bufsize, DMA_FROM_DEVICE);
708 return false; 708 return false;
709 }
709 710
710 __skb_unlink(skb, &rx_edma->rx_fifo); 711 __skb_unlink(skb, &rx_edma->rx_fifo);
711 if (ret == -EINVAL) { 712 if (ret == -EINVAL) {
@@ -814,13 +815,263 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
814 * 1. accessing the frame 815 * 1. accessing the frame
815 * 2. requeueing the same buffer to h/w 816 * 2. requeueing the same buffer to h/w
816 */ 817 */
817 dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, 818 dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
818 common->rx_bufsize, 819 common->rx_bufsize,
819 DMA_FROM_DEVICE); 820 DMA_FROM_DEVICE);
820 821
821 return bf; 822 return bf;
822} 823}
823 824
825/* Assumes you've already done the endian to CPU conversion */
826static bool ath9k_rx_accept(struct ath_common *common,
827 struct ieee80211_hdr *hdr,
828 struct ieee80211_rx_status *rxs,
829 struct ath_rx_status *rx_stats,
830 bool *decrypt_error)
831{
832 struct ath_hw *ah = common->ah;
833 __le16 fc;
834 u8 rx_status_len = ah->caps.rx_status_len;
835
836 fc = hdr->frame_control;
837
838 if (!rx_stats->rs_datalen)
839 return false;
840 /*
841 * rs_status follows rs_datalen so if rs_datalen is too large
842 * we can take a hint that hardware corrupted it, so ignore
843 * those frames.
844 */
845 if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
846 return false;
847
848 /*
849 * rs_more indicates chained descriptors which can be used
850 * to link buffers together for a sort of scatter-gather
851 * operation.
852 * reject the frame, we don't support scatter-gather yet and
853 * the frame is probably corrupt anyway
854 */
855 if (rx_stats->rs_more)
856 return false;
857
858 /*
859 * The rx_stats->rs_status will not be set until the end of the
860 * chained descriptors so it can be ignored if rs_more is set. The
861 * rs_more will be false at the last element of the chained
862 * descriptors.
863 */
864 if (rx_stats->rs_status != 0) {
865 if (rx_stats->rs_status & ATH9K_RXERR_CRC)
866 rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
867 if (rx_stats->rs_status & ATH9K_RXERR_PHY)
868 return false;
869
870 if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
871 *decrypt_error = true;
872 } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
873 if (ieee80211_is_ctl(fc))
874 /*
875 * Sometimes, we get invalid
876 * MIC failures on valid control frames.
877 * Remove these mic errors.
878 */
879 rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
880 else
881 rxs->flag |= RX_FLAG_MMIC_ERROR;
882 }
883 /*
884 * Reject error frames with the exception of
885 * decryption and MIC failures. For monitor mode,
886 * we also ignore the CRC error.
887 */
888 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
889 if (rx_stats->rs_status &
890 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
891 ATH9K_RXERR_CRC))
892 return false;
893 } else {
894 if (rx_stats->rs_status &
895 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
896 return false;
897 }
898 }
899 }
900 return true;
901}
902
903static int ath9k_process_rate(struct ath_common *common,
904 struct ieee80211_hw *hw,
905 struct ath_rx_status *rx_stats,
906 struct ieee80211_rx_status *rxs)
907{
908 struct ieee80211_supported_band *sband;
909 enum ieee80211_band band;
910 unsigned int i = 0;
911
912 band = hw->conf.channel->band;
913 sband = hw->wiphy->bands[band];
914
915 if (rx_stats->rs_rate & 0x80) {
916 /* HT rate */
917 rxs->flag |= RX_FLAG_HT;
918 if (rx_stats->rs_flags & ATH9K_RX_2040)
919 rxs->flag |= RX_FLAG_40MHZ;
920 if (rx_stats->rs_flags & ATH9K_RX_GI)
921 rxs->flag |= RX_FLAG_SHORT_GI;
922 rxs->rate_idx = rx_stats->rs_rate & 0x7f;
923 return 0;
924 }
925
926 for (i = 0; i < sband->n_bitrates; i++) {
927 if (sband->bitrates[i].hw_value == rx_stats->rs_rate) {
928 rxs->rate_idx = i;
929 return 0;
930 }
931 if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
932 rxs->flag |= RX_FLAG_SHORTPRE;
933 rxs->rate_idx = i;
934 return 0;
935 }
936 }
937
938 /*
939 * No valid hardware bitrate found -- we should not get here
940 * because hardware has already validated this frame as OK.
941 */
942 ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected "
943 "0x%02x using 1 Mbit\n", rx_stats->rs_rate);
944
945 return -EINVAL;
946}
947
948static void ath9k_process_rssi(struct ath_common *common,
949 struct ieee80211_hw *hw,
950 struct ieee80211_hdr *hdr,
951 struct ath_rx_status *rx_stats)
952{
953 struct ath_hw *ah = common->ah;
954 struct ieee80211_sta *sta;
955 struct ath_node *an;
956 int last_rssi = ATH_RSSI_DUMMY_MARKER;
957 __le16 fc;
958
959 fc = hdr->frame_control;
960
961 rcu_read_lock();
962 /*
963 * XXX: use ieee80211_find_sta! This requires quite a bit of work
964 * under the current ath9k virtual wiphy implementation as we have
965 * no way of tying a vif to wiphy. Typically vifs are attached to
966 * at least one sdata of a wiphy on mac80211 but with ath9k virtual
967 * wiphy you'd have to iterate over every wiphy and each sdata.
968 */
969 sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
970 if (sta) {
971 an = (struct ath_node *) sta->drv_priv;
972 if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
973 !rx_stats->rs_moreaggr)
974 ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
975 last_rssi = an->last_rssi;
976 }
977 rcu_read_unlock();
978
979 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
980 rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
981 ATH_RSSI_EP_MULTIPLIER);
982 if (rx_stats->rs_rssi < 0)
983 rx_stats->rs_rssi = 0;
984
985 /* Update Beacon RSSI, this is used by ANI. */
986 if (ieee80211_is_beacon(fc))
987 ah->stats.avgbrssi = rx_stats->rs_rssi;
988}
989
990/*
991 * For Decrypt or Demic errors, we only mark packet status here and always push
992 * up the frame up to let mac80211 handle the actual error case, be it no
993 * decryption key or real decryption error. This let us keep statistics there.
994 */
995static int ath9k_rx_skb_preprocess(struct ath_common *common,
996 struct ieee80211_hw *hw,
997 struct ieee80211_hdr *hdr,
998 struct ath_rx_status *rx_stats,
999 struct ieee80211_rx_status *rx_status,
1000 bool *decrypt_error)
1001{
1002 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
1003
1004 /*
1005 * everything but the rate is checked here, the rate check is done
1006 * separately to avoid doing two lookups for a rate for each frame.
1007 */
1008 if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
1009 return -EINVAL;
1010
1011 ath9k_process_rssi(common, hw, hdr, rx_stats);
1012
1013 if (ath9k_process_rate(common, hw, rx_stats, rx_status))
1014 return -EINVAL;
1015
1016 rx_status->band = hw->conf.channel->band;
1017 rx_status->freq = hw->conf.channel->center_freq;
1018 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
1019 rx_status->antenna = rx_stats->rs_antenna;
1020 rx_status->flag |= RX_FLAG_TSFT;
1021
1022 return 0;
1023}
1024
1025static void ath9k_rx_skb_postprocess(struct ath_common *common,
1026 struct sk_buff *skb,
1027 struct ath_rx_status *rx_stats,
1028 struct ieee80211_rx_status *rxs,
1029 bool decrypt_error)
1030{
1031 struct ath_hw *ah = common->ah;
1032 struct ieee80211_hdr *hdr;
1033 int hdrlen, padpos, padsize;
1034 u8 keyix;
1035 __le16 fc;
1036
1037 /* see if any padding is done by the hw and remove it */
1038 hdr = (struct ieee80211_hdr *) skb->data;
1039 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1040 fc = hdr->frame_control;
1041 padpos = ath9k_cmn_padpos(hdr->frame_control);
1042
1043 /* The MAC header is padded to have 32-bit boundary if the
1044 * packet payload is non-zero. The general calculation for
1045 * padsize would take into account odd header lengths:
1046 * padsize = (4 - padpos % 4) % 4; However, since only
1047 * even-length headers are used, padding can only be 0 or 2
1048 * bytes and we can optimize this a bit. In addition, we must
1049 * not try to remove padding from short control frames that do
1050 * not have payload. */
1051 padsize = padpos & 3;
1052 if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
1053 memmove(skb->data + padsize, skb->data, padpos);
1054 skb_pull(skb, padsize);
1055 }
1056
1057 keyix = rx_stats->rs_keyix;
1058
1059 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error &&
1060 ieee80211_has_protected(fc)) {
1061 rxs->flag |= RX_FLAG_DECRYPTED;
1062 } else if (ieee80211_has_protected(fc)
1063 && !decrypt_error && skb->len >= hdrlen + 4) {
1064 keyix = skb->data[hdrlen + 3] >> 6;
1065
1066 if (test_bit(keyix, common->keymap))
1067 rxs->flag |= RX_FLAG_DECRYPTED;
1068 }
1069 if (ah->sw_mgmt_crypto &&
1070 (rxs->flag & RX_FLAG_DECRYPTED) &&
1071 ieee80211_is_mgmt(fc))
1072 /* Use software decrypt for management frames. */
1073 rxs->flag &= ~RX_FLAG_DECRYPTED;
1074}
824 1075
825int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) 1076int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
826{ 1077{
@@ -842,15 +1093,21 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
842 enum ath9k_rx_qtype qtype; 1093 enum ath9k_rx_qtype qtype;
843 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); 1094 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
844 int dma_type; 1095 int dma_type;
1096 u8 rx_status_len = ah->caps.rx_status_len;
1097 u64 tsf = 0;
1098 u32 tsf_lower = 0;
845 1099
846 if (edma) 1100 if (edma)
847 dma_type = DMA_FROM_DEVICE;
848 else
849 dma_type = DMA_BIDIRECTIONAL; 1101 dma_type = DMA_BIDIRECTIONAL;
1102 else
1103 dma_type = DMA_FROM_DEVICE;
850 1104
851 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; 1105 qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
852 spin_lock_bh(&sc->rx.rxbuflock); 1106 spin_lock_bh(&sc->rx.rxbuflock);
853 1107
1108 tsf = ath9k_hw_gettsf64(ah);
1109 tsf_lower = tsf & 0xffffffff;
1110
854 do { 1111 do {
855 /* If handling rx interrupt and flush is in progress => exit */ 1112 /* If handling rx interrupt and flush is in progress => exit */
856 if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) 1113 if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
@@ -869,7 +1126,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
869 if (!skb) 1126 if (!skb)
870 continue; 1127 continue;
871 1128
872 hdr = (struct ieee80211_hdr *) skb->data; 1129 hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len);
873 rxs = IEEE80211_SKB_RXCB(skb); 1130 rxs = IEEE80211_SKB_RXCB(skb);
874 1131
875 hw = ath_get_virt_hw(sc, hdr); 1132 hw = ath_get_virt_hw(sc, hdr);
@@ -883,8 +1140,17 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
883 if (flush) 1140 if (flush)
884 goto requeue; 1141 goto requeue;
885 1142
886 retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, &rs, 1143 rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
887 rxs, &decrypt_error); 1144 if (rs.rs_tstamp > tsf_lower &&
1145 unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
1146 rxs->mactime -= 0x100000000ULL;
1147
1148 if (rs.rs_tstamp < tsf_lower &&
1149 unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
1150 rxs->mactime += 0x100000000ULL;
1151
1152 retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
1153 rxs, &decrypt_error);
888 if (retval) 1154 if (retval)
889 goto requeue; 1155 goto requeue;
890 1156
@@ -908,8 +1174,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
908 if (ah->caps.rx_status_len) 1174 if (ah->caps.rx_status_len)
909 skb_pull(skb, ah->caps.rx_status_len); 1175 skb_pull(skb, ah->caps.rx_status_len);
910 1176
911 ath9k_cmn_rx_skb_postprocess(common, skb, &rs, 1177 ath9k_rx_skb_postprocess(common, skb, &rs,
912 rxs, decrypt_error); 1178 rxs, decrypt_error);
913 1179
914 /* We will now give hardware our shiny new allocated skb */ 1180 /* We will now give hardware our shiny new allocated skb */
915 bf->bf_mpdu = requeue_skb; 1181 bf->bf_mpdu = requeue_skb;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index d4371a43bdaa..47be667fe4ff 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -222,6 +222,7 @@
222 222
223#define AR_ISR_S2 0x008c 223#define AR_ISR_S2 0x008c
224#define AR_ISR_S2_QCU_TXURN 0x000003FF 224#define AR_ISR_S2_QCU_TXURN 0x000003FF
225#define AR_ISR_S2_BB_WATCHDOG 0x00010000
225#define AR_ISR_S2_CST 0x00400000 226#define AR_ISR_S2_CST 0x00400000
226#define AR_ISR_S2_GTT 0x00800000 227#define AR_ISR_S2_GTT 0x00800000
227#define AR_ISR_S2_TIM 0x01000000 228#define AR_ISR_S2_TIM 0x01000000
@@ -699,7 +700,15 @@
699#define AR_RC_HOSTIF 0x00000100 700#define AR_RC_HOSTIF 0x00000100
700 701
701#define AR_WA 0x4004 702#define AR_WA 0x4004
703#define AR_WA_BIT6 (1 << 6)
704#define AR_WA_BIT7 (1 << 7)
705#define AR_WA_BIT23 (1 << 23)
702#define AR_WA_D3_L1_DISABLE (1 << 14) 706#define AR_WA_D3_L1_DISABLE (1 << 14)
707#define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16)
708#define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17)
709#define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */
710#define AR_WA_ANALOG_SHIFT (1 << 20)
711#define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */
703#define AR9285_WA_DEFAULT 0x004a050b 712#define AR9285_WA_DEFAULT 0x004a050b
704#define AR9280_WA_DEFAULT 0x0040073b 713#define AR9280_WA_DEFAULT 0x0040073b
705#define AR_WA_DEFAULT 0x0000073f 714#define AR_WA_DEFAULT 0x0000073f
@@ -756,32 +765,33 @@
756#define AR_SREV_REVISION2 0x00000F00 765#define AR_SREV_REVISION2 0x00000F00
757#define AR_SREV_REVISION2_S 8 766#define AR_SREV_REVISION2_S 8
758 767
759#define AR_SREV_VERSION_5416_PCI 0xD 768#define AR_SREV_VERSION_5416_PCI 0xD
760#define AR_SREV_VERSION_5416_PCIE 0xC 769#define AR_SREV_VERSION_5416_PCIE 0xC
761#define AR_SREV_REVISION_5416_10 0 770#define AR_SREV_REVISION_5416_10 0
762#define AR_SREV_REVISION_5416_20 1 771#define AR_SREV_REVISION_5416_20 1
763#define AR_SREV_REVISION_5416_22 2 772#define AR_SREV_REVISION_5416_22 2
764#define AR_SREV_VERSION_9100 0x14 773#define AR_SREV_VERSION_9100 0x14
765#define AR_SREV_VERSION_9160 0x40 774#define AR_SREV_VERSION_9160 0x40
766#define AR_SREV_REVISION_9160_10 0 775#define AR_SREV_REVISION_9160_10 0
767#define AR_SREV_REVISION_9160_11 1 776#define AR_SREV_REVISION_9160_11 1
768#define AR_SREV_VERSION_9280 0x80 777#define AR_SREV_VERSION_9280 0x80
769#define AR_SREV_REVISION_9280_10 0 778#define AR_SREV_REVISION_9280_10 0
770#define AR_SREV_REVISION_9280_20 1 779#define AR_SREV_REVISION_9280_20 1
771#define AR_SREV_REVISION_9280_21 2 780#define AR_SREV_REVISION_9280_21 2
772#define AR_SREV_VERSION_9285 0xC0 781#define AR_SREV_VERSION_9285 0xC0
773#define AR_SREV_REVISION_9285_10 0 782#define AR_SREV_REVISION_9285_10 0
774#define AR_SREV_REVISION_9285_11 1 783#define AR_SREV_REVISION_9285_11 1
775#define AR_SREV_REVISION_9285_12 2 784#define AR_SREV_REVISION_9285_12 2
776#define AR_SREV_VERSION_9287 0x180 785#define AR_SREV_VERSION_9287 0x180
777#define AR_SREV_REVISION_9287_10 0 786#define AR_SREV_REVISION_9287_10 0
778#define AR_SREV_REVISION_9287_11 1 787#define AR_SREV_REVISION_9287_11 1
779#define AR_SREV_REVISION_9287_12 2 788#define AR_SREV_REVISION_9287_12 2
780#define AR_SREV_VERSION_9271 0x140 789#define AR_SREV_REVISION_9287_13 3
781#define AR_SREV_REVISION_9271_10 0 790#define AR_SREV_VERSION_9271 0x140
782#define AR_SREV_REVISION_9271_11 1 791#define AR_SREV_REVISION_9271_10 0
783#define AR_SREV_VERSION_9300 0x1c0 792#define AR_SREV_REVISION_9271_11 1
784#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ 793#define AR_SREV_VERSION_9300 0x1c0
794#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */
785 795
786#define AR_SREV_5416(_ah) \ 796#define AR_SREV_5416(_ah) \
787 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 797 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -859,6 +869,11 @@
859 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \ 869 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
860 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ 870 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
861 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_12))) 871 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_12)))
872#define AR_SREV_9287_13_OR_LATER(_ah) \
873 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
874 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
875 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_13)))
876
862#define AR_SREV_9271(_ah) \ 877#define AR_SREV_9271(_ah) \
863 (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271) 878 (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271)
864#define AR_SREV_9271_10(_ah) \ 879#define AR_SREV_9271_10(_ah) \
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 105ad40968f6..89423ca23d2c 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -219,7 +219,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
219 info->control.rates[1].idx = -1; 219 info->control.rates[1].idx = -1;
220 220
221 memset(&txctl, 0, sizeof(struct ath_tx_control)); 221 memset(&txctl, 0, sizeof(struct ath_tx_control));
222 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; 222 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]];
223 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; 223 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
224 224
225 if (ath_tx_start(aphy->hw, skb, &txctl) != 0) 225 if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index e23172c9caaf..6260faa658a2 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -279,9 +279,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
279 if (wmi->drv_priv->op_flags & OP_UNPLUGGED) 279 if (wmi->drv_priv->op_flags & OP_UNPLUGGED)
280 return 0; 280 return 0;
281 281
282 if (!wmi)
283 return -EINVAL;
284
285 skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC); 282 skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC);
286 if (!skb) 283 if (!skb)
287 return -ENOMEM; 284 return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 859aa4ab0769..c41185b28c0a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -941,6 +941,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
941 if (!ATH_TXQ_SETUP(sc, qnum)) { 941 if (!ATH_TXQ_SETUP(sc, qnum)) {
942 struct ath_txq *txq = &sc->tx.txq[qnum]; 942 struct ath_txq *txq = &sc->tx.txq[qnum];
943 943
944 txq->axq_class = subtype;
944 txq->axq_qnum = qnum; 945 txq->axq_qnum = qnum;
945 txq->axq_link = NULL; 946 txq->axq_link = NULL;
946 INIT_LIST_HEAD(&txq->axq_q); 947 INIT_LIST_HEAD(&txq->axq_q);
@@ -958,58 +959,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
958 return &sc->tx.txq[qnum]; 959 return &sc->tx.txq[qnum];
959} 960}
960 961
961int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
962{
963 int qnum;
964
965 switch (qtype) {
966 case ATH9K_TX_QUEUE_DATA:
967 if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
968 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
969 "HAL AC %u out of range, max %zu!\n",
970 haltype, ARRAY_SIZE(sc->tx.hwq_map));
971 return -1;
972 }
973 qnum = sc->tx.hwq_map[haltype];
974 break;
975 case ATH9K_TX_QUEUE_BEACON:
976 qnum = sc->beacon.beaconq;
977 break;
978 case ATH9K_TX_QUEUE_CAB:
979 qnum = sc->beacon.cabq->axq_qnum;
980 break;
981 default:
982 qnum = -1;
983 }
984 return qnum;
985}
986
987struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
988{
989 struct ath_txq *txq = NULL;
990 u16 skb_queue = skb_get_queue_mapping(skb);
991 int qnum;
992
993 qnum = ath_get_hal_qnum(skb_queue, sc);
994 txq = &sc->tx.txq[qnum];
995
996 spin_lock_bh(&txq->axq_lock);
997
998 if (txq->axq_depth >= (ATH_TXBUF - 20)) {
999 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
1000 "TX queue: %d is full, depth: %d\n",
1001 qnum, txq->axq_depth);
1002 ath_mac80211_stop_queue(sc, skb_queue);
1003 txq->stopped = 1;
1004 spin_unlock_bh(&txq->axq_lock);
1005 return NULL;
1006 }
1007
1008 spin_unlock_bh(&txq->axq_lock);
1009
1010 return txq;
1011}
1012
1013int ath_txq_update(struct ath_softc *sc, int qnum, 962int ath_txq_update(struct ath_softc *sc, int qnum,
1014 struct ath9k_tx_queue_info *qinfo) 963 struct ath9k_tx_queue_info *qinfo)
1015{ 964{
@@ -1688,12 +1637,15 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1688 bf->bf_frmlen -= padsize; 1637 bf->bf_frmlen -= padsize;
1689 } 1638 }
1690 1639
1691 if (conf_is_ht(&hw->conf)) { 1640 if (!txctl->paprd && conf_is_ht(&hw->conf)) {
1692 bf->bf_state.bf_type |= BUF_HT; 1641 bf->bf_state.bf_type |= BUF_HT;
1693 if (tx_info->flags & IEEE80211_TX_CTL_LDPC) 1642 if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
1694 use_ldpc = true; 1643 use_ldpc = true;
1695 } 1644 }
1696 1645
1646 bf->bf_state.bfs_paprd = txctl->paprd;
1647 if (txctl->paprd)
1648 bf->bf_state.bfs_paprd_timestamp = jiffies;
1697 bf->bf_flags = setup_tx_flags(skb, use_ldpc); 1649 bf->bf_flags = setup_tx_flags(skb, use_ldpc);
1698 1650
1699 bf->bf_keytype = get_hw_crypto_keytype(skb); 1651 bf->bf_keytype = get_hw_crypto_keytype(skb);
@@ -1768,6 +1720,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1768 bf->bf_buf_addr, 1720 bf->bf_buf_addr,
1769 txctl->txq->axq_qnum); 1721 txctl->txq->axq_qnum);
1770 1722
1723 if (bf->bf_state.bfs_paprd)
1724 ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd);
1725
1771 spin_lock_bh(&txctl->txq->axq_lock); 1726 spin_lock_bh(&txctl->txq->axq_lock);
1772 1727
1773 if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && 1728 if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
@@ -1809,8 +1764,9 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1809 struct ath_wiphy *aphy = hw->priv; 1764 struct ath_wiphy *aphy = hw->priv;
1810 struct ath_softc *sc = aphy->sc; 1765 struct ath_softc *sc = aphy->sc;
1811 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1766 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1767 struct ath_txq *txq = txctl->txq;
1812 struct ath_buf *bf; 1768 struct ath_buf *bf;
1813 int r; 1769 int q, r;
1814 1770
1815 bf = ath_tx_get_buffer(sc); 1771 bf = ath_tx_get_buffer(sc);
1816 if (!bf) { 1772 if (!bf) {
@@ -1820,8 +1776,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1820 1776
1821 r = ath_tx_setup_buffer(hw, bf, skb, txctl); 1777 r = ath_tx_setup_buffer(hw, bf, skb, txctl);
1822 if (unlikely(r)) { 1778 if (unlikely(r)) {
1823 struct ath_txq *txq = txctl->txq;
1824
1825 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); 1779 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
1826 1780
1827 /* upon ath_tx_processq() this TX queue will be resumed, we 1781 /* upon ath_tx_processq() this TX queue will be resumed, we
@@ -1829,7 +1783,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1829 * we will at least have to run TX completionon one buffer 1783 * we will at least have to run TX completionon one buffer
1830 * on the queue */ 1784 * on the queue */
1831 spin_lock_bh(&txq->axq_lock); 1785 spin_lock_bh(&txq->axq_lock);
1832 if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { 1786 if (!txq->stopped && txq->axq_depth > 1) {
1833 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); 1787 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1834 txq->stopped = 1; 1788 txq->stopped = 1;
1835 } 1789 }
@@ -1840,6 +1794,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1840 return r; 1794 return r;
1841 } 1795 }
1842 1796
1797 q = skb_get_queue_mapping(skb);
1798 if (q >= 4)
1799 q = 0;
1800
1801 spin_lock_bh(&txq->axq_lock);
1802 if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) {
1803 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1804 txq->stopped = 1;
1805 }
1806 spin_unlock_bh(&txq->axq_lock);
1807
1843 ath_tx_start_dma(sc, bf, txctl); 1808 ath_tx_start_dma(sc, bf, txctl);
1844 1809
1845 return 0; 1810 return 0;
@@ -1909,7 +1874,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1909 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1874 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1910 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1875 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1911 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; 1876 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1912 int padpos, padsize; 1877 int q, padpos, padsize;
1913 1878
1914 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); 1879 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
1915 1880
@@ -1948,8 +1913,16 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1948 1913
1949 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) 1914 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
1950 ath9k_tx_status(hw, skb); 1915 ath9k_tx_status(hw, skb);
1951 else 1916 else {
1917 q = skb_get_queue_mapping(skb);
1918 if (q >= 4)
1919 q = 0;
1920
1921 if (--sc->tx.pending_frames[q] < 0)
1922 sc->tx.pending_frames[q] = 0;
1923
1952 ieee80211_tx_status(hw, skb); 1924 ieee80211_tx_status(hw, skb);
1925 }
1953} 1926}
1954 1927
1955static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 1928static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
@@ -1971,8 +1944,18 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1971 } 1944 }
1972 1945
1973 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1946 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1974 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1947
1975 ath_debug_stat_tx(sc, txq, bf, ts); 1948 if (bf->bf_state.bfs_paprd) {
1949 if (time_after(jiffies,
1950 bf->bf_state.bfs_paprd_timestamp +
1951 msecs_to_jiffies(ATH_PAPRD_TIMEOUT)))
1952 dev_kfree_skb_any(skb);
1953 else
1954 complete(&sc->paprd_complete);
1955 } else {
1956 ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1957 ath_debug_stat_tx(sc, txq, bf, ts);
1958 }
1976 1959
1977 /* 1960 /*
1978 * Return the list of ath_buf of this mpdu to free queue 1961 * Return the list of ath_buf of this mpdu to free queue
@@ -2057,14 +2040,14 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
2057{ 2040{
2058 int qnum; 2041 int qnum;
2059 2042
2043 qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
2044 if (qnum == -1)
2045 return;
2046
2060 spin_lock_bh(&txq->axq_lock); 2047 spin_lock_bh(&txq->axq_lock);
2061 if (txq->stopped && 2048 if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
2062 sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) { 2049 ath_mac80211_start_queue(sc, qnum);
2063 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); 2050 txq->stopped = 0;
2064 if (qnum != -1) {
2065 ath_mac80211_start_queue(sc, qnum);
2066 txq->stopped = 0;
2067 }
2068 } 2051 }
2069 spin_unlock_bh(&txq->axq_lock); 2052 spin_unlock_bh(&txq->axq_lock);
2070} 2053}
@@ -2279,6 +2262,17 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2279 2262
2280 txok = !(txs.ts_status & ATH9K_TXERR_MASK); 2263 txok = !(txs.ts_status & ATH9K_TXERR_MASK);
2281 2264
2265 /*
2266 * Make sure null func frame is acked before configuring
2267 * hw into ps mode.
2268 */
2269 if (bf->bf_isnullfunc && txok) {
2270 if ((sc->ps_flags & PS_ENABLED))
2271 ath9k_enable_ps(sc);
2272 else
2273 sc->ps_flags |= PS_NULLFUNC_COMPLETED;
2274 }
2275
2282 if (!bf_isampdu(bf)) { 2276 if (!bf_isampdu(bf)) {
2283 bf->bf_retries = txs.ts_longretry; 2277 bf->bf_retries = txs.ts_longretry;
2284 if (txs.ts_status & ATH9K_TXERR_XRETRY) 2278 if (txs.ts_status & ATH9K_TXERR_XRETRY)
@@ -2424,26 +2418,8 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2424 for (acno = 0, ac = &an->ac[acno]; 2418 for (acno = 0, ac = &an->ac[acno];
2425 acno < WME_NUM_AC; acno++, ac++) { 2419 acno < WME_NUM_AC; acno++, ac++) {
2426 ac->sched = false; 2420 ac->sched = false;
2421 ac->qnum = sc->tx.hwq_map[acno];
2427 INIT_LIST_HEAD(&ac->tid_q); 2422 INIT_LIST_HEAD(&ac->tid_q);
2428
2429 switch (acno) {
2430 case WME_AC_BE:
2431 ac->qnum = ath_tx_get_qnum(sc,
2432 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
2433 break;
2434 case WME_AC_BK:
2435 ac->qnum = ath_tx_get_qnum(sc,
2436 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
2437 break;
2438 case WME_AC_VI:
2439 ac->qnum = ath_tx_get_qnum(sc,
2440 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
2441 break;
2442 case WME_AC_VO:
2443 ac->qnum = ath_tx_get_qnum(sc,
2444 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
2445 break;
2446 }
2447 } 2423 }
2448} 2424}
2449 2425
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index fa40fdfea719..10d0aaf754c5 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -333,11 +333,11 @@ static inline
333 dma_addr_t dmaaddr; 333 dma_addr_t dmaaddr;
334 334
335 if (tx) { 335 if (tx) {
336 dmaaddr = ssb_dma_map_single(ring->dev->dev, 336 dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
337 buf, len, DMA_TO_DEVICE); 337 buf, len, DMA_TO_DEVICE);
338 } else { 338 } else {
339 dmaaddr = ssb_dma_map_single(ring->dev->dev, 339 dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
340 buf, len, DMA_FROM_DEVICE); 340 buf, len, DMA_FROM_DEVICE);
341 } 341 }
342 342
343 return dmaaddr; 343 return dmaaddr;
@@ -348,11 +348,11 @@ static inline
348 dma_addr_t addr, size_t len, int tx) 348 dma_addr_t addr, size_t len, int tx)
349{ 349{
350 if (tx) { 350 if (tx) {
351 ssb_dma_unmap_single(ring->dev->dev, 351 dma_unmap_single(ring->dev->dev->dma_dev,
352 addr, len, DMA_TO_DEVICE); 352 addr, len, DMA_TO_DEVICE);
353 } else { 353 } else {
354 ssb_dma_unmap_single(ring->dev->dev, 354 dma_unmap_single(ring->dev->dev->dma_dev,
355 addr, len, DMA_FROM_DEVICE); 355 addr, len, DMA_FROM_DEVICE);
356 } 356 }
357} 357}
358 358
@@ -361,7 +361,7 @@ static inline
361 dma_addr_t addr, size_t len) 361 dma_addr_t addr, size_t len)
362{ 362{
363 B43_WARN_ON(ring->tx); 363 B43_WARN_ON(ring->tx);
364 ssb_dma_sync_single_for_cpu(ring->dev->dev, 364 dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
365 addr, len, DMA_FROM_DEVICE); 365 addr, len, DMA_FROM_DEVICE);
366} 366}
367 367
@@ -370,8 +370,8 @@ static inline
370 dma_addr_t addr, size_t len) 370 dma_addr_t addr, size_t len)
371{ 371{
372 B43_WARN_ON(ring->tx); 372 B43_WARN_ON(ring->tx);
373 ssb_dma_sync_single_for_device(ring->dev->dev, 373 dma_sync_single_for_device(ring->dev->dev->dma_dev,
374 addr, len, DMA_FROM_DEVICE); 374 addr, len, DMA_FROM_DEVICE);
375} 375}
376 376
377static inline 377static inline
@@ -401,9 +401,9 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
401 */ 401 */
402 if (ring->type == B43_DMA_64BIT) 402 if (ring->type == B43_DMA_64BIT)
403 flags |= GFP_DMA; 403 flags |= GFP_DMA;
404 ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, 404 ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev,
405 B43_DMA_RINGMEMSIZE, 405 B43_DMA_RINGMEMSIZE,
406 &(ring->dmabase), flags); 406 &(ring->dmabase), flags);
407 if (!ring->descbase) { 407 if (!ring->descbase) {
408 b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); 408 b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
409 return -ENOMEM; 409 return -ENOMEM;
@@ -420,8 +420,8 @@ static void free_ringmemory(struct b43_dmaring *ring)
420 if (ring->type == B43_DMA_64BIT) 420 if (ring->type == B43_DMA_64BIT)
421 flags |= GFP_DMA; 421 flags |= GFP_DMA;
422 422
423 ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, 423 dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
424 ring->descbase, ring->dmabase, flags); 424 ring->descbase, ring->dmabase);
425} 425}
426 426
427/* Reset the RX DMA channel */ 427/* Reset the RX DMA channel */
@@ -528,7 +528,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
528 dma_addr_t addr, 528 dma_addr_t addr,
529 size_t buffersize, bool dma_to_device) 529 size_t buffersize, bool dma_to_device)
530{ 530{
531 if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) 531 if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr)))
532 return 1; 532 return 1;
533 533
534 switch (ring->type) { 534 switch (ring->type) {
@@ -874,10 +874,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
874 goto err_kfree_meta; 874 goto err_kfree_meta;
875 875
876 /* test for ability to dma to txhdr_cache */ 876 /* test for ability to dma to txhdr_cache */
877 dma_test = ssb_dma_map_single(dev->dev, 877 dma_test = dma_map_single(dev->dev->dma_dev,
878 ring->txhdr_cache, 878 ring->txhdr_cache,
879 b43_txhdr_size(dev), 879 b43_txhdr_size(dev),
880 DMA_TO_DEVICE); 880 DMA_TO_DEVICE);
881 881
882 if (b43_dma_mapping_error(ring, dma_test, 882 if (b43_dma_mapping_error(ring, dma_test,
883 b43_txhdr_size(dev), 1)) { 883 b43_txhdr_size(dev), 1)) {
@@ -889,10 +889,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
889 if (!ring->txhdr_cache) 889 if (!ring->txhdr_cache)
890 goto err_kfree_meta; 890 goto err_kfree_meta;
891 891
892 dma_test = ssb_dma_map_single(dev->dev, 892 dma_test = dma_map_single(dev->dev->dma_dev,
893 ring->txhdr_cache, 893 ring->txhdr_cache,
894 b43_txhdr_size(dev), 894 b43_txhdr_size(dev),
895 DMA_TO_DEVICE); 895 DMA_TO_DEVICE);
896 896
897 if (b43_dma_mapping_error(ring, dma_test, 897 if (b43_dma_mapping_error(ring, dma_test,
898 b43_txhdr_size(dev), 1)) { 898 b43_txhdr_size(dev), 1)) {
@@ -903,9 +903,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
903 } 903 }
904 } 904 }
905 905
906 ssb_dma_unmap_single(dev->dev, 906 dma_unmap_single(dev->dev->dma_dev,
907 dma_test, b43_txhdr_size(dev), 907 dma_test, b43_txhdr_size(dev),
908 DMA_TO_DEVICE); 908 DMA_TO_DEVICE);
909 } 909 }
910 910
911 err = alloc_ringmemory(ring); 911 err = alloc_ringmemory(ring);
@@ -1018,9 +1018,12 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
1018 /* Try to set the DMA mask. If it fails, try falling back to a 1018 /* Try to set the DMA mask. If it fails, try falling back to a
1019 * lower mask, as we can always also support a lower one. */ 1019 * lower mask, as we can always also support a lower one. */
1020 while (1) { 1020 while (1) {
1021 err = ssb_dma_set_mask(dev->dev, mask); 1021 err = dma_set_mask(dev->dev->dma_dev, mask);
1022 if (!err) 1022 if (!err) {
1023 break; 1023 err = dma_set_coherent_mask(dev->dev->dma_dev, mask);
1024 if (!err)
1025 break;
1026 }
1024 if (mask == DMA_BIT_MASK(64)) { 1027 if (mask == DMA_BIT_MASK(64)) {
1025 mask = DMA_BIT_MASK(32); 1028 mask = DMA_BIT_MASK(32);
1026 fallback = 1; 1029 fallback = 1;
@@ -1221,14 +1224,14 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1221 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); 1224 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1222 /* create a bounce buffer in zone_dma on mapping failure. */ 1225 /* create a bounce buffer in zone_dma on mapping failure. */
1223 if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { 1226 if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
1224 priv_info->bouncebuffer = kmalloc(skb->len, GFP_ATOMIC | GFP_DMA); 1227 priv_info->bouncebuffer = kmemdup(skb->data, skb->len,
1228 GFP_ATOMIC | GFP_DMA);
1225 if (!priv_info->bouncebuffer) { 1229 if (!priv_info->bouncebuffer) {
1226 ring->current_slot = old_top_slot; 1230 ring->current_slot = old_top_slot;
1227 ring->used_slots = old_used_slots; 1231 ring->used_slots = old_used_slots;
1228 err = -ENOMEM; 1232 err = -ENOMEM;
1229 goto out_unmap_hdr; 1233 goto out_unmap_hdr;
1230 } 1234 }
1231 memcpy(priv_info->bouncebuffer, skb->data, skb->len);
1232 1235
1233 meta->dmaaddr = map_descbuffer(ring, priv_info->bouncebuffer, skb->len, 1); 1236 meta->dmaaddr = map_descbuffer(ring, priv_info->bouncebuffer, skb->len, 1);
1234 if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { 1237 if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7965b70efbab..8e243798ae93 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1804,7 +1804,7 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
1804 dma_reason[2], dma_reason[3], 1804 dma_reason[2], dma_reason[3],
1805 dma_reason[4], dma_reason[5]); 1805 dma_reason[4], dma_reason[5]);
1806 b43err(dev->wl, "This device does not support DMA " 1806 b43err(dev->wl, "This device does not support DMA "
1807 "on your system. Please use PIO instead.\n"); 1807 "on your system. It will now be switched to PIO.\n");
1808 /* Fall back to PIO transfers if we get fatal DMA errors! */ 1808 /* Fall back to PIO transfers if we get fatal DMA errors! */
1809 dev->use_pio = 1; 1809 dev->use_pio = 1;
1810 b43_controller_restart(dev, "DMA error"); 1810 b43_controller_restart(dev, "DMA error");
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index e91520d0312e..e03e01d0bc35 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -394,11 +394,11 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring,
394 dma_addr_t dmaaddr; 394 dma_addr_t dmaaddr;
395 395
396 if (tx) 396 if (tx)
397 dmaaddr = ssb_dma_map_single(ring->dev->dev, 397 dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
398 buf, len, 398 buf, len,
399 DMA_TO_DEVICE); 399 DMA_TO_DEVICE);
400 else 400 else
401 dmaaddr = ssb_dma_map_single(ring->dev->dev, 401 dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
402 buf, len, 402 buf, len,
403 DMA_FROM_DEVICE); 403 DMA_FROM_DEVICE);
404 404
@@ -412,11 +412,11 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring,
412 int tx) 412 int tx)
413{ 413{
414 if (tx) 414 if (tx)
415 ssb_dma_unmap_single(ring->dev->dev, 415 dma_unmap_single(ring->dev->dev->dma_dev,
416 addr, len, 416 addr, len,
417 DMA_TO_DEVICE); 417 DMA_TO_DEVICE);
418 else 418 else
419 ssb_dma_unmap_single(ring->dev->dev, 419 dma_unmap_single(ring->dev->dev->dma_dev,
420 addr, len, 420 addr, len,
421 DMA_FROM_DEVICE); 421 DMA_FROM_DEVICE);
422} 422}
@@ -428,8 +428,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
428{ 428{
429 B43legacy_WARN_ON(ring->tx); 429 B43legacy_WARN_ON(ring->tx);
430 430
431 ssb_dma_sync_single_for_cpu(ring->dev->dev, 431 dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
432 addr, len, DMA_FROM_DEVICE); 432 addr, len, DMA_FROM_DEVICE);
433} 433}
434 434
435static inline 435static inline
@@ -439,8 +439,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
439{ 439{
440 B43legacy_WARN_ON(ring->tx); 440 B43legacy_WARN_ON(ring->tx);
441 441
442 ssb_dma_sync_single_for_device(ring->dev->dev, 442 dma_sync_single_for_device(ring->dev->dev->dma_dev,
443 addr, len, DMA_FROM_DEVICE); 443 addr, len, DMA_FROM_DEVICE);
444} 444}
445 445
446static inline 446static inline
@@ -460,10 +460,10 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring,
460static int alloc_ringmemory(struct b43legacy_dmaring *ring) 460static int alloc_ringmemory(struct b43legacy_dmaring *ring)
461{ 461{
462 /* GFP flags must match the flags in free_ringmemory()! */ 462 /* GFP flags must match the flags in free_ringmemory()! */
463 ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, 463 ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev,
464 B43legacy_DMA_RINGMEMSIZE, 464 B43legacy_DMA_RINGMEMSIZE,
465 &(ring->dmabase), 465 &(ring->dmabase),
466 GFP_KERNEL); 466 GFP_KERNEL);
467 if (!ring->descbase) { 467 if (!ring->descbase) {
468 b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" 468 b43legacyerr(ring->dev->wl, "DMA ringmemory allocation"
469 " failed\n"); 469 " failed\n");
@@ -476,8 +476,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring)
476 476
477static void free_ringmemory(struct b43legacy_dmaring *ring) 477static void free_ringmemory(struct b43legacy_dmaring *ring)
478{ 478{
479 ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE, 479 dma_free_coherent(ring->dev->dev->dma_dev, B43legacy_DMA_RINGMEMSIZE,
480 ring->descbase, ring->dmabase, GFP_KERNEL); 480 ring->descbase, ring->dmabase);
481} 481}
482 482
483/* Reset the RX DMA channel */ 483/* Reset the RX DMA channel */
@@ -589,7 +589,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
589 size_t buffersize, 589 size_t buffersize,
590 bool dma_to_device) 590 bool dma_to_device)
591{ 591{
592 if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) 592 if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr)))
593 return 1; 593 return 1;
594 594
595 switch (ring->type) { 595 switch (ring->type) {
@@ -906,7 +906,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
906 goto err_kfree_meta; 906 goto err_kfree_meta;
907 907
908 /* test for ability to dma to txhdr_cache */ 908 /* test for ability to dma to txhdr_cache */
909 dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache, 909 dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache,
910 sizeof(struct b43legacy_txhdr_fw3), 910 sizeof(struct b43legacy_txhdr_fw3),
911 DMA_TO_DEVICE); 911 DMA_TO_DEVICE);
912 912
@@ -920,7 +920,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
920 if (!ring->txhdr_cache) 920 if (!ring->txhdr_cache)
921 goto err_kfree_meta; 921 goto err_kfree_meta;
922 922
923 dma_test = ssb_dma_map_single(dev->dev, 923 dma_test = dma_map_single(dev->dev->dma_dev,
924 ring->txhdr_cache, 924 ring->txhdr_cache,
925 sizeof(struct b43legacy_txhdr_fw3), 925 sizeof(struct b43legacy_txhdr_fw3),
926 DMA_TO_DEVICE); 926 DMA_TO_DEVICE);
@@ -930,9 +930,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
930 goto err_kfree_txhdr_cache; 930 goto err_kfree_txhdr_cache;
931 } 931 }
932 932
933 ssb_dma_unmap_single(dev->dev, dma_test, 933 dma_unmap_single(dev->dev->dma_dev, dma_test,
934 sizeof(struct b43legacy_txhdr_fw3), 934 sizeof(struct b43legacy_txhdr_fw3),
935 DMA_TO_DEVICE); 935 DMA_TO_DEVICE);
936 } 936 }
937 937
938 ring->nr_slots = nr_slots; 938 ring->nr_slots = nr_slots;
@@ -1040,9 +1040,12 @@ static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
1040 /* Try to set the DMA mask. If it fails, try falling back to a 1040 /* Try to set the DMA mask. If it fails, try falling back to a
1041 * lower mask, as we can always also support a lower one. */ 1041 * lower mask, as we can always also support a lower one. */
1042 while (1) { 1042 while (1) {
1043 err = ssb_dma_set_mask(dev->dev, mask); 1043 err = dma_set_mask(dev->dev->dma_dev, mask);
1044 if (!err) 1044 if (!err) {
1045 break; 1045 err = dma_set_coherent_mask(dev->dev->dma_dev, mask);
1046 if (!err)
1047 break;
1048 }
1046 if (mask == DMA_BIT_MASK(64)) { 1049 if (mask == DMA_BIT_MASK(64)) {
1047 mask = DMA_BIT_MASK(32); 1050 mask = DMA_BIT_MASK(32);
1048 fallback = 1; 1051 fallback = 1;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 231dbd77f5f5..9cadaa296fac 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -688,7 +688,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
688 struct ap_data *ap = data; 688 struct ap_data *ap = data;
689 struct net_device *dev = ap->local->dev; 689 struct net_device *dev = ap->local->dev;
690 struct ieee80211_hdr *hdr; 690 struct ieee80211_hdr *hdr;
691 u16 fc, status; 691 u16 status;
692 __le16 *pos; 692 __le16 *pos;
693 struct sta_info *sta = NULL; 693 struct sta_info *sta = NULL;
694 char *txt = NULL; 694 char *txt = NULL;
@@ -699,7 +699,6 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
699 } 699 }
700 700
701 hdr = (struct ieee80211_hdr *) skb->data; 701 hdr = (struct ieee80211_hdr *) skb->data;
702 fc = le16_to_cpu(hdr->frame_control);
703 if ((!ieee80211_is_assoc_resp(hdr->frame_control) && 702 if ((!ieee80211_is_assoc_resp(hdr->frame_control) &&
704 !ieee80211_is_reassoc_resp(hdr->frame_control)) || 703 !ieee80211_is_reassoc_resp(hdr->frame_control)) ||
705 skb->len < IEEE80211_MGMT_HDR_LEN + 4) { 704 skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index eb57d1ea361f..eaee84b55887 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -741,9 +741,7 @@ void hostap_set_multicast_list_queue(struct work_struct *work)
741 local_info_t *local = 741 local_info_t *local =
742 container_of(work, local_info_t, set_multicast_list_queue); 742 container_of(work, local_info_t, set_multicast_list_queue);
743 struct net_device *dev = local->dev; 743 struct net_device *dev = local->dev;
744 struct hostap_interface *iface;
745 744
746 iface = netdev_priv(dev);
747 if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, 745 if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE,
748 local->is_promisc)) { 746 local->is_promisc)) {
749 printk(KERN_INFO "%s: %sabling promiscuous mode failed\n", 747 printk(KERN_INFO "%s: %sabling promiscuous mode failed\n",
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 0bd4dfa59a8a..18ebd602670d 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -3467,10 +3467,8 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3467 dma_addr_t p; 3467 dma_addr_t p;
3468 3468
3469 priv->msg_buffers = 3469 priv->msg_buffers =
3470 (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE * 3470 kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
3471 sizeof(struct 3471 GFP_KERNEL);
3472 ipw2100_tx_packet),
3473 GFP_KERNEL);
3474 if (!priv->msg_buffers) { 3472 if (!priv->msg_buffers) {
3475 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " 3473 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
3476 "buffers.\n", priv->net_dev->name); 3474 "buffers.\n", priv->net_dev->name);
@@ -4499,10 +4497,8 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4499 } 4497 }
4500 4498
4501 priv->tx_buffers = 4499 priv->tx_buffers =
4502 (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH * 4500 kmalloc(TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet),
4503 sizeof(struct 4501 GFP_ATOMIC);
4504 ipw2100_tx_packet),
4505 GFP_ATOMIC);
4506 if (!priv->tx_buffers) { 4502 if (!priv->tx_buffers) {
4507 printk(KERN_ERR DRV_NAME 4503 printk(KERN_ERR DRV_NAME
4508 ": %s: alloc failed form tx buffers.\n", 4504 ": %s: alloc failed form tx buffers.\n",
@@ -4651,9 +4647,9 @@ static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4651 /* 4647 /*
4652 * allocate packets 4648 * allocate packets
4653 */ 4649 */
4654 priv->rx_buffers = (struct ipw2100_rx_packet *) 4650 priv->rx_buffers = kmalloc(RX_QUEUE_LENGTH *
4655 kmalloc(RX_QUEUE_LENGTH * sizeof(struct ipw2100_rx_packet), 4651 sizeof(struct ipw2100_rx_packet),
4656 GFP_KERNEL); 4652 GFP_KERNEL);
4657 if (!priv->rx_buffers) { 4653 if (!priv->rx_buffers) {
4658 IPW_DEBUG_INFO("can't allocate rx packet buffer table\n"); 4654 IPW_DEBUG_INFO("can't allocate rx packet buffer table\n");
4659 4655
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 3aa3bb18f615..cb2552a6777c 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -96,7 +96,7 @@ static int network_mode = 0;
96static u32 ipw_debug_level; 96static u32 ipw_debug_level;
97static int associate; 97static int associate;
98static int auto_create = 1; 98static int auto_create = 1;
99static int led_support = 0; 99static int led_support = 1;
100static int disable = 0; 100static int disable = 0;
101static int bt_coexist = 0; 101static int bt_coexist = 0;
102static int hwcrypto = 0; 102static int hwcrypto = 0;
@@ -6624,13 +6624,12 @@ static int ipw_wx_set_genie(struct net_device *dev,
6624 return -EINVAL; 6624 return -EINVAL;
6625 6625
6626 if (wrqu->data.length) { 6626 if (wrqu->data.length) {
6627 buf = kmalloc(wrqu->data.length, GFP_KERNEL); 6627 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
6628 if (buf == NULL) { 6628 if (buf == NULL) {
6629 err = -ENOMEM; 6629 err = -ENOMEM;
6630 goto out; 6630 goto out;
6631 } 6631 }
6632 6632
6633 memcpy(buf, extra, wrqu->data.length);
6634 kfree(ieee->wpa_ie); 6633 kfree(ieee->wpa_ie);
6635 ieee->wpa_ie = buf; 6634 ieee->wpa_ie = buf;
6636 ieee->wpa_ie_len = wrqu->data.length; 6635 ieee->wpa_ie_len = wrqu->data.length;
@@ -12083,7 +12082,7 @@ module_param(auto_create, int, 0444);
12083MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 12082MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
12084 12083
12085module_param_named(led, led_support, int, 0444); 12084module_param_named(led, led_support, int, 0444);
12086MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)"); 12085MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)");
12087 12086
12088module_param(debug, int, 0444); 12087module_param(debug, int, 0444);
12089MODULE_PARM_DESC(debug, "debug output mask"); 12088MODULE_PARM_DESC(debug, "debug output mask");
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index dc8ed1527666..6491e27baac5 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -30,9 +30,11 @@ config IWLWIFI_DEBUG
30 30
31config IWLWIFI_DEBUGFS 31config IWLWIFI_DEBUGFS
32 bool "iwlagn debugfs support" 32 bool "iwlagn debugfs support"
33 depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS 33 depends on IWLWIFI && MAC80211_DEBUGFS
34 ---help--- 34 ---help---
35 Enable creation of debugfs files for the iwlwifi drivers. 35 Enable creation of debugfs files for the iwlwifi drivers. This
36 is a low-impact option that allows getting insight into the
37 driver's state at runtime.
36 38
37config IWLWIFI_DEVICE_TRACING 39config IWLWIFI_DEVICE_TRACING
38 bool "iwlwifi device access tracing" 40 bool "iwlwifi device access tracing"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 7c7235385513..728bb858ba97 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,6 +1,6 @@
1obj-$(CONFIG_IWLWIFI) += iwlcore.o 1obj-$(CONFIG_IWLWIFI) += iwlcore.o
2iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o 2iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o 3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
4iwlcore-objs += iwl-scan.o iwl-led.o 4iwlcore-objs += iwl-scan.o iwl-led.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
@@ -11,7 +11,7 @@ CFLAGS_iwl-devtrace.o := -I$(src)
11obj-$(CONFIG_IWLAGN) += iwlagn.o 11obj-$(CONFIG_IWLAGN) += iwlagn.o
12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o 12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o 13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
14iwlagn-objs += iwl-agn-lib.o 14iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
15iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o 15iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
16 16
17iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 17iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 6be2992f8f21..dba91e0233b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -158,6 +158,8 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
158 BIT(IWL_CALIB_TX_IQ_PERD) | 158 BIT(IWL_CALIB_TX_IQ_PERD) |
159 BIT(IWL_CALIB_BASE_BAND); 159 BIT(IWL_CALIB_BASE_BAND);
160 160
161 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
162
161 return 0; 163 return 0;
162} 164}
163 165
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
index 6a9c64a50e36..ef0835b01b6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
@@ -28,6 +28,28 @@
28 28
29#include "iwl-3945-debugfs.h" 29#include "iwl-3945-debugfs.h"
30 30
31
32static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
33{
34 int p = 0;
35
36 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
37 le32_to_cpu(priv->_3945.statistics.flag));
38 if (le32_to_cpu(priv->_3945.statistics.flag) &
39 UCODE_STATISTICS_CLEAR_MSK)
40 p += scnprintf(buf + p, bufsz - p,
41 "\tStatistics have been cleared\n");
42 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
43 (le32_to_cpu(priv->_3945.statistics.flag) &
44 UCODE_STATISTICS_FREQUENCY_MSK)
45 ? "2.4 GHz" : "5.2 GHz");
46 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
47 (le32_to_cpu(priv->_3945.statistics.flag) &
48 UCODE_STATISTICS_NARROW_BAND_MSK)
49 ? "enabled" : "disabled");
50 return p;
51}
52
31ssize_t iwl3945_ucode_rx_stats_read(struct file *file, 53ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
32 char __user *user_buf, 54 char __user *user_buf,
33 size_t count, loff_t *ppos) 55 size_t count, loff_t *ppos)
@@ -70,7 +92,7 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
70 max_cck = &priv->_3945.max_delta.rx.cck; 92 max_cck = &priv->_3945.max_delta.rx.cck;
71 max_general = &priv->_3945.max_delta.rx.general; 93 max_general = &priv->_3945.max_delta.rx.general;
72 94
73 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 95 pos += iwl3945_statistics_flag(priv, buf, bufsz);
74 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 96 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
75 "acumulative delta max\n", 97 "acumulative delta max\n",
76 "Statistics_Rx - OFDM:"); 98 "Statistics_Rx - OFDM:");
@@ -331,7 +353,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
331 accum_tx = &priv->_3945.accum_statistics.tx; 353 accum_tx = &priv->_3945.accum_statistics.tx;
332 delta_tx = &priv->_3945.delta_statistics.tx; 354 delta_tx = &priv->_3945.delta_statistics.tx;
333 max_tx = &priv->_3945.max_delta.tx; 355 max_tx = &priv->_3945.max_delta.tx;
334 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 356 pos += iwl3945_statistics_flag(priv, buf, bufsz);
335 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 357 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
336 "acumulative delta max\n", 358 "acumulative delta max\n",
337 "Statistics_Tx:"); 359 "Statistics_Tx:");
@@ -438,7 +460,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file,
438 accum_div = &priv->_3945.accum_statistics.general.div; 460 accum_div = &priv->_3945.accum_statistics.general.div;
439 delta_div = &priv->_3945.delta_statistics.general.div; 461 delta_div = &priv->_3945.delta_statistics.general.div;
440 max_div = &priv->_3945.max_delta.general.div; 462 max_div = &priv->_3945.max_delta.general.div;
441 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 463 pos += iwl3945_statistics_flag(priv, buf, bufsz);
442 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 464 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
443 "acumulative delta max\n", 465 "acumulative delta max\n",
444 "Statistics_General:"); 466 "Statistics_General:");
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index c44a303e62ed..93d513e14186 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -279,8 +279,8 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
279 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 279 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
280 280
281 tx_info = &txq->txb[txq->q.read_ptr]; 281 tx_info = &txq->txb[txq->q.read_ptr];
282 ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); 282 ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
283 tx_info->skb[0] = NULL; 283 tx_info->skb = NULL;
284 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 284 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
285 } 285 }
286 286
@@ -315,7 +315,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
315 return; 315 return;
316 } 316 }
317 317
318 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); 318 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
319 ieee80211_tx_info_clear_status(info); 319 ieee80211_tx_info_clear_status(info);
320 320
321 /* Fill the MRR chain with some info about on-chip retransmissions */ 321 /* Fill the MRR chain with some info about on-chip retransmissions */
@@ -352,7 +352,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
352 * RX handler implementations 352 * RX handler implementations
353 * 353 *
354 *****************************************************************************/ 354 *****************************************************************************/
355#ifdef CONFIG_IWLWIFI_DEBUG 355#ifdef CONFIG_IWLWIFI_DEBUGFS
356/* 356/*
357 * based on the assumption of all statistics counter are in DWORD 357 * based on the assumption of all statistics counter are in DWORD
358 * FIXME: This function is for debugging, do not deal with 358 * FIXME: This function is for debugging, do not deal with
@@ -460,7 +460,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
460 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 460 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
461 (int)sizeof(struct iwl3945_notif_statistics), 461 (int)sizeof(struct iwl3945_notif_statistics),
462 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 462 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
463#ifdef CONFIG_IWLWIFI_DEBUG 463#ifdef CONFIG_IWLWIFI_DEBUGFS
464 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); 464 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
465#endif 465#endif
466 iwl_recover_from_statistics(priv, pkt); 466 iwl_recover_from_statistics(priv, pkt);
@@ -475,7 +475,7 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
475 __le32 *flag = (__le32 *)&pkt->u.raw; 475 __le32 *flag = (__le32 *)&pkt->u.raw;
476 476
477 if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { 477 if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) {
478#ifdef CONFIG_IWLWIFI_DEBUG 478#ifdef CONFIG_IWLWIFI_DEBUGFS
479 memset(&priv->_3945.accum_statistics, 0, 479 memset(&priv->_3945.accum_statistics, 0,
480 sizeof(struct iwl3945_notif_statistics)); 480 sizeof(struct iwl3945_notif_statistics));
481 memset(&priv->_3945.delta_statistics, 0, 481 memset(&priv->_3945.delta_statistics, 0,
@@ -494,158 +494,6 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
494 * Misc. internal state and helper functions 494 * Misc. internal state and helper functions
495 * 495 *
496 ******************************************************************************/ 496 ******************************************************************************/
497#ifdef CONFIG_IWLWIFI_DEBUG
498
499/**
500 * iwl3945_report_frame - dump frame to syslog during debug sessions
501 *
502 * You may hack this function to show different aspects of received frames,
503 * including selective frame dumps.
504 * group100 parameter selects whether to show 1 out of 100 good frames.
505 */
506static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
507 struct iwl_rx_packet *pkt,
508 struct ieee80211_hdr *header, int group100)
509{
510 u32 to_us;
511 u32 print_summary = 0;
512 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
513 u32 hundred = 0;
514 u32 dataframe = 0;
515 __le16 fc;
516 u16 seq_ctl;
517 u16 channel;
518 u16 phy_flags;
519 u16 length;
520 u16 status;
521 u16 bcn_tmr;
522 u32 tsf_low;
523 u64 tsf;
524 u8 rssi;
525 u8 agc;
526 u16 sig_avg;
527 u16 noise_diff;
528 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
529 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
530 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
531 u8 *data = IWL_RX_DATA(pkt);
532
533 /* MAC header */
534 fc = header->frame_control;
535 seq_ctl = le16_to_cpu(header->seq_ctrl);
536
537 /* metadata */
538 channel = le16_to_cpu(rx_hdr->channel);
539 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
540 length = le16_to_cpu(rx_hdr->len);
541
542 /* end-of-frame status and timestamp */
543 status = le32_to_cpu(rx_end->status);
544 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
545 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
546 tsf = le64_to_cpu(rx_end->timestamp);
547
548 /* signal statistics */
549 rssi = rx_stats->rssi;
550 agc = rx_stats->agc;
551 sig_avg = le16_to_cpu(rx_stats->sig_avg);
552 noise_diff = le16_to_cpu(rx_stats->noise_diff);
553
554 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
555
556 /* if data frame is to us and all is good,
557 * (optionally) print summary for only 1 out of every 100 */
558 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
559 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
560 dataframe = 1;
561 if (!group100)
562 print_summary = 1; /* print each frame */
563 else if (priv->framecnt_to_us < 100) {
564 priv->framecnt_to_us++;
565 print_summary = 0;
566 } else {
567 priv->framecnt_to_us = 0;
568 print_summary = 1;
569 hundred = 1;
570 }
571 } else {
572 /* print summary for all other frames */
573 print_summary = 1;
574 }
575
576 if (print_summary) {
577 char *title;
578 int rate;
579
580 if (hundred)
581 title = "100Frames";
582 else if (ieee80211_has_retry(fc))
583 title = "Retry";
584 else if (ieee80211_is_assoc_resp(fc))
585 title = "AscRsp";
586 else if (ieee80211_is_reassoc_resp(fc))
587 title = "RasRsp";
588 else if (ieee80211_is_probe_resp(fc)) {
589 title = "PrbRsp";
590 print_dump = 1; /* dump frame contents */
591 } else if (ieee80211_is_beacon(fc)) {
592 title = "Beacon";
593 print_dump = 1; /* dump frame contents */
594 } else if (ieee80211_is_atim(fc))
595 title = "ATIM";
596 else if (ieee80211_is_auth(fc))
597 title = "Auth";
598 else if (ieee80211_is_deauth(fc))
599 title = "DeAuth";
600 else if (ieee80211_is_disassoc(fc))
601 title = "DisAssoc";
602 else
603 title = "Frame";
604
605 rate = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
606 if (rate == -1)
607 rate = 0;
608 else
609 rate = iwl3945_rates[rate].ieee / 2;
610
611 /* print frame summary.
612 * MAC addresses show just the last byte (for brevity),
613 * but you can hack it to show more, if you'd like to. */
614 if (dataframe)
615 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
616 "len=%u, rssi=%d, chnl=%d, rate=%d,\n",
617 title, le16_to_cpu(fc), header->addr1[5],
618 length, rssi, channel, rate);
619 else {
620 /* src/dst addresses assume managed mode */
621 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, "
622 "src=0x%02x, rssi=%u, tim=%lu usec, "
623 "phy=0x%02x, chnl=%d\n",
624 title, le16_to_cpu(fc), header->addr1[5],
625 header->addr3[5], rssi,
626 tsf_low - priv->scan_start_tsf,
627 phy_flags, channel);
628 }
629 }
630 if (print_dump)
631 iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
632}
633
634static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
635 struct iwl_rx_packet *pkt,
636 struct ieee80211_hdr *header, int group100)
637{
638 if (iwl_get_debug_level(priv) & IWL_DL_RX)
639 _iwl3945_dbg_report_frame(priv, pkt, header, group100);
640}
641
642#else
643static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
644 struct iwl_rx_packet *pkt,
645 struct ieee80211_hdr *header, int group100)
646{
647}
648#endif
649 497
650/* This is necessary only for a number of statistics, see the caller. */ 498/* This is necessary only for a number of statistics, see the caller. */
651static int iwl3945_is_network_packet(struct iwl_priv *priv, 499static int iwl3945_is_network_packet(struct iwl_priv *priv,
@@ -777,8 +625,6 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
777 rx_status.signal, rx_status.signal, 625 rx_status.signal, rx_status.signal,
778 rx_status.rate_idx); 626 rx_status.rate_idx);
779 627
780 /* Set "1" to report good data frames in groups of 100 */
781 iwl3945_dbg_report_frame(priv, pkt, header, 1);
782 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); 628 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
783 629
784 if (network_packet) { 630 if (network_packet) {
@@ -850,25 +696,28 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
850 /* Unmap tx_cmd */ 696 /* Unmap tx_cmd */
851 if (counter) 697 if (counter)
852 pci_unmap_single(dev, 698 pci_unmap_single(dev,
853 pci_unmap_addr(&txq->meta[index], mapping), 699 dma_unmap_addr(&txq->meta[index], mapping),
854 pci_unmap_len(&txq->meta[index], len), 700 dma_unmap_len(&txq->meta[index], len),
855 PCI_DMA_TODEVICE); 701 PCI_DMA_TODEVICE);
856 702
857 /* unmap chunks if any */ 703 /* unmap chunks if any */
858 704
859 for (i = 1; i < counter; i++) { 705 for (i = 1; i < counter; i++)
860 pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), 706 pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr),
861 le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); 707 le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE);
862 if (txq->txb[txq->q.read_ptr].skb[0]) { 708
863 struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0]; 709 /* free SKB */
864 if (txq->txb[txq->q.read_ptr].skb[0]) { 710 if (txq->txb) {
865 /* Can be called from interrupt context */ 711 struct sk_buff *skb;
866 dev_kfree_skb_any(skb); 712
867 txq->txb[txq->q.read_ptr].skb[0] = NULL; 713 skb = txq->txb[txq->q.read_ptr].skb;
868 } 714
715 /* can be called from irqs-disabled context */
716 if (skb) {
717 dev_kfree_skb_any(skb);
718 txq->txb[txq->q.read_ptr].skb = NULL;
869 } 719 }
870 } 720 }
871 return ;
872} 721}
873 722
874/** 723/**
@@ -947,8 +796,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
947 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); 796 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
948} 797}
949 798
950static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, 799static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
951 u16 tx_rate, u8 flags)
952{ 800{
953 unsigned long flags_spin; 801 unsigned long flags_spin;
954 struct iwl_station_entry *station; 802 struct iwl_station_entry *station;
@@ -962,10 +810,9 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
962 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; 810 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
963 station->sta.rate_n_flags = cpu_to_le16(tx_rate); 811 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
964 station->sta.mode = STA_CONTROL_MODIFY_MSK; 812 station->sta.mode = STA_CONTROL_MODIFY_MSK;
965 813 iwl_send_add_sta(priv, &station->sta, CMD_ASYNC);
966 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 814 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
967 815
968 iwl_send_add_sta(priv, &station->sta, flags);
969 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", 816 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
970 sta_id, tx_rate); 817 sta_id, tx_rate);
971 return sta_id; 818 return sta_id;
@@ -997,7 +844,7 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
997 844
998static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) 845static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
999{ 846{
1000 iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr); 847 iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma);
1001 iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); 848 iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
1002 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); 849 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
1003 iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 850 iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
@@ -2473,8 +2320,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2473 2320
2474 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, 2321 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
2475 (priv->band == IEEE80211_BAND_5GHZ) ? 2322 (priv->band == IEEE80211_BAND_5GHZ) ?
2476 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 2323 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP);
2477 CMD_ASYNC);
2478 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); 2324 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
2479 2325
2480 return 0; 2326 return 0;
@@ -2590,6 +2436,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2590 2436
2591 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; 2437 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
2592 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; 2438 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
2439 priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS;
2593 2440
2594 return 0; 2441 return 0;
2595} 2442}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d3afddae8d9f..67526a1be025 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -346,9 +346,19 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
346{ 346{
347 struct iwl_chain_noise_data *data = &(priv->chain_noise_data); 347 struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
348 348
349 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { 349 if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
350 iwl_is_associated(priv)) {
350 struct iwl_calib_diff_gain_cmd cmd; 351 struct iwl_calib_diff_gain_cmd cmd;
351 352
353 /* clear data for chain noise calibration algorithm */
354 data->chain_noise_a = 0;
355 data->chain_noise_b = 0;
356 data->chain_noise_c = 0;
357 data->chain_signal_a = 0;
358 data->chain_signal_b = 0;
359 data->chain_signal_c = 0;
360 data->beacon_count = 0;
361
352 memset(&cmd, 0, sizeof(cmd)); 362 memset(&cmd, 0, sizeof(cmd));
353 cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; 363 cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
354 cmd.diff_gain_a = 0; 364 cmd.diff_gain_a = 0;
@@ -419,13 +429,6 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
419 /* Mark so we run this algo only once! */ 429 /* Mark so we run this algo only once! */
420 data->state = IWL_CHAIN_NOISE_CALIBRATED; 430 data->state = IWL_CHAIN_NOISE_CALIBRATED;
421 } 431 }
422 data->chain_noise_a = 0;
423 data->chain_noise_b = 0;
424 data->chain_noise_c = 0;
425 data->chain_signal_a = 0;
426 data->chain_signal_b = 0;
427 data->chain_signal_c = 0;
428 data->beacon_count = 0;
429} 432}
430 433
431static void iwl4965_bg_txpower_work(struct work_struct *work) 434static void iwl4965_bg_txpower_work(struct work_struct *work)
@@ -669,6 +672,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
669 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); 672 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
670 673
671 priv->hw_params.sens = &iwl4965_sensitivity; 674 priv->hw_params.sens = &iwl4965_sensitivity;
675 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
672 676
673 return 0; 677 return 0;
674} 678}
@@ -1441,7 +1445,8 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
1441 return ret; 1445 return ret;
1442} 1446}
1443 1447
1444static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) 1448static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1449 struct ieee80211_channel_switch *ch_switch)
1445{ 1450{
1446 int rc; 1451 int rc;
1447 u8 band = 0; 1452 u8 band = 0;
@@ -1449,11 +1454,14 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1449 u8 ctrl_chan_high = 0; 1454 u8 ctrl_chan_high = 0;
1450 struct iwl4965_channel_switch_cmd cmd; 1455 struct iwl4965_channel_switch_cmd cmd;
1451 const struct iwl_channel_info *ch_info; 1456 const struct iwl_channel_info *ch_info;
1452 1457 u32 switch_time_in_usec, ucode_switch_time;
1458 u16 ch;
1459 u32 tsf_low;
1460 u8 switch_count;
1461 u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
1462 struct ieee80211_vif *vif = priv->vif;
1453 band = priv->band == IEEE80211_BAND_2GHZ; 1463 band = priv->band == IEEE80211_BAND_2GHZ;
1454 1464
1455 ch_info = iwl_get_channel_info(priv, priv->band, channel);
1456
1457 is_ht40 = is_ht40_channel(priv->staging_rxon.flags); 1465 is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
1458 1466
1459 if (is_ht40 && 1467 if (is_ht40 &&
@@ -1462,26 +1470,56 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1462 1470
1463 cmd.band = band; 1471 cmd.band = band;
1464 cmd.expect_beacon = 0; 1472 cmd.expect_beacon = 0;
1465 cmd.channel = cpu_to_le16(channel); 1473 ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
1474 cmd.channel = cpu_to_le16(ch);
1466 cmd.rxon_flags = priv->staging_rxon.flags; 1475 cmd.rxon_flags = priv->staging_rxon.flags;
1467 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; 1476 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
1468 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); 1477 switch_count = ch_switch->count;
1478 tsf_low = ch_switch->timestamp & 0x0ffffffff;
1479 /*
1480 * calculate the ucode channel switch time
1481 * adding TSF as one of the factor for when to switch
1482 */
1483 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
1484 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
1485 beacon_interval)) {
1486 switch_count -= (priv->ucode_beacon_time -
1487 tsf_low) / beacon_interval;
1488 } else
1489 switch_count = 0;
1490 }
1491 if (switch_count <= 1)
1492 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
1493 else {
1494 switch_time_in_usec =
1495 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
1496 ucode_switch_time = iwl_usecs_to_beacons(priv,
1497 switch_time_in_usec,
1498 beacon_interval);
1499 cmd.switch_time = iwl_add_beacon_time(priv,
1500 priv->ucode_beacon_time,
1501 ucode_switch_time,
1502 beacon_interval);
1503 }
1504 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
1505 cmd.switch_time);
1506 ch_info = iwl_get_channel_info(priv, priv->band, ch);
1469 if (ch_info) 1507 if (ch_info)
1470 cmd.expect_beacon = is_channel_radar(ch_info); 1508 cmd.expect_beacon = is_channel_radar(ch_info);
1471 else { 1509 else {
1472 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 1510 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
1473 priv->active_rxon.channel, channel); 1511 priv->active_rxon.channel, ch);
1474 return -EFAULT; 1512 return -EFAULT;
1475 } 1513 }
1476 1514
1477 rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40, 1515 rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40,
1478 ctrl_chan_high, &cmd.tx_power); 1516 ctrl_chan_high, &cmd.tx_power);
1479 if (rc) { 1517 if (rc) {
1480 IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); 1518 IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc);
1481 return rc; 1519 return rc;
1482 } 1520 }
1483 1521
1484 priv->switch_rxon.channel = cpu_to_le16(channel); 1522 priv->switch_rxon.channel = cmd.channel;
1485 priv->switch_rxon.switch_in_progress = true; 1523 priv->switch_rxon.switch_in_progress = true;
1486 1524
1487 return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); 1525 return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
@@ -1542,7 +1580,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
1542 u32 R4; 1580 u32 R4;
1543 1581
1544 if (test_bit(STATUS_TEMPERATURE, &priv->status) && 1582 if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
1545 (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { 1583 (priv->_agn.statistics.flag &
1584 STATISTICS_REPLY_FLG_HT40_MODE_MSK)) {
1546 IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); 1585 IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n");
1547 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); 1586 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
1548 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); 1587 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
@@ -1566,8 +1605,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
1566 if (!test_bit(STATUS_TEMPERATURE, &priv->status)) 1605 if (!test_bit(STATUS_TEMPERATURE, &priv->status))
1567 vt = sign_extend(R4, 23); 1606 vt = sign_extend(R4, 23);
1568 else 1607 else
1569 vt = sign_extend( 1608 vt = sign_extend(le32_to_cpu(
1570 le32_to_cpu(priv->statistics.general.temperature), 23); 1609 priv->_agn.statistics.general.temperature), 23);
1571 1610
1572 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); 1611 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
1573 1612
@@ -1747,6 +1786,7 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1747{ 1786{
1748 unsigned long flags; 1787 unsigned long flags;
1749 u16 ra_tid; 1788 u16 ra_tid;
1789 int ret;
1750 1790
1751 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || 1791 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1752 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 1792 (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
@@ -1762,7 +1802,9 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1762 ra_tid = BUILD_RAxTID(sta_id, tid); 1802 ra_tid = BUILD_RAxTID(sta_id, tid);
1763 1803
1764 /* Modify device's station table to Tx this TID */ 1804 /* Modify device's station table to Tx this TID */
1765 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 1805 ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
1806 if (ret)
1807 return ret;
1766 1808
1767 spin_lock_irqsave(&priv->lock, flags); 1809 spin_lock_irqsave(&priv->lock, flags);
1768 1810
@@ -1870,7 +1912,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
1870 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", 1912 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
1871 agg->frame_count, agg->start_idx, idx); 1913 agg->frame_count, agg->start_idx, idx);
1872 1914
1873 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); 1915 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb);
1874 info->status.rates[0].count = tx_resp->failure_frame + 1; 1916 info->status.rates[0].count = tx_resp->failure_frame + 1;
1875 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 1917 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
1876 info->flags |= iwl_tx_status_to_mac80211(status); 1918 info->flags |= iwl_tx_status_to_mac80211(status);
@@ -2026,6 +2068,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2026 int sta_id; 2068 int sta_id;
2027 int freed; 2069 int freed;
2028 u8 *qc = NULL; 2070 u8 *qc = NULL;
2071 unsigned long flags;
2029 2072
2030 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 2073 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
2031 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 2074 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -2035,7 +2078,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2035 return; 2078 return;
2036 } 2079 }
2037 2080
2038 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); 2081 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
2039 memset(&info->status, 0, sizeof(info->status)); 2082 memset(&info->status, 0, sizeof(info->status));
2040 2083
2041 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); 2084 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
@@ -2050,10 +2093,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2050 return; 2093 return;
2051 } 2094 }
2052 2095
2096 spin_lock_irqsave(&priv->sta_lock, flags);
2053 if (txq->sched_retry) { 2097 if (txq->sched_retry) {
2054 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); 2098 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2055 struct iwl_ht_agg *agg = NULL; 2099 struct iwl_ht_agg *agg = NULL;
2056
2057 WARN_ON(!qc); 2100 WARN_ON(!qc);
2058 2101
2059 agg = &priv->stations[sta_id].tid[tid].agg; 2102 agg = &priv->stations[sta_id].tid[tid].agg;
@@ -2110,6 +2153,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2110 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 2153 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2111 2154
2112 iwl_check_abort_status(priv, tx_resp->frame_count, status); 2155 iwl_check_abort_status(priv, tx_resp->frame_count, status);
2156
2157 spin_unlock_irqrestore(&priv->sta_lock, flags);
2113} 2158}
2114 2159
2115static int iwl4965_calc_rssi(struct iwl_priv *priv, 2160static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2285,7 +2330,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2285 * Force use of chains B and C for scan RX on 5 GHz band 2330 * Force use of chains B and C for scan RX on 5 GHz band
2286 * because the device has off-channel reception on chain A. 2331 * because the device has off-channel reception on chain A.
2287 */ 2332 */
2288 .scan_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, 2333 .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
2289}; 2334};
2290 2335
2291/* Module firmware */ 2336/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a28af7eb67eb..c6ccc25d6c13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -208,6 +208,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
208 BIT(IWL_CALIB_TX_IQ_PERD) | 208 BIT(IWL_CALIB_TX_IQ_PERD) |
209 BIT(IWL_CALIB_BASE_BAND); 209 BIT(IWL_CALIB_BASE_BAND);
210 210
211 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
212
211 return 0; 213 return 0;
212} 214}
213 215
@@ -252,6 +254,8 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
252 BIT(IWL_CALIB_TX_IQ) | 254 BIT(IWL_CALIB_TX_IQ) |
253 BIT(IWL_CALIB_BASE_BAND); 255 BIT(IWL_CALIB_BASE_BAND);
254 256
257 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
258
255 return 0; 259 return 0;
256} 260}
257 261
@@ -260,40 +264,76 @@ static void iwl5150_temperature(struct iwl_priv *priv)
260 u32 vt = 0; 264 u32 vt = 0;
261 s32 offset = iwl_temp_calib_to_offset(priv); 265 s32 offset = iwl_temp_calib_to_offset(priv);
262 266
263 vt = le32_to_cpu(priv->statistics.general.temperature); 267 vt = le32_to_cpu(priv->_agn.statistics.general.temperature);
264 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 268 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
265 /* now vt hold the temperature in Kelvin */ 269 /* now vt hold the temperature in Kelvin */
266 priv->temperature = KELVIN_TO_CELSIUS(vt); 270 priv->temperature = KELVIN_TO_CELSIUS(vt);
267 iwl_tt_handler(priv); 271 iwl_tt_handler(priv);
268} 272}
269 273
270static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) 274static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
275 struct ieee80211_channel_switch *ch_switch)
271{ 276{
272 struct iwl5000_channel_switch_cmd cmd; 277 struct iwl5000_channel_switch_cmd cmd;
273 const struct iwl_channel_info *ch_info; 278 const struct iwl_channel_info *ch_info;
279 u32 switch_time_in_usec, ucode_switch_time;
280 u16 ch;
281 u32 tsf_low;
282 u8 switch_count;
283 u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
284 struct ieee80211_vif *vif = priv->vif;
274 struct iwl_host_cmd hcmd = { 285 struct iwl_host_cmd hcmd = {
275 .id = REPLY_CHANNEL_SWITCH, 286 .id = REPLY_CHANNEL_SWITCH,
276 .len = sizeof(cmd), 287 .len = sizeof(cmd),
277 .flags = CMD_SIZE_HUGE, 288 .flags = CMD_SYNC,
278 .data = &cmd, 289 .data = &cmd,
279 }; 290 };
280 291
281 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
282 priv->active_rxon.channel, channel);
283 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 292 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
284 cmd.channel = cpu_to_le16(channel); 293 ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
294 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
295 priv->active_rxon.channel, ch);
296 cmd.channel = cpu_to_le16(ch);
285 cmd.rxon_flags = priv->staging_rxon.flags; 297 cmd.rxon_flags = priv->staging_rxon.flags;
286 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; 298 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
287 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); 299 switch_count = ch_switch->count;
288 ch_info = iwl_get_channel_info(priv, priv->band, channel); 300 tsf_low = ch_switch->timestamp & 0x0ffffffff;
301 /*
302 * calculate the ucode channel switch time
303 * adding TSF as one of the factor for when to switch
304 */
305 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
306 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
307 beacon_interval)) {
308 switch_count -= (priv->ucode_beacon_time -
309 tsf_low) / beacon_interval;
310 } else
311 switch_count = 0;
312 }
313 if (switch_count <= 1)
314 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
315 else {
316 switch_time_in_usec =
317 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
318 ucode_switch_time = iwl_usecs_to_beacons(priv,
319 switch_time_in_usec,
320 beacon_interval);
321 cmd.switch_time = iwl_add_beacon_time(priv,
322 priv->ucode_beacon_time,
323 ucode_switch_time,
324 beacon_interval);
325 }
326 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
327 cmd.switch_time);
328 ch_info = iwl_get_channel_info(priv, priv->band, ch);
289 if (ch_info) 329 if (ch_info)
290 cmd.expect_beacon = is_channel_radar(ch_info); 330 cmd.expect_beacon = is_channel_radar(ch_info);
291 else { 331 else {
292 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 332 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
293 priv->active_rxon.channel, channel); 333 priv->active_rxon.channel, ch);
294 return -EFAULT; 334 return -EFAULT;
295 } 335 }
296 priv->switch_rxon.channel = cpu_to_le16(channel); 336 priv->switch_rxon.channel = cmd.channel;
297 priv->switch_rxon.switch_in_progress = true; 337 priv->switch_rxon.switch_in_progress = true;
298 338
299 return iwl_send_cmd_sync(priv, &hcmd); 339 return iwl_send_cmd_sync(priv, &hcmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 9fbf54cd3e1a..afdeec56b13f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -71,6 +71,10 @@
71#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode" 71#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
72#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api) 72#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
73 73
74#define IWL6000G2B_FW_PRE "iwlwifi-6000g2b-"
75#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
76#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
77
74 78
75static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 79static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
76{ 80{
@@ -183,6 +187,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
183 BIT(IWL_CALIB_TX_IQ) | 187 BIT(IWL_CALIB_TX_IQ) |
184 BIT(IWL_CALIB_BASE_BAND); 188 BIT(IWL_CALIB_BASE_BAND);
185 189
190 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
191
186 return 0; 192 return 0;
187} 193}
188 194
@@ -228,37 +234,74 @@ static int iwl6050_hw_set_hw_params(struct iwl_priv *priv)
228 BIT(IWL_CALIB_TX_IQ) | 234 BIT(IWL_CALIB_TX_IQ) |
229 BIT(IWL_CALIB_BASE_BAND); 235 BIT(IWL_CALIB_BASE_BAND);
230 236
237 priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
238
231 return 0; 239 return 0;
232} 240}
233 241
234static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel) 242static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
243 struct ieee80211_channel_switch *ch_switch)
235{ 244{
236 struct iwl6000_channel_switch_cmd cmd; 245 struct iwl6000_channel_switch_cmd cmd;
237 const struct iwl_channel_info *ch_info; 246 const struct iwl_channel_info *ch_info;
247 u32 switch_time_in_usec, ucode_switch_time;
248 u16 ch;
249 u32 tsf_low;
250 u8 switch_count;
251 u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
252 struct ieee80211_vif *vif = priv->vif;
238 struct iwl_host_cmd hcmd = { 253 struct iwl_host_cmd hcmd = {
239 .id = REPLY_CHANNEL_SWITCH, 254 .id = REPLY_CHANNEL_SWITCH,
240 .len = sizeof(cmd), 255 .len = sizeof(cmd),
241 .flags = CMD_SIZE_HUGE, 256 .flags = CMD_SYNC,
242 .data = &cmd, 257 .data = &cmd,
243 }; 258 };
244 259
245 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
246 priv->active_rxon.channel, channel);
247
248 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 260 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
249 cmd.channel = cpu_to_le16(channel); 261 ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq);
262 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
263 priv->active_rxon.channel, ch);
264 cmd.channel = cpu_to_le16(ch);
250 cmd.rxon_flags = priv->staging_rxon.flags; 265 cmd.rxon_flags = priv->staging_rxon.flags;
251 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; 266 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
252 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); 267 switch_count = ch_switch->count;
253 ch_info = iwl_get_channel_info(priv, priv->band, channel); 268 tsf_low = ch_switch->timestamp & 0x0ffffffff;
269 /*
270 * calculate the ucode channel switch time
271 * adding TSF as one of the factor for when to switch
272 */
273 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
274 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
275 beacon_interval)) {
276 switch_count -= (priv->ucode_beacon_time -
277 tsf_low) / beacon_interval;
278 } else
279 switch_count = 0;
280 }
281 if (switch_count <= 1)
282 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
283 else {
284 switch_time_in_usec =
285 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
286 ucode_switch_time = iwl_usecs_to_beacons(priv,
287 switch_time_in_usec,
288 beacon_interval);
289 cmd.switch_time = iwl_add_beacon_time(priv,
290 priv->ucode_beacon_time,
291 ucode_switch_time,
292 beacon_interval);
293 }
294 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
295 cmd.switch_time);
296 ch_info = iwl_get_channel_info(priv, priv->band, ch);
254 if (ch_info) 297 if (ch_info)
255 cmd.expect_beacon = is_channel_radar(ch_info); 298 cmd.expect_beacon = is_channel_radar(ch_info);
256 else { 299 else {
257 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 300 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
258 priv->active_rxon.channel, channel); 301 priv->active_rxon.channel, ch);
259 return -EFAULT; 302 return -EFAULT;
260 } 303 }
261 priv->switch_rxon.channel = cpu_to_le16(channel); 304 priv->switch_rxon.channel = cmd.channel;
262 priv->switch_rxon.switch_in_progress = true; 305 priv->switch_rxon.switch_in_progress = true;
263 306
264 return iwl_send_cmd_sync(priv, &hcmd); 307 return iwl_send_cmd_sync(priv, &hcmd);
@@ -335,6 +378,25 @@ static const struct iwl_ops iwl6000_ops = {
335 .led = &iwlagn_led_ops, 378 .led = &iwlagn_led_ops,
336}; 379};
337 380
381static void do_not_send_bt_config(struct iwl_priv *priv)
382{
383}
384
385static struct iwl_hcmd_ops iwl6000g2b_hcmd = {
386 .rxon_assoc = iwlagn_send_rxon_assoc,
387 .commit_rxon = iwl_commit_rxon,
388 .set_rxon_chain = iwl_set_rxon_chain,
389 .set_tx_ant = iwlagn_send_tx_ant_config,
390 .send_bt_config = do_not_send_bt_config,
391};
392
393static const struct iwl_ops iwl6000g2b_ops = {
394 .lib = &iwl6000_lib,
395 .hcmd = &iwl6000g2b_hcmd,
396 .utils = &iwlagn_hcmd_utils,
397 .led = &iwlagn_led_ops,
398};
399
338static struct iwl_lib_ops iwl6050_lib = { 400static struct iwl_lib_ops iwl6050_lib = {
339 .set_hw_params = iwl6050_hw_set_hw_params, 401 .set_hw_params = iwl6050_hw_set_hw_params,
340 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 402 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
@@ -445,6 +507,268 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
445 .chain_noise_calib_by_driver = true, 507 .chain_noise_calib_by_driver = true,
446}; 508};
447 509
510struct iwl_cfg iwl6000g2a_2abg_cfg = {
511 .name = "6000 Series 2x2 ABG Gen2a",
512 .fw_name_pre = IWL6000G2A_FW_PRE,
513 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
514 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
515 .sku = IWL_SKU_A|IWL_SKU_G,
516 .ops = &iwl6000_ops,
517 .eeprom_size = OTP_LOW_IMAGE_SIZE,
518 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
519 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
520 .num_of_queues = IWLAGN_NUM_QUEUES,
521 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
522 .mod_params = &iwlagn_mod_params,
523 .valid_tx_ant = ANT_AB,
524 .valid_rx_ant = ANT_AB,
525 .pll_cfg_val = 0,
526 .set_l0s = true,
527 .use_bsm = false,
528 .pa_type = IWL_PA_SYSTEM,
529 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
530 .shadow_ram_support = true,
531 .led_compensation = 51,
532 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
533 .supports_idle = true,
534 .adv_thermal_throttle = true,
535 .support_ct_kill_exit = true,
536 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
537 .chain_noise_scale = 1000,
538 .monitor_recover_period = IWL_MONITORING_PERIOD,
539 .max_event_log_size = 512,
540};
541
542struct iwl_cfg iwl6000g2a_2bg_cfg = {
543 .name = "6000 Series 2x2 BG Gen2a",
544 .fw_name_pre = IWL6000G2A_FW_PRE,
545 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
546 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
547 .sku = IWL_SKU_G,
548 .ops = &iwl6000_ops,
549 .eeprom_size = OTP_LOW_IMAGE_SIZE,
550 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
551 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
552 .num_of_queues = IWLAGN_NUM_QUEUES,
553 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
554 .mod_params = &iwlagn_mod_params,
555 .valid_tx_ant = ANT_AB,
556 .valid_rx_ant = ANT_AB,
557 .pll_cfg_val = 0,
558 .set_l0s = true,
559 .use_bsm = false,
560 .pa_type = IWL_PA_SYSTEM,
561 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
562 .shadow_ram_support = true,
563 .led_compensation = 51,
564 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
565 .supports_idle = true,
566 .adv_thermal_throttle = true,
567 .support_ct_kill_exit = true,
568 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
569 .chain_noise_scale = 1000,
570 .monitor_recover_period = IWL_MONITORING_PERIOD,
571 .max_event_log_size = 512,
572};
573
574struct iwl_cfg iwl6000g2b_2agn_cfg = {
575 .name = "6000 Series 2x2 AGN Gen2b",
576 .fw_name_pre = IWL6000G2B_FW_PRE,
577 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
578 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
579 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
580 .ops = &iwl6000g2b_ops,
581 .eeprom_size = OTP_LOW_IMAGE_SIZE,
582 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
583 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
584 .num_of_queues = IWLAGN_NUM_QUEUES,
585 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
586 .mod_params = &iwlagn_mod_params,
587 .valid_tx_ant = ANT_AB,
588 .valid_rx_ant = ANT_AB,
589 .pll_cfg_val = 0,
590 .set_l0s = true,
591 .use_bsm = false,
592 .pa_type = IWL_PA_SYSTEM,
593 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
594 .shadow_ram_support = true,
595 .ht_greenfield_support = true,
596 .led_compensation = 51,
597 .use_rts_for_ht = true, /* use rts/cts protection */
598 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
599 .supports_idle = true,
600 .adv_thermal_throttle = true,
601 .support_ct_kill_exit = true,
602 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
603 .chain_noise_scale = 1000,
604 .monitor_recover_period = IWL_MONITORING_PERIOD,
605 .max_event_log_size = 512,
606};
607
608struct iwl_cfg iwl6000g2b_2abg_cfg = {
609 .name = "6000 Series 2x2 ABG Gen2b",
610 .fw_name_pre = IWL6000G2B_FW_PRE,
611 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
612 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
613 .sku = IWL_SKU_A|IWL_SKU_G,
614 .ops = &iwl6000g2b_ops,
615 .eeprom_size = OTP_LOW_IMAGE_SIZE,
616 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
617 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
618 .num_of_queues = IWLAGN_NUM_QUEUES,
619 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
620 .mod_params = &iwlagn_mod_params,
621 .valid_tx_ant = ANT_AB,
622 .valid_rx_ant = ANT_AB,
623 .pll_cfg_val = 0,
624 .set_l0s = true,
625 .use_bsm = false,
626 .pa_type = IWL_PA_SYSTEM,
627 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
628 .shadow_ram_support = true,
629 .led_compensation = 51,
630 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
631 .supports_idle = true,
632 .adv_thermal_throttle = true,
633 .support_ct_kill_exit = true,
634 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
635 .chain_noise_scale = 1000,
636 .monitor_recover_period = IWL_MONITORING_PERIOD,
637 .max_event_log_size = 512,
638};
639
640struct iwl_cfg iwl6000g2b_2bgn_cfg = {
641 .name = "6000 Series 2x2 BGN Gen2b",
642 .fw_name_pre = IWL6000G2B_FW_PRE,
643 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
644 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
645 .sku = IWL_SKU_G|IWL_SKU_N,
646 .ops = &iwl6000g2b_ops,
647 .eeprom_size = OTP_LOW_IMAGE_SIZE,
648 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
649 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
650 .num_of_queues = IWLAGN_NUM_QUEUES,
651 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
652 .mod_params = &iwlagn_mod_params,
653 .valid_tx_ant = ANT_AB,
654 .valid_rx_ant = ANT_AB,
655 .pll_cfg_val = 0,
656 .set_l0s = true,
657 .use_bsm = false,
658 .pa_type = IWL_PA_SYSTEM,
659 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
660 .shadow_ram_support = true,
661 .ht_greenfield_support = true,
662 .led_compensation = 51,
663 .use_rts_for_ht = true, /* use rts/cts protection */
664 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
665 .supports_idle = true,
666 .adv_thermal_throttle = true,
667 .support_ct_kill_exit = true,
668 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
669 .chain_noise_scale = 1000,
670 .monitor_recover_period = IWL_MONITORING_PERIOD,
671 .max_event_log_size = 512,
672};
673
674struct iwl_cfg iwl6000g2b_2bg_cfg = {
675 .name = "6000 Series 2x2 BG Gen2b",
676 .fw_name_pre = IWL6000G2B_FW_PRE,
677 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
678 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
679 .sku = IWL_SKU_G,
680 .ops = &iwl6000g2b_ops,
681 .eeprom_size = OTP_LOW_IMAGE_SIZE,
682 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
683 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
684 .num_of_queues = IWLAGN_NUM_QUEUES,
685 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
686 .mod_params = &iwlagn_mod_params,
687 .valid_tx_ant = ANT_AB,
688 .valid_rx_ant = ANT_AB,
689 .pll_cfg_val = 0,
690 .set_l0s = true,
691 .use_bsm = false,
692 .pa_type = IWL_PA_SYSTEM,
693 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
694 .shadow_ram_support = true,
695 .led_compensation = 51,
696 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
697 .supports_idle = true,
698 .adv_thermal_throttle = true,
699 .support_ct_kill_exit = true,
700 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
701 .chain_noise_scale = 1000,
702 .monitor_recover_period = IWL_MONITORING_PERIOD,
703 .max_event_log_size = 512,
704};
705
706struct iwl_cfg iwl6000g2b_bgn_cfg = {
707 .name = "6000 Series 1x2 BGN Gen2b",
708 .fw_name_pre = IWL6000G2B_FW_PRE,
709 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
710 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
711 .sku = IWL_SKU_G|IWL_SKU_N,
712 .ops = &iwl6000g2b_ops,
713 .eeprom_size = OTP_LOW_IMAGE_SIZE,
714 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
715 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
716 .num_of_queues = IWLAGN_NUM_QUEUES,
717 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
718 .mod_params = &iwlagn_mod_params,
719 .valid_tx_ant = ANT_A,
720 .valid_rx_ant = ANT_AB,
721 .pll_cfg_val = 0,
722 .set_l0s = true,
723 .use_bsm = false,
724 .pa_type = IWL_PA_SYSTEM,
725 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
726 .shadow_ram_support = true,
727 .ht_greenfield_support = true,
728 .led_compensation = 51,
729 .use_rts_for_ht = true, /* use rts/cts protection */
730 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
731 .supports_idle = true,
732 .adv_thermal_throttle = true,
733 .support_ct_kill_exit = true,
734 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
735 .chain_noise_scale = 1000,
736 .monitor_recover_period = IWL_MONITORING_PERIOD,
737 .max_event_log_size = 512,
738};
739
740struct iwl_cfg iwl6000g2b_bg_cfg = {
741 .name = "6000 Series 1x2 BG Gen2b",
742 .fw_name_pre = IWL6000G2B_FW_PRE,
743 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
744 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
745 .sku = IWL_SKU_G,
746 .ops = &iwl6000g2b_ops,
747 .eeprom_size = OTP_LOW_IMAGE_SIZE,
748 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
749 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
750 .num_of_queues = IWLAGN_NUM_QUEUES,
751 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
752 .mod_params = &iwlagn_mod_params,
753 .valid_tx_ant = ANT_A,
754 .valid_rx_ant = ANT_AB,
755 .pll_cfg_val = 0,
756 .set_l0s = true,
757 .use_bsm = false,
758 .pa_type = IWL_PA_SYSTEM,
759 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
760 .shadow_ram_support = true,
761 .led_compensation = 51,
762 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
763 .supports_idle = true,
764 .adv_thermal_throttle = true,
765 .support_ct_kill_exit = true,
766 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
767 .chain_noise_scale = 1000,
768 .monitor_recover_period = IWL_MONITORING_PERIOD,
769 .max_event_log_size = 512,
770};
771
448/* 772/*
449 * "i": Internal configuration, use internal Power Amplifier 773 * "i": Internal configuration, use internal Power Amplifier
450 */ 774 */
@@ -667,3 +991,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {
667MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 991MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
668MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 992MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
669MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 993MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
994MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 7e8227773213..400eb312b555 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -96,17 +96,16 @@ int iwl_send_calib_results(struct iwl_priv *priv)
96 hcmd.len = priv->calib_results[i].buf_len; 96 hcmd.len = priv->calib_results[i].buf_len;
97 hcmd.data = priv->calib_results[i].buf; 97 hcmd.data = priv->calib_results[i].buf;
98 ret = iwl_send_cmd_sync(priv, &hcmd); 98 ret = iwl_send_cmd_sync(priv, &hcmd);
99 if (ret) 99 if (ret) {
100 goto err; 100 IWL_ERR(priv, "Error %d iteration %d\n",
101 ret, i);
102 break;
103 }
101 } 104 }
102 } 105 }
103 106
104 return 0;
105err:
106 IWL_ERR(priv, "Error %d iteration %d\n", ret, i);
107 return ret; 107 return ret;
108} 108}
109EXPORT_SYMBOL(iwl_send_calib_results);
110 109
111int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len) 110int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
112{ 111{
@@ -121,7 +120,6 @@ int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
121 memcpy(res->buf, buf, len); 120 memcpy(res->buf, buf, len);
122 return 0; 121 return 0;
123} 122}
124EXPORT_SYMBOL(iwl_calib_set);
125 123
126void iwl_calib_free_results(struct iwl_priv *priv) 124void iwl_calib_free_results(struct iwl_priv *priv)
127{ 125{
@@ -133,7 +131,6 @@ void iwl_calib_free_results(struct iwl_priv *priv)
133 priv->calib_results[i].buf_len = 0; 131 priv->calib_results[i].buf_len = 0;
134 } 132 }
135} 133}
136EXPORT_SYMBOL(iwl_calib_free_results);
137 134
138/***************************************************************************** 135/*****************************************************************************
139 * RUNTIME calibrations framework 136 * RUNTIME calibrations framework
@@ -533,7 +530,6 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
533 ret |= iwl_sensitivity_write(priv); 530 ret |= iwl_sensitivity_write(priv);
534 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); 531 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
535} 532}
536EXPORT_SYMBOL(iwl_init_sensitivity);
537 533
538void iwl_sensitivity_calibration(struct iwl_priv *priv, 534void iwl_sensitivity_calibration(struct iwl_priv *priv,
539 struct iwl_notif_statistics *resp) 535 struct iwl_notif_statistics *resp)
@@ -639,7 +635,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
639 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); 635 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
640 iwl_sensitivity_write(priv); 636 iwl_sensitivity_write(priv);
641} 637}
642EXPORT_SYMBOL(iwl_sensitivity_calibration);
643 638
644static inline u8 find_first_chain(u8 mask) 639static inline u8 find_first_chain(u8 mask)
645{ 640{
@@ -846,6 +841,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
846 } 841 }
847 } 842 }
848 843
844 if (active_chains != priv->hw_params.valid_rx_ant &&
845 active_chains != priv->chain_noise_data.active_chains)
846 IWL_WARN(priv,
847 "Detected that not all antennas are connected! "
848 "Connected: %#x, valid: %#x.\n",
849 active_chains, priv->hw_params.valid_rx_ant);
850
849 /* Save for use within RXON, TX, SCAN commands, etc. */ 851 /* Save for use within RXON, TX, SCAN commands, etc. */
850 priv->chain_noise_data.active_chains = active_chains; 852 priv->chain_noise_data.active_chains = active_chains;
851 IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n", 853 IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
@@ -890,8 +892,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
890 data->state = IWL_CHAIN_NOISE_DONE; 892 data->state = IWL_CHAIN_NOISE_DONE;
891 iwl_power_update_mode(priv, false); 893 iwl_power_update_mode(priv, false);
892} 894}
893EXPORT_SYMBOL(iwl_chain_noise_calibration);
894
895 895
896void iwl_reset_run_time_calib(struct iwl_priv *priv) 896void iwl_reset_run_time_calib(struct iwl_priv *priv)
897{ 897{
@@ -908,5 +908,3 @@ void iwl_reset_run_time_calib(struct iwl_priv *priv)
908 * periodically after association */ 908 * periodically after association */
909 iwl_send_statistics_request(priv, CMD_ASYNC, true); 909 iwl_send_statistics_request(priv, CMD_ASYNC, true);
910} 910}
911EXPORT_SYMBOL(iwl_reset_run_time_calib);
912
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index 48c023b4ca36..75d6bfcbc607 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -28,6 +28,27 @@
28 28
29#include "iwl-agn-debugfs.h" 29#include "iwl-agn-debugfs.h"
30 30
31static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
32{
33 int p = 0;
34
35 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
36 le32_to_cpu(priv->_agn.statistics.flag));
37 if (le32_to_cpu(priv->_agn.statistics.flag) &
38 UCODE_STATISTICS_CLEAR_MSK)
39 p += scnprintf(buf + p, bufsz - p,
40 "\tStatistics have been cleared\n");
41 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
42 (le32_to_cpu(priv->_agn.statistics.flag) &
43 UCODE_STATISTICS_FREQUENCY_MSK)
44 ? "2.4 GHz" : "5.2 GHz");
45 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
46 (le32_to_cpu(priv->_agn.statistics.flag) &
47 UCODE_STATISTICS_NARROW_BAND_MSK)
48 ? "enabled" : "disabled");
49 return p;
50}
51
31ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, 52ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
32 size_t count, loff_t *ppos) 53 size_t count, loff_t *ppos)
33 { 54 {
@@ -58,24 +79,24 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
58 * the last statistics notification from uCode 79 * the last statistics notification from uCode
59 * might not reflect the current uCode activity 80 * might not reflect the current uCode activity
60 */ 81 */
61 ofdm = &priv->statistics.rx.ofdm; 82 ofdm = &priv->_agn.statistics.rx.ofdm;
62 cck = &priv->statistics.rx.cck; 83 cck = &priv->_agn.statistics.rx.cck;
63 general = &priv->statistics.rx.general; 84 general = &priv->_agn.statistics.rx.general;
64 ht = &priv->statistics.rx.ofdm_ht; 85 ht = &priv->_agn.statistics.rx.ofdm_ht;
65 accum_ofdm = &priv->accum_statistics.rx.ofdm; 86 accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
66 accum_cck = &priv->accum_statistics.rx.cck; 87 accum_cck = &priv->_agn.accum_statistics.rx.cck;
67 accum_general = &priv->accum_statistics.rx.general; 88 accum_general = &priv->_agn.accum_statistics.rx.general;
68 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 89 accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
69 delta_ofdm = &priv->delta_statistics.rx.ofdm; 90 delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
70 delta_cck = &priv->delta_statistics.rx.cck; 91 delta_cck = &priv->_agn.delta_statistics.rx.cck;
71 delta_general = &priv->delta_statistics.rx.general; 92 delta_general = &priv->_agn.delta_statistics.rx.general;
72 delta_ht = &priv->delta_statistics.rx.ofdm_ht; 93 delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
73 max_ofdm = &priv->max_delta.rx.ofdm; 94 max_ofdm = &priv->_agn.max_delta.rx.ofdm;
74 max_cck = &priv->max_delta.rx.cck; 95 max_cck = &priv->_agn.max_delta.rx.cck;
75 max_general = &priv->max_delta.rx.general; 96 max_general = &priv->_agn.max_delta.rx.general;
76 max_ht = &priv->max_delta.rx.ofdm_ht; 97 max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
77 98
78 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 99 pos += iwl_statistics_flag(priv, buf, bufsz);
79 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 100 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
80 "acumulative delta max\n", 101 "acumulative delta max\n",
81 "Statistics_Rx - OFDM:"); 102 "Statistics_Rx - OFDM:");
@@ -539,11 +560,11 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
539 * the last statistics notification from uCode 560 * the last statistics notification from uCode
540 * might not reflect the current uCode activity 561 * might not reflect the current uCode activity
541 */ 562 */
542 tx = &priv->statistics.tx; 563 tx = &priv->_agn.statistics.tx;
543 accum_tx = &priv->accum_statistics.tx; 564 accum_tx = &priv->_agn.accum_statistics.tx;
544 delta_tx = &priv->delta_statistics.tx; 565 delta_tx = &priv->_agn.delta_statistics.tx;
545 max_tx = &priv->max_delta.tx; 566 max_tx = &priv->_agn.max_delta.tx;
546 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 567 pos += iwl_statistics_flag(priv, buf, bufsz);
547 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 568 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
548 "acumulative delta max\n", 569 "acumulative delta max\n",
549 "Statistics_Tx:"); 570 "Statistics_Tx:");
@@ -756,19 +777,19 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
756 * the last statistics notification from uCode 777 * the last statistics notification from uCode
757 * might not reflect the current uCode activity 778 * might not reflect the current uCode activity
758 */ 779 */
759 general = &priv->statistics.general; 780 general = &priv->_agn.statistics.general;
760 dbg = &priv->statistics.general.dbg; 781 dbg = &priv->_agn.statistics.general.dbg;
761 div = &priv->statistics.general.div; 782 div = &priv->_agn.statistics.general.div;
762 accum_general = &priv->accum_statistics.general; 783 accum_general = &priv->_agn.accum_statistics.general;
763 delta_general = &priv->delta_statistics.general; 784 delta_general = &priv->_agn.delta_statistics.general;
764 max_general = &priv->max_delta.general; 785 max_general = &priv->_agn.max_delta.general;
765 accum_dbg = &priv->accum_statistics.general.dbg; 786 accum_dbg = &priv->_agn.accum_statistics.general.dbg;
766 delta_dbg = &priv->delta_statistics.general.dbg; 787 delta_dbg = &priv->_agn.delta_statistics.general.dbg;
767 max_dbg = &priv->max_delta.general.dbg; 788 max_dbg = &priv->_agn.max_delta.general.dbg;
768 accum_div = &priv->accum_statistics.general.div; 789 accum_div = &priv->_agn.accum_statistics.general.div;
769 delta_div = &priv->delta_statistics.general.div; 790 delta_div = &priv->_agn.delta_statistics.general.div;
770 max_div = &priv->max_delta.general.div; 791 max_div = &priv->_agn.max_delta.general.div;
771 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 792 pos += iwl_statistics_flag(priv, buf, bufsz);
772 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 793 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
773 "acumulative delta max\n", 794 "acumulative delta max\n",
774 "Statistics_General:"); 795 "Statistics_General:");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 01658cf82d39..d89a11c6558e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -37,7 +37,7 @@
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-agn.h" 38#include "iwl-agn.h"
39 39
40static int iwlagn_send_rxon_assoc(struct iwl_priv *priv) 40int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
41{ 41{
42 int ret = 0; 42 int ret = 0;
43 struct iwl5000_rxon_assoc_cmd rxon_assoc; 43 struct iwl5000_rxon_assoc_cmd rxon_assoc;
@@ -84,7 +84,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
84 return ret; 84 return ret;
85} 85}
86 86
87static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) 87int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
88{ 88{
89 struct iwl_tx_ant_config_cmd tx_ant_cmd = { 89 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
90 .valid = cpu_to_le32(valid_tx_ant), 90 .valid = cpu_to_le32(valid_tx_ant),
@@ -176,14 +176,6 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
176 data->radio_write = 1; 176 data->radio_write = 1;
177 data->state = IWL_CHAIN_NOISE_CALIBRATED; 177 data->state = IWL_CHAIN_NOISE_CALIBRATED;
178 } 178 }
179
180 data->chain_noise_a = 0;
181 data->chain_noise_b = 0;
182 data->chain_noise_c = 0;
183 data->chain_signal_a = 0;
184 data->chain_signal_b = 0;
185 data->chain_signal_c = 0;
186 data->beacon_count = 0;
187} 179}
188 180
189static void iwlagn_chain_noise_reset(struct iwl_priv *priv) 181static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
@@ -191,10 +183,20 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
191 struct iwl_chain_noise_data *data = &priv->chain_noise_data; 183 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
192 int ret; 184 int ret;
193 185
194 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { 186 if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
187 iwl_is_associated(priv)) {
195 struct iwl_calib_chain_noise_reset_cmd cmd; 188 struct iwl_calib_chain_noise_reset_cmd cmd;
196 memset(&cmd, 0, sizeof(cmd));
197 189
190 /* clear data for chain noise calibration algorithm */
191 data->chain_noise_a = 0;
192 data->chain_noise_b = 0;
193 data->chain_noise_c = 0;
194 data->chain_signal_a = 0;
195 data->chain_signal_b = 0;
196 data->chain_signal_c = 0;
197 data->beacon_count = 0;
198
199 memset(&cmd, 0, sizeof(cmd));
198 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; 200 cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
199 cmd.hdr.first_group = 0; 201 cmd.hdr.first_group = 0;
200 cmd.hdr.groups_num = 1; 202 cmd.hdr.groups_num = 1;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 0f292a210ed9..5f1e7d802cbf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -77,7 +77,7 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
77 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", 77 IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
78 agg->frame_count, agg->start_idx, idx); 78 agg->frame_count, agg->start_idx, idx);
79 79
80 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); 80 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb);
81 info->status.rates[0].count = tx_resp->failure_frame + 1; 81 info->status.rates[0].count = tx_resp->failure_frame + 1;
82 info->flags &= ~IEEE80211_TX_CTL_AMPDU; 82 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
83 info->flags |= iwl_tx_status_to_mac80211(status); 83 info->flags |= iwl_tx_status_to_mac80211(status);
@@ -93,6 +93,12 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
93 } else { 93 } else {
94 /* Two or more frames were attempted; expect block-ack */ 94 /* Two or more frames were attempted; expect block-ack */
95 u64 bitmap = 0; 95 u64 bitmap = 0;
96
97 /*
98 * Start is the lowest frame sent. It may not be the first
99 * frame in the batch; we figure this out dynamically during
100 * the following loop.
101 */
96 int start = agg->start_idx; 102 int start = agg->start_idx;
97 103
98 /* Construct bit-map of pending frames within Tx window */ 104 /* Construct bit-map of pending frames within Tx window */
@@ -131,25 +137,58 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv,
131 IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", 137 IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
132 i, idx, SEQ_TO_SN(sc)); 138 i, idx, SEQ_TO_SN(sc));
133 139
140 /*
141 * sh -> how many frames ahead of the starting frame is
142 * the current one?
143 *
144 * Note that all frames sent in the batch must be in a
145 * 64-frame window, so this number should be in [0,63].
146 * If outside of this window, then we've found a new
147 * "first" frame in the batch and need to change start.
148 */
134 sh = idx - start; 149 sh = idx - start;
135 if (sh > 64) { 150
136 sh = (start - idx) + 0xff; 151 /*
152 * If >= 64, out of window. start must be at the front
153 * of the circular buffer, idx must be near the end of
154 * the buffer, and idx is the new "first" frame. Shift
155 * the indices around.
156 */
157 if (sh >= 64) {
158 /* Shift bitmap by start - idx, wrapped */
159 sh = 0x100 - idx + start;
137 bitmap = bitmap << sh; 160 bitmap = bitmap << sh;
161 /* Now idx is the new start so sh = 0 */
138 sh = 0; 162 sh = 0;
139 start = idx; 163 start = idx;
140 } else if (sh < -64) 164 /*
141 sh = 0xff - (start - idx); 165 * If <= -64 then wraps the 256-pkt circular buffer
142 else if (sh < 0) { 166 * (e.g., start = 255 and idx = 0, sh should be 1)
167 */
168 } else if (sh <= -64) {
169 sh = 0x100 - start + idx;
170 /*
171 * If < 0 but > -64, out of window. idx is before start
172 * but not wrapped. Shift the indices around.
173 */
174 } else if (sh < 0) {
175 /* Shift by how far start is ahead of idx */
143 sh = start - idx; 176 sh = start - idx;
144 start = idx;
145 bitmap = bitmap << sh; 177 bitmap = bitmap << sh;
178 /* Now idx is the new start so sh = 0 */
179 start = idx;
146 sh = 0; 180 sh = 0;
147 } 181 }
182 /* Sequence number start + sh was sent in this batch */
148 bitmap |= 1ULL << sh; 183 bitmap |= 1ULL << sh;
149 IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n", 184 IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
150 start, (unsigned long long)bitmap); 185 start, (unsigned long long)bitmap);
151 } 186 }
152 187
188 /*
189 * Store the bitmap and possibly the new start, if we wrapped
190 * the buffer above
191 */
153 agg->bitmap = bitmap; 192 agg->bitmap = bitmap;
154 agg->start_idx = start; 193 agg->start_idx = start;
155 IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", 194 IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
@@ -184,6 +223,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
184 int tid; 223 int tid;
185 int sta_id; 224 int sta_id;
186 int freed; 225 int freed;
226 unsigned long flags;
187 227
188 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 228 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
189 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 229 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -193,15 +233,16 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
193 return; 233 return;
194 } 234 }
195 235
196 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); 236 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
197 memset(&info->status, 0, sizeof(info->status)); 237 memset(&info->status, 0, sizeof(info->status));
198 238
199 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; 239 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
200 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; 240 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
201 241
242 spin_lock_irqsave(&priv->sta_lock, flags);
202 if (txq->sched_retry) { 243 if (txq->sched_retry) {
203 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); 244 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
204 struct iwl_ht_agg *agg = NULL; 245 struct iwl_ht_agg *agg;
205 246
206 agg = &priv->stations[sta_id].tid[tid].agg; 247 agg = &priv->stations[sta_id].tid[tid].agg;
207 248
@@ -256,6 +297,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
256 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 297 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
257 298
258 iwl_check_abort_status(priv, tx_resp->frame_count, status); 299 iwl_check_abort_status(priv, tx_resp->frame_count, status);
300 spin_unlock_irqrestore(&priv->sta_lock, flags);
259} 301}
260 302
261void iwlagn_rx_handler_setup(struct iwl_priv *priv) 303void iwlagn_rx_handler_setup(struct iwl_priv *priv)
@@ -319,7 +361,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
319void iwlagn_temperature(struct iwl_priv *priv) 361void iwlagn_temperature(struct iwl_priv *priv)
320{ 362{
321 /* store temperature from statistics (in Celsius) */ 363 /* store temperature from statistics (in Celsius) */
322 priv->temperature = le32_to_cpu(priv->statistics.general.temperature); 364 priv->temperature =
365 le32_to_cpu(priv->_agn.statistics.general.temperature);
323 iwl_tt_handler(priv); 366 iwl_tt_handler(priv);
324} 367}
325 368
@@ -444,7 +487,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
444 487
445 /* Tell device where to find RBD circular buffer in DRAM */ 488 /* Tell device where to find RBD circular buffer in DRAM */
446 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, 489 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
447 (u32)(rxq->dma_addr >> 8)); 490 (u32)(rxq->bd_dma >> 8));
448 491
449 /* Tell device where in DRAM to update its Rx status */ 492 /* Tell device where in DRAM to update its Rx status */
450 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, 493 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
@@ -709,7 +752,7 @@ void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
709 } 752 }
710 753
711 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, 754 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
712 rxq->dma_addr); 755 rxq->bd_dma);
713 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), 756 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
714 rxq->rb_stts, rxq->rb_stts_dma); 757 rxq->rb_stts, rxq->rb_stts_dma);
715 rxq->bd = NULL; 758 rxq->bd = NULL;
@@ -755,132 +798,6 @@ static inline int iwlagn_calc_rssi(struct iwl_priv *priv,
755 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp); 798 return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
756} 799}
757 800
758#ifdef CONFIG_IWLWIFI_DEBUG
759/**
760 * iwlagn_dbg_report_frame - dump frame to syslog during debug sessions
761 *
762 * You may hack this function to show different aspects of received frames,
763 * including selective frame dumps.
764 * group100 parameter selects whether to show 1 out of 100 good data frames.
765 * All beacon and probe response frames are printed.
766 */
767static void iwlagn_dbg_report_frame(struct iwl_priv *priv,
768 struct iwl_rx_phy_res *phy_res, u16 length,
769 struct ieee80211_hdr *header, int group100)
770{
771 u32 to_us;
772 u32 print_summary = 0;
773 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
774 u32 hundred = 0;
775 u32 dataframe = 0;
776 __le16 fc;
777 u16 seq_ctl;
778 u16 channel;
779 u16 phy_flags;
780 u32 rate_n_flags;
781 u32 tsf_low;
782 int rssi;
783
784 if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
785 return;
786
787 /* MAC header */
788 fc = header->frame_control;
789 seq_ctl = le16_to_cpu(header->seq_ctrl);
790
791 /* metadata */
792 channel = le16_to_cpu(phy_res->channel);
793 phy_flags = le16_to_cpu(phy_res->phy_flags);
794 rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
795
796 /* signal statistics */
797 rssi = iwlagn_calc_rssi(priv, phy_res);
798 tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff;
799
800 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
801
802 /* if data frame is to us and all is good,
803 * (optionally) print summary for only 1 out of every 100 */
804 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
805 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
806 dataframe = 1;
807 if (!group100)
808 print_summary = 1; /* print each frame */
809 else if (priv->framecnt_to_us < 100) {
810 priv->framecnt_to_us++;
811 print_summary = 0;
812 } else {
813 priv->framecnt_to_us = 0;
814 print_summary = 1;
815 hundred = 1;
816 }
817 } else {
818 /* print summary for all other frames */
819 print_summary = 1;
820 }
821
822 if (print_summary) {
823 char *title;
824 int rate_idx;
825 u32 bitrate;
826
827 if (hundred)
828 title = "100Frames";
829 else if (ieee80211_has_retry(fc))
830 title = "Retry";
831 else if (ieee80211_is_assoc_resp(fc))
832 title = "AscRsp";
833 else if (ieee80211_is_reassoc_resp(fc))
834 title = "RasRsp";
835 else if (ieee80211_is_probe_resp(fc)) {
836 title = "PrbRsp";
837 print_dump = 1; /* dump frame contents */
838 } else if (ieee80211_is_beacon(fc)) {
839 title = "Beacon";
840 print_dump = 1; /* dump frame contents */
841 } else if (ieee80211_is_atim(fc))
842 title = "ATIM";
843 else if (ieee80211_is_auth(fc))
844 title = "Auth";
845 else if (ieee80211_is_deauth(fc))
846 title = "DeAuth";
847 else if (ieee80211_is_disassoc(fc))
848 title = "DisAssoc";
849 else
850 title = "Frame";
851
852 rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
853 if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) {
854 bitrate = 0;
855 WARN_ON_ONCE(1);
856 } else {
857 bitrate = iwl_rates[rate_idx].ieee / 2;
858 }
859
860 /* print frame summary.
861 * MAC addresses show just the last byte (for brevity),
862 * but you can hack it to show more, if you'd like to. */
863 if (dataframe)
864 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
865 "len=%u, rssi=%d, chnl=%d, rate=%u,\n",
866 title, le16_to_cpu(fc), header->addr1[5],
867 length, rssi, channel, bitrate);
868 else {
869 /* src/dst addresses assume managed mode */
870 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
871 "len=%u, rssi=%d, tim=%lu usec, "
872 "phy=0x%02x, chnl=%d\n",
873 title, le16_to_cpu(fc), header->addr1[5],
874 header->addr3[5], length, rssi,
875 tsf_low - priv->scan_start_tsf,
876 phy_flags, channel);
877 }
878 }
879 if (print_dump)
880 iwl_print_hex_dump(priv, IWL_DL_RX, header, length);
881}
882#endif
883
884static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) 801static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
885{ 802{
886 u32 decrypt_out = 0; 803 u32 decrypt_out = 0;
@@ -988,7 +905,7 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
988 struct iwl_rx_packet *pkt = rxb_addr(rxb); 905 struct iwl_rx_packet *pkt = rxb_addr(rxb);
989 struct iwl_rx_phy_res *phy_res; 906 struct iwl_rx_phy_res *phy_res;
990 __le32 rx_pkt_status; 907 __le32 rx_pkt_status;
991 struct iwl4965_rx_mpdu_res_start *amsdu; 908 struct iwl_rx_mpdu_res_start *amsdu;
992 u32 len; 909 u32 len;
993 u32 ampdu_status; 910 u32 ampdu_status;
994 u32 rate_n_flags; 911 u32 rate_n_flags;
@@ -1017,7 +934,7 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
1017 return; 934 return;
1018 } 935 }
1019 phy_res = &priv->_agn.last_phy_res; 936 phy_res = &priv->_agn.last_phy_res;
1020 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; 937 amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
1021 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); 938 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
1022 len = le16_to_cpu(amsdu->byte_count); 939 len = le16_to_cpu(amsdu->byte_count);
1023 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); 940 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
@@ -1060,11 +977,6 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv,
1060 /* Find max signal strength (dBm) among 3 antenna/receiver chains */ 977 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1061 rx_status.signal = iwlagn_calc_rssi(priv, phy_res); 978 rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
1062 979
1063#ifdef CONFIG_IWLWIFI_DEBUG
1064 /* Set "1" to report good data frames in groups of 100 */
1065 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1066 iwlagn_dbg_report_frame(priv, phy_res, len, header, 1);
1067#endif
1068 iwl_dbg_log_rx_data_frame(priv, len, header); 980 iwl_dbg_log_rx_data_frame(priv, len, header);
1069 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", 981 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
1070 rx_status.signal, (unsigned long long)rx_status.mactime); 982 rx_status.signal, (unsigned long long)rx_status.mactime);
@@ -1252,6 +1164,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1252 bool is_active = false; 1164 bool is_active = false;
1253 int chan_mod; 1165 int chan_mod;
1254 u8 active_chains; 1166 u8 active_chains;
1167 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
1255 1168
1256 conf = ieee80211_get_hw_conf(priv->hw); 1169 conf = ieee80211_get_hw_conf(priv->hw);
1257 1170
@@ -1403,11 +1316,14 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1403 1316
1404 band = priv->scan_band; 1317 band = priv->scan_band;
1405 1318
1406 if (priv->cfg->scan_antennas[band]) 1319 if (priv->cfg->scan_rx_antennas[band])
1407 rx_ant = priv->cfg->scan_antennas[band]; 1320 rx_ant = priv->cfg->scan_rx_antennas[band];
1408 1321
1409 priv->scan_tx_ant[band] = 1322 if (priv->cfg->scan_tx_antennas[band])
1410 iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]); 1323 scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
1324
1325 priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
1326 scan_tx_antennas);
1411 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); 1327 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
1412 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); 1328 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
1413 1329
@@ -1433,13 +1349,15 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1433 if (!priv->is_internal_short_scan) { 1349 if (!priv->is_internal_short_scan) {
1434 cmd_len = iwl_fill_probe_req(priv, 1350 cmd_len = iwl_fill_probe_req(priv,
1435 (struct ieee80211_mgmt *)scan->data, 1351 (struct ieee80211_mgmt *)scan->data,
1352 vif->addr,
1436 priv->scan_request->ie, 1353 priv->scan_request->ie,
1437 priv->scan_request->ie_len, 1354 priv->scan_request->ie_len,
1438 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 1355 IWL_MAX_SCAN_SIZE - sizeof(*scan));
1439 } else { 1356 } else {
1357 /* use bcast addr, will not be transmitted but must be valid */
1440 cmd_len = iwl_fill_probe_req(priv, 1358 cmd_len = iwl_fill_probe_req(priv,
1441 (struct ieee80211_mgmt *)scan->data, 1359 (struct ieee80211_mgmt *)scan->data,
1442 NULL, 0, 1360 iwl_bcast_addr, NULL, 0,
1443 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 1361 IWL_MAX_SCAN_SIZE - sizeof(*scan));
1444 1362
1445 } 1363 }
@@ -1502,3 +1420,18 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1502 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, 1420 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
1503 vif->bss_conf.bssid); 1421 vif->bss_conf.bssid);
1504} 1422}
1423
1424void iwl_free_tfds_in_queue(struct iwl_priv *priv,
1425 int sta_id, int tid, int freed)
1426{
1427 WARN_ON(!spin_is_locked(&priv->sta_lock));
1428
1429 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
1430 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1431 else {
1432 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
1433 priv->stations[sta_id].tid[tid].tfds_in_queue,
1434 freed);
1435 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
1436 }
1437}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index cf4a95bae4ff..40933a5de027 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -313,8 +313,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
313 */ 313 */
314 IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", 314 IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
315 tid); 315 tid);
316 ieee80211_stop_tx_ba_session(sta, tid, 316 ieee80211_stop_tx_ba_session(sta, tid);
317 WLAN_BACK_INITIATOR);
318 } 317 }
319 } else 318 } else
320 IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid); 319 IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
new file mode 100644
index 000000000000..ad2bead25c82
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -0,0 +1,278 @@
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-calib.h"
38#include "iwl-sta.h"
39#include "iwl-io.h"
40#include "iwl-helpers.h"
41#include "iwl-agn-hw.h"
42#include "iwl-agn.h"
43
44void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
45 struct iwl_rx_mem_buffer *rxb)
46
47{
48 struct iwl_rx_packet *pkt = rxb_addr(rxb);
49 struct iwl_missed_beacon_notif *missed_beacon;
50
51 missed_beacon = &pkt->u.missed_beacon;
52 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
53 priv->missed_beacon_threshold) {
54 IWL_DEBUG_CALIB(priv,
55 "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
56 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
57 le32_to_cpu(missed_beacon->total_missed_becons),
58 le32_to_cpu(missed_beacon->num_recvd_beacons),
59 le32_to_cpu(missed_beacon->num_expected_beacons));
60 if (!test_bit(STATUS_SCANNING, &priv->status))
61 iwl_init_sensitivity(priv);
62 }
63}
64
65/* Calculate noise level, based on measurements during network silence just
66 * before arriving beacon. This measurement can be done only if we know
67 * exactly when to expect beacons, therefore only when we're associated. */
68static void iwl_rx_calc_noise(struct iwl_priv *priv)
69{
70 struct statistics_rx_non_phy *rx_info
71 = &(priv->_agn.statistics.rx.general);
72 int num_active_rx = 0;
73 int total_silence = 0;
74 int bcn_silence_a =
75 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
76 int bcn_silence_b =
77 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
78 int bcn_silence_c =
79 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
80 int last_rx_noise;
81
82 if (bcn_silence_a) {
83 total_silence += bcn_silence_a;
84 num_active_rx++;
85 }
86 if (bcn_silence_b) {
87 total_silence += bcn_silence_b;
88 num_active_rx++;
89 }
90 if (bcn_silence_c) {
91 total_silence += bcn_silence_c;
92 num_active_rx++;
93 }
94
95 /* Average among active antennas */
96 if (num_active_rx)
97 last_rx_noise = (total_silence / num_active_rx) - 107;
98 else
99 last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
100
101 IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
102 bcn_silence_a, bcn_silence_b, bcn_silence_c,
103 last_rx_noise);
104}
105
106#ifdef CONFIG_IWLWIFI_DEBUGFS
107/*
108 * based on the assumption of all statistics counter are in DWORD
109 * FIXME: This function is for debugging, do not deal with
110 * the case of counters roll-over.
111 */
112static void iwl_accumulative_statistics(struct iwl_priv *priv,
113 __le32 *stats)
114{
115 int i;
116 __le32 *prev_stats;
117 u32 *accum_stats;
118 u32 *delta, *max_delta;
119
120 prev_stats = (__le32 *)&priv->_agn.statistics;
121 accum_stats = (u32 *)&priv->_agn.accum_statistics;
122 delta = (u32 *)&priv->_agn.delta_statistics;
123 max_delta = (u32 *)&priv->_agn.max_delta;
124
125 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
126 i += sizeof(__le32), stats++, prev_stats++, delta++,
127 max_delta++, accum_stats++) {
128 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
129 *delta = (le32_to_cpu(*stats) -
130 le32_to_cpu(*prev_stats));
131 *accum_stats += *delta;
132 if (*delta > *max_delta)
133 *max_delta = *delta;
134 }
135 }
136
137 /* reset accumulative statistics for "no-counter" type statistics */
138 priv->_agn.accum_statistics.general.temperature =
139 priv->_agn.statistics.general.temperature;
140 priv->_agn.accum_statistics.general.temperature_m =
141 priv->_agn.statistics.general.temperature_m;
142 priv->_agn.accum_statistics.general.ttl_timestamp =
143 priv->_agn.statistics.general.ttl_timestamp;
144 priv->_agn.accum_statistics.tx.tx_power.ant_a =
145 priv->_agn.statistics.tx.tx_power.ant_a;
146 priv->_agn.accum_statistics.tx.tx_power.ant_b =
147 priv->_agn.statistics.tx.tx_power.ant_b;
148 priv->_agn.accum_statistics.tx.tx_power.ant_c =
149 priv->_agn.statistics.tx.tx_power.ant_c;
150}
151#endif
152
153#define REG_RECALIB_PERIOD (60)
154
155/**
156 * iwl_good_plcp_health - checks for plcp error.
157 *
158 * When the plcp error is exceeding the thresholds, reset the radio
159 * to improve the throughput.
160 */
161bool iwl_good_plcp_health(struct iwl_priv *priv,
162 struct iwl_rx_packet *pkt)
163{
164 bool rc = true;
165 int combined_plcp_delta;
166 unsigned int plcp_msec;
167 unsigned long plcp_received_jiffies;
168
169 /*
170 * check for plcp_err and trigger radio reset if it exceeds
171 * the plcp error threshold plcp_delta.
172 */
173 plcp_received_jiffies = jiffies;
174 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
175 (long) priv->plcp_jiffies);
176 priv->plcp_jiffies = plcp_received_jiffies;
177 /*
178 * check to make sure plcp_msec is not 0 to prevent division
179 * by zero.
180 */
181 if (plcp_msec) {
182 combined_plcp_delta =
183 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
184 le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) +
185 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
186 le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err));
187
188 if ((combined_plcp_delta > 0) &&
189 ((combined_plcp_delta * 100) / plcp_msec) >
190 priv->cfg->plcp_delta_threshold) {
191 /*
192 * if plcp_err exceed the threshold,
193 * the following data is printed in csv format:
194 * Text: plcp_err exceeded %d,
195 * Received ofdm.plcp_err,
196 * Current ofdm.plcp_err,
197 * Received ofdm_ht.plcp_err,
198 * Current ofdm_ht.plcp_err,
199 * combined_plcp_delta,
200 * plcp_msec
201 */
202 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
203 "%u, %u, %u, %u, %d, %u mSecs\n",
204 priv->cfg->plcp_delta_threshold,
205 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
206 le32_to_cpu(
207 priv->_agn.statistics.rx.ofdm.plcp_err),
208 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
209 le32_to_cpu(
210 priv->_agn.statistics.rx.ofdm_ht.plcp_err),
211 combined_plcp_delta, plcp_msec);
212 rc = false;
213 }
214 }
215 return rc;
216}
217
218void iwl_rx_statistics(struct iwl_priv *priv,
219 struct iwl_rx_mem_buffer *rxb)
220{
221 int change;
222 struct iwl_rx_packet *pkt = rxb_addr(rxb);
223
224
225 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
226 (int)sizeof(priv->_agn.statistics),
227 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
228
229 change = ((priv->_agn.statistics.general.temperature !=
230 pkt->u.stats.general.temperature) ||
231 ((priv->_agn.statistics.flag &
232 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
233 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
234
235#ifdef CONFIG_IWLWIFI_DEBUGFS
236 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
237#endif
238 iwl_recover_from_statistics(priv, pkt);
239
240 memcpy(&priv->_agn.statistics, &pkt->u.stats,
241 sizeof(priv->_agn.statistics));
242
243 set_bit(STATUS_STATISTICS, &priv->status);
244
245 /* Reschedule the statistics timer to occur in
246 * REG_RECALIB_PERIOD seconds to ensure we get a
247 * thermal update even if the uCode doesn't give
248 * us one */
249 mod_timer(&priv->statistics_periodic, jiffies +
250 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
251
252 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
253 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
254 iwl_rx_calc_noise(priv);
255 queue_work(priv->workqueue, &priv->run_time_calib_work);
256 }
257 if (priv->cfg->ops->lib->temp_ops.temperature && change)
258 priv->cfg->ops->lib->temp_ops.temperature(priv);
259}
260
261void iwl_reply_statistics(struct iwl_priv *priv,
262 struct iwl_rx_mem_buffer *rxb)
263{
264 struct iwl_rx_packet *pkt = rxb_addr(rxb);
265
266 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
267#ifdef CONFIG_IWLWIFI_DEBUGFS
268 memset(&priv->_agn.accum_statistics, 0,
269 sizeof(struct iwl_notif_statistics));
270 memset(&priv->_agn.delta_statistics, 0,
271 sizeof(struct iwl_notif_statistics));
272 memset(&priv->_agn.max_delta, 0,
273 sizeof(struct iwl_notif_statistics));
274#endif
275 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
276 }
277 iwl_rx_statistics(priv, rxb);
278}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 7d614c4d3c62..2573234e4db1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -233,6 +233,7 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
233{ 233{
234 unsigned long flags; 234 unsigned long flags;
235 u16 ra_tid; 235 u16 ra_tid;
236 int ret;
236 237
237 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 238 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
238 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues 239 (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
@@ -248,7 +249,9 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
248 ra_tid = BUILD_RAxTID(sta_id, tid); 249 ra_tid = BUILD_RAxTID(sta_id, tid);
249 250
250 /* Modify device's station table to Tx this TID */ 251 /* Modify device's station table to Tx this TID */
251 iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 252 ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
253 if (ret)
254 return ret;
252 255
253 spin_lock_irqsave(&priv->lock, flags); 256 spin_lock_irqsave(&priv->lock, flags);
254 257
@@ -469,7 +472,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
469 } 472 }
470 473
471 /* Set up antennas */ 474 /* Set up antennas */
472 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); 475 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
476 priv->hw_params.valid_tx_ant);
473 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 477 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
474 478
475 /* Set the rate in the TX cmd */ 479 /* Set the rate in the TX cmd */
@@ -567,10 +571,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
567 hdr_len = ieee80211_hdrlen(fc); 571 hdr_len = ieee80211_hdrlen(fc);
568 572
569 /* Find index into station table for destination station */ 573 /* Find index into station table for destination station */
570 if (!info->control.sta) 574 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
571 sta_id = priv->hw_params.bcast_sta_id;
572 else
573 sta_id = iwl_sta_id(info->control.sta);
574 if (sta_id == IWL_INVALID_STATION) { 575 if (sta_id == IWL_INVALID_STATION) {
575 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 576 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
576 hdr->addr1); 577 hdr->addr1);
@@ -598,11 +599,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
598 } 599 }
599 600
600 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); 601 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
602
603 /* irqs already disabled/saved above when locking priv->lock */
604 spin_lock(&priv->sta_lock);
605
601 if (ieee80211_is_data_qos(fc)) { 606 if (ieee80211_is_data_qos(fc)) {
602 qc = ieee80211_get_qos_ctl(hdr); 607 qc = ieee80211_get_qos_ctl(hdr);
603 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 608 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
604 if (unlikely(tid >= MAX_TID_COUNT)) 609 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
610 spin_unlock(&priv->sta_lock);
605 goto drop_unlock; 611 goto drop_unlock;
612 }
606 seq_number = priv->stations[sta_id].tid[tid].seq_number; 613 seq_number = priv->stations[sta_id].tid[tid].seq_number;
607 seq_number &= IEEE80211_SCTL_SEQ; 614 seq_number &= IEEE80211_SCTL_SEQ;
608 hdr->seq_ctrl = hdr->seq_ctrl & 615 hdr->seq_ctrl = hdr->seq_ctrl &
@@ -620,15 +627,22 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
620 swq_id = txq->swq_id; 627 swq_id = txq->swq_id;
621 q = &txq->q; 628 q = &txq->q;
622 629
623 if (unlikely(iwl_queue_space(q) < q->high_mark)) 630 if (unlikely(iwl_queue_space(q) < q->high_mark)) {
631 spin_unlock(&priv->sta_lock);
624 goto drop_unlock; 632 goto drop_unlock;
633 }
625 634
626 if (ieee80211_is_data_qos(fc)) 635 if (ieee80211_is_data_qos(fc)) {
627 priv->stations[sta_id].tid[tid].tfds_in_queue++; 636 priv->stations[sta_id].tid[tid].tfds_in_queue++;
637 if (!ieee80211_has_morefrags(fc))
638 priv->stations[sta_id].tid[tid].seq_number = seq_number;
639 }
640
641 spin_unlock(&priv->sta_lock);
628 642
629 /* Set up driver data for this TFD */ 643 /* Set up driver data for this TFD */
630 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 644 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
631 txq->txb[q->write_ptr].skb[0] = skb; 645 txq->txb[q->write_ptr].skb = skb;
632 646
633 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 647 /* Set up first empty entry in queue's array of Tx/cmd buffers */
634 out_cmd = txq->cmd[q->write_ptr]; 648 out_cmd = txq->cmd[q->write_ptr];
@@ -694,8 +708,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
694 txcmd_phys = pci_map_single(priv->pci_dev, 708 txcmd_phys = pci_map_single(priv->pci_dev,
695 &out_cmd->hdr, len, 709 &out_cmd->hdr, len,
696 PCI_DMA_BIDIRECTIONAL); 710 PCI_DMA_BIDIRECTIONAL);
697 pci_unmap_addr_set(out_meta, mapping, txcmd_phys); 711 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
698 pci_unmap_len_set(out_meta, len, len); 712 dma_unmap_len_set(out_meta, len, len);
699 /* Add buffer containing Tx command and MAC(!) header to TFD's 713 /* Add buffer containing Tx command and MAC(!) header to TFD's
700 * first entry */ 714 * first entry */
701 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 715 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -703,8 +717,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
703 717
704 if (!ieee80211_has_morefrags(hdr->frame_control)) { 718 if (!ieee80211_has_morefrags(hdr->frame_control)) {
705 txq->need_update = 1; 719 txq->need_update = 1;
706 if (qc)
707 priv->stations[sta_id].tid[tid].seq_number = seq_number;
708 } else { 720 } else {
709 wait_write_ptr = 1; 721 wait_write_ptr = 1;
710 txq->need_update = 0; 722 txq->need_update = 0;
@@ -1009,6 +1021,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1009 if (ret) 1021 if (ret)
1010 return ret; 1022 return ret;
1011 1023
1024 spin_lock_irqsave(&priv->sta_lock, flags);
1025 tid_data = &priv->stations[sta_id].tid[tid];
1012 if (tid_data->tfds_in_queue == 0) { 1026 if (tid_data->tfds_in_queue == 0) {
1013 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1027 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1014 tid_data->agg.state = IWL_AGG_ON; 1028 tid_data->agg.state = IWL_AGG_ON;
@@ -1018,6 +1032,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1018 tid_data->tfds_in_queue); 1032 tid_data->tfds_in_queue);
1019 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; 1033 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
1020 } 1034 }
1035 spin_unlock_irqrestore(&priv->sta_lock, flags);
1021 return ret; 1036 return ret;
1022} 1037}
1023 1038
@@ -1040,11 +1055,14 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1040 return -ENXIO; 1055 return -ENXIO;
1041 } 1056 }
1042 1057
1058 spin_lock_irqsave(&priv->sta_lock, flags);
1059
1043 if (priv->stations[sta_id].tid[tid].agg.state == 1060 if (priv->stations[sta_id].tid[tid].agg.state ==
1044 IWL_EMPTYING_HW_QUEUE_ADDBA) { 1061 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1045 IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); 1062 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1046 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1063 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1047 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1064 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1065 spin_unlock_irqrestore(&priv->sta_lock, flags);
1048 return 0; 1066 return 0;
1049 } 1067 }
1050 1068
@@ -1062,13 +1080,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1062 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); 1080 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1063 priv->stations[sta_id].tid[tid].agg.state = 1081 priv->stations[sta_id].tid[tid].agg.state =
1064 IWL_EMPTYING_HW_QUEUE_DELBA; 1082 IWL_EMPTYING_HW_QUEUE_DELBA;
1083 spin_unlock_irqrestore(&priv->sta_lock, flags);
1065 return 0; 1084 return 0;
1066 } 1085 }
1067 1086
1068 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1087 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1069 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1088 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1070 1089
1071 spin_lock_irqsave(&priv->lock, flags); 1090 /* do not restore/save irqs */
1091 spin_unlock(&priv->sta_lock);
1092 spin_lock(&priv->lock);
1093
1072 /* 1094 /*
1073 * the only reason this call can fail is queue number out of range, 1095 * the only reason this call can fail is queue number out of range,
1074 * which can happen if uCode is reloaded and all the station 1096 * which can happen if uCode is reloaded and all the station
@@ -1092,6 +1114,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1092 u8 *addr = priv->stations[sta_id].sta.sta.addr; 1114 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1093 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; 1115 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1094 1116
1117 WARN_ON(!spin_is_locked(&priv->sta_lock));
1118
1095 switch (priv->stations[sta_id].tid[tid].agg.state) { 1119 switch (priv->stations[sta_id].tid[tid].agg.state) {
1096 case IWL_EMPTYING_HW_QUEUE_DELBA: 1120 case IWL_EMPTYING_HW_QUEUE_DELBA:
1097 /* We are reclaiming the last packet of the */ 1121 /* We are reclaiming the last packet of the */
@@ -1116,6 +1140,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1116 } 1140 }
1117 break; 1141 break;
1118 } 1142 }
1143
1119 return 0; 1144 return 0;
1120} 1145}
1121 1146
@@ -1159,12 +1184,12 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1159 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 1184 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1160 1185
1161 tx_info = &txq->txb[txq->q.read_ptr]; 1186 tx_info = &txq->txb[txq->q.read_ptr];
1162 iwlagn_tx_status(priv, tx_info->skb[0]); 1187 iwlagn_tx_status(priv, tx_info->skb);
1163 1188
1164 hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data; 1189 hdr = (struct ieee80211_hdr *)tx_info->skb->data;
1165 if (hdr && ieee80211_is_data_qos(hdr->frame_control)) 1190 if (hdr && ieee80211_is_data_qos(hdr->frame_control))
1166 nfreed++; 1191 nfreed++;
1167 tx_info->skb[0] = NULL; 1192 tx_info->skb = NULL;
1168 1193
1169 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) 1194 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1170 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); 1195 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
@@ -1188,7 +1213,7 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1188 int i, sh, ack; 1213 int i, sh, ack;
1189 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); 1214 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1190 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1215 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1191 u64 bitmap; 1216 u64 bitmap, sent_bitmap;
1192 int successes = 0; 1217 int successes = 0;
1193 struct ieee80211_tx_info *info; 1218 struct ieee80211_tx_info *info;
1194 1219
@@ -1216,24 +1241,26 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1216 1241
1217 /* check for success or failure according to the 1242 /* check for success or failure according to the
1218 * transmitted bitmap and block-ack bitmap */ 1243 * transmitted bitmap and block-ack bitmap */
1219 bitmap &= agg->bitmap; 1244 sent_bitmap = bitmap & agg->bitmap;
1220 1245
1221 /* For each frame attempted in aggregation, 1246 /* For each frame attempted in aggregation,
1222 * update driver's record of tx frame's status. */ 1247 * update driver's record of tx frame's status. */
1223 for (i = 0; i < agg->frame_count ; i++) { 1248 i = 0;
1224 ack = bitmap & (1ULL << i); 1249 while (sent_bitmap) {
1225 successes += !!ack; 1250 ack = sent_bitmap & 1ULL;
1251 successes += ack;
1226 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", 1252 IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
1227 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, 1253 ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
1228 agg->start_idx + i); 1254 agg->start_idx + i);
1255 sent_bitmap >>= 1;
1256 ++i;
1229 } 1257 }
1230 1258
1231 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]); 1259 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
1232 memset(&info->status, 0, sizeof(info->status)); 1260 memset(&info->status, 0, sizeof(info->status));
1233 info->flags |= IEEE80211_TX_STAT_ACK; 1261 info->flags |= IEEE80211_TX_STAT_ACK;
1234 info->flags |= IEEE80211_TX_STAT_AMPDU; 1262 info->flags |= IEEE80211_TX_STAT_AMPDU;
1235 info->status.ampdu_ack_len = successes; 1263 info->status.ampdu_ack_len = successes;
1236 info->status.ampdu_ack_map = bitmap;
1237 info->status.ampdu_len = agg->frame_count; 1264 info->status.ampdu_len = agg->frame_count;
1238 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); 1265 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1239 1266
@@ -1281,6 +1308,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1281 int index; 1308 int index;
1282 int sta_id; 1309 int sta_id;
1283 int tid; 1310 int tid;
1311 unsigned long flags;
1284 1312
1285 /* "flow" corresponds to Tx queue */ 1313 /* "flow" corresponds to Tx queue */
1286 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1314 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
@@ -1308,7 +1336,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1308 /* Find index just before block-ack window */ 1336 /* Find index just before block-ack window */
1309 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); 1337 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1310 1338
1311 /* TODO: Need to get this copy more safely - now good for debug */ 1339 spin_lock_irqsave(&priv->sta_lock, flags);
1312 1340
1313 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " 1341 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1314 "sta_id = %d\n", 1342 "sta_id = %d\n",
@@ -1344,4 +1372,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1344 1372
1345 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); 1373 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
1346 } 1374 }
1375
1376 spin_unlock_irqrestore(&priv->sta_lock, flags);
1347} 1377}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 637286c396fe..6f77441cb65a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -423,3 +423,126 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
423 423
424 return 0; 424 return 0;
425} 425}
426
427
428/**
429 * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
430 * using sample data 100 bytes apart. If these sample points are good,
431 * it's a pretty good bet that everything between them is good, too.
432 */
433static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
434{
435 u32 val;
436 int ret = 0;
437 u32 errcnt = 0;
438 u32 i;
439
440 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
441
442 for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
443 /* read data comes through single port, auto-incr addr */
444 /* NOTE: Use the debugless read so we don't flood kernel log
445 * if IWL_DL_IO is set */
446 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
447 i + IWLAGN_RTC_INST_LOWER_BOUND);
448 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
449 if (val != le32_to_cpu(*image)) {
450 ret = -EIO;
451 errcnt++;
452 if (errcnt >= 3)
453 break;
454 }
455 }
456
457 return ret;
458}
459
460/**
461 * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
462 * looking at all data.
463 */
464static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
465 u32 len)
466{
467 u32 val;
468 u32 save_len = len;
469 int ret = 0;
470 u32 errcnt;
471
472 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
473
474 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
475 IWLAGN_RTC_INST_LOWER_BOUND);
476
477 errcnt = 0;
478 for (; len > 0; len -= sizeof(u32), image++) {
479 /* read data comes through single port, auto-incr addr */
480 /* NOTE: Use the debugless read so we don't flood kernel log
481 * if IWL_DL_IO is set */
482 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
483 if (val != le32_to_cpu(*image)) {
484 IWL_ERR(priv, "uCode INST section is invalid at "
485 "offset 0x%x, is 0x%x, s/b 0x%x\n",
486 save_len - len, val, le32_to_cpu(*image));
487 ret = -EIO;
488 errcnt++;
489 if (errcnt >= 20)
490 break;
491 }
492 }
493
494 if (!errcnt)
495 IWL_DEBUG_INFO(priv,
496 "ucode image in INSTRUCTION memory is good\n");
497
498 return ret;
499}
500
501/**
502 * iwl_verify_ucode - determine which instruction image is in SRAM,
503 * and verify its contents
504 */
505int iwl_verify_ucode(struct iwl_priv *priv)
506{
507 __le32 *image;
508 u32 len;
509 int ret;
510
511 /* Try bootstrap */
512 image = (__le32 *)priv->ucode_boot.v_addr;
513 len = priv->ucode_boot.len;
514 ret = iwlcore_verify_inst_sparse(priv, image, len);
515 if (!ret) {
516 IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
517 return 0;
518 }
519
520 /* Try initialize */
521 image = (__le32 *)priv->ucode_init.v_addr;
522 len = priv->ucode_init.len;
523 ret = iwlcore_verify_inst_sparse(priv, image, len);
524 if (!ret) {
525 IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
526 return 0;
527 }
528
529 /* Try runtime/protocol */
530 image = (__le32 *)priv->ucode_code.v_addr;
531 len = priv->ucode_code.len;
532 ret = iwlcore_verify_inst_sparse(priv, image, len);
533 if (!ret) {
534 IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
535 return 0;
536 }
537
538 IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
539
540 /* Since nothing seems to match, show first several data entries in
541 * instruction SRAM, so maybe visual inspection will give a clue.
542 * Selection of bootstrap image (vs. other images) is arbitrary. */
543 image = (__le32 *)priv->ucode_boot.v_addr;
544 len = priv->ucode_boot.len;
545 ret = iwl_verify_inst_full(priv, image, len);
546
547 return ret;
548}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 24aff654fa9c..7488a68b83b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -120,7 +120,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
120 (priv->switch_rxon.channel != priv->staging_rxon.channel)) { 120 (priv->switch_rxon.channel != priv->staging_rxon.channel)) {
121 IWL_DEBUG_11H(priv, "abort channel switch on %d\n", 121 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
122 le16_to_cpu(priv->switch_rxon.channel)); 122 le16_to_cpu(priv->switch_rxon.channel));
123 priv->switch_rxon.switch_in_progress = false; 123 iwl_chswitch_done(priv, false);
124 } 124 }
125 125
126 /* If we don't need to send a full RXON, we can use 126 /* If we don't need to send a full RXON, we can use
@@ -367,7 +367,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
367 367
368 /* Set up packet rate and flags */ 368 /* Set up packet rate and flags */
369 rate = iwl_rate_get_lowest_plcp(priv); 369 rate = iwl_rate_get_lowest_plcp(priv);
370 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); 370 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
371 priv->hw_params.valid_tx_ant);
371 rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 372 rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
372 if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) 373 if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE))
373 rate_flags |= RATE_MCS_CCK_MSK; 374 rate_flags |= RATE_MCS_CCK_MSK;
@@ -474,18 +475,25 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
474 /* Unmap tx_cmd */ 475 /* Unmap tx_cmd */
475 if (num_tbs) 476 if (num_tbs)
476 pci_unmap_single(dev, 477 pci_unmap_single(dev,
477 pci_unmap_addr(&txq->meta[index], mapping), 478 dma_unmap_addr(&txq->meta[index], mapping),
478 pci_unmap_len(&txq->meta[index], len), 479 dma_unmap_len(&txq->meta[index], len),
479 PCI_DMA_BIDIRECTIONAL); 480 PCI_DMA_BIDIRECTIONAL);
480 481
481 /* Unmap chunks, if any. */ 482 /* Unmap chunks, if any. */
482 for (i = 1; i < num_tbs; i++) { 483 for (i = 1; i < num_tbs; i++)
483 pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), 484 pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
484 iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); 485 iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
485 486
486 if (txq->txb) { 487 /* free SKB */
487 dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]); 488 if (txq->txb) {
488 txq->txb[txq->q.read_ptr].skb[i - 1] = NULL; 489 struct sk_buff *skb;
490
491 skb = txq->txb[txq->q.read_ptr].skb;
492
493 /* can be called from irqs-disabled context */
494 if (skb) {
495 dev_kfree_skb_any(skb);
496 txq->txb[txq->q.read_ptr].skb = NULL;
489 } 497 }
490 } 498 }
491} 499}
@@ -933,6 +941,8 @@ void iwl_rx_handle(struct iwl_priv *priv)
933 fill_rx = 1; 941 fill_rx = 1;
934 942
935 while (i != r) { 943 while (i != r) {
944 int len;
945
936 rxb = rxq->queue[i]; 946 rxb = rxq->queue[i];
937 947
938 /* If an RXB doesn't have a Rx queue slot associated with it, 948 /* If an RXB doesn't have a Rx queue slot associated with it,
@@ -947,8 +957,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
947 PCI_DMA_FROMDEVICE); 957 PCI_DMA_FROMDEVICE);
948 pkt = rxb_addr(rxb); 958 pkt = rxb_addr(rxb);
949 959
950 trace_iwlwifi_dev_rx(priv, pkt, 960 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
951 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 961 len += sizeof(u32); /* account for status word */
962 trace_iwlwifi_dev_rx(priv, pkt, len);
952 963
953 /* Reclaim a command buffer only if this packet is a response 964 /* Reclaim a command buffer only if this packet is a response
954 * to a (driver-originated) command. 965 * to a (driver-originated) command.
@@ -1450,13 +1461,13 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
1450 1461
1451 actual_ack_cnt_delta = 1462 actual_ack_cnt_delta =
1452 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - 1463 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
1453 le32_to_cpu(priv->statistics.tx.actual_ack_cnt); 1464 le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt);
1454 expected_ack_cnt_delta = 1465 expected_ack_cnt_delta =
1455 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - 1466 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
1456 le32_to_cpu(priv->statistics.tx.expected_ack_cnt); 1467 le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt);
1457 ba_timeout_delta = 1468 ba_timeout_delta =
1458 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - 1469 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
1459 le32_to_cpu(priv->statistics.tx.agg.ba_timeout); 1470 le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout);
1460 if ((priv->_agn.agg_tids_count > 0) && 1471 if ((priv->_agn.agg_tids_count > 0) &&
1461 (expected_ack_cnt_delta > 0) && 1472 (expected_ack_cnt_delta > 0) &&
1462 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) 1473 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
@@ -1466,12 +1477,17 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
1466 " expected_ack_cnt = %d\n", 1477 " expected_ack_cnt = %d\n",
1467 actual_ack_cnt_delta, expected_ack_cnt_delta); 1478 actual_ack_cnt_delta, expected_ack_cnt_delta);
1468 1479
1469#ifdef CONFIG_IWLWIFI_DEBUG 1480#ifdef CONFIG_IWLWIFI_DEBUGFS
1481 /*
1482 * This is ifdef'ed on DEBUGFS because otherwise the
1483 * statistics aren't available. If DEBUGFS is set but
1484 * DEBUG is not, these will just compile out.
1485 */
1470 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", 1486 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
1471 priv->delta_statistics.tx.rx_detected_cnt); 1487 priv->_agn.delta_statistics.tx.rx_detected_cnt);
1472 IWL_DEBUG_RADIO(priv, 1488 IWL_DEBUG_RADIO(priv,
1473 "ack_or_ba_timeout_collision delta = %d\n", 1489 "ack_or_ba_timeout_collision delta = %d\n",
1474 priv->delta_statistics.tx. 1490 priv->_agn.delta_statistics.tx.
1475 ack_or_ba_timeout_collision); 1491 ack_or_ba_timeout_collision);
1476#endif 1492#endif
1477 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", 1493 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
@@ -1694,6 +1710,9 @@ struct iwlagn_firmware_pieces {
1694 size_t inst_size, data_size, init_size, init_data_size, boot_size; 1710 size_t inst_size, data_size, init_size, init_data_size, boot_size;
1695 1711
1696 u32 build; 1712 u32 build;
1713
1714 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1715 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1697}; 1716};
1698 1717
1699static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, 1718static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
@@ -1871,6 +1890,42 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1871 capa->max_probe_length = 1890 capa->max_probe_length =
1872 le32_to_cpup((__le32 *)tlv_data); 1891 le32_to_cpup((__le32 *)tlv_data);
1873 break; 1892 break;
1893 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1894 if (tlv_len != 4)
1895 return -EINVAL;
1896 pieces->init_evtlog_ptr =
1897 le32_to_cpup((__le32 *)tlv_data);
1898 break;
1899 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
1900 if (tlv_len != 4)
1901 return -EINVAL;
1902 pieces->init_evtlog_size =
1903 le32_to_cpup((__le32 *)tlv_data);
1904 break;
1905 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
1906 if (tlv_len != 4)
1907 return -EINVAL;
1908 pieces->init_errlog_ptr =
1909 le32_to_cpup((__le32 *)tlv_data);
1910 break;
1911 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
1912 if (tlv_len != 4)
1913 return -EINVAL;
1914 pieces->inst_evtlog_ptr =
1915 le32_to_cpup((__le32 *)tlv_data);
1916 break;
1917 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
1918 if (tlv_len != 4)
1919 return -EINVAL;
1920 pieces->inst_evtlog_size =
1921 le32_to_cpup((__le32 *)tlv_data);
1922 break;
1923 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
1924 if (tlv_len != 4)
1925 return -EINVAL;
1926 pieces->inst_errlog_ptr =
1927 le32_to_cpup((__le32 *)tlv_data);
1928 break;
1874 default: 1929 default:
1875 break; 1930 break;
1876 } 1931 }
@@ -2063,6 +2118,26 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
2063 goto err_pci_alloc; 2118 goto err_pci_alloc;
2064 } 2119 }
2065 2120
2121 /* Now that we can no longer fail, copy information */
2122
2123 /*
2124 * The (size - 16) / 12 formula is based on the information recorded
2125 * for each event, which is of mode 1 (including timestamp) for all
2126 * new microcodes that include this information.
2127 */
2128 priv->_agn.init_evtlog_ptr = pieces.init_evtlog_ptr;
2129 if (pieces.init_evtlog_size)
2130 priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
2131 else
2132 priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size;
2133 priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
2134 priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
2135 if (pieces.inst_evtlog_size)
2136 priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
2137 else
2138 priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
2139 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
2140
2066 /* Copy images into buffers for card's bus-master reads ... */ 2141 /* Copy images into buffers for card's bus-master reads ... */
2067 2142
2068 /* Runtime instructions (first block of data in file) */ 2143 /* Runtime instructions (first block of data in file) */
@@ -2195,10 +2270,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
2195 u32 blink1, blink2, ilink1, ilink2; 2270 u32 blink1, blink2, ilink1, ilink2;
2196 u32 pc, hcmd; 2271 u32 pc, hcmd;
2197 2272
2198 if (priv->ucode_type == UCODE_INIT) 2273 if (priv->ucode_type == UCODE_INIT) {
2199 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); 2274 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
2200 else 2275 if (!base)
2276 base = priv->_agn.init_errlog_ptr;
2277 } else {
2201 base = le32_to_cpu(priv->card_alive.error_event_table_ptr); 2278 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
2279 if (!base)
2280 base = priv->_agn.inst_errlog_ptr;
2281 }
2202 2282
2203 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 2283 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2204 IWL_ERR(priv, 2284 IWL_ERR(priv,
@@ -2230,9 +2310,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
2230 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, 2310 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
2231 blink1, blink2, ilink1, ilink2); 2311 blink1, blink2, ilink1, ilink2);
2232 2312
2233 IWL_ERR(priv, "Desc Time " 2313 IWL_ERR(priv, "Desc Time "
2234 "data1 data2 line\n"); 2314 "data1 data2 line\n");
2235 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", 2315 IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n",
2236 desc_lookup(desc), desc, time, data1, data2, line); 2316 desc_lookup(desc), desc, time, data1, data2, line);
2237 IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); 2317 IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n");
2238 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", 2318 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n",
@@ -2258,10 +2338,16 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2258 2338
2259 if (num_events == 0) 2339 if (num_events == 0)
2260 return pos; 2340 return pos;
2261 if (priv->ucode_type == UCODE_INIT) 2341
2342 if (priv->ucode_type == UCODE_INIT) {
2262 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 2343 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2263 else 2344 if (!base)
2345 base = priv->_agn.init_evtlog_ptr;
2346 } else {
2264 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 2347 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2348 if (!base)
2349 base = priv->_agn.inst_evtlog_ptr;
2350 }
2265 2351
2266 if (mode == 0) 2352 if (mode == 0)
2267 event_size = 2 * sizeof(u32); 2353 event_size = 2 * sizeof(u32);
@@ -2363,13 +2449,21 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2363 u32 num_wraps; /* # times uCode wrapped to top of log */ 2449 u32 num_wraps; /* # times uCode wrapped to top of log */
2364 u32 next_entry; /* index of next entry to be written by uCode */ 2450 u32 next_entry; /* index of next entry to be written by uCode */
2365 u32 size; /* # entries that we'll print */ 2451 u32 size; /* # entries that we'll print */
2452 u32 logsize;
2366 int pos = 0; 2453 int pos = 0;
2367 size_t bufsz = 0; 2454 size_t bufsz = 0;
2368 2455
2369 if (priv->ucode_type == UCODE_INIT) 2456 if (priv->ucode_type == UCODE_INIT) {
2370 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 2457 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2371 else 2458 logsize = priv->_agn.init_evtlog_size;
2459 if (!base)
2460 base = priv->_agn.init_evtlog_ptr;
2461 } else {
2372 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 2462 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2463 logsize = priv->_agn.inst_evtlog_size;
2464 if (!base)
2465 base = priv->_agn.inst_evtlog_ptr;
2466 }
2373 2467
2374 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 2468 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2375 IWL_ERR(priv, 2469 IWL_ERR(priv,
@@ -2384,16 +2478,16 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2384 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 2478 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
2385 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); 2479 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
2386 2480
2387 if (capacity > priv->cfg->max_event_log_size) { 2481 if (capacity > logsize) {
2388 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", 2482 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
2389 capacity, priv->cfg->max_event_log_size); 2483 capacity, logsize);
2390 capacity = priv->cfg->max_event_log_size; 2484 capacity = logsize;
2391 } 2485 }
2392 2486
2393 if (next_entry > priv->cfg->max_event_log_size) { 2487 if (next_entry > logsize) {
2394 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", 2488 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
2395 next_entry, priv->cfg->max_event_log_size); 2489 next_entry, logsize);
2396 next_entry = priv->cfg->max_event_log_size; 2490 next_entry = logsize;
2397 } 2491 }
2398 2492
2399 size = num_wraps ? capacity : next_entry; 2493 size = num_wraps ? capacity : next_entry;
@@ -2518,8 +2612,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
2518 2612
2519 if (priv->cfg->ops->hcmd->set_rxon_chain) 2613 if (priv->cfg->ops->hcmd->set_rxon_chain)
2520 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2614 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2521
2522 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2523 } 2615 }
2524 2616
2525 /* Configure Bluetooth device coexistence support */ 2617 /* Configure Bluetooth device coexistence support */
@@ -2843,9 +2935,9 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2843 } 2935 }
2844 2936
2845 if (priv->start_calib) { 2937 if (priv->start_calib) {
2846 iwl_chain_noise_calibration(priv, &priv->statistics); 2938 iwl_chain_noise_calibration(priv, &priv->_agn.statistics);
2847 2939
2848 iwl_sensitivity_calibration(priv, &priv->statistics); 2940 iwl_sensitivity_calibration(priv, &priv->_agn.statistics);
2849 } 2941 }
2850 2942
2851 mutex_unlock(&priv->mutex); 2943 mutex_unlock(&priv->mutex);
@@ -2934,20 +3026,16 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
2934 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3026 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2935 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3027 vif->bss_conf.aid, vif->bss_conf.beacon_int);
2936 3028
2937 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3029 if (vif->bss_conf.use_short_preamble)
2938 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3030 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2939 else 3031 else
2940 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3032 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2941 3033
2942 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3034 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
2943 if (vif->bss_conf.assoc_capability & 3035 if (vif->bss_conf.use_short_slot)
2944 WLAN_CAPABILITY_SHORT_SLOT_TIME)
2945 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3036 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
2946 else 3037 else
2947 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3038 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2948
2949 if (vif->type == NL80211_IFTYPE_ADHOC)
2950 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2951 } 3039 }
2952 3040
2953 iwlcore_commit_rxon(priv); 3041 iwlcore_commit_rxon(priv);
@@ -3173,8 +3261,7 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3173 3261
3174 priv->staging_rxon.assoc_id = 0; 3262 priv->staging_rxon.assoc_id = 0;
3175 3263
3176 if (vif->bss_conf.assoc_capability & 3264 if (vif->bss_conf.use_short_preamble)
3177 WLAN_CAPABILITY_SHORT_PREAMBLE)
3178 priv->staging_rxon.flags |= 3265 priv->staging_rxon.flags |=
3179 RXON_FLG_SHORT_PREAMBLE_MSK; 3266 RXON_FLG_SHORT_PREAMBLE_MSK;
3180 else 3267 else
@@ -3182,17 +3269,12 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3182 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3269 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3183 3270
3184 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3271 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3185 if (vif->bss_conf.assoc_capability & 3272 if (vif->bss_conf.use_short_slot)
3186 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3187 priv->staging_rxon.flags |= 3273 priv->staging_rxon.flags |=
3188 RXON_FLG_SHORT_SLOT_MSK; 3274 RXON_FLG_SHORT_SLOT_MSK;
3189 else 3275 else
3190 priv->staging_rxon.flags &= 3276 priv->staging_rxon.flags &=
3191 ~RXON_FLG_SHORT_SLOT_MSK; 3277 ~RXON_FLG_SHORT_SLOT_MSK;
3192
3193 if (vif->type == NL80211_IFTYPE_ADHOC)
3194 priv->staging_rxon.flags &=
3195 ~RXON_FLG_SHORT_SLOT_MSK;
3196 } 3278 }
3197 /* restore RXON assoc */ 3279 /* restore RXON assoc */
3198 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3280 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -3238,17 +3320,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3238 return -EOPNOTSUPP; 3320 return -EOPNOTSUPP;
3239 } 3321 }
3240 3322
3241 if (sta) { 3323 sta_id = iwl_sta_id_or_broadcast(priv, sta);
3242 sta_id = iwl_sta_id(sta); 3324 if (sta_id == IWL_INVALID_STATION)
3243 3325 return -EINVAL;
3244 if (sta_id == IWL_INVALID_STATION) {
3245 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
3246 sta->addr);
3247 return -EINVAL;
3248 }
3249 } else {
3250 sta_id = priv->hw_params.bcast_sta_id;
3251 }
3252 3326
3253 mutex_lock(&priv->mutex); 3327 mutex_lock(&priv->mutex);
3254 iwl_scan_cancel_timeout(priv, 100); 3328 iwl_scan_cancel_timeout(priv, 100);
@@ -3300,7 +3374,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3300 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3374 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3301{ 3375{
3302 struct iwl_priv *priv = hw->priv; 3376 struct iwl_priv *priv = hw->priv;
3303 int ret; 3377 int ret = -EINVAL;
3304 3378
3305 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", 3379 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
3306 sta->addr, tid); 3380 sta->addr, tid);
@@ -3308,17 +3382,19 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3308 if (!(priv->cfg->sku & IWL_SKU_N)) 3382 if (!(priv->cfg->sku & IWL_SKU_N))
3309 return -EACCES; 3383 return -EACCES;
3310 3384
3385 mutex_lock(&priv->mutex);
3386
3311 switch (action) { 3387 switch (action) {
3312 case IEEE80211_AMPDU_RX_START: 3388 case IEEE80211_AMPDU_RX_START:
3313 IWL_DEBUG_HT(priv, "start Rx\n"); 3389 IWL_DEBUG_HT(priv, "start Rx\n");
3314 return iwl_sta_rx_agg_start(priv, sta, tid, *ssn); 3390 ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
3391 break;
3315 case IEEE80211_AMPDU_RX_STOP: 3392 case IEEE80211_AMPDU_RX_STOP:
3316 IWL_DEBUG_HT(priv, "stop Rx\n"); 3393 IWL_DEBUG_HT(priv, "stop Rx\n");
3317 ret = iwl_sta_rx_agg_stop(priv, sta, tid); 3394 ret = iwl_sta_rx_agg_stop(priv, sta, tid);
3318 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3395 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3319 return 0; 3396 ret = 0;
3320 else 3397 break;
3321 return ret;
3322 case IEEE80211_AMPDU_TX_START: 3398 case IEEE80211_AMPDU_TX_START:
3323 IWL_DEBUG_HT(priv, "start Tx\n"); 3399 IWL_DEBUG_HT(priv, "start Tx\n");
3324 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); 3400 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
@@ -3327,7 +3403,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3327 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n", 3403 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
3328 priv->_agn.agg_tids_count); 3404 priv->_agn.agg_tids_count);
3329 } 3405 }
3330 return ret; 3406 break;
3331 case IEEE80211_AMPDU_TX_STOP: 3407 case IEEE80211_AMPDU_TX_STOP:
3332 IWL_DEBUG_HT(priv, "stop Tx\n"); 3408 IWL_DEBUG_HT(priv, "stop Tx\n");
3333 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); 3409 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
@@ -3337,18 +3413,15 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3337 priv->_agn.agg_tids_count); 3413 priv->_agn.agg_tids_count);
3338 } 3414 }
3339 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3415 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3340 return 0; 3416 ret = 0;
3341 else 3417 break;
3342 return ret;
3343 case IEEE80211_AMPDU_TX_OPERATIONAL: 3418 case IEEE80211_AMPDU_TX_OPERATIONAL:
3344 /* do nothing */ 3419 /* do nothing, return value ignored */
3345 return -EOPNOTSUPP;
3346 default:
3347 IWL_DEBUG_HT(priv, "unknown\n");
3348 return -EINVAL;
3349 break; 3420 break;
3350 } 3421 }
3351 return 0; 3422 mutex_unlock(&priv->mutex);
3423
3424 return ret;
3352} 3425}
3353 3426
3354static void iwl_mac_sta_notify(struct ieee80211_hw *hw, 3427static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
@@ -3423,6 +3496,98 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3423 return 0; 3496 return 0;
3424} 3497}
3425 3498
3499static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3500 struct ieee80211_channel_switch *ch_switch)
3501{
3502 struct iwl_priv *priv = hw->priv;
3503 const struct iwl_channel_info *ch_info;
3504 struct ieee80211_conf *conf = &hw->conf;
3505 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
3506 u16 ch;
3507 unsigned long flags = 0;
3508
3509 IWL_DEBUG_MAC80211(priv, "enter\n");
3510
3511 if (iwl_is_rfkill(priv))
3512 goto out_exit;
3513
3514 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
3515 test_bit(STATUS_SCANNING, &priv->status))
3516 goto out_exit;
3517
3518 if (!iwl_is_associated(priv))
3519 goto out_exit;
3520
3521 /* channel switch in progress */
3522 if (priv->switch_rxon.switch_in_progress == true)
3523 goto out_exit;
3524
3525 mutex_lock(&priv->mutex);
3526 if (priv->cfg->ops->lib->set_channel_switch) {
3527
3528 ch = ieee80211_frequency_to_channel(
3529 ch_switch->channel->center_freq);
3530 if (le16_to_cpu(priv->active_rxon.channel) != ch) {
3531 ch_info = iwl_get_channel_info(priv,
3532 conf->channel->band,
3533 ch);
3534 if (!is_channel_valid(ch_info)) {
3535 IWL_DEBUG_MAC80211(priv, "invalid channel\n");
3536 goto out;
3537 }
3538 spin_lock_irqsave(&priv->lock, flags);
3539
3540 priv->current_ht_config.smps = conf->smps_mode;
3541
3542 /* Configure HT40 channels */
3543 ht_conf->is_ht = conf_is_ht(conf);
3544 if (ht_conf->is_ht) {
3545 if (conf_is_ht40_minus(conf)) {
3546 ht_conf->extension_chan_offset =
3547 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
3548 ht_conf->is_40mhz = true;
3549 } else if (conf_is_ht40_plus(conf)) {
3550 ht_conf->extension_chan_offset =
3551 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
3552 ht_conf->is_40mhz = true;
3553 } else {
3554 ht_conf->extension_chan_offset =
3555 IEEE80211_HT_PARAM_CHA_SEC_NONE;
3556 ht_conf->is_40mhz = false;
3557 }
3558 } else
3559 ht_conf->is_40mhz = false;
3560
3561 /* if we are switching from ht to 2.4 clear flags
3562 * from any ht related info since 2.4 does not
3563 * support ht */
3564 if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
3565 priv->staging_rxon.flags = 0;
3566
3567 iwl_set_rxon_channel(priv, conf->channel);
3568 iwl_set_rxon_ht(priv, ht_conf);
3569 iwl_set_flags_for_band(priv, conf->channel->band,
3570 priv->vif);
3571 spin_unlock_irqrestore(&priv->lock, flags);
3572
3573 iwl_set_rate(priv);
3574 /*
3575 * at this point, staging_rxon has the
3576 * configuration for channel switch
3577 */
3578 if (priv->cfg->ops->lib->set_channel_switch(priv,
3579 ch_switch))
3580 priv->switch_rxon.switch_in_progress = false;
3581 }
3582 }
3583out:
3584 mutex_unlock(&priv->mutex);
3585out_exit:
3586 if (!priv->switch_rxon.switch_in_progress)
3587 ieee80211_chswitch_done(priv->vif, false);
3588 IWL_DEBUG_MAC80211(priv, "leave\n");
3589}
3590
3426/***************************************************************************** 3591/*****************************************************************************
3427 * 3592 *
3428 * driver setup and teardown 3593 * driver setup and teardown
@@ -3479,6 +3644,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3479 cancel_delayed_work(&priv->scan_check); 3644 cancel_delayed_work(&priv->scan_check);
3480 cancel_work_sync(&priv->start_internal_scan); 3645 cancel_work_sync(&priv->start_internal_scan);
3481 cancel_delayed_work(&priv->alive_start); 3646 cancel_delayed_work(&priv->alive_start);
3647 cancel_work_sync(&priv->run_time_calib_work);
3482 cancel_work_sync(&priv->beacon_update); 3648 cancel_work_sync(&priv->beacon_update);
3483 del_timer_sync(&priv->statistics_periodic); 3649 del_timer_sync(&priv->statistics_periodic);
3484 del_timer_sync(&priv->ucode_trace); 3650 del_timer_sync(&priv->ucode_trace);
@@ -3594,6 +3760,7 @@ static struct ieee80211_ops iwl_hw_ops = {
3594 .sta_notify = iwl_mac_sta_notify, 3760 .sta_notify = iwl_mac_sta_notify,
3595 .sta_add = iwlagn_mac_sta_add, 3761 .sta_add = iwlagn_mac_sta_add,
3596 .sta_remove = iwl_mac_sta_remove, 3762 .sta_remove = iwl_mac_sta_remove,
3763 .channel_switch = iwl_mac_channel_switch,
3597}; 3764};
3598 3765
3599static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3766static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -3604,6 +3771,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3604 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 3771 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
3605 unsigned long flags; 3772 unsigned long flags;
3606 u16 pci_cmd; 3773 u16 pci_cmd;
3774 u8 perm_addr[ETH_ALEN];
3607 3775
3608 /************************ 3776 /************************
3609 * 1. Allocating HW data 3777 * 1. Allocating HW data
@@ -3633,9 +3801,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3633 priv->pci_dev = pdev; 3801 priv->pci_dev = pdev;
3634 priv->inta_mask = CSR_INI_SET_MASK; 3802 priv->inta_mask = CSR_INI_SET_MASK;
3635 3803
3636#ifdef CONFIG_IWLWIFI_DEBUG
3637 atomic_set(&priv->restrict_refcnt, 0);
3638#endif
3639 if (iwl_alloc_traffic_mem(priv)) 3804 if (iwl_alloc_traffic_mem(priv))
3640 IWL_ERR(priv, "Not enough memory to generate traffic log\n"); 3805 IWL_ERR(priv, "Not enough memory to generate traffic log\n");
3641 3806
@@ -3724,9 +3889,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3724 goto out_free_eeprom; 3889 goto out_free_eeprom;
3725 3890
3726 /* extract MAC Address */ 3891 /* extract MAC Address */
3727 iwl_eeprom_get_mac(priv, priv->mac_addr); 3892 iwl_eeprom_get_mac(priv, perm_addr);
3728 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr); 3893 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr);
3729 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); 3894 SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr);
3730 3895
3731 /************************ 3896 /************************
3732 * 5. Setup HW constants 3897 * 5. Setup HW constants
@@ -3993,6 +4158,47 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
3993 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)}, 4158 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
3994 {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)}, 4159 {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
3995 {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)}, 4160 {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
4161 {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)},
4162 {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)},
4163 {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)},
4164 {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)},
4165 {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)},
4166 {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)},
4167 {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)},
4168 {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2a_2agn_cfg)},
4169 {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6000g2a_2abg_cfg)},
4170 {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2a_2agn_cfg)},
4171 {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)},
4172
4173/* 6x00 Series Gen2b */
4174 {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)},
4175 {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)},
4176 {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)},
4177 {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)},
4178 {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)},
4179 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
4180 {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)},
4181 {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)},
4182 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
4183 {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)},
4184 {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)},
4185 {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)},
4186 {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)},
4187 {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)},
4188 {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)},
4189 {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)},
4190 {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)},
4191 {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)},
4192 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
4193 {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)},
4194 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
4195 {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6000g2b_2agn_cfg)},
4196 {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6000g2b_2bgn_cfg)},
4197 {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6000g2b_2abg_cfg)},
4198 {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6000g2b_2bg_cfg)},
4199 {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6000g2b_2agn_cfg)},
4200 {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6000g2b_2bgn_cfg)},
4201 {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6000g2b_2abg_cfg)},
3996 4202
3997/* 6x50 WiFi/WiMax Series */ 4203/* 6x50 WiFi/WiMax Series */
3998 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, 4204 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 2d748053358e..be9d298cae2c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -65,6 +65,33 @@
65 65
66#include "iwl-dev.h" 66#include "iwl-dev.h"
67 67
68/* configuration for the _agn devices */
69extern struct iwl_cfg iwl4965_agn_cfg;
70extern struct iwl_cfg iwl5300_agn_cfg;
71extern struct iwl_cfg iwl5100_agn_cfg;
72extern struct iwl_cfg iwl5350_agn_cfg;
73extern struct iwl_cfg iwl5100_bgn_cfg;
74extern struct iwl_cfg iwl5100_abg_cfg;
75extern struct iwl_cfg iwl5150_agn_cfg;
76extern struct iwl_cfg iwl5150_abg_cfg;
77extern struct iwl_cfg iwl6000g2a_2agn_cfg;
78extern struct iwl_cfg iwl6000g2a_2abg_cfg;
79extern struct iwl_cfg iwl6000g2a_2bg_cfg;
80extern struct iwl_cfg iwl6000g2b_bgn_cfg;
81extern struct iwl_cfg iwl6000g2b_bg_cfg;
82extern struct iwl_cfg iwl6000g2b_2agn_cfg;
83extern struct iwl_cfg iwl6000g2b_2abg_cfg;
84extern struct iwl_cfg iwl6000g2b_2bgn_cfg;
85extern struct iwl_cfg iwl6000g2b_2bg_cfg;
86extern struct iwl_cfg iwl6000i_2agn_cfg;
87extern struct iwl_cfg iwl6000i_2abg_cfg;
88extern struct iwl_cfg iwl6000i_2bg_cfg;
89extern struct iwl_cfg iwl6000_3agn_cfg;
90extern struct iwl_cfg iwl6050_2agn_cfg;
91extern struct iwl_cfg iwl6050_2abg_cfg;
92extern struct iwl_cfg iwl1000_bgn_cfg;
93extern struct iwl_cfg iwl1000_bg_cfg;
94
68extern struct iwl_mod_params iwlagn_mod_params; 95extern struct iwl_mod_params iwlagn_mod_params;
69extern struct iwl_hcmd_ops iwlagn_hcmd; 96extern struct iwl_hcmd_ops iwlagn_hcmd;
70extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; 97extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
@@ -93,6 +120,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
93int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, 120int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
94 u16 ssn_idx, u8 tx_fifo); 121 u16 ssn_idx, u8 tx_fifo);
95void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); 122void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
123void iwl_free_tfds_in_queue(struct iwl_priv *priv,
124 int sta_id, int tid, int freed);
96 125
97/* uCode */ 126/* uCode */
98int iwlagn_load_ucode(struct iwl_priv *priv); 127int iwlagn_load_ucode(struct iwl_priv *priv);
@@ -102,6 +131,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv,
102 struct iwl_rx_mem_buffer *rxb); 131 struct iwl_rx_mem_buffer *rxb);
103void iwlagn_init_alive_start(struct iwl_priv *priv); 132void iwlagn_init_alive_start(struct iwl_priv *priv);
104int iwlagn_alive_notify(struct iwl_priv *priv); 133int iwlagn_alive_notify(struct iwl_priv *priv);
134int iwl_verify_ucode(struct iwl_priv *priv);
105 135
106/* lib */ 136/* lib */
107void iwl_check_abort_status(struct iwl_priv *priv, 137void iwl_check_abort_status(struct iwl_priv *priv,
@@ -171,6 +201,16 @@ static inline bool iwl_is_tx_success(u32 status)
171 (status == TX_STATUS_DIRECT_DONE); 201 (status == TX_STATUS_DIRECT_DONE);
172} 202}
173 203
204/* rx */
205void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
206 struct iwl_rx_mem_buffer *rxb);
207bool iwl_good_plcp_health(struct iwl_priv *priv,
208 struct iwl_rx_packet *pkt);
209void iwl_rx_statistics(struct iwl_priv *priv,
210 struct iwl_rx_mem_buffer *rxb);
211void iwl_reply_statistics(struct iwl_priv *priv,
212 struct iwl_rx_mem_buffer *rxb);
213
174/* scan */ 214/* scan */
175void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 215void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
176 216
@@ -178,4 +218,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
178int iwlagn_manage_ibss_station(struct iwl_priv *priv, 218int iwlagn_manage_ibss_station(struct iwl_priv *priv,
179 struct ieee80211_vif *vif, bool add); 219 struct ieee80211_vif *vif, bool add);
180 220
221/* hcmd */
222int iwlagn_send_rxon_assoc(struct iwl_priv *priv);
223int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
224
181#endif /* __iwl_agn_h__ */ 225#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9aab020c474b..498492565912 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -95,7 +95,7 @@ enum {
95 95
96 /* Multi-Station support */ 96 /* Multi-Station support */
97 REPLY_ADD_STA = 0x18, 97 REPLY_ADD_STA = 0x18,
98 REPLY_REMOVE_STA = 0x19, /* not used */ 98 REPLY_REMOVE_STA = 0x19,
99 REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ 99 REPLY_REMOVE_ALL_STA = 0x1a, /* not used */
100 100
101 /* Security */ 101 /* Security */
@@ -952,7 +952,6 @@ struct iwl_qosparam_cmd {
952 952
953/* Special, dedicated locations within device's station table */ 953/* Special, dedicated locations within device's station table */
954#define IWL_AP_ID 0 954#define IWL_AP_ID 0
955#define IWL_MULTICAST_ID 1
956#define IWL_STA_ID 2 955#define IWL_STA_ID 2
957#define IWL3945_BROADCAST_ID 24 956#define IWL3945_BROADCAST_ID 24
958#define IWL3945_STATION_COUNT 25 957#define IWL3945_STATION_COUNT 25
@@ -1367,7 +1366,7 @@ struct iwl_rx_phy_res {
1367 __le16 reserved3; 1366 __le16 reserved3;
1368} __attribute__ ((packed)); 1367} __attribute__ ((packed));
1369 1368
1370struct iwl4965_rx_mpdu_res_start { 1369struct iwl_rx_mpdu_res_start {
1371 __le16 byte_count; 1370 __le16 byte_count;
1372 __le16 reserved; 1371 __le16 reserved;
1373} __attribute__ ((packed)); 1372} __attribute__ ((packed));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5bbc5298ef96..329e5107b5c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -141,13 +141,14 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
141} 141}
142EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); 142EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
143 143
144u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) 144u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
145{ 145{
146 int i; 146 int i;
147 u8 ind = ant; 147 u8 ind = ant;
148
148 for (i = 0; i < RATE_ANT_NUM - 1; i++) { 149 for (i = 0; i < RATE_ANT_NUM - 1; i++) {
149 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; 150 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
150 if (priv->hw_params.valid_tx_ant & BIT(ind)) 151 if (valid & BIT(ind))
151 return ind; 152 return ind;
152 } 153 }
153 return ant; 154 return ant;
@@ -457,7 +458,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
457 if (!sta_ht_inf->ht_supported) 458 if (!sta_ht_inf->ht_supported)
458 return 0; 459 return 0;
459 } 460 }
460#ifdef CONFIG_IWLWIFI_DEBUG 461#ifdef CONFIG_IWLWIFI_DEBUGFS
461 if (priv->disable_ht40) 462 if (priv->disable_ht40)
462 return 0; 463 return 0;
463#endif 464#endif
@@ -506,11 +507,11 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
506 } 507 }
507 508
508 beacon_int = iwl_adjust_beacon_interval(beacon_int, 509 beacon_int = iwl_adjust_beacon_interval(beacon_int,
509 priv->hw_params.max_beacon_itrvl * 1024); 510 priv->hw_params.max_beacon_itrvl * TIME_UNIT);
510 priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); 511 priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
511 512
512 tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ 513 tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
513 interval_tm = beacon_int * 1024; 514 interval_tm = beacon_int * TIME_UNIT;
514 rem = do_div(tsf, interval_tm); 515 rem = do_div(tsf, interval_tm);
515 priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem); 516 priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
516 517
@@ -932,9 +933,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
932} 933}
933EXPORT_SYMBOL(iwl_set_rxon_channel); 934EXPORT_SYMBOL(iwl_set_rxon_channel);
934 935
935static void iwl_set_flags_for_band(struct iwl_priv *priv, 936void iwl_set_flags_for_band(struct iwl_priv *priv,
936 enum ieee80211_band band, 937 enum ieee80211_band band,
937 struct ieee80211_vif *vif) 938 struct ieee80211_vif *vif)
938{ 939{
939 if (band == IEEE80211_BAND_5GHZ) { 940 if (band == IEEE80211_BAND_5GHZ) {
940 priv->staging_rxon.flags &= 941 priv->staging_rxon.flags &=
@@ -943,19 +944,17 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
943 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 944 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
944 } else { 945 } else {
945 /* Copied from iwl_post_associate() */ 946 /* Copied from iwl_post_associate() */
946 if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 947 if (vif && vif->bss_conf.use_short_slot)
947 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 948 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
948 else 949 else
949 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 950 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
950 951
951 if (vif && vif->type == NL80211_IFTYPE_ADHOC)
952 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
953
954 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; 952 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
955 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; 953 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
956 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; 954 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
957 } 955 }
958} 956}
957EXPORT_SYMBOL(iwl_set_flags_for_band);
959 958
960/* 959/*
961 * initialize rxon structure with default values from eeprom 960 * initialize rxon structure with default values from eeprom
@@ -1021,15 +1020,17 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
1021 /* clear both MIX and PURE40 mode flag */ 1020 /* clear both MIX and PURE40 mode flag */
1022 priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | 1021 priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
1023 RXON_FLG_CHANNEL_MODE_PURE_40); 1022 RXON_FLG_CHANNEL_MODE_PURE_40);
1024 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 1023
1025 memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); 1024 if (vif)
1025 memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN);
1026
1026 priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; 1027 priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
1027 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; 1028 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
1028 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff; 1029 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff;
1029} 1030}
1030EXPORT_SYMBOL(iwl_connection_init_rx_config); 1031EXPORT_SYMBOL(iwl_connection_init_rx_config);
1031 1032
1032static void iwl_set_rate(struct iwl_priv *priv) 1033void iwl_set_rate(struct iwl_priv *priv)
1033{ 1034{
1034 const struct ieee80211_supported_band *hw = NULL; 1035 const struct ieee80211_supported_band *hw = NULL;
1035 struct ieee80211_rate *rate; 1036 struct ieee80211_rate *rate;
@@ -1057,6 +1058,21 @@ static void iwl_set_rate(struct iwl_priv *priv)
1057 priv->staging_rxon.ofdm_basic_rates = 1058 priv->staging_rxon.ofdm_basic_rates =
1058 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 1059 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1059} 1060}
1061EXPORT_SYMBOL(iwl_set_rate);
1062
1063void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
1064{
1065 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
1066 return;
1067
1068 if (priv->switch_rxon.switch_in_progress) {
1069 ieee80211_chswitch_done(priv->vif, is_success);
1070 mutex_lock(&priv->mutex);
1071 priv->switch_rxon.switch_in_progress = false;
1072 mutex_unlock(&priv->mutex);
1073 }
1074}
1075EXPORT_SYMBOL(iwl_chswitch_done);
1060 1076
1061void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1077void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1062{ 1078{
@@ -1071,11 +1087,12 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1071 priv->staging_rxon.channel = csa->channel; 1087 priv->staging_rxon.channel = csa->channel;
1072 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", 1088 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
1073 le16_to_cpu(csa->channel)); 1089 le16_to_cpu(csa->channel));
1074 } else 1090 iwl_chswitch_done(priv, true);
1091 } else {
1075 IWL_ERR(priv, "CSA notif (fail) : channel %d\n", 1092 IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
1076 le16_to_cpu(csa->channel)); 1093 le16_to_cpu(csa->channel));
1077 1094 iwl_chswitch_done(priv, false);
1078 priv->switch_rxon.switch_in_progress = false; 1095 }
1079 } 1096 }
1080} 1097}
1081EXPORT_SYMBOL(iwl_rx_csa); 1098EXPORT_SYMBOL(iwl_rx_csa);
@@ -1507,130 +1524,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
1507} 1524}
1508EXPORT_SYMBOL(iwl_send_statistics_request); 1525EXPORT_SYMBOL(iwl_send_statistics_request);
1509 1526
1510/**
1511 * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
1512 * using sample data 100 bytes apart. If these sample points are good,
1513 * it's a pretty good bet that everything between them is good, too.
1514 */
1515static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
1516{
1517 u32 val;
1518 int ret = 0;
1519 u32 errcnt = 0;
1520 u32 i;
1521
1522 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
1523
1524 for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
1525 /* read data comes through single port, auto-incr addr */
1526 /* NOTE: Use the debugless read so we don't flood kernel log
1527 * if IWL_DL_IO is set */
1528 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
1529 i + IWL49_RTC_INST_LOWER_BOUND);
1530 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1531 if (val != le32_to_cpu(*image)) {
1532 ret = -EIO;
1533 errcnt++;
1534 if (errcnt >= 3)
1535 break;
1536 }
1537 }
1538
1539 return ret;
1540}
1541
1542/**
1543 * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
1544 * looking at all data.
1545 */
1546static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
1547 u32 len)
1548{
1549 u32 val;
1550 u32 save_len = len;
1551 int ret = 0;
1552 u32 errcnt;
1553
1554 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
1555
1556 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
1557 IWL49_RTC_INST_LOWER_BOUND);
1558
1559 errcnt = 0;
1560 for (; len > 0; len -= sizeof(u32), image++) {
1561 /* read data comes through single port, auto-incr addr */
1562 /* NOTE: Use the debugless read so we don't flood kernel log
1563 * if IWL_DL_IO is set */
1564 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1565 if (val != le32_to_cpu(*image)) {
1566 IWL_ERR(priv, "uCode INST section is invalid at "
1567 "offset 0x%x, is 0x%x, s/b 0x%x\n",
1568 save_len - len, val, le32_to_cpu(*image));
1569 ret = -EIO;
1570 errcnt++;
1571 if (errcnt >= 20)
1572 break;
1573 }
1574 }
1575
1576 if (!errcnt)
1577 IWL_DEBUG_INFO(priv,
1578 "ucode image in INSTRUCTION memory is good\n");
1579
1580 return ret;
1581}
1582
1583/**
1584 * iwl_verify_ucode - determine which instruction image is in SRAM,
1585 * and verify its contents
1586 */
1587int iwl_verify_ucode(struct iwl_priv *priv)
1588{
1589 __le32 *image;
1590 u32 len;
1591 int ret;
1592
1593 /* Try bootstrap */
1594 image = (__le32 *)priv->ucode_boot.v_addr;
1595 len = priv->ucode_boot.len;
1596 ret = iwlcore_verify_inst_sparse(priv, image, len);
1597 if (!ret) {
1598 IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
1599 return 0;
1600 }
1601
1602 /* Try initialize */
1603 image = (__le32 *)priv->ucode_init.v_addr;
1604 len = priv->ucode_init.len;
1605 ret = iwlcore_verify_inst_sparse(priv, image, len);
1606 if (!ret) {
1607 IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
1608 return 0;
1609 }
1610
1611 /* Try runtime/protocol */
1612 image = (__le32 *)priv->ucode_code.v_addr;
1613 len = priv->ucode_code.len;
1614 ret = iwlcore_verify_inst_sparse(priv, image, len);
1615 if (!ret) {
1616 IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
1617 return 0;
1618 }
1619
1620 IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
1621
1622 /* Since nothing seems to match, show first several data entries in
1623 * instruction SRAM, so maybe visual inspection will give a clue.
1624 * Selection of bootstrap image (vs. other images) is arbitrary. */
1625 image = (__le32 *)priv->ucode_boot.v_addr;
1626 len = priv->ucode_boot.len;
1627 ret = iwl_verify_inst_full(priv, image, len);
1628
1629 return ret;
1630}
1631EXPORT_SYMBOL(iwl_verify_ucode);
1632
1633
1634void iwl_rf_kill_ct_config(struct iwl_priv *priv) 1527void iwl_rf_kill_ct_config(struct iwl_priv *priv)
1635{ 1528{
1636 struct iwl_ct_kill_config cmd; 1529 struct iwl_ct_kill_config cmd;
@@ -2051,8 +1944,6 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
2051 if (priv->cfg->ops->hcmd->set_rxon_chain) 1944 if (priv->cfg->ops->hcmd->set_rxon_chain)
2052 priv->cfg->ops->hcmd->set_rxon_chain(priv); 1945 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2053 1946
2054 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2055
2056 return iwlcore_commit_rxon(priv); 1947 return iwlcore_commit_rxon(priv);
2057} 1948}
2058 1949
@@ -2061,7 +1952,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2061 struct iwl_priv *priv = hw->priv; 1952 struct iwl_priv *priv = hw->priv;
2062 int err = 0; 1953 int err = 0;
2063 1954
2064 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type); 1955 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
1956 vif->type, vif->addr);
2065 1957
2066 mutex_lock(&priv->mutex); 1958 mutex_lock(&priv->mutex);
2067 1959
@@ -2079,9 +1971,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2079 priv->vif = vif; 1971 priv->vif = vif;
2080 priv->iw_mode = vif->type; 1972 priv->iw_mode = vif->type;
2081 1973
2082 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2083 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
2084
2085 err = iwl_set_mode(priv, vif); 1974 err = iwl_set_mode(priv, vif);
2086 if (err) 1975 if (err)
2087 goto out_err; 1976 goto out_err;
@@ -2115,6 +2004,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2115 } 2004 }
2116 if (priv->vif == vif) { 2005 if (priv->vif == vif) {
2117 priv->vif = NULL; 2006 priv->vif = NULL;
2007 if (priv->scan_vif == vif) {
2008 ieee80211_scan_completed(priv->hw, true);
2009 priv->scan_vif = NULL;
2010 priv->scan_request = NULL;
2011 }
2118 memset(priv->bssid, 0, ETH_ALEN); 2012 memset(priv->bssid, 0, ETH_ALEN);
2119 } 2013 }
2120 mutex_unlock(&priv->mutex); 2014 mutex_unlock(&priv->mutex);
@@ -2215,22 +2109,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2215 2109
2216 iwl_set_flags_for_band(priv, conf->channel->band, priv->vif); 2110 iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
2217 spin_unlock_irqrestore(&priv->lock, flags); 2111 spin_unlock_irqrestore(&priv->lock, flags);
2218 if (iwl_is_associated(priv) && 2112
2219 (le16_to_cpu(priv->active_rxon.channel) != ch) &&
2220 priv->cfg->ops->lib->set_channel_switch) {
2221 iwl_set_rate(priv);
2222 /*
2223 * at this point, staging_rxon has the
2224 * configuration for channel switch
2225 */
2226 ret = priv->cfg->ops->lib->set_channel_switch(priv,
2227 ch);
2228 if (!ret) {
2229 iwl_print_rx_config_cmd(priv);
2230 goto out;
2231 }
2232 priv->switch_rxon.switch_in_progress = false;
2233 }
2234 set_ch_out: 2113 set_ch_out:
2235 /* The list of supported rates and rate mask can be different 2114 /* The list of supported rates and rate mask can be different
2236 * for each band; since the band may have changed, reset 2115 * for each band; since the band may have changed, reset
@@ -2588,7 +2467,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
2588EXPORT_SYMBOL(iwl_update_stats); 2467EXPORT_SYMBOL(iwl_update_stats);
2589#endif 2468#endif
2590 2469
2591const static char *get_csr_string(int cmd) 2470static const char *get_csr_string(int cmd)
2592{ 2471{
2593 switch (cmd) { 2472 switch (cmd) {
2594 IWL_CMD(CSR_HW_IF_CONFIG_REG); 2473 IWL_CMD(CSR_HW_IF_CONFIG_REG);
@@ -2659,7 +2538,7 @@ void iwl_dump_csr(struct iwl_priv *priv)
2659} 2538}
2660EXPORT_SYMBOL(iwl_dump_csr); 2539EXPORT_SYMBOL(iwl_dump_csr);
2661 2540
2662const static char *get_fh_string(int cmd) 2541static const char *get_fh_string(int cmd)
2663{ 2542{
2664 switch (cmd) { 2543 switch (cmd) {
2665 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); 2544 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
@@ -2881,6 +2760,61 @@ void iwl_bg_monitor_recover(unsigned long data)
2881} 2760}
2882EXPORT_SYMBOL(iwl_bg_monitor_recover); 2761EXPORT_SYMBOL(iwl_bg_monitor_recover);
2883 2762
2763
2764/*
2765 * extended beacon time format
2766 * time in usec will be changed into a 32-bit value in extended:internal format
2767 * the extended part is the beacon counts
2768 * the internal part is the time in usec within one beacon interval
2769 */
2770u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval)
2771{
2772 u32 quot;
2773 u32 rem;
2774 u32 interval = beacon_interval * TIME_UNIT;
2775
2776 if (!interval || !usec)
2777 return 0;
2778
2779 quot = (usec / interval) &
2780 (iwl_beacon_time_mask_high(priv,
2781 priv->hw_params.beacon_time_tsf_bits) >>
2782 priv->hw_params.beacon_time_tsf_bits);
2783 rem = (usec % interval) & iwl_beacon_time_mask_low(priv,
2784 priv->hw_params.beacon_time_tsf_bits);
2785
2786 return (quot << priv->hw_params.beacon_time_tsf_bits) + rem;
2787}
2788EXPORT_SYMBOL(iwl_usecs_to_beacons);
2789
2790/* base is usually what we get from ucode with each received frame,
2791 * the same as HW timer counter counting down
2792 */
2793__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
2794 u32 addon, u32 beacon_interval)
2795{
2796 u32 base_low = base & iwl_beacon_time_mask_low(priv,
2797 priv->hw_params.beacon_time_tsf_bits);
2798 u32 addon_low = addon & iwl_beacon_time_mask_low(priv,
2799 priv->hw_params.beacon_time_tsf_bits);
2800 u32 interval = beacon_interval * TIME_UNIT;
2801 u32 res = (base & iwl_beacon_time_mask_high(priv,
2802 priv->hw_params.beacon_time_tsf_bits)) +
2803 (addon & iwl_beacon_time_mask_high(priv,
2804 priv->hw_params.beacon_time_tsf_bits));
2805
2806 if (base_low > addon_low)
2807 res += base_low - addon_low;
2808 else if (base_low < addon_low) {
2809 res += interval + base_low - addon_low;
2810 res += (1 << priv->hw_params.beacon_time_tsf_bits);
2811 } else
2812 res += (1 << priv->hw_params.beacon_time_tsf_bits);
2813
2814 return cpu_to_le32(res);
2815}
2816EXPORT_SYMBOL(iwl_add_beacon_time);
2817
2884#ifdef CONFIG_PM 2818#ifdef CONFIG_PM
2885 2819
2886int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 2820int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 31775bd9c361..5e72d743d9ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -79,6 +79,8 @@ struct iwl_cmd;
79 .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ 79 .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
80 .driver_data = (kernel_ulong_t)&(cfg) 80 .driver_data = (kernel_ulong_t)&(cfg)
81 81
82#define TIME_UNIT 1024
83
82#define IWL_SKU_G 0x1 84#define IWL_SKU_G 0x1
83#define IWL_SKU_A 0x2 85#define IWL_SKU_A 0x2
84#define IWL_SKU_N 0x8 86#define IWL_SKU_N 0x8
@@ -173,7 +175,8 @@ struct iwl_lib_ops {
173 void (*dump_nic_error_log)(struct iwl_priv *priv); 175 void (*dump_nic_error_log)(struct iwl_priv *priv);
174 void (*dump_csr)(struct iwl_priv *priv); 176 void (*dump_csr)(struct iwl_priv *priv);
175 int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); 177 int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
176 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 178 int (*set_channel_switch)(struct iwl_priv *priv,
179 struct ieee80211_channel_switch *ch_switch);
177 /* power management */ 180 /* power management */
178 struct iwl_apm_ops apm_ops; 181 struct iwl_apm_ops apm_ops;
179 182
@@ -325,7 +328,8 @@ struct iwl_cfg {
325 const bool ucode_tracing; 328 const bool ucode_tracing;
326 const bool sensitivity_calib_by_driver; 329 const bool sensitivity_calib_by_driver;
327 const bool chain_noise_calib_by_driver; 330 const bool chain_noise_calib_by_driver;
328 u8 scan_antennas[IEEE80211_NUM_BANDS]; 331 u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
332 u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
329}; 333};
330 334
331/*************************** 335/***************************
@@ -343,6 +347,9 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv);
343int iwl_full_rxon_required(struct iwl_priv *priv); 347int iwl_full_rxon_required(struct iwl_priv *priv);
344void iwl_set_rxon_chain(struct iwl_priv *priv); 348void iwl_set_rxon_chain(struct iwl_priv *priv);
345int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); 349int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
350void iwl_set_flags_for_band(struct iwl_priv *priv,
351 enum ieee80211_band band,
352 struct ieee80211_vif *vif);
346u8 iwl_get_single_channel_number(struct iwl_priv *priv, 353u8 iwl_get_single_channel_number(struct iwl_priv *priv,
347 enum ieee80211_band band); 354 enum ieee80211_band band);
348void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); 355void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
@@ -350,6 +357,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
350 struct ieee80211_sta_ht_cap *sta_ht_inf); 357 struct ieee80211_sta_ht_cap *sta_ht_inf);
351void iwl_connection_init_rx_config(struct iwl_priv *priv, 358void iwl_connection_init_rx_config(struct iwl_priv *priv,
352 struct ieee80211_vif *vif); 359 struct ieee80211_vif *vif);
360void iwl_set_rate(struct iwl_priv *priv);
353int iwl_set_decrypted_flag(struct iwl_priv *priv, 361int iwl_set_decrypted_flag(struct iwl_priv *priv,
354 struct ieee80211_hdr *hdr, 362 struct ieee80211_hdr *hdr,
355 u32 decrypt_res, 363 u32 decrypt_res,
@@ -447,20 +455,11 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
447int iwl_rx_queue_space(const struct iwl_rx_queue *q); 455int iwl_rx_queue_space(const struct iwl_rx_queue *q);
448void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 456void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
449/* Handlers */ 457/* Handlers */
450void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
451 struct iwl_rx_mem_buffer *rxb);
452void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 458void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
453 struct iwl_rx_mem_buffer *rxb); 459 struct iwl_rx_mem_buffer *rxb);
454bool iwl_good_plcp_health(struct iwl_priv *priv,
455 struct iwl_rx_packet *pkt);
456bool iwl_good_ack_health(struct iwl_priv *priv,
457 struct iwl_rx_packet *pkt);
458void iwl_recover_from_statistics(struct iwl_priv *priv, 460void iwl_recover_from_statistics(struct iwl_priv *priv,
459 struct iwl_rx_packet *pkt); 461 struct iwl_rx_packet *pkt);
460void iwl_rx_statistics(struct iwl_priv *priv, 462void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
461 struct iwl_rx_mem_buffer *rxb);
462void iwl_reply_statistics(struct iwl_priv *priv,
463 struct iwl_rx_mem_buffer *rxb);
464void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 463void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
465 464
466/* TX helpers */ 465/* TX helpers */
@@ -474,8 +473,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
474 dma_addr_t addr, u16 len, u8 reset, u8 pad); 473 dma_addr_t addr, u16 len, u8 reset, u8 pad);
475int iwl_hw_tx_queue_init(struct iwl_priv *priv, 474int iwl_hw_tx_queue_init(struct iwl_priv *priv,
476 struct iwl_tx_queue *txq); 475 struct iwl_tx_queue *txq);
477void iwl_free_tfds_in_queue(struct iwl_priv *priv,
478 int sta_id, int tid, int freed);
479void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 476void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
480int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 477int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
481 int slots_num, u32 txq_id); 478 int slots_num, u32 txq_id);
@@ -495,7 +492,7 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
495 492
496u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 493u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
497 494
498u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx); 495u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
499 496
500static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) 497static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
501{ 498{
@@ -528,7 +525,7 @@ void iwl_bg_start_internal_scan(struct work_struct *work);
528void iwl_internal_short_hw_scan(struct iwl_priv *priv); 525void iwl_internal_short_hw_scan(struct iwl_priv *priv);
529int iwl_force_reset(struct iwl_priv *priv, int mode); 526int iwl_force_reset(struct iwl_priv *priv, int mode);
530u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 527u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
531 const u8 *ie, int ie_len, int left); 528 const u8 *ta, const u8 *ie, int ie_len, int left);
532void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 529void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
533u16 iwl_get_active_dwell_time(struct iwl_priv *priv, 530u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
534 enum ieee80211_band band, 531 enum ieee80211_band band,
@@ -595,6 +592,9 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
595} 592}
596 593
597void iwl_bg_monitor_recover(unsigned long data); 594void iwl_bg_monitor_recover(unsigned long data);
595u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
596__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
597 u32 addon, u32 beacon_interval);
598 598
599#ifdef CONFIG_PM 599#ifdef CONFIG_PM
600int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); 600int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
@@ -693,7 +693,6 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
693extern void iwl_send_bt_config(struct iwl_priv *priv); 693extern void iwl_send_bt_config(struct iwl_priv *priv);
694extern int iwl_send_statistics_request(struct iwl_priv *priv, 694extern int iwl_send_statistics_request(struct iwl_priv *priv,
695 u8 flags, bool clear); 695 u8 flags, bool clear);
696extern int iwl_verify_ucode(struct iwl_priv *priv);
697extern int iwl_send_lq_cmd(struct iwl_priv *priv, 696extern int iwl_send_lq_cmd(struct iwl_priv *priv,
698 struct iwl_link_quality_cmd *lq, u8 flags, bool init); 697 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
699void iwl_apm_stop(struct iwl_priv *priv); 698void iwl_apm_stop(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 9659c5d01df9..cee3d12eb383 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -106,27 +106,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
106 .open = iwl_dbgfs_open_file_generic, \ 106 .open = iwl_dbgfs_open_file_generic, \
107}; 107};
108 108
109int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
110{
111 int p = 0;
112
113 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
114 le32_to_cpu(priv->statistics.flag));
115 if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
116 p += scnprintf(buf + p, bufsz - p,
117 "\tStatistics have been cleared\n");
118 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
119 (le32_to_cpu(priv->statistics.flag) &
120 UCODE_STATISTICS_FREQUENCY_MSK)
121 ? "2.4 GHz" : "5.2 GHz");
122 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
123 (le32_to_cpu(priv->statistics.flag) &
124 UCODE_STATISTICS_NARROW_BAND_MSK)
125 ? "enabled" : "disabled");
126 return p;
127}
128EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
129
130static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 109static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
131 char __user *user_buf, 110 char __user *user_buf,
132 size_t count, loff_t *ppos) { 111 size_t count, loff_t *ppos) {
@@ -330,45 +309,35 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
330 309
331 for (i = 0; i < max_sta; i++) { 310 for (i = 0; i < max_sta; i++) {
332 station = &priv->stations[i]; 311 station = &priv->stations[i];
333 if (station->used) { 312 if (!station->used)
334 pos += scnprintf(buf + pos, bufsz - pos, 313 continue;
335 "station %d:\ngeneral data:\n", i+1); 314 pos += scnprintf(buf + pos, bufsz - pos,
336 pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", 315 "station %d - addr: %pM, flags: %#x\n",
337 station->sta.sta.sta_id); 316 i, station->sta.sta.addr,
338 pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", 317 station->sta.station_flags_msk);
339 station->sta.mode); 318 pos += scnprintf(buf + pos, bufsz - pos,
340 pos += scnprintf(buf + pos, bufsz - pos, 319 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
341 "flags: 0x%x\n", 320 pos += scnprintf(buf + pos, bufsz - pos,
342 station->sta.station_flags_msk); 321 "start_idx\tbitmap\t\t\trate_n_flags\n");
343 pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
344 pos += scnprintf(buf + pos, bufsz - pos,
345 "seq_num\t\ttxq_id");
346 pos += scnprintf(buf + pos, bufsz - pos,
347 "\tframe_count\twait_for_ba\t");
348 pos += scnprintf(buf + pos, bufsz - pos,
349 "start_idx\tbitmap0\t");
350 pos += scnprintf(buf + pos, bufsz - pos,
351 "bitmap1\trate_n_flags");
352 pos += scnprintf(buf + pos, bufsz - pos, "\n");
353 322
354 for (j = 0; j < MAX_TID_COUNT; j++) { 323 for (j = 0; j < MAX_TID_COUNT; j++) {
355 pos += scnprintf(buf + pos, bufsz - pos, 324 pos += scnprintf(buf + pos, bufsz - pos,
356 "[%d]:\t\t%u", j, 325 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
357 station->tid[j].seq_number); 326 j, station->tid[j].seq_number,
358 pos += scnprintf(buf + pos, bufsz - pos, 327 station->tid[j].agg.txq_id,
359 "\t%u\t\t%u\t\t%u\t\t", 328 station->tid[j].agg.frame_count,
360 station->tid[j].agg.txq_id, 329 station->tid[j].tfds_in_queue,
361 station->tid[j].agg.frame_count, 330 station->tid[j].agg.start_idx,
362 station->tid[j].agg.wait_for_ba); 331 station->tid[j].agg.bitmap,
332 station->tid[j].agg.rate_n_flags);
333
334 if (station->tid[j].agg.wait_for_ba)
363 pos += scnprintf(buf + pos, bufsz - pos, 335 pos += scnprintf(buf + pos, bufsz - pos,
364 "%u\t%llu\t%u", 336 " - waitforba");
365 station->tid[j].agg.start_idx,
366 (unsigned long long)station->tid[j].agg.bitmap,
367 station->tid[j].agg.rate_n_flags);
368 pos += scnprintf(buf + pos, bufsz - pos, "\n");
369 }
370 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 337 pos += scnprintf(buf + pos, bufsz - pos, "\n");
371 } 338 }
339
340 pos += scnprintf(buf + pos, bufsz - pos, "\n");
372 } 341 }
373 342
374 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 343 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -1049,8 +1018,13 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1049 rxq->write); 1018 rxq->write);
1050 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 1019 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1051 rxq->free_count); 1020 rxq->free_count);
1052 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", 1021 if (rxq->rb_stts) {
1022 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1053 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); 1023 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF);
1024 } else {
1025 pos += scnprintf(buf + pos, bufsz - pos,
1026 "closed_rb_num: Not Allocated\n");
1027 }
1054 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1028 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1055} 1029}
1056 1030
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f3f3473c5c7e..1af845c0f0b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -48,25 +48,6 @@
48#include "iwl-power.h" 48#include "iwl-power.h"
49#include "iwl-agn-rs.h" 49#include "iwl-agn-rs.h"
50 50
51/* configuration for the iwl4965 */
52extern struct iwl_cfg iwl4965_agn_cfg;
53extern struct iwl_cfg iwl5300_agn_cfg;
54extern struct iwl_cfg iwl5100_agn_cfg;
55extern struct iwl_cfg iwl5350_agn_cfg;
56extern struct iwl_cfg iwl5100_bgn_cfg;
57extern struct iwl_cfg iwl5100_abg_cfg;
58extern struct iwl_cfg iwl5150_agn_cfg;
59extern struct iwl_cfg iwl5150_abg_cfg;
60extern struct iwl_cfg iwl6000g2a_2agn_cfg;
61extern struct iwl_cfg iwl6000i_2agn_cfg;
62extern struct iwl_cfg iwl6000i_2abg_cfg;
63extern struct iwl_cfg iwl6000i_2bg_cfg;
64extern struct iwl_cfg iwl6000_3agn_cfg;
65extern struct iwl_cfg iwl6050_2agn_cfg;
66extern struct iwl_cfg iwl6050_2abg_cfg;
67extern struct iwl_cfg iwl1000_bgn_cfg;
68extern struct iwl_cfg iwl1000_bg_cfg;
69
70struct iwl_tx_queue; 51struct iwl_tx_queue;
71 52
72/* CT-KILL constants */ 53/* CT-KILL constants */
@@ -133,8 +114,8 @@ struct iwl_cmd_meta {
133 * structure is stored at the end of the shared queue memory. */ 114 * structure is stored at the end of the shared queue memory. */
134 u32 flags; 115 u32 flags;
135 116
136 DECLARE_PCI_UNMAP_ADDR(mapping) 117 DEFINE_DMA_UNMAP_ADDR(mapping);
137 DECLARE_PCI_UNMAP_LEN(len) 118 DEFINE_DMA_UNMAP_LEN(len);
138}; 119};
139 120
140/* 121/*
@@ -161,7 +142,7 @@ struct iwl_queue {
161 142
162/* One for each TFD */ 143/* One for each TFD */
163struct iwl_tx_info { 144struct iwl_tx_info {
164 struct sk_buff *skb[IWL_NUM_OF_TBS - 1]; 145 struct sk_buff *skb;
165}; 146};
166 147
167/** 148/**
@@ -367,7 +348,7 @@ struct iwl_host_cmd {
367/** 348/**
368 * struct iwl_rx_queue - Rx queue 349 * struct iwl_rx_queue - Rx queue
369 * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) 350 * @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
370 * @dma_addr: bus address of buffer of receive buffer descriptors (rbd) 351 * @bd_dma: bus address of buffer of receive buffer descriptors (rbd)
371 * @read: Shared index to newest available Rx buffer 352 * @read: Shared index to newest available Rx buffer
372 * @write: Shared index to oldest written Rx packet 353 * @write: Shared index to oldest written Rx packet
373 * @free_count: Number of pre-allocated buffers in rx_free 354 * @free_count: Number of pre-allocated buffers in rx_free
@@ -381,7 +362,7 @@ struct iwl_host_cmd {
381 */ 362 */
382struct iwl_rx_queue { 363struct iwl_rx_queue {
383 __le32 *bd; 364 __le32 *bd;
384 dma_addr_t dma_addr; 365 dma_addr_t bd_dma;
385 struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; 366 struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
386 struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; 367 struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
387 u32 read; 368 u32 read;
@@ -433,7 +414,7 @@ struct iwl_ht_agg {
433 414
434 415
435struct iwl_tid_data { 416struct iwl_tid_data {
436 u16 seq_number; 417 u16 seq_number; /* agn only */
437 u16 tfds_in_queue; 418 u16 tfds_in_queue;
438 struct iwl_ht_agg agg; 419 struct iwl_ht_agg agg;
439}; 420};
@@ -583,6 +564,12 @@ enum iwl_ucode_tlv_type {
583 IWL_UCODE_TLV_INIT_DATA = 4, 564 IWL_UCODE_TLV_INIT_DATA = 4,
584 IWL_UCODE_TLV_BOOT = 5, 565 IWL_UCODE_TLV_BOOT = 5,
585 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ 566 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
567 IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8,
568 IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9,
569 IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10,
570 IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11,
571 IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
572 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
586}; 573};
587 574
588struct iwl_ucode_tlv { 575struct iwl_ucode_tlv {
@@ -675,6 +662,7 @@ struct iwl_sensitivity_ranges {
675 * @sw_crypto: 0 for hw, 1 for sw 662 * @sw_crypto: 0 for hw, 1 for sw
676 * @max_xxx_size: for ucode uses 663 * @max_xxx_size: for ucode uses
677 * @ct_kill_threshold: temperature threshold 664 * @ct_kill_threshold: temperature threshold
665 * @beacon_time_tsf_bits: number of valid tsf bits for beacon time
678 * @calib_init_cfg: setup initial calibrations for the hw 666 * @calib_init_cfg: setup initial calibrations for the hw
679 * @struct iwl_sensitivity_ranges: range of sensitivity values 667 * @struct iwl_sensitivity_ranges: range of sensitivity values
680 */ 668 */
@@ -701,6 +689,7 @@ struct iwl_hw_params {
701 u32 ct_kill_threshold; /* value in hw-dependent units */ 689 u32 ct_kill_threshold; /* value in hw-dependent units */
702 u32 ct_kill_exit_threshold; /* value in hw-dependent units */ 690 u32 ct_kill_exit_threshold; /* value in hw-dependent units */
703 /* for 1000, 6000 series and up */ 691 /* for 1000, 6000 series and up */
692 u16 beacon_time_tsf_bits;
704 u32 calib_init_cfg; 693 u32 calib_init_cfg;
705 const struct iwl_sensitivity_ranges *sens; 694 const struct iwl_sensitivity_ranges *sens;
706}; 695};
@@ -1075,6 +1064,20 @@ struct iwl_force_reset {
1075 unsigned long last_force_reset_jiffies; 1064 unsigned long last_force_reset_jiffies;
1076}; 1065};
1077 1066
1067/* extend beacon time format bit shifting */
1068/*
1069 * for _3945 devices
1070 * bits 31:24 - extended
1071 * bits 23:0 - interval
1072 */
1073#define IWL3945_EXT_BEACON_TIME_POS 24
1074/*
1075 * for _agn devices
1076 * bits 31:22 - extended
1077 * bits 21:0 - interval
1078 */
1079#define IWLAGN_EXT_BEACON_TIME_POS 22
1080
1078struct iwl_priv { 1081struct iwl_priv {
1079 1082
1080 /* ieee device used by generic ieee processing code */ 1083 /* ieee device used by generic ieee processing code */
@@ -1109,7 +1112,7 @@ struct iwl_priv {
1109 /* force reset */ 1112 /* force reset */
1110 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; 1113 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
1111 1114
1112 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1115 /* we allocate array of iwl_channel_info for NIC's valid channels.
1113 * Access via channel # using indirect index array */ 1116 * Access via channel # using indirect index array */
1114 struct iwl_channel_info *channel_info; /* channel info array */ 1117 struct iwl_channel_info *channel_info; /* channel info array */
1115 u8 channel_count; /* # of channels */ 1118 u8 channel_count; /* # of channels */
@@ -1127,6 +1130,7 @@ struct iwl_priv {
1127 void *scan_cmd; 1130 void *scan_cmd;
1128 enum ieee80211_band scan_band; 1131 enum ieee80211_band scan_band;
1129 struct cfg80211_scan_request *scan_request; 1132 struct cfg80211_scan_request *scan_request;
1133 struct ieee80211_vif *scan_vif;
1130 bool is_internal_short_scan; 1134 bool is_internal_short_scan;
1131 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 1135 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
1132 u8 mgmt_tx_ant; 1136 u8 mgmt_tx_ant;
@@ -1174,7 +1178,7 @@ struct iwl_priv {
1174 struct iwl_switch_rxon switch_rxon; 1178 struct iwl_switch_rxon switch_rxon;
1175 1179
1176 /* 1st responses from initialize and runtime uCode images. 1180 /* 1st responses from initialize and runtime uCode images.
1177 * 4965's initialize alive response contains some calibration data. */ 1181 * _agn's initialize alive response contains some calibration data. */
1178 struct iwl_init_alive_resp card_alive_init; 1182 struct iwl_init_alive_resp card_alive_init;
1179 struct iwl_alive_resp card_alive; 1183 struct iwl_alive_resp card_alive;
1180 1184
@@ -1220,18 +1224,12 @@ struct iwl_priv {
1220 struct iwl_power_mgr power_data; 1224 struct iwl_power_mgr power_data;
1221 struct iwl_tt_mgmt thermal_throttle; 1225 struct iwl_tt_mgmt thermal_throttle;
1222 1226
1223 struct iwl_notif_statistics statistics;
1224#ifdef CONFIG_IWLWIFI_DEBUG
1225 struct iwl_notif_statistics accum_statistics;
1226 struct iwl_notif_statistics delta_statistics;
1227 struct iwl_notif_statistics max_delta;
1228#endif
1229
1230 /* context information */ 1227 /* context information */
1231 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ 1228 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
1232 u8 mac_addr[ETH_ALEN];
1233 1229
1234 /*station table variables */ 1230 /* station table variables */
1231
1232 /* Note: if lock and sta_lock are needed, lock must be acquired first */
1235 spinlock_t sta_lock; 1233 spinlock_t sta_lock;
1236 int num_stations; 1234 int num_stations;
1237 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1235 struct iwl_station_entry stations[IWL_STATION_COUNT];
@@ -1273,7 +1271,7 @@ struct iwl_priv {
1273 struct delayed_work rfkill_poll; 1271 struct delayed_work rfkill_poll;
1274 1272
1275 struct iwl3945_notif_statistics statistics; 1273 struct iwl3945_notif_statistics statistics;
1276#ifdef CONFIG_IWLWIFI_DEBUG 1274#ifdef CONFIG_IWLWIFI_DEBUGFS
1277 struct iwl3945_notif_statistics accum_statistics; 1275 struct iwl3945_notif_statistics accum_statistics;
1278 struct iwl3945_notif_statistics delta_statistics; 1276 struct iwl3945_notif_statistics delta_statistics;
1279 struct iwl3945_notif_statistics max_delta; 1277 struct iwl3945_notif_statistics max_delta;
@@ -1315,6 +1313,16 @@ struct iwl_priv {
1315 bool last_phy_res_valid; 1313 bool last_phy_res_valid;
1316 1314
1317 struct completion firmware_loading_complete; 1315 struct completion firmware_loading_complete;
1316
1317 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1318 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1319
1320 struct iwl_notif_statistics statistics;
1321#ifdef CONFIG_IWLWIFI_DEBUGFS
1322 struct iwl_notif_statistics accum_statistics;
1323 struct iwl_notif_statistics delta_statistics;
1324 struct iwl_notif_statistics max_delta;
1325#endif
1318 } _agn; 1326 } _agn;
1319#endif 1327#endif
1320 }; 1328 };
@@ -1353,9 +1361,7 @@ struct iwl_priv {
1353 /* debugging info */ 1361 /* debugging info */
1354 u32 debug_level; /* per device debugging will override global 1362 u32 debug_level; /* per device debugging will override global
1355 iwl_debug_level if set */ 1363 iwl_debug_level if set */
1356 u32 framecnt_to_us; 1364#endif /* CONFIG_IWLWIFI_DEBUG */
1357 atomic_t restrict_refcnt;
1358 bool disable_ht40;
1359#ifdef CONFIG_IWLWIFI_DEBUGFS 1365#ifdef CONFIG_IWLWIFI_DEBUGFS
1360 /* debugfs */ 1366 /* debugfs */
1361 u16 tx_traffic_idx; 1367 u16 tx_traffic_idx;
@@ -1364,8 +1370,8 @@ struct iwl_priv {
1364 u8 *rx_traffic; 1370 u8 *rx_traffic;
1365 struct dentry *debugfs_dir; 1371 struct dentry *debugfs_dir;
1366 u32 dbgfs_sram_offset, dbgfs_sram_len; 1372 u32 dbgfs_sram_offset, dbgfs_sram_len;
1373 bool disable_ht40;
1367#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1374#endif /* CONFIG_IWLWIFI_DEBUGFS */
1368#endif /* CONFIG_IWLWIFI_DEBUG */
1369 1375
1370 struct work_struct txpower_work; 1376 struct work_struct txpower_work;
1371 u32 disable_sens_cal; 1377 u32 disable_sens_cal;
@@ -1419,9 +1425,9 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
1419static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, 1425static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
1420 int txq_id, int idx) 1426 int txq_id, int idx)
1421{ 1427{
1422 if (priv->txq[txq_id].txb[idx].skb[0]) 1428 if (priv->txq[txq_id].txb[idx].skb)
1423 return (struct ieee80211_hdr *)priv->txq[txq_id]. 1429 return (struct ieee80211_hdr *)priv->txq[txq_id].
1424 txb[idx].skb[0]->data; 1430 txb[idx].skb->data;
1425 return NULL; 1431 return NULL;
1426} 1432}
1427 1433
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 3ff6b9d25a10..621abe3c5afc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -92,6 +92,11 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
92static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, 92static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
93 struct fw_desc *desc) 93 struct fw_desc *desc)
94{ 94{
95 if (!desc->len) {
96 desc->v_addr = NULL;
97 return -EINVAL;
98 }
99
95 desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, 100 desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
96 &desc->p_addr, GFP_KERNEL); 101 &desc->p_addr, GFP_KERNEL);
97 return (desc->v_addr != NULL) ? 0 : -ENOMEM; 102 return (desc->v_addr != NULL) ? 0 : -ENOMEM;
@@ -170,4 +175,26 @@ static inline void iwl_enable_interrupts(struct iwl_priv *priv)
170 iwl_write32(priv, CSR_INT_MASK, priv->inta_mask); 175 iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
171} 176}
172 177
178/**
179 * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
180 * @priv -- pointer to iwl_priv data structure
181 * @tsf_bits -- number of bits need to shift for masking)
182 */
183static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
184 u16 tsf_bits)
185{
186 return (1 << tsf_bits) - 1;
187}
188
189/**
190 * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
191 * @priv -- pointer to iwl_priv data structure
192 * @tsf_bits -- number of bits need to shift for masking)
193 */
194static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
195 u16 tsf_bits)
196{
197 return ((1 << (32 - tsf_bits)) - 1) << tsf_bits;
198}
199
173#endif /* __iwl_helpers_h__ */ 200#endif /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 0a5d7cf25196..b437f317b979 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -175,7 +175,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
175 INIT_LIST_HEAD(&rxq->rx_used); 175 INIT_LIST_HEAD(&rxq->rx_used);
176 176
177 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ 177 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
178 rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr, 178 rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
179 GFP_KERNEL); 179 GFP_KERNEL);
180 if (!rxq->bd) 180 if (!rxq->bd)
181 goto err_bd; 181 goto err_bd;
@@ -199,32 +199,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
199 199
200err_rb: 200err_rb:
201 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, 201 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
202 rxq->dma_addr); 202 rxq->bd_dma);
203err_bd: 203err_bd:
204 return -ENOMEM; 204 return -ENOMEM;
205} 205}
206EXPORT_SYMBOL(iwl_rx_queue_alloc); 206EXPORT_SYMBOL(iwl_rx_queue_alloc);
207 207
208void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
209 struct iwl_rx_mem_buffer *rxb)
210
211{
212 struct iwl_rx_packet *pkt = rxb_addr(rxb);
213 struct iwl_missed_beacon_notif *missed_beacon;
214
215 missed_beacon = &pkt->u.missed_beacon;
216 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
217 priv->missed_beacon_threshold) {
218 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
219 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
220 le32_to_cpu(missed_beacon->total_missed_becons),
221 le32_to_cpu(missed_beacon->num_recvd_beacons),
222 le32_to_cpu(missed_beacon->num_expected_beacons));
223 if (!test_bit(STATUS_SCANNING, &priv->status))
224 iwl_init_sensitivity(priv);
225 }
226}
227EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
228 208
229void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 209void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
230 struct iwl_rx_mem_buffer *rxb) 210 struct iwl_rx_mem_buffer *rxb)
@@ -243,161 +223,6 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
243} 223}
244EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); 224EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
245 225
246
247
248/* Calculate noise level, based on measurements during network silence just
249 * before arriving beacon. This measurement can be done only if we know
250 * exactly when to expect beacons, therefore only when we're associated. */
251static void iwl_rx_calc_noise(struct iwl_priv *priv)
252{
253 struct statistics_rx_non_phy *rx_info
254 = &(priv->statistics.rx.general);
255 int num_active_rx = 0;
256 int total_silence = 0;
257 int bcn_silence_a =
258 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
259 int bcn_silence_b =
260 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
261 int bcn_silence_c =
262 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
263 int last_rx_noise;
264
265 if (bcn_silence_a) {
266 total_silence += bcn_silence_a;
267 num_active_rx++;
268 }
269 if (bcn_silence_b) {
270 total_silence += bcn_silence_b;
271 num_active_rx++;
272 }
273 if (bcn_silence_c) {
274 total_silence += bcn_silence_c;
275 num_active_rx++;
276 }
277
278 /* Average among active antennas */
279 if (num_active_rx)
280 last_rx_noise = (total_silence / num_active_rx) - 107;
281 else
282 last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
283
284 IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
285 bcn_silence_a, bcn_silence_b, bcn_silence_c,
286 last_rx_noise);
287}
288
289#ifdef CONFIG_IWLWIFI_DEBUG
290/*
291 * based on the assumption of all statistics counter are in DWORD
292 * FIXME: This function is for debugging, do not deal with
293 * the case of counters roll-over.
294 */
295static void iwl_accumulative_statistics(struct iwl_priv *priv,
296 __le32 *stats)
297{
298 int i;
299 __le32 *prev_stats;
300 u32 *accum_stats;
301 u32 *delta, *max_delta;
302
303 prev_stats = (__le32 *)&priv->statistics;
304 accum_stats = (u32 *)&priv->accum_statistics;
305 delta = (u32 *)&priv->delta_statistics;
306 max_delta = (u32 *)&priv->max_delta;
307
308 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
309 i += sizeof(__le32), stats++, prev_stats++, delta++,
310 max_delta++, accum_stats++) {
311 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
312 *delta = (le32_to_cpu(*stats) -
313 le32_to_cpu(*prev_stats));
314 *accum_stats += *delta;
315 if (*delta > *max_delta)
316 *max_delta = *delta;
317 }
318 }
319
320 /* reset accumulative statistics for "no-counter" type statistics */
321 priv->accum_statistics.general.temperature =
322 priv->statistics.general.temperature;
323 priv->accum_statistics.general.temperature_m =
324 priv->statistics.general.temperature_m;
325 priv->accum_statistics.general.ttl_timestamp =
326 priv->statistics.general.ttl_timestamp;
327 priv->accum_statistics.tx.tx_power.ant_a =
328 priv->statistics.tx.tx_power.ant_a;
329 priv->accum_statistics.tx.tx_power.ant_b =
330 priv->statistics.tx.tx_power.ant_b;
331 priv->accum_statistics.tx.tx_power.ant_c =
332 priv->statistics.tx.tx_power.ant_c;
333}
334#endif
335
336#define REG_RECALIB_PERIOD (60)
337
338/**
339 * iwl_good_plcp_health - checks for plcp error.
340 *
341 * When the plcp error is exceeding the thresholds, reset the radio
342 * to improve the throughput.
343 */
344bool iwl_good_plcp_health(struct iwl_priv *priv,
345 struct iwl_rx_packet *pkt)
346{
347 bool rc = true;
348 int combined_plcp_delta;
349 unsigned int plcp_msec;
350 unsigned long plcp_received_jiffies;
351
352 /*
353 * check for plcp_err and trigger radio reset if it exceeds
354 * the plcp error threshold plcp_delta.
355 */
356 plcp_received_jiffies = jiffies;
357 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
358 (long) priv->plcp_jiffies);
359 priv->plcp_jiffies = plcp_received_jiffies;
360 /*
361 * check to make sure plcp_msec is not 0 to prevent division
362 * by zero.
363 */
364 if (plcp_msec) {
365 combined_plcp_delta =
366 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
367 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
368 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
369 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
370
371 if ((combined_plcp_delta > 0) &&
372 ((combined_plcp_delta * 100) / plcp_msec) >
373 priv->cfg->plcp_delta_threshold) {
374 /*
375 * if plcp_err exceed the threshold,
376 * the following data is printed in csv format:
377 * Text: plcp_err exceeded %d,
378 * Received ofdm.plcp_err,
379 * Current ofdm.plcp_err,
380 * Received ofdm_ht.plcp_err,
381 * Current ofdm_ht.plcp_err,
382 * combined_plcp_delta,
383 * plcp_msec
384 */
385 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
386 "%u, %u, %u, %u, %d, %u mSecs\n",
387 priv->cfg->plcp_delta_threshold,
388 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
389 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
390 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
391 le32_to_cpu(
392 priv->statistics.rx.ofdm_ht.plcp_err),
393 combined_plcp_delta, plcp_msec);
394 rc = false;
395 }
396 }
397 return rc;
398}
399EXPORT_SYMBOL(iwl_good_plcp_health);
400
401void iwl_recover_from_statistics(struct iwl_priv *priv, 226void iwl_recover_from_statistics(struct iwl_priv *priv,
402 struct iwl_rx_packet *pkt) 227 struct iwl_rx_packet *pkt)
403{ 228{
@@ -431,69 +256,6 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
431} 256}
432EXPORT_SYMBOL(iwl_recover_from_statistics); 257EXPORT_SYMBOL(iwl_recover_from_statistics);
433 258
434void iwl_rx_statistics(struct iwl_priv *priv,
435 struct iwl_rx_mem_buffer *rxb)
436{
437 int change;
438 struct iwl_rx_packet *pkt = rxb_addr(rxb);
439
440
441 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
442 (int)sizeof(priv->statistics),
443 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
444
445 change = ((priv->statistics.general.temperature !=
446 pkt->u.stats.general.temperature) ||
447 ((priv->statistics.flag &
448 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
449 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
450
451#ifdef CONFIG_IWLWIFI_DEBUG
452 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
453#endif
454 iwl_recover_from_statistics(priv, pkt);
455
456 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
457
458 set_bit(STATUS_STATISTICS, &priv->status);
459
460 /* Reschedule the statistics timer to occur in
461 * REG_RECALIB_PERIOD seconds to ensure we get a
462 * thermal update even if the uCode doesn't give
463 * us one */
464 mod_timer(&priv->statistics_periodic, jiffies +
465 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
466
467 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
468 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
469 iwl_rx_calc_noise(priv);
470 queue_work(priv->workqueue, &priv->run_time_calib_work);
471 }
472 if (priv->cfg->ops->lib->temp_ops.temperature && change)
473 priv->cfg->ops->lib->temp_ops.temperature(priv);
474}
475EXPORT_SYMBOL(iwl_rx_statistics);
476
477void iwl_reply_statistics(struct iwl_priv *priv,
478 struct iwl_rx_mem_buffer *rxb)
479{
480 struct iwl_rx_packet *pkt = rxb_addr(rxb);
481
482 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
483#ifdef CONFIG_IWLWIFI_DEBUG
484 memset(&priv->accum_statistics, 0,
485 sizeof(struct iwl_notif_statistics));
486 memset(&priv->delta_statistics, 0,
487 sizeof(struct iwl_notif_statistics));
488 memset(&priv->max_delta, 0,
489 sizeof(struct iwl_notif_statistics));
490#endif
491 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
492 }
493 iwl_rx_statistics(priv, rxb);
494}
495EXPORT_SYMBOL(iwl_reply_statistics);
496
497/* 259/*
498 * returns non-zero if packet should be dropped 260 * returns non-zero if packet should be dropped
499 */ 261 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 386c5f96eff8..798f93e0ff50 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -333,7 +333,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
333 goto out_unlock; 333 goto out_unlock;
334 } 334 }
335 335
336 if (test_bit(STATUS_SCANNING, &priv->status)) { 336 if (test_bit(STATUS_SCANNING, &priv->status) &&
337 !priv->is_internal_short_scan) {
337 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); 338 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
338 ret = -EAGAIN; 339 ret = -EAGAIN;
339 goto out_unlock; 340 goto out_unlock;
@@ -348,8 +349,16 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
348 /* mac80211 will only ask for one band at a time */ 349 /* mac80211 will only ask for one band at a time */
349 priv->scan_band = req->channels[0]->band; 350 priv->scan_band = req->channels[0]->band;
350 priv->scan_request = req; 351 priv->scan_request = req;
352 priv->scan_vif = vif;
351 353
352 ret = iwl_scan_initiate(priv, vif); 354 /*
355 * If an internal scan is in progress, just set
356 * up the scan_request as per above.
357 */
358 if (priv->is_internal_short_scan)
359 ret = 0;
360 else
361 ret = iwl_scan_initiate(priv, vif);
353 362
354 IWL_DEBUG_MAC80211(priv, "leave\n"); 363 IWL_DEBUG_MAC80211(priv, "leave\n");
355 364
@@ -438,7 +447,7 @@ EXPORT_SYMBOL(iwl_bg_scan_check);
438 */ 447 */
439 448
440u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 449u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
441 const u8 *ies, int ie_len, int left) 450 const u8 *ta, const u8 *ies, int ie_len, int left)
442{ 451{
443 int len = 0; 452 int len = 0;
444 u8 *pos = NULL; 453 u8 *pos = NULL;
@@ -451,7 +460,7 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
451 460
452 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 461 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
453 memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); 462 memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
454 memcpy(frame->sa, priv->mac_addr, ETH_ALEN); 463 memcpy(frame->sa, ta, ETH_ALEN);
455 memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); 464 memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
456 frame->seq_ctrl = 0; 465 frame->seq_ctrl = 0;
457 466
@@ -514,7 +523,21 @@ void iwl_bg_scan_completed(struct work_struct *work)
514 priv->is_internal_short_scan = false; 523 priv->is_internal_short_scan = false;
515 IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); 524 IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
516 internal = true; 525 internal = true;
526 } else {
527 priv->scan_request = NULL;
528 priv->scan_vif = NULL;
517 } 529 }
530
531 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
532 goto out;
533
534 if (internal && priv->scan_request)
535 iwl_scan_initiate(priv, priv->scan_vif);
536
537 /* Since setting the TXPOWER may have been deferred while
538 * performing the scan, fire one off */
539 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
540 out:
518 mutex_unlock(&priv->mutex); 541 mutex_unlock(&priv->mutex);
519 542
520 /* 543 /*
@@ -524,15 +547,6 @@ void iwl_bg_scan_completed(struct work_struct *work)
524 */ 547 */
525 if (!internal) 548 if (!internal)
526 ieee80211_scan_completed(priv->hw, false); 549 ieee80211_scan_completed(priv->hw, false);
527
528 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
529 return;
530
531 /* Since setting the TXPOWER may have been deferred while
532 * performing the scan, fire one off */
533 mutex_lock(&priv->mutex);
534 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
535 mutex_unlock(&priv->mutex);
536} 550}
537EXPORT_SYMBOL(iwl_bg_scan_completed); 551EXPORT_SYMBOL(iwl_bg_scan_completed);
538 552
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index c27c13fbb1ae..6a9cd08bd449 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -30,6 +30,7 @@
30#include <net/mac80211.h> 30#include <net/mac80211.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/lockdep.h>
33 34
34#include "iwl-dev.h" 35#include "iwl-dev.h"
35#include "iwl-core.h" 36#include "iwl-core.h"
@@ -54,18 +55,19 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
54 } 55 }
55} 56}
56 57
57static void iwl_process_add_sta_resp(struct iwl_priv *priv, 58static int iwl_process_add_sta_resp(struct iwl_priv *priv,
58 struct iwl_addsta_cmd *addsta, 59 struct iwl_addsta_cmd *addsta,
59 struct iwl_rx_packet *pkt, 60 struct iwl_rx_packet *pkt,
60 bool sync) 61 bool sync)
61{ 62{
62 u8 sta_id = addsta->sta.sta_id; 63 u8 sta_id = addsta->sta.sta_id;
63 unsigned long flags; 64 unsigned long flags;
65 int ret = -EIO;
64 66
65 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 67 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
66 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 68 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
67 pkt->hdr.flags); 69 pkt->hdr.flags);
68 return; 70 return ret;
69 } 71 }
70 72
71 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", 73 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
@@ -77,6 +79,7 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
77 case ADD_STA_SUCCESS_MSK: 79 case ADD_STA_SUCCESS_MSK:
78 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); 80 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
79 iwl_sta_ucode_activate(priv, sta_id); 81 iwl_sta_ucode_activate(priv, sta_id);
82 ret = 0;
80 break; 83 break;
81 case ADD_STA_NO_ROOM_IN_TABLE: 84 case ADD_STA_NO_ROOM_IN_TABLE:
82 IWL_ERR(priv, "Adding station %d failed, no room in table.\n", 85 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
@@ -114,6 +117,8 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
114 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 117 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
115 addsta->sta.addr); 118 addsta->sta.addr);
116 spin_unlock_irqrestore(&priv->sta_lock, flags); 119 spin_unlock_irqrestore(&priv->sta_lock, flags);
120
121 return ret;
117} 122}
118 123
119static void iwl_add_sta_callback(struct iwl_priv *priv, 124static void iwl_add_sta_callback(struct iwl_priv *priv,
@@ -145,8 +150,10 @@ int iwl_send_add_sta(struct iwl_priv *priv,
145 150
146 if (flags & CMD_ASYNC) 151 if (flags & CMD_ASYNC)
147 cmd.callback = iwl_add_sta_callback; 152 cmd.callback = iwl_add_sta_callback;
148 else 153 else {
149 cmd.flags |= CMD_WANT_SKB; 154 cmd.flags |= CMD_WANT_SKB;
155 might_sleep();
156 }
150 157
151 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); 158 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
152 ret = iwl_send_cmd(priv, &cmd); 159 ret = iwl_send_cmd(priv, &cmd);
@@ -156,7 +163,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
156 163
157 if (ret == 0) { 164 if (ret == 0) {
158 pkt = (struct iwl_rx_packet *)cmd.reply_page; 165 pkt = (struct iwl_rx_packet *)cmd.reply_page;
159 iwl_process_add_sta_resp(priv, sta, pkt, true); 166 ret = iwl_process_add_sta_resp(priv, sta, pkt, true);
160 } 167 }
161 iwl_free_pages(priv, cmd.reply_page); 168 iwl_free_pages(priv, cmd.reply_page);
162 169
@@ -311,10 +318,10 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
311 struct ieee80211_sta_ht_cap *ht_info, 318 struct ieee80211_sta_ht_cap *ht_info,
312 u8 *sta_id_r) 319 u8 *sta_id_r)
313{ 320{
314 struct iwl_station_entry *station;
315 unsigned long flags_spin; 321 unsigned long flags_spin;
316 int ret = 0; 322 int ret = 0;
317 u8 sta_id; 323 u8 sta_id;
324 struct iwl_addsta_cmd sta_cmd;
318 325
319 *sta_id_r = 0; 326 *sta_id_r = 0;
320 spin_lock_irqsave(&priv->sta_lock, flags_spin); 327 spin_lock_irqsave(&priv->sta_lock, flags_spin);
@@ -347,14 +354,15 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
347 } 354 }
348 355
349 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; 356 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
350 station = &priv->stations[sta_id]; 357 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
351 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 358 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
352 359
353 /* Add station to device's station table */ 360 /* Add station to device's station table */
354 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC); 361 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
355 if (ret) { 362 if (ret) {
356 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
357 spin_lock_irqsave(&priv->sta_lock, flags_spin); 363 spin_lock_irqsave(&priv->sta_lock, flags_spin);
364 IWL_ERR(priv, "Adding station %pM failed.\n",
365 priv->stations[sta_id].sta.sta.addr);
358 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 366 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
359 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; 367 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
360 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 368 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -488,7 +496,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
488} 496}
489 497
490static int iwl_send_remove_station(struct iwl_priv *priv, 498static int iwl_send_remove_station(struct iwl_priv *priv,
491 struct iwl_station_entry *station) 499 const u8 *addr, int sta_id)
492{ 500{
493 struct iwl_rx_packet *pkt; 501 struct iwl_rx_packet *pkt;
494 int ret; 502 int ret;
@@ -505,7 +513,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
505 513
506 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 514 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
507 rm_sta_cmd.num_sta = 1; 515 rm_sta_cmd.num_sta = 1;
508 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN); 516 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
509 517
510 cmd.flags |= CMD_WANT_SKB; 518 cmd.flags |= CMD_WANT_SKB;
511 519
@@ -525,7 +533,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
525 switch (pkt->u.rem_sta.status) { 533 switch (pkt->u.rem_sta.status) {
526 case REM_STA_SUCCESS_MSK: 534 case REM_STA_SUCCESS_MSK:
527 spin_lock_irqsave(&priv->sta_lock, flags_spin); 535 spin_lock_irqsave(&priv->sta_lock, flags_spin);
528 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id); 536 iwl_sta_ucode_deactivate(priv, sta_id);
529 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 537 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
530 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 538 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
531 break; 539 break;
@@ -546,7 +554,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
546int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, 554int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
547 const u8 *addr) 555 const u8 *addr)
548{ 556{
549 struct iwl_station_entry *station;
550 unsigned long flags; 557 unsigned long flags;
551 558
552 if (!iwl_is_ready(priv)) { 559 if (!iwl_is_ready(priv)) {
@@ -592,10 +599,9 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
592 599
593 BUG_ON(priv->num_stations < 0); 600 BUG_ON(priv->num_stations < 0);
594 601
595 station = &priv->stations[sta_id];
596 spin_unlock_irqrestore(&priv->sta_lock, flags); 602 spin_unlock_irqrestore(&priv->sta_lock, flags);
597 603
598 return iwl_send_remove_station(priv, station); 604 return iwl_send_remove_station(priv, addr, sta_id);
599out_err: 605out_err:
600 spin_unlock_irqrestore(&priv->sta_lock, flags); 606 spin_unlock_irqrestore(&priv->sta_lock, flags);
601 return -EINVAL; 607 return -EINVAL;
@@ -643,11 +649,13 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
643 */ 649 */
644void iwl_restore_stations(struct iwl_priv *priv) 650void iwl_restore_stations(struct iwl_priv *priv)
645{ 651{
646 struct iwl_station_entry *station; 652 struct iwl_addsta_cmd sta_cmd;
653 struct iwl_link_quality_cmd lq;
647 unsigned long flags_spin; 654 unsigned long flags_spin;
648 int i; 655 int i;
649 bool found = false; 656 bool found = false;
650 int ret; 657 int ret;
658 bool send_lq;
651 659
652 if (!iwl_is_ready(priv)) { 660 if (!iwl_is_ready(priv)) {
653 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); 661 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
@@ -669,13 +677,20 @@ void iwl_restore_stations(struct iwl_priv *priv)
669 677
670 for (i = 0; i < priv->hw_params.max_stations; i++) { 678 for (i = 0; i < priv->hw_params.max_stations; i++) {
671 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { 679 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
680 memcpy(&sta_cmd, &priv->stations[i].sta,
681 sizeof(struct iwl_addsta_cmd));
682 send_lq = false;
683 if (priv->stations[i].lq) {
684 memcpy(&lq, priv->stations[i].lq,
685 sizeof(struct iwl_link_quality_cmd));
686 send_lq = true;
687 }
672 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 688 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
673 station = &priv->stations[i]; 689 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
674 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
675 if (ret) { 690 if (ret) {
676 IWL_ERR(priv, "Adding station %pM failed.\n",
677 station->sta.sta.addr);
678 spin_lock_irqsave(&priv->sta_lock, flags_spin); 691 spin_lock_irqsave(&priv->sta_lock, flags_spin);
692 IWL_ERR(priv, "Adding station %pM failed.\n",
693 priv->stations[i].sta.sta.addr);
679 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; 694 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
680 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 695 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
681 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 696 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -684,8 +699,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
684 * Rate scaling has already been initialized, send 699 * Rate scaling has already been initialized, send
685 * current LQ command 700 * current LQ command
686 */ 701 */
687 if (station->lq) 702 if (send_lq)
688 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true); 703 iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true);
689 spin_lock_irqsave(&priv->sta_lock, flags_spin); 704 spin_lock_irqsave(&priv->sta_lock, flags_spin);
690 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 705 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
691 } 706 }
@@ -823,7 +838,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
823{ 838{
824 unsigned long flags; 839 unsigned long flags;
825 __le16 key_flags = 0; 840 __le16 key_flags = 0;
826 int ret; 841 struct iwl_addsta_cmd sta_cmd;
842
843 lockdep_assert_held(&priv->mutex);
827 844
828 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; 845 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
829 846
@@ -863,11 +880,10 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
863 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 880 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
864 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 881 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
865 882
866 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 883 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
867
868 spin_unlock_irqrestore(&priv->sta_lock, flags); 884 spin_unlock_irqrestore(&priv->sta_lock, flags);
869 885
870 return ret; 886 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
871} 887}
872 888
873static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, 889static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
@@ -876,7 +892,9 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
876{ 892{
877 unsigned long flags; 893 unsigned long flags;
878 __le16 key_flags = 0; 894 __le16 key_flags = 0;
879 int ret; 895 struct iwl_addsta_cmd sta_cmd;
896
897 lockdep_assert_held(&priv->mutex);
880 898
881 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); 899 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
882 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 900 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
@@ -911,11 +929,10 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
911 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 929 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
912 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 930 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
913 931
914 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 932 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
915
916 spin_unlock_irqrestore(&priv->sta_lock, flags); 933 spin_unlock_irqrestore(&priv->sta_lock, flags);
917 934
918 return ret; 935 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
919} 936}
920 937
921static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, 938static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
@@ -972,24 +989,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
972 unsigned long flags; 989 unsigned long flags;
973 int i; 990 int i;
974 991
975 if (sta) {
976 sta_id = iwl_sta_id(sta);
977
978 if (sta_id == IWL_INVALID_STATION) {
979 IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
980 sta->addr);
981 return;
982 }
983 } else
984 sta_id = priv->hw_params.bcast_sta_id;
985
986
987 if (iwl_scan_cancel(priv)) { 992 if (iwl_scan_cancel(priv)) {
988 /* cancel scan failed, just live w/ bad key and rely 993 /* cancel scan failed, just live w/ bad key and rely
989 briefly on SW decryption */ 994 briefly on SW decryption */
990 return; 995 return;
991 } 996 }
992 997
998 sta_id = iwl_sta_id_or_broadcast(priv, sta);
999 if (sta_id == IWL_INVALID_STATION)
1000 return;
1001
993 spin_lock_irqsave(&priv->sta_lock, flags); 1002 spin_lock_irqsave(&priv->sta_lock, flags);
994 1003
995 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; 1004 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
@@ -1013,9 +1022,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
1013 u8 sta_id) 1022 u8 sta_id)
1014{ 1023{
1015 unsigned long flags; 1024 unsigned long flags;
1016 int ret = 0;
1017 u16 key_flags; 1025 u16 key_flags;
1018 u8 keyidx; 1026 u8 keyidx;
1027 struct iwl_addsta_cmd sta_cmd;
1028
1029 lockdep_assert_held(&priv->mutex);
1019 1030
1020 priv->key_mapping_key--; 1031 priv->key_mapping_key--;
1021 1032
@@ -1062,9 +1073,10 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
1062 spin_unlock_irqrestore(&priv->sta_lock, flags); 1073 spin_unlock_irqrestore(&priv->sta_lock, flags);
1063 return 0; 1074 return 0;
1064 } 1075 }
1065 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1076 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1066 spin_unlock_irqrestore(&priv->sta_lock, flags); 1077 spin_unlock_irqrestore(&priv->sta_lock, flags);
1067 return ret; 1078
1079 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1068} 1080}
1069EXPORT_SYMBOL(iwl_remove_dynamic_key); 1081EXPORT_SYMBOL(iwl_remove_dynamic_key);
1070 1082
@@ -1073,6 +1085,8 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
1073{ 1085{
1074 int ret; 1086 int ret;
1075 1087
1088 lockdep_assert_held(&priv->mutex);
1089
1076 priv->key_mapping_key++; 1090 priv->key_mapping_key++;
1077 keyconf->hw_key_idx = HW_KEY_DYNAMIC; 1091 keyconf->hw_key_idx = HW_KEY_DYNAMIC;
1078 1092
@@ -1268,18 +1282,22 @@ EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station);
1268/** 1282/**
1269 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table 1283 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
1270 */ 1284 */
1271void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) 1285int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
1272{ 1286{
1273 unsigned long flags; 1287 unsigned long flags;
1288 struct iwl_addsta_cmd sta_cmd;
1289
1290 lockdep_assert_held(&priv->mutex);
1274 1291
1275 /* Remove "disable" flag, to enable Tx for this TID */ 1292 /* Remove "disable" flag, to enable Tx for this TID */
1276 spin_lock_irqsave(&priv->sta_lock, flags); 1293 spin_lock_irqsave(&priv->sta_lock, flags);
1277 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; 1294 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
1278 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); 1295 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
1279 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1296 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1297 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1280 spin_unlock_irqrestore(&priv->sta_lock, flags); 1298 spin_unlock_irqrestore(&priv->sta_lock, flags);
1281 1299
1282 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1300 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1283} 1301}
1284EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1302EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1285 1303
@@ -1288,6 +1306,9 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
1288{ 1306{
1289 unsigned long flags; 1307 unsigned long flags;
1290 int sta_id; 1308 int sta_id;
1309 struct iwl_addsta_cmd sta_cmd;
1310
1311 lockdep_assert_held(&priv->mutex);
1291 1312
1292 sta_id = iwl_sta_id(sta); 1313 sta_id = iwl_sta_id(sta);
1293 if (sta_id == IWL_INVALID_STATION) 1314 if (sta_id == IWL_INVALID_STATION)
@@ -1299,10 +1320,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
1299 priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; 1320 priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
1300 priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); 1321 priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
1301 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1322 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1323 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1302 spin_unlock_irqrestore(&priv->sta_lock, flags); 1324 spin_unlock_irqrestore(&priv->sta_lock, flags);
1303 1325
1304 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1326 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1305 CMD_ASYNC);
1306} 1327}
1307EXPORT_SYMBOL(iwl_sta_rx_agg_start); 1328EXPORT_SYMBOL(iwl_sta_rx_agg_start);
1308 1329
@@ -1311,6 +1332,9 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1311{ 1332{
1312 unsigned long flags; 1333 unsigned long flags;
1313 int sta_id; 1334 int sta_id;
1335 struct iwl_addsta_cmd sta_cmd;
1336
1337 lockdep_assert_held(&priv->mutex);
1314 1338
1315 sta_id = iwl_sta_id(sta); 1339 sta_id = iwl_sta_id(sta);
1316 if (sta_id == IWL_INVALID_STATION) { 1340 if (sta_id == IWL_INVALID_STATION) {
@@ -1323,10 +1347,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1323 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 1347 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
1324 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; 1348 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
1325 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1349 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1350 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
1326 spin_unlock_irqrestore(&priv->sta_lock, flags); 1351 spin_unlock_irqrestore(&priv->sta_lock, flags);
1327 1352
1328 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1353 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
1329 CMD_ASYNC);
1330} 1354}
1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop); 1355EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1332 1356
@@ -1340,9 +1364,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1340 priv->stations[sta_id].sta.sta.modify_mask = 0; 1364 priv->stations[sta_id].sta.sta.modify_mask = 0;
1341 priv->stations[sta_id].sta.sleep_tx_count = 0; 1365 priv->stations[sta_id].sta.sleep_tx_count = 0;
1342 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1366 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1367 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1343 spin_unlock_irqrestore(&priv->sta_lock, flags); 1368 spin_unlock_irqrestore(&priv->sta_lock, flags);
1344 1369
1345 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1346} 1370}
1347EXPORT_SYMBOL(iwl_sta_modify_ps_wake); 1371EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
1348 1372
@@ -1357,9 +1381,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1357 STA_MODIFY_SLEEP_TX_COUNT_MSK; 1381 STA_MODIFY_SLEEP_TX_COUNT_MSK;
1358 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); 1382 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
1359 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1383 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1384 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1360 spin_unlock_irqrestore(&priv->sta_lock, flags); 1385 spin_unlock_irqrestore(&priv->sta_lock, flags);
1361 1386
1362 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1363} 1387}
1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); 1388EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1365 1389
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index c2a453a1a991..619bb99d85cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -73,7 +73,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
73 const u8 *addr); 73 const u8 *addr);
74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
75 struct ieee80211_sta *sta); 75 struct ieee80211_sta *sta);
76void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 76int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
77int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, 77int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
78 int tid, u16 ssn); 78 int tid, u16 ssn);
79int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, 79int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
@@ -107,4 +107,33 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
107 107
108 return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id; 108 return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
109} 109}
110
111/**
112 * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
113 * @priv: iwl priv
114 * @sta: mac80211 station
115 *
116 * In certain circumstances mac80211 passes a station pointer
117 * that may be %NULL, for example during TX or key setup. In
118 * that case, we need to use the broadcast station, so this
119 * inline wraps that pattern.
120 */
121static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
122 struct ieee80211_sta *sta)
123{
124 int sta_id;
125
126 if (!sta)
127 return priv->hw_params.bcast_sta_id;
128
129 sta_id = iwl_sta_id(sta);
130
131 /*
132 * mac80211 should not be passing a partially
133 * initialised station!
134 */
135 WARN_ON(sta_id == IWL_INVALID_STATION);
136
137 return sta_id;
138}
110#endif /* __iwl_sta_h__ */ 139#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1ece2ea09773..a81989c06983 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -77,21 +77,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
77} 77}
78EXPORT_SYMBOL(iwl_txq_update_write_ptr); 78EXPORT_SYMBOL(iwl_txq_update_write_ptr);
79 79
80
81void iwl_free_tfds_in_queue(struct iwl_priv *priv,
82 int sta_id, int tid, int freed)
83{
84 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
85 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
86 else {
87 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
88 priv->stations[sta_id].tid[tid].tfds_in_queue,
89 freed);
90 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
91 }
92}
93EXPORT_SYMBOL(iwl_free_tfds_in_queue);
94
95/** 80/**
96 * iwl_tx_queue_free - Deallocate DMA queue. 81 * iwl_tx_queue_free - Deallocate DMA queue.
97 * @txq: Transmit queue to deallocate. 82 * @txq: Transmit queue to deallocate.
@@ -169,15 +154,15 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
169 } 154 }
170 155
171 pci_unmap_single(priv->pci_dev, 156 pci_unmap_single(priv->pci_dev,
172 pci_unmap_addr(&txq->meta[i], mapping), 157 dma_unmap_addr(&txq->meta[i], mapping),
173 pci_unmap_len(&txq->meta[i], len), 158 dma_unmap_len(&txq->meta[i], len),
174 PCI_DMA_BIDIRECTIONAL); 159 PCI_DMA_BIDIRECTIONAL);
175 } 160 }
176 if (huge) { 161 if (huge) {
177 i = q->n_window; 162 i = q->n_window;
178 pci_unmap_single(priv->pci_dev, 163 pci_unmap_single(priv->pci_dev,
179 pci_unmap_addr(&txq->meta[i], mapping), 164 dma_unmap_addr(&txq->meta[i], mapping),
180 pci_unmap_len(&txq->meta[i], len), 165 dma_unmap_len(&txq->meta[i], len),
181 PCI_DMA_BIDIRECTIONAL); 166 PCI_DMA_BIDIRECTIONAL);
182 } 167 }
183 168
@@ -287,7 +272,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
287 /* Driver private data, only for Tx (not command) queues, 272 /* Driver private data, only for Tx (not command) queues,
288 * not shared with device. */ 273 * not shared with device. */
289 if (id != IWL_CMD_QUEUE_NUM) { 274 if (id != IWL_CMD_QUEUE_NUM) {
290 txq->txb = kmalloc(sizeof(txq->txb[0]) * 275 txq->txb = kzalloc(sizeof(txq->txb[0]) *
291 TFD_QUEUE_SIZE_MAX, GFP_KERNEL); 276 TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
292 if (!txq->txb) { 277 if (!txq->txb) {
293 IWL_ERR(priv, "kmalloc for auxiliary BD " 278 IWL_ERR(priv, "kmalloc for auxiliary BD "
@@ -531,8 +516,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
531 516
532 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, 517 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
533 fix_size, PCI_DMA_BIDIRECTIONAL); 518 fix_size, PCI_DMA_BIDIRECTIONAL);
534 pci_unmap_addr_set(out_meta, mapping, phys_addr); 519 dma_unmap_addr_set(out_meta, mapping, phys_addr);
535 pci_unmap_len_set(out_meta, len, fix_size); 520 dma_unmap_len_set(out_meta, len, fix_size);
536 521
537 trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); 522 trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
538 523
@@ -626,8 +611,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
626 meta = &txq->meta[cmd_index]; 611 meta = &txq->meta[cmd_index];
627 612
628 pci_unmap_single(priv->pci_dev, 613 pci_unmap_single(priv->pci_dev,
629 pci_unmap_addr(meta, mapping), 614 dma_unmap_addr(meta, mapping),
630 pci_unmap_len(meta, len), 615 dma_unmap_len(meta, len),
631 PCI_DMA_BIDIRECTIONAL); 616 PCI_DMA_BIDIRECTIONAL);
632 617
633 /* Input error checking is done when commands are added to queue. */ 618 /* Input error checking is done when commands are added to queue. */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a27872de4106..8eb347106902 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -197,6 +197,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
197static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) 197static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
198{ 198{
199 unsigned long flags; 199 unsigned long flags;
200 struct iwl_addsta_cmd sta_cmd;
200 201
201 spin_lock_irqsave(&priv->sta_lock, flags); 202 spin_lock_irqsave(&priv->sta_lock, flags);
202 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 203 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
@@ -205,11 +206,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
205 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 206 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
206 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 207 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
207 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 208 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
209 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
208 spin_unlock_irqrestore(&priv->sta_lock, flags); 210 spin_unlock_irqrestore(&priv->sta_lock, flags);
209 211
210 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 212 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
211 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); 213 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
212 return 0;
213} 214}
214 215
215static int iwl3945_set_dynamic_key(struct iwl_priv *priv, 216static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
@@ -474,10 +475,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
474 u8 unicast; 475 u8 unicast;
475 u8 sta_id; 476 u8 sta_id;
476 u8 tid = 0; 477 u8 tid = 0;
477 u16 seq_number = 0;
478 __le16 fc; 478 __le16 fc;
479 u8 wait_write_ptr = 0; 479 u8 wait_write_ptr = 0;
480 u8 *qc = NULL;
481 unsigned long flags; 480 unsigned long flags;
482 481
483 spin_lock_irqsave(&priv->lock, flags); 482 spin_lock_irqsave(&priv->lock, flags);
@@ -510,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
510 hdr_len = ieee80211_hdrlen(fc); 509 hdr_len = ieee80211_hdrlen(fc);
511 510
512 /* Find index into station table for destination station */ 511 /* Find index into station table for destination station */
513 if (!info->control.sta) 512 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
514 sta_id = priv->hw_params.bcast_sta_id;
515 else
516 sta_id = iwl_sta_id(info->control.sta);
517 if (sta_id == IWL_INVALID_STATION) { 513 if (sta_id == IWL_INVALID_STATION) {
518 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 514 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
519 hdr->addr1); 515 hdr->addr1);
@@ -523,16 +519,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
523 IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); 519 IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
524 520
525 if (ieee80211_is_data_qos(fc)) { 521 if (ieee80211_is_data_qos(fc)) {
526 qc = ieee80211_get_qos_ctl(hdr); 522 u8 *qc = ieee80211_get_qos_ctl(hdr);
527 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 523 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
528 if (unlikely(tid >= MAX_TID_COUNT)) 524 if (unlikely(tid >= MAX_TID_COUNT))
529 goto drop; 525 goto drop;
530 seq_number = priv->stations[sta_id].tid[tid].seq_number &
531 IEEE80211_SCTL_SEQ;
532 hdr->seq_ctrl = cpu_to_le16(seq_number) |
533 (hdr->seq_ctrl &
534 cpu_to_le16(IEEE80211_SCTL_FRAG));
535 seq_number += 0x10;
536 } 526 }
537 527
538 /* Descriptor for chosen Tx queue */ 528 /* Descriptor for chosen Tx queue */
@@ -548,7 +538,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
548 538
549 /* Set up driver data for this TFD */ 539 /* Set up driver data for this TFD */
550 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 540 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
551 txq->txb[q->write_ptr].skb[0] = skb; 541 txq->txb[q->write_ptr].skb = skb;
552 542
553 /* Init first empty entry in queue's array of Tx/cmd buffers */ 543 /* Init first empty entry in queue's array of Tx/cmd buffers */
554 out_cmd = txq->cmd[idx]; 544 out_cmd = txq->cmd[idx];
@@ -591,8 +581,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
591 581
592 if (!ieee80211_has_morefrags(hdr->frame_control)) { 582 if (!ieee80211_has_morefrags(hdr->frame_control)) {
593 txq->need_update = 1; 583 txq->need_update = 1;
594 if (qc)
595 priv->stations[sta_id].tid[tid].seq_number = seq_number;
596 } else { 584 } else {
597 wait_write_ptr = 1; 585 wait_write_ptr = 1;
598 txq->need_update = 0; 586 txq->need_update = 0;
@@ -631,8 +619,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
631 len, PCI_DMA_TODEVICE); 619 len, PCI_DMA_TODEVICE);
632 /* we do not map meta data ... so we can safely access address to 620 /* we do not map meta data ... so we can safely access address to
633 * provide to unmap command*/ 621 * provide to unmap command*/
634 pci_unmap_addr_set(out_meta, mapping, txcmd_phys); 622 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
635 pci_unmap_len_set(out_meta, len, len); 623 dma_unmap_len_set(out_meta, len, len);
636 624
637 /* Add buffer containing Tx command and MAC(!) header to TFD's 625 /* Add buffer containing Tx command and MAC(!) header to TFD's
638 * first entry */ 626 * first entry */
@@ -677,55 +665,6 @@ drop:
677 return -1; 665 return -1;
678} 666}
679 667
680#define BEACON_TIME_MASK_LOW 0x00FFFFFF
681#define BEACON_TIME_MASK_HIGH 0xFF000000
682#define TIME_UNIT 1024
683
684/*
685 * extended beacon time format
686 * time in usec will be changed into a 32-bit value in 8:24 format
687 * the high 1 byte is the beacon counts
688 * the lower 3 bytes is the time in usec within one beacon interval
689 */
690
691static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval)
692{
693 u32 quot;
694 u32 rem;
695 u32 interval = beacon_interval * 1024;
696
697 if (!interval || !usec)
698 return 0;
699
700 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
701 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
702
703 return (quot << 24) + rem;
704}
705
706/* base is usually what we get from ucode with each received frame,
707 * the same as HW timer counter counting down
708 */
709
710static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
711{
712 u32 base_low = base & BEACON_TIME_MASK_LOW;
713 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
714 u32 interval = beacon_interval * TIME_UNIT;
715 u32 res = (base & BEACON_TIME_MASK_HIGH) +
716 (addon & BEACON_TIME_MASK_HIGH);
717
718 if (base_low > addon_low)
719 res += base_low - addon_low;
720 else if (base_low < addon_low) {
721 res += interval + base_low - addon_low;
722 res += (1 << 24);
723 } else
724 res += (1 << 24);
725
726 return cpu_to_le32(res);
727}
728
729static int iwl3945_get_measurement(struct iwl_priv *priv, 668static int iwl3945_get_measurement(struct iwl_priv *priv,
730 struct ieee80211_measurement_params *params, 669 struct ieee80211_measurement_params *params,
731 u8 type) 670 u8 type)
@@ -743,8 +682,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
743 int duration = le16_to_cpu(params->duration); 682 int duration = le16_to_cpu(params->duration);
744 683
745 if (iwl_is_associated(priv)) 684 if (iwl_is_associated(priv))
746 add_time = 685 add_time = iwl_usecs_to_beacons(priv,
747 iwl3945_usecs_to_beacons(
748 le64_to_cpu(params->start_time) - priv->_3945.last_tsf, 686 le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
749 le16_to_cpu(priv->rxon_timing.beacon_interval)); 687 le16_to_cpu(priv->rxon_timing.beacon_interval));
750 688
@@ -759,8 +697,8 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
759 697
760 if (iwl_is_associated(priv)) 698 if (iwl_is_associated(priv))
761 spectrum.start_time = 699 spectrum.start_time =
762 iwl3945_add_beacon_time(priv->_3945.last_beacon_time, 700 iwl_add_beacon_time(priv,
763 add_time, 701 priv->_3945.last_beacon_time, add_time,
764 le16_to_cpu(priv->rxon_timing.beacon_interval)); 702 le16_to_cpu(priv->rxon_timing.beacon_interval));
765 else 703 else
766 spectrum.start_time = 0; 704 spectrum.start_time = 0;
@@ -1233,7 +1171,7 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx
1233 } 1171 }
1234 1172
1235 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, 1173 dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,
1236 rxq->dma_addr); 1174 rxq->bd_dma);
1237 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), 1175 dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),
1238 rxq->rb_stts, rxq->rb_stts_dma); 1176 rxq->rb_stts, rxq->rb_stts_dma);
1239 rxq->bd = NULL; 1177 rxq->bd = NULL;
@@ -1314,6 +1252,8 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1314 IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); 1252 IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
1315 1253
1316 while (i != r) { 1254 while (i != r) {
1255 int len;
1256
1317 rxb = rxq->queue[i]; 1257 rxb = rxq->queue[i];
1318 1258
1319 /* If an RXB doesn't have a Rx queue slot associated with it, 1259 /* If an RXB doesn't have a Rx queue slot associated with it,
@@ -1328,8 +1268,9 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1328 PCI_DMA_FROMDEVICE); 1268 PCI_DMA_FROMDEVICE);
1329 pkt = rxb_addr(rxb); 1269 pkt = rxb_addr(rxb);
1330 1270
1331 trace_iwlwifi_dev_rx(priv, pkt, 1271 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
1332 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 1272 len += sizeof(u32); /* account for status word */
1273 trace_iwlwifi_dev_rx(priv, pkt, len);
1333 1274
1334 /* Reclaim a command buffer only if this packet is a response 1275 /* Reclaim a command buffer only if this packet is a response
1335 * to a (driver-originated) command. 1276 * to a (driver-originated) command.
@@ -1483,7 +1424,7 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1483 iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); 1424 iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32));
1484 1425
1485 IWL_ERR(priv, 1426 IWL_ERR(priv,
1486 "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", 1427 "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
1487 desc_lookup(desc), desc, time, blink1, blink2, 1428 desc_lookup(desc), desc, time, blink1, blink2,
1488 ilink1, ilink2, data1); 1429 ilink1, ilink2, data1);
1489 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0, 1430 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0,
@@ -3022,14 +2963,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
3022 scan->tx_cmd.len = cpu_to_le16( 2963 scan->tx_cmd.len = cpu_to_le16(
3023 iwl_fill_probe_req(priv, 2964 iwl_fill_probe_req(priv,
3024 (struct ieee80211_mgmt *)scan->data, 2965 (struct ieee80211_mgmt *)scan->data,
2966 vif->addr,
3025 priv->scan_request->ie, 2967 priv->scan_request->ie,
3026 priv->scan_request->ie_len, 2968 priv->scan_request->ie_len,
3027 IWL_MAX_SCAN_SIZE - sizeof(*scan))); 2969 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
3028 } else { 2970 } else {
2971 /* use bcast addr, will not be transmitted but must be valid */
3029 scan->tx_cmd.len = cpu_to_le16( 2972 scan->tx_cmd.len = cpu_to_le16(
3030 iwl_fill_probe_req(priv, 2973 iwl_fill_probe_req(priv,
3031 (struct ieee80211_mgmt *)scan->data, 2974 (struct ieee80211_mgmt *)scan->data,
3032 NULL, 0, 2975 iwl_bcast_addr, NULL, 0,
3033 IWL_MAX_SCAN_SIZE - sizeof(*scan))); 2976 IWL_MAX_SCAN_SIZE - sizeof(*scan)));
3034 } 2977 }
3035 /* select Rx antennas */ 2978 /* select Rx antennas */
@@ -3158,19 +3101,16 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3158 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3101 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3159 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3102 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3160 3103
3161 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3104 if (vif->bss_conf.use_short_preamble)
3162 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3105 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3163 else 3106 else
3164 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3107 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3165 3108
3166 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3109 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3167 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 3110 if (vif->bss_conf.use_short_slot)
3168 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3111 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
3169 else 3112 else
3170 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3113 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3171
3172 if (vif->type == NL80211_IFTYPE_ADHOC)
3173 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3174 } 3114 }
3175 3115
3176 iwlcore_commit_rxon(priv); 3116 iwlcore_commit_rxon(priv);
@@ -3334,8 +3274,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3334 3274
3335 priv->staging_rxon.assoc_id = 0; 3275 priv->staging_rxon.assoc_id = 0;
3336 3276
3337 if (vif->bss_conf.assoc_capability & 3277 if (vif->bss_conf.use_short_preamble)
3338 WLAN_CAPABILITY_SHORT_PREAMBLE)
3339 priv->staging_rxon.flags |= 3278 priv->staging_rxon.flags |=
3340 RXON_FLG_SHORT_PREAMBLE_MSK; 3279 RXON_FLG_SHORT_PREAMBLE_MSK;
3341 else 3280 else
@@ -3343,17 +3282,12 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3343 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3282 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3344 3283
3345 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3284 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3346 if (vif->bss_conf.assoc_capability & 3285 if (vif->bss_conf.use_short_slot)
3347 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3348 priv->staging_rxon.flags |= 3286 priv->staging_rxon.flags |=
3349 RXON_FLG_SHORT_SLOT_MSK; 3287 RXON_FLG_SHORT_SLOT_MSK;
3350 else 3288 else
3351 priv->staging_rxon.flags &= 3289 priv->staging_rxon.flags &=
3352 ~RXON_FLG_SHORT_SLOT_MSK; 3290 ~RXON_FLG_SHORT_SLOT_MSK;
3353
3354 if (vif->type == NL80211_IFTYPE_ADHOC)
3355 priv->staging_rxon.flags &=
3356 ~RXON_FLG_SHORT_SLOT_MSK;
3357 } 3291 }
3358 /* restore RXON assoc */ 3292 /* restore RXON assoc */
3359 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3293 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -3386,17 +3320,9 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3386 static_key = !iwl_is_associated(priv); 3320 static_key = !iwl_is_associated(priv);
3387 3321
3388 if (!static_key) { 3322 if (!static_key) {
3389 if (!sta) { 3323 sta_id = iwl_sta_id_or_broadcast(priv, sta);
3390 sta_id = priv->hw_params.bcast_sta_id; 3324 if (sta_id == IWL_INVALID_STATION)
3391 } else { 3325 return -EINVAL;
3392 sta_id = iwl_sta_id(sta);
3393 if (sta_id == IWL_INVALID_STATION) {
3394 IWL_DEBUG_MAC80211(priv,
3395 "leave - %pM not in station map.\n",
3396 sta->addr);
3397 return -EINVAL;
3398 }
3399 }
3400 } 3326 }
3401 3327
3402 mutex_lock(&priv->mutex); 3328 mutex_lock(&priv->mutex);
@@ -4028,9 +3954,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4028 priv->pci_dev = pdev; 3954 priv->pci_dev = pdev;
4029 priv->inta_mask = CSR_INI_SET_MASK; 3955 priv->inta_mask = CSR_INI_SET_MASK;
4030 3956
4031#ifdef CONFIG_IWLWIFI_DEBUG
4032 atomic_set(&priv->restrict_refcnt, 0);
4033#endif
4034 if (iwl_alloc_traffic_mem(priv)) 3957 if (iwl_alloc_traffic_mem(priv))
4035 IWL_ERR(priv, "Not enough memory to generate traffic log\n"); 3958 IWL_ERR(priv, "Not enough memory to generate traffic log\n");
4036 3959
@@ -4099,9 +4022,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4099 } 4022 }
4100 /* MAC Address location in EEPROM same for 3945/4965 */ 4023 /* MAC Address location in EEPROM same for 3945/4965 */
4101 eeprom = (struct iwl3945_eeprom *)priv->eeprom; 4024 eeprom = (struct iwl3945_eeprom *)priv->eeprom;
4102 memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN); 4025 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address);
4103 IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr); 4026 SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address);
4104 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
4105 4027
4106 /*********************** 4028 /***********************
4107 * 5. Setup HW Constants 4029 * 5. Setup HW Constants
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 902e95f70f6e..60619678f4ec 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -670,20 +670,24 @@ static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
670} 670}
671 671
672static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, 672static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
673 enum tx_power_setting type, int dbm) 673 enum nl80211_tx_power_setting type, int mbm)
674{ 674{
675 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); 675 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
676 int ret; 676 int ret;
677 677
678 switch (type) { 678 switch (type) {
679 case TX_POWER_AUTOMATIC: 679 case NL80211_TX_POWER_AUTOMATIC:
680 return 0; 680 return 0;
681 case TX_POWER_FIXED: 681 case NL80211_TX_POWER_FIXED:
682 if (mbm < 0 || (mbm % 100))
683 return -EOPNOTSUPP;
684
682 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 685 if (!test_bit(IWM_STATUS_READY, &iwm->status))
683 return 0; 686 return 0;
684 687
685 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, 688 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
686 CFG_TX_PWR_LIMIT_USR, dbm * 2); 689 CFG_TX_PWR_LIMIT_USR,
690 MBM_TO_DBM(mbm) * 2);
687 if (ret < 0) 691 if (ret < 0)
688 return ret; 692 return ret;
689 693
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index 9531b18cf72a..907ac890997c 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -54,7 +54,7 @@
54 * LMAC. If you look at LMAC commands you'll se that they 54 * LMAC. If you look at LMAC commands you'll se that they
55 * are actually regular iwlwifi target commands encapsulated 55 * are actually regular iwlwifi target commands encapsulated
56 * into a special UMAC command called UMAC passthrough. 56 * into a special UMAC command called UMAC passthrough.
57 * This is due to the fact the the host talks exclusively 57 * This is due to the fact the host talks exclusively
58 * to the UMAC and so there needs to be a special UMAC 58 * to the UMAC and so there needs to be a special UMAC
59 * command for talking to the LMAC. 59 * command for talking to the LMAC.
60 * This is how a wifi command is layed out: 60 * This is how a wifi command is layed out:
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index e1184deca559..c02fcedea9fa 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -321,14 +321,14 @@ iwm_rx_ticket_node_alloc(struct iwm_priv *iwm, struct iwm_rx_ticket *ticket)
321 return ERR_PTR(-ENOMEM); 321 return ERR_PTR(-ENOMEM);
322 } 322 }
323 323
324 ticket_node->ticket = kzalloc(sizeof(struct iwm_rx_ticket), GFP_KERNEL); 324 ticket_node->ticket = kmemdup(ticket, sizeof(struct iwm_rx_ticket),
325 GFP_KERNEL);
325 if (!ticket_node->ticket) { 326 if (!ticket_node->ticket) {
326 IWM_ERR(iwm, "Couldn't allocate RX ticket\n"); 327 IWM_ERR(iwm, "Couldn't allocate RX ticket\n");
327 kfree(ticket_node); 328 kfree(ticket_node);
328 return ERR_PTR(-ENOMEM); 329 return ERR_PTR(-ENOMEM);
329 } 330 }
330 331
331 memcpy(ticket_node->ticket, ticket, sizeof(struct iwm_rx_ticket));
332 INIT_LIST_HEAD(&ticket_node->node); 332 INIT_LIST_HEAD(&ticket_node->node);
333 333
334 return ticket_node; 334 return ticket_node;
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 45e870e33117..f7d01bfa2e4a 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -1,4 +1,3 @@
1libertas-y += assoc.o
2libertas-y += cfg.o 1libertas-y += cfg.o
3libertas-y += cmd.o 2libertas-y += cmd.o
4libertas-y += cmdresp.o 3libertas-y += cmdresp.o
@@ -6,9 +5,7 @@ libertas-y += debugfs.o
6libertas-y += ethtool.o 5libertas-y += ethtool.o
7libertas-y += main.o 6libertas-y += main.o
8libertas-y += rx.o 7libertas-y += rx.o
9libertas-y += scan.o
10libertas-y += tx.o 8libertas-y += tx.o
11libertas-y += wext.o
12libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o 9libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
13 10
14usb8xxx-objs += if_usb.o 11usb8xxx-objs += if_usb.o
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
deleted file mode 100644
index aa06070e5eab..000000000000
--- a/drivers/net/wireless/libertas/assoc.c
+++ /dev/null
@@ -1,2264 +0,0 @@
1/* Copyright (C) 2006, Red Hat, Inc. */
2
3#include <linux/types.h>
4#include <linux/etherdevice.h>
5#include <linux/ieee80211.h>
6#include <linux/if_arp.h>
7#include <linux/slab.h>
8#include <net/lib80211.h>
9
10#include "assoc.h"
11#include "decl.h"
12#include "host.h"
13#include "scan.h"
14#include "cmd.h"
15
16static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
17 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
18static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
19 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
20
21/* The firmware needs the following bits masked out of the beacon-derived
22 * capability field when associating/joining to a BSS:
23 * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
24 */
25#define CAPINFO_MASK (~(0xda00))
26
27/**
28 * 802.11b/g supported bitrates (in 500Kb/s units)
29 */
30u8 lbs_bg_rates[MAX_RATES] =
31 { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
320x00, 0x00 };
33
34
35static int assoc_helper_wep_keys(struct lbs_private *priv,
36 struct assoc_request *assoc_req);
37
38/**
39 * @brief This function finds common rates between rates and card rates.
40 *
41 * It will fill common rates in rates as output if found.
42 *
43 * NOTE: Setting the MSB of the basic rates need to be taken
44 * care, either before or after calling this function
45 *
46 * @param priv A pointer to struct lbs_private structure
47 * @param rates the buffer which keeps input and output
48 * @param rates_size the size of rates buffer; new size of buffer on return,
49 * which will be less than or equal to original rates_size
50 *
51 * @return 0 on success, or -1 on error
52 */
53static int get_common_rates(struct lbs_private *priv,
54 u8 *rates,
55 u16 *rates_size)
56{
57 int i, j;
58 u8 intersection[MAX_RATES];
59 u16 intersection_size;
60 u16 num_rates = 0;
61
62 intersection_size = min_t(u16, *rates_size, ARRAY_SIZE(intersection));
63
64 /* Allow each rate from 'rates' that is supported by the hardware */
65 for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && lbs_bg_rates[i]; i++) {
66 for (j = 0; j < intersection_size && rates[j]; j++) {
67 if (rates[j] == lbs_bg_rates[i])
68 intersection[num_rates++] = rates[j];
69 }
70 }
71
72 lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
73 lbs_deb_hex(LBS_DEB_JOIN, "card rates ", lbs_bg_rates,
74 ARRAY_SIZE(lbs_bg_rates));
75 lbs_deb_hex(LBS_DEB_JOIN, "common rates", intersection, num_rates);
76 lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
77
78 if (!priv->enablehwauto) {
79 for (i = 0; i < num_rates; i++) {
80 if (intersection[i] == priv->cur_rate)
81 goto done;
82 }
83 lbs_pr_alert("Previously set fixed data rate %#x isn't "
84 "compatible with the network.\n", priv->cur_rate);
85 return -1;
86 }
87
88done:
89 memset(rates, 0, *rates_size);
90 *rates_size = num_rates;
91 memcpy(rates, intersection, num_rates);
92 return 0;
93}
94
95
96/**
97 * @brief Sets the MSB on basic rates as the firmware requires
98 *
99 * Scan through an array and set the MSB for basic data rates.
100 *
101 * @param rates buffer of data rates
102 * @param len size of buffer
103 */
104static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
105{
106 int i;
107
108 for (i = 0; i < len; i++) {
109 if (rates[i] == 0x02 || rates[i] == 0x04 ||
110 rates[i] == 0x0b || rates[i] == 0x16)
111 rates[i] |= 0x80;
112 }
113}
114
115
116static u8 iw_auth_to_ieee_auth(u8 auth)
117{
118 if (auth == IW_AUTH_ALG_OPEN_SYSTEM)
119 return 0x00;
120 else if (auth == IW_AUTH_ALG_SHARED_KEY)
121 return 0x01;
122 else if (auth == IW_AUTH_ALG_LEAP)
123 return 0x80;
124
125 lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth);
126 return 0;
127}
128
129/**
130 * @brief This function prepares the authenticate command. AUTHENTICATE only
131 * sets the authentication suite for future associations, as the firmware
132 * handles authentication internally during the ASSOCIATE command.
133 *
134 * @param priv A pointer to struct lbs_private structure
135 * @param bssid The peer BSSID with which to authenticate
136 * @param auth The authentication mode to use (from wireless.h)
137 *
138 * @return 0 or -1
139 */
140static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth)
141{
142 struct cmd_ds_802_11_authenticate cmd;
143 int ret = -1;
144
145 lbs_deb_enter(LBS_DEB_JOIN);
146
147 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
148 memcpy(cmd.bssid, bssid, ETH_ALEN);
149
150 cmd.authtype = iw_auth_to_ieee_auth(auth);
151
152 lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", bssid, cmd.authtype);
153
154 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
155
156 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
157 return ret;
158}
159
160
161int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
162 struct assoc_request *assoc)
163{
164 struct cmd_ds_802_11_set_wep cmd;
165 int ret = 0;
166
167 lbs_deb_enter(LBS_DEB_CMD);
168
169 memset(&cmd, 0, sizeof(cmd));
170 cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
171 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
172
173 cmd.action = cpu_to_le16(cmd_action);
174
175 if (cmd_action == CMD_ACT_ADD) {
176 int i;
177
178 /* default tx key index */
179 cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx &
180 CMD_WEP_KEY_INDEX_MASK);
181
182 /* Copy key types and material to host command structure */
183 for (i = 0; i < 4; i++) {
184 struct enc_key *pkey = &assoc->wep_keys[i];
185
186 switch (pkey->len) {
187 case KEY_LEN_WEP_40:
188 cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
189 memmove(cmd.keymaterial[i], pkey->key, pkey->len);
190 lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
191 break;
192 case KEY_LEN_WEP_104:
193 cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
194 memmove(cmd.keymaterial[i], pkey->key, pkey->len);
195 lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
196 break;
197 case 0:
198 break;
199 default:
200 lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
201 i, pkey->len);
202 ret = -1;
203 goto done;
204 break;
205 }
206 }
207 } else if (cmd_action == CMD_ACT_REMOVE) {
208 /* ACT_REMOVE clears _all_ WEP keys */
209
210 /* default tx key index */
211 cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx &
212 CMD_WEP_KEY_INDEX_MASK);
213 lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
214 }
215
216 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
217done:
218 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
219 return ret;
220}
221
222int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
223 uint16_t *enable)
224{
225 struct cmd_ds_802_11_enable_rsn cmd;
226 int ret;
227
228 lbs_deb_enter(LBS_DEB_CMD);
229
230 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
231 cmd.action = cpu_to_le16(cmd_action);
232
233 if (cmd_action == CMD_ACT_GET)
234 cmd.enable = 0;
235 else {
236 if (*enable)
237 cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
238 else
239 cmd.enable = cpu_to_le16(CMD_DISABLE_RSN);
240 lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
241 }
242
243 ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
244 if (!ret && cmd_action == CMD_ACT_GET)
245 *enable = le16_to_cpu(cmd.enable);
246
247 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
248 return ret;
249}
250
251static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
252 struct enc_key *key)
253{
254 lbs_deb_enter(LBS_DEB_CMD);
255
256 if (key->flags & KEY_INFO_WPA_ENABLED)
257 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
258 if (key->flags & KEY_INFO_WPA_UNICAST)
259 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
260 if (key->flags & KEY_INFO_WPA_MCAST)
261 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
262
263 keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
264 keyparam->keytypeid = cpu_to_le16(key->type);
265 keyparam->keylen = cpu_to_le16(key->len);
266 memcpy(keyparam->key, key->key, key->len);
267
268 /* Length field doesn't include the {type,length} header */
269 keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
270 lbs_deb_leave(LBS_DEB_CMD);
271}
272
273int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
274 struct assoc_request *assoc)
275{
276 struct cmd_ds_802_11_key_material cmd;
277 int ret = 0;
278 int index = 0;
279
280 lbs_deb_enter(LBS_DEB_CMD);
281
282 cmd.action = cpu_to_le16(cmd_action);
283 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
284
285 if (cmd_action == CMD_ACT_GET) {
286 cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_header) + 2);
287 } else {
288 memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
289
290 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
291 set_one_wpa_key(&cmd.keyParamSet[index],
292 &assoc->wpa_unicast_key);
293 index++;
294 }
295
296 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
297 set_one_wpa_key(&cmd.keyParamSet[index],
298 &assoc->wpa_mcast_key);
299 index++;
300 }
301
302 /* The common header and as many keys as we included */
303 cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
304 keyParamSet[index]));
305 }
306 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
307 /* Copy the returned key to driver private data */
308 if (!ret && cmd_action == CMD_ACT_GET) {
309 void *buf_ptr = cmd.keyParamSet;
310 void *resp_end = &(&cmd)[1];
311
312 while (buf_ptr < resp_end) {
313 struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
314 struct enc_key *key;
315 uint16_t param_set_len = le16_to_cpu(keyparam->length);
316 uint16_t key_len = le16_to_cpu(keyparam->keylen);
317 uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
318 uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
319 void *end;
320
321 end = (void *)keyparam + sizeof(keyparam->type)
322 + sizeof(keyparam->length) + param_set_len;
323
324 /* Make sure we don't access past the end of the IEs */
325 if (end > resp_end)
326 break;
327
328 if (key_flags & KEY_INFO_WPA_UNICAST)
329 key = &priv->wpa_unicast_key;
330 else if (key_flags & KEY_INFO_WPA_MCAST)
331 key = &priv->wpa_mcast_key;
332 else
333 break;
334
335 /* Copy returned key into driver */
336 memset(key, 0, sizeof(struct enc_key));
337 if (key_len > sizeof(key->key))
338 break;
339 key->type = key_type;
340 key->flags = key_flags;
341 key->len = key_len;
342 memcpy(key->key, keyparam->key, key->len);
343
344 buf_ptr = end + 1;
345 }
346 }
347
348 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
349 return ret;
350}
351
352static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok)
353{
354/* Bit Rate
355* 15:13 Reserved
356* 12 54 Mbps
357* 11 48 Mbps
358* 10 36 Mbps
359* 9 24 Mbps
360* 8 18 Mbps
361* 7 12 Mbps
362* 6 9 Mbps
363* 5 6 Mbps
364* 4 Reserved
365* 3 11 Mbps
366* 2 5.5 Mbps
367* 1 2 Mbps
368* 0 1 Mbps
369**/
370
371 uint16_t ratemask;
372 int i = lbs_data_rate_to_fw_index(rate);
373 if (lower_rates_ok)
374 ratemask = (0x1fef >> (12 - i));
375 else
376 ratemask = (1 << i);
377 return cpu_to_le16(ratemask);
378}
379
380int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
381 uint16_t cmd_action)
382{
383 struct cmd_ds_802_11_rate_adapt_rateset cmd;
384 int ret;
385
386 lbs_deb_enter(LBS_DEB_CMD);
387
388 if (!priv->cur_rate && !priv->enablehwauto)
389 return -EINVAL;
390
391 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
392
393 cmd.action = cpu_to_le16(cmd_action);
394 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
395 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
396 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
397 if (!ret && cmd_action == CMD_ACT_GET)
398 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
399
400 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
401 return ret;
402}
403
404/**
405 * @brief Set the data rate
406 *
407 * @param priv A pointer to struct lbs_private structure
408 * @param rate The desired data rate, or 0 to clear a locked rate
409 *
410 * @return 0 on success, error on failure
411 */
412int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
413{
414 struct cmd_ds_802_11_data_rate cmd;
415 int ret = 0;
416
417 lbs_deb_enter(LBS_DEB_CMD);
418
419 memset(&cmd, 0, sizeof(cmd));
420 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
421
422 if (rate > 0) {
423 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
424 cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
425 if (cmd.rates[0] == 0) {
426 lbs_deb_cmd("DATA_RATE: invalid requested rate of"
427 " 0x%02X\n", rate);
428 ret = 0;
429 goto out;
430 }
431 lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
432 } else {
433 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
434 lbs_deb_cmd("DATA_RATE: setting auto\n");
435 }
436
437 ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
438 if (ret)
439 goto out;
440
441 lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd));
442
443 /* FIXME: get actual rates FW can do if this command actually returns
444 * all data rates supported.
445 */
446 priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
447 lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
448
449out:
450 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
451 return ret;
452}
453
454
455int lbs_cmd_802_11_rssi(struct lbs_private *priv,
456 struct cmd_ds_command *cmd)
457{
458
459 lbs_deb_enter(LBS_DEB_CMD);
460 cmd->command = cpu_to_le16(CMD_802_11_RSSI);
461 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) +
462 sizeof(struct cmd_header));
463 cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
464
465 /* reset Beacon SNR/NF/RSSI values */
466 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
467 priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
468 priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
469 priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
470 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
471 priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
472
473 lbs_deb_leave(LBS_DEB_CMD);
474 return 0;
475}
476
477int lbs_ret_802_11_rssi(struct lbs_private *priv,
478 struct cmd_ds_command *resp)
479{
480 struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
481
482 lbs_deb_enter(LBS_DEB_CMD);
483
484 /* store the non average value */
485 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
486 priv->NF[TYPE_BEACON][TYPE_NOAVG] =
487 get_unaligned_le16(&rssirsp->noisefloor);
488
489 priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
490 priv->NF[TYPE_BEACON][TYPE_AVG] =
491 get_unaligned_le16(&rssirsp->avgnoisefloor);
492
493 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
494 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
495 priv->NF[TYPE_BEACON][TYPE_NOAVG]);
496
497 priv->RSSI[TYPE_BEACON][TYPE_AVG] =
498 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
499 priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
500
501 lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
502 priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
503 priv->RSSI[TYPE_BEACON][TYPE_AVG]);
504
505 lbs_deb_leave(LBS_DEB_CMD);
506 return 0;
507}
508
509
510int lbs_cmd_bcn_ctrl(struct lbs_private *priv,
511 struct cmd_ds_command *cmd,
512 u16 cmd_action)
513{
514 struct cmd_ds_802_11_beacon_control
515 *bcn_ctrl = &cmd->params.bcn_ctrl;
516
517 lbs_deb_enter(LBS_DEB_CMD);
518 cmd->size =
519 cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
520 + sizeof(struct cmd_header));
521 cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
522
523 bcn_ctrl->action = cpu_to_le16(cmd_action);
524 bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
525 bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
526
527 lbs_deb_leave(LBS_DEB_CMD);
528 return 0;
529}
530
531int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv,
532 struct cmd_ds_command *resp)
533{
534 struct cmd_ds_802_11_beacon_control *bcn_ctrl =
535 &resp->params.bcn_ctrl;
536
537 lbs_deb_enter(LBS_DEB_CMD);
538
539 if (bcn_ctrl->action == CMD_ACT_GET) {
540 priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
541 priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
542 }
543
544 lbs_deb_enter(LBS_DEB_CMD);
545 return 0;
546}
547
548
549
550static int lbs_assoc_post(struct lbs_private *priv,
551 struct cmd_ds_802_11_associate_response *resp)
552{
553 int ret = 0;
554 union iwreq_data wrqu;
555 struct bss_descriptor *bss;
556 u16 status_code;
557
558 lbs_deb_enter(LBS_DEB_ASSOC);
559
560 if (!priv->in_progress_assoc_req) {
561 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
562 ret = -1;
563 goto done;
564 }
565 bss = &priv->in_progress_assoc_req->bss;
566
567 /*
568 * Older FW versions map the IEEE 802.11 Status Code in the association
569 * response to the following values returned in resp->statuscode:
570 *
571 * IEEE Status Code Marvell Status Code
572 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
573 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
574 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
575 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
576 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
577 * others -> 0x0003 ASSOC_RESULT_REFUSED
578 *
579 * Other response codes:
580 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
581 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
582 * association response from the AP)
583 */
584
585 status_code = le16_to_cpu(resp->statuscode);
586 if (priv->fwrelease < 0x09000000) {
587 switch (status_code) {
588 case 0x00:
589 break;
590 case 0x01:
591 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
592 break;
593 case 0x02:
594 lbs_deb_assoc("ASSOC_RESP: internal timer "
595 "expired while waiting for the AP\n");
596 break;
597 case 0x03:
598 lbs_deb_assoc("ASSOC_RESP: association "
599 "refused by AP\n");
600 break;
601 case 0x04:
602 lbs_deb_assoc("ASSOC_RESP: authentication "
603 "refused by AP\n");
604 break;
605 default:
606 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
607 " unknown\n", status_code);
608 break;
609 }
610 } else {
611 /* v9+ returns the AP's association response */
612 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code);
613 }
614
615 if (status_code) {
616 lbs_mac_event_disconnected(priv);
617 ret = status_code;
618 goto done;
619 }
620
621 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP",
622 (void *) (resp + sizeof (resp->hdr)),
623 le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr));
624
625 /* Send a Media Connected event, according to the Spec */
626 priv->connect_status = LBS_CONNECTED;
627
628 /* Update current SSID and BSSID */
629 memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN);
630 priv->curbssparams.ssid_len = bss->ssid_len;
631 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
632
633 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
634 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
635
636 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
637 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
638 priv->nextSNRNF = 0;
639 priv->numSNRNF = 0;
640
641 netif_carrier_on(priv->dev);
642 if (!priv->tx_pending_len)
643 netif_wake_queue(priv->dev);
644
645 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
646 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
647 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
648
649done:
650 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
651 return ret;
652}
653
654/**
655 * @brief This function prepares an association-class command.
656 *
657 * @param priv A pointer to struct lbs_private structure
658 * @param assoc_req The association request describing the BSS to associate
659 * or reassociate with
660 * @param command The actual command, either CMD_802_11_ASSOCIATE or
661 * CMD_802_11_REASSOCIATE
662 *
663 * @return 0 or -1
664 */
665static int lbs_associate(struct lbs_private *priv,
666 struct assoc_request *assoc_req,
667 u16 command)
668{
669 struct cmd_ds_802_11_associate cmd;
670 int ret = 0;
671 struct bss_descriptor *bss = &assoc_req->bss;
672 u8 *pos = &(cmd.iebuf[0]);
673 u16 tmpcap, tmplen, tmpauth;
674 struct mrvl_ie_ssid_param_set *ssid;
675 struct mrvl_ie_ds_param_set *ds;
676 struct mrvl_ie_cf_param_set *cf;
677 struct mrvl_ie_rates_param_set *rates;
678 struct mrvl_ie_rsn_param_set *rsn;
679 struct mrvl_ie_auth_type *auth;
680
681 lbs_deb_enter(LBS_DEB_ASSOC);
682
683 BUG_ON((command != CMD_802_11_ASSOCIATE) &&
684 (command != CMD_802_11_REASSOCIATE));
685
686 memset(&cmd, 0, sizeof(cmd));
687 cmd.hdr.command = cpu_to_le16(command);
688
689 /* Fill in static fields */
690 memcpy(cmd.bssid, bss->bssid, ETH_ALEN);
691 cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
692
693 /* Capability info */
694 tmpcap = (bss->capability & CAPINFO_MASK);
695 if (bss->mode == IW_MODE_INFRA)
696 tmpcap |= WLAN_CAPABILITY_ESS;
697 cmd.capability = cpu_to_le16(tmpcap);
698 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
699
700 /* SSID */
701 ssid = (struct mrvl_ie_ssid_param_set *) pos;
702 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
703 tmplen = bss->ssid_len;
704 ssid->header.len = cpu_to_le16(tmplen);
705 memcpy(ssid->ssid, bss->ssid, tmplen);
706 pos += sizeof(ssid->header) + tmplen;
707
708 ds = (struct mrvl_ie_ds_param_set *) pos;
709 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
710 ds->header.len = cpu_to_le16(1);
711 ds->channel = bss->phy.ds.channel;
712 pos += sizeof(ds->header) + 1;
713
714 cf = (struct mrvl_ie_cf_param_set *) pos;
715 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
716 tmplen = sizeof(*cf) - sizeof (cf->header);
717 cf->header.len = cpu_to_le16(tmplen);
718 /* IE payload should be zeroed, firmware fills it in for us */
719 pos += sizeof(*cf);
720
721 rates = (struct mrvl_ie_rates_param_set *) pos;
722 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
723 tmplen = min_t(u16, ARRAY_SIZE(bss->rates), MAX_RATES);
724 memcpy(&rates->rates, &bss->rates, tmplen);
725 if (get_common_rates(priv, rates->rates, &tmplen)) {
726 ret = -1;
727 goto done;
728 }
729 pos += sizeof(rates->header) + tmplen;
730 rates->header.len = cpu_to_le16(tmplen);
731 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
732
733 /* Copy the infra. association rates into Current BSS state structure */
734 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
735 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
736
737 /* Set MSB on basic rates as the firmware requires, but _after_
738 * copying to current bss rates.
739 */
740 lbs_set_basic_rate_flags(rates->rates, tmplen);
741
742 /* Firmware v9+ indicate authentication suites as a TLV */
743 if (priv->fwrelease >= 0x09000000) {
744 auth = (struct mrvl_ie_auth_type *) pos;
745 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
746 auth->header.len = cpu_to_le16(2);
747 tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
748 auth->auth = cpu_to_le16(tmpauth);
749 pos += sizeof(auth->header) + 2;
750
751 lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
752 bss->bssid, priv->secinfo.auth_mode);
753 }
754
755 /* WPA/WPA2 IEs */
756 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
757 rsn = (struct mrvl_ie_rsn_param_set *) pos;
758 /* WPA_IE or WPA2_IE */
759 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
760 tmplen = (u16) assoc_req->wpa_ie[1];
761 rsn->header.len = cpu_to_le16(tmplen);
762 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
763 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn,
764 sizeof(rsn->header) + tmplen);
765 pos += sizeof(rsn->header) + tmplen;
766 }
767
768 cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) +
769 (u16)(pos - (u8 *) &cmd.iebuf));
770
771 /* update curbssparams */
772 priv->channel = bss->phy.ds.channel;
773
774 ret = lbs_cmd_with_response(priv, command, &cmd);
775 if (ret == 0) {
776 ret = lbs_assoc_post(priv,
777 (struct cmd_ds_802_11_associate_response *) &cmd);
778 }
779
780done:
781 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
782 return ret;
783}
784
785/**
786 * @brief Associate to a specific BSS discovered in a scan
787 *
788 * @param priv A pointer to struct lbs_private structure
789 * @param assoc_req The association request describing the BSS to associate with
790 *
791 * @return 0-success, otherwise fail
792 */
793static int lbs_try_associate(struct lbs_private *priv,
794 struct assoc_request *assoc_req)
795{
796 int ret;
797 u8 preamble = RADIO_PREAMBLE_LONG;
798
799 lbs_deb_enter(LBS_DEB_ASSOC);
800
801 /* FW v9 and higher indicate authentication suites as a TLV in the
802 * association command, not as a separate authentication command.
803 */
804 if (priv->fwrelease < 0x09000000) {
805 ret = lbs_set_authentication(priv, assoc_req->bss.bssid,
806 priv->secinfo.auth_mode);
807 if (ret)
808 goto out;
809 }
810
811 /* Use short preamble only when both the BSS and firmware support it */
812 if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
813 preamble = RADIO_PREAMBLE_SHORT;
814
815 ret = lbs_set_radio(priv, preamble, 1);
816 if (ret)
817 goto out;
818
819 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
820 /* If the association fails with current auth mode, let's
821 * try by changing the auth mode
822 */
823 if ((priv->authtype_auto) &&
824 (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) &&
825 (assoc_req->secinfo.wep_enabled) &&
826 (priv->connect_status != LBS_CONNECTED)) {
827 if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM)
828 priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
829 else
830 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
831 if (!assoc_helper_wep_keys(priv, assoc_req))
832 ret = lbs_associate(priv, assoc_req,
833 CMD_802_11_ASSOCIATE);
834 }
835
836 if (ret)
837 ret = -1;
838out:
839 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
840 return ret;
841}
842
843static int lbs_adhoc_post(struct lbs_private *priv,
844 struct cmd_ds_802_11_ad_hoc_result *resp)
845{
846 int ret = 0;
847 u16 command = le16_to_cpu(resp->hdr.command);
848 u16 result = le16_to_cpu(resp->hdr.result);
849 union iwreq_data wrqu;
850 struct bss_descriptor *bss;
851 DECLARE_SSID_BUF(ssid);
852
853 lbs_deb_enter(LBS_DEB_JOIN);
854
855 if (!priv->in_progress_assoc_req) {
856 lbs_deb_join("ADHOC_RESP: no in-progress association "
857 "request\n");
858 ret = -1;
859 goto done;
860 }
861 bss = &priv->in_progress_assoc_req->bss;
862
863 /*
864 * Join result code 0 --> SUCCESS
865 */
866 if (result) {
867 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
868 if (priv->connect_status == LBS_CONNECTED)
869 lbs_mac_event_disconnected(priv);
870 ret = -1;
871 goto done;
872 }
873
874 /* Send a Media Connected event, according to the Spec */
875 priv->connect_status = LBS_CONNECTED;
876
877 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
878 /* Update the created network descriptor with the new BSSID */
879 memcpy(bss->bssid, resp->bssid, ETH_ALEN);
880 }
881
882 /* Set the BSSID from the joined/started descriptor */
883 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
884
885 /* Set the new SSID to current SSID */
886 memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN);
887 priv->curbssparams.ssid_len = bss->ssid_len;
888
889 netif_carrier_on(priv->dev);
890 if (!priv->tx_pending_len)
891 netif_wake_queue(priv->dev);
892
893 memset(&wrqu, 0, sizeof(wrqu));
894 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
895 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
896 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
897
898 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
899 print_ssid(ssid, bss->ssid, bss->ssid_len),
900 priv->curbssparams.bssid,
901 priv->channel);
902
903done:
904 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
905 return ret;
906}
907
908/**
909 * @brief Join an adhoc network found in a previous scan
910 *
911 * @param priv A pointer to struct lbs_private structure
912 * @param assoc_req The association request describing the BSS to join
913 *
914 * @return 0 on success, error on failure
915 */
916static int lbs_adhoc_join(struct lbs_private *priv,
917 struct assoc_request *assoc_req)
918{
919 struct cmd_ds_802_11_ad_hoc_join cmd;
920 struct bss_descriptor *bss = &assoc_req->bss;
921 u8 preamble = RADIO_PREAMBLE_LONG;
922 DECLARE_SSID_BUF(ssid);
923 u16 ratesize = 0;
924 int ret = 0;
925
926 lbs_deb_enter(LBS_DEB_ASSOC);
927
928 lbs_deb_join("current SSID '%s', ssid length %u\n",
929 print_ssid(ssid, priv->curbssparams.ssid,
930 priv->curbssparams.ssid_len),
931 priv->curbssparams.ssid_len);
932 lbs_deb_join("requested ssid '%s', ssid length %u\n",
933 print_ssid(ssid, bss->ssid, bss->ssid_len),
934 bss->ssid_len);
935
936 /* check if the requested SSID is already joined */
937 if (priv->curbssparams.ssid_len &&
938 !lbs_ssid_cmp(priv->curbssparams.ssid,
939 priv->curbssparams.ssid_len,
940 bss->ssid, bss->ssid_len) &&
941 (priv->mode == IW_MODE_ADHOC) &&
942 (priv->connect_status == LBS_CONNECTED)) {
943 union iwreq_data wrqu;
944
945 lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as "
946 "current, not attempting to re-join");
947
948 /* Send the re-association event though, because the association
949 * request really was successful, even if just a null-op.
950 */
951 memset(&wrqu, 0, sizeof(wrqu));
952 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid,
953 ETH_ALEN);
954 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
955 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
956 goto out;
957 }
958
959 /* Use short preamble only when both the BSS and firmware support it */
960 if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
961 lbs_deb_join("AdhocJoin: Short preamble\n");
962 preamble = RADIO_PREAMBLE_SHORT;
963 }
964
965 ret = lbs_set_radio(priv, preamble, 1);
966 if (ret)
967 goto out;
968
969 lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
970 lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
971
972 priv->adhoccreate = 0;
973 priv->channel = bss->channel;
974
975 /* Build the join command */
976 memset(&cmd, 0, sizeof(cmd));
977 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
978
979 cmd.bss.type = CMD_BSS_TYPE_IBSS;
980 cmd.bss.beaconperiod = cpu_to_le16(bss->beaconperiod);
981
982 memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN);
983 memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len);
984
985 memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set));
986
987 memcpy(&cmd.bss.ibss, &bss->ss.ibss,
988 sizeof(struct ieee_ie_ibss_param_set));
989
990 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
991 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
992 bss->capability, CAPINFO_MASK);
993
994 /* information on BSSID descriptor passed to FW */
995 lbs_deb_join("ADHOC_J_CMD: BSSID = %pM, SSID = '%s'\n",
996 cmd.bss.bssid, cmd.bss.ssid);
997
998 /* Only v8 and below support setting these */
999 if (priv->fwrelease < 0x09000000) {
1000 /* failtimeout */
1001 cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1002 /* probedelay */
1003 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1004 }
1005
1006 /* Copy Data rates from the rates recorded in scan response */
1007 memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates));
1008 ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), ARRAY_SIZE (bss->rates));
1009 memcpy(cmd.bss.rates, bss->rates, ratesize);
1010 if (get_common_rates(priv, cmd.bss.rates, &ratesize)) {
1011 lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n");
1012 ret = -1;
1013 goto out;
1014 }
1015
1016 /* Copy the ad-hoc creation rates into Current BSS state structure */
1017 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1018 memcpy(&priv->curbssparams.rates, cmd.bss.rates, ratesize);
1019
1020 /* Set MSB on basic rates as the firmware requires, but _after_
1021 * copying to current bss rates.
1022 */
1023 lbs_set_basic_rate_flags(cmd.bss.rates, ratesize);
1024
1025 cmd.bss.ibss.atimwindow = bss->atimwindow;
1026
1027 if (assoc_req->secinfo.wep_enabled) {
1028 u16 tmp = le16_to_cpu(cmd.bss.capability);
1029 tmp |= WLAN_CAPABILITY_PRIVACY;
1030 cmd.bss.capability = cpu_to_le16(tmp);
1031 }
1032
1033 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
1034 __le32 local_ps_mode = cpu_to_le32(LBS802_11POWERMODECAM);
1035
1036 /* wake up first */
1037 ret = lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
1038 CMD_ACT_SET, 0, 0,
1039 &local_ps_mode);
1040 if (ret) {
1041 ret = -1;
1042 goto out;
1043 }
1044 }
1045
1046 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
1047 if (ret == 0) {
1048 ret = lbs_adhoc_post(priv,
1049 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
1050 }
1051
1052out:
1053 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1054 return ret;
1055}
1056
1057/**
1058 * @brief Start an Adhoc Network
1059 *
1060 * @param priv A pointer to struct lbs_private structure
1061 * @param assoc_req The association request describing the BSS to start
1062 *
1063 * @return 0 on success, error on failure
1064 */
1065static int lbs_adhoc_start(struct lbs_private *priv,
1066 struct assoc_request *assoc_req)
1067{
1068 struct cmd_ds_802_11_ad_hoc_start cmd;
1069 u8 preamble = RADIO_PREAMBLE_SHORT;
1070 size_t ratesize = 0;
1071 u16 tmpcap = 0;
1072 int ret = 0;
1073 DECLARE_SSID_BUF(ssid);
1074
1075 lbs_deb_enter(LBS_DEB_ASSOC);
1076
1077 ret = lbs_set_radio(priv, preamble, 1);
1078 if (ret)
1079 goto out;
1080
1081 /* Build the start command */
1082 memset(&cmd, 0, sizeof(cmd));
1083 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1084
1085 memcpy(cmd.ssid, assoc_req->ssid, assoc_req->ssid_len);
1086
1087 lbs_deb_join("ADHOC_START: SSID '%s', ssid length %u\n",
1088 print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len),
1089 assoc_req->ssid_len);
1090
1091 cmd.bsstype = CMD_BSS_TYPE_IBSS;
1092
1093 if (priv->beacon_period == 0)
1094 priv->beacon_period = MRVDRV_BEACON_INTERVAL;
1095 cmd.beaconperiod = cpu_to_le16(priv->beacon_period);
1096
1097 WARN_ON(!assoc_req->channel);
1098
1099 /* set Physical parameter set */
1100 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1101 cmd.ds.header.len = 1;
1102 cmd.ds.channel = assoc_req->channel;
1103
1104 /* set IBSS parameter set */
1105 cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1106 cmd.ibss.header.len = 2;
1107 cmd.ibss.atimwindow = cpu_to_le16(0);
1108
1109 /* set capability info */
1110 tmpcap = WLAN_CAPABILITY_IBSS;
1111 if (assoc_req->secinfo.wep_enabled ||
1112 assoc_req->secinfo.WPAenabled ||
1113 assoc_req->secinfo.WPA2enabled) {
1114 lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n");
1115 tmpcap |= WLAN_CAPABILITY_PRIVACY;
1116 } else
1117 lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n");
1118
1119 cmd.capability = cpu_to_le16(tmpcap);
1120
1121 /* Only v8 and below support setting probe delay */
1122 if (priv->fwrelease < 0x09000000)
1123 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1124
1125 ratesize = min(sizeof(cmd.rates), sizeof(lbs_bg_rates));
1126 memcpy(cmd.rates, lbs_bg_rates, ratesize);
1127
1128 /* Copy the ad-hoc creating rates into Current BSS state structure */
1129 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1130 memcpy(&priv->curbssparams.rates, &cmd.rates, ratesize);
1131
1132 /* Set MSB on basic rates as the firmware requires, but _after_
1133 * copying to current bss rates.
1134 */
1135 lbs_set_basic_rate_flags(cmd.rates, ratesize);
1136
1137 lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n",
1138 cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]);
1139
1140 lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n",
1141 assoc_req->channel, assoc_req->band);
1142
1143 priv->adhoccreate = 1;
1144 priv->mode = IW_MODE_ADHOC;
1145
1146 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
1147 if (ret == 0)
1148 ret = lbs_adhoc_post(priv,
1149 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
1150
1151out:
1152 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1153 return ret;
1154}
1155
1156/**
1157 * @brief Stop and Ad-Hoc network and exit Ad-Hoc mode
1158 *
1159 * @param priv A pointer to struct lbs_private structure
1160 * @return 0 on success, or an error
1161 */
1162int lbs_adhoc_stop(struct lbs_private *priv)
1163{
1164 struct cmd_ds_802_11_ad_hoc_stop cmd;
1165 int ret;
1166
1167 lbs_deb_enter(LBS_DEB_JOIN);
1168
1169 memset(&cmd, 0, sizeof (cmd));
1170 cmd.hdr.size = cpu_to_le16 (sizeof (cmd));
1171
1172 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
1173
1174 /* Clean up everything even if there was an error */
1175 lbs_mac_event_disconnected(priv);
1176
1177 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1178 return ret;
1179}
1180
1181static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
1182 struct bss_descriptor *match_bss)
1183{
1184 if (!secinfo->wep_enabled &&
1185 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1186 match_bss->wpa_ie[0] != WLAN_EID_GENERIC &&
1187 match_bss->rsn_ie[0] != WLAN_EID_RSN &&
1188 !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1189 return 1;
1190 else
1191 return 0;
1192}
1193
1194static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
1195 struct bss_descriptor *match_bss)
1196{
1197 if (secinfo->wep_enabled &&
1198 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1199 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1200 return 1;
1201 else
1202 return 0;
1203}
1204
1205static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
1206 struct bss_descriptor *match_bss)
1207{
1208 if (!secinfo->wep_enabled && secinfo->WPAenabled &&
1209 (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
1210 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
1211 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
1212 )
1213 return 1;
1214 else
1215 return 0;
1216}
1217
1218static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
1219 struct bss_descriptor *match_bss)
1220{
1221 if (!secinfo->wep_enabled && secinfo->WPA2enabled &&
1222 (match_bss->rsn_ie[0] == WLAN_EID_RSN)
1223 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
1224 (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
1225 )
1226 return 1;
1227 else
1228 return 0;
1229}
1230
1231static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
1232 struct bss_descriptor *match_bss)
1233{
1234 if (!secinfo->wep_enabled &&
1235 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1236 (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) &&
1237 (match_bss->rsn_ie[0] != WLAN_EID_RSN) &&
1238 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1239 return 1;
1240 else
1241 return 0;
1242}
1243
1244/**
1245 * @brief Check if a scanned network compatible with the driver settings
1246 *
1247 * WEP WPA WPA2 ad-hoc encrypt Network
1248 * enabled enabled enabled AES mode privacy WPA WPA2 Compatible
1249 * 0 0 0 0 NONE 0 0 0 yes No security
1250 * 1 0 0 0 NONE 1 0 0 yes Static WEP
1251 * 0 1 0 0 x 1x 1 x yes WPA
1252 * 0 0 1 0 x 1x x 1 yes WPA2
1253 * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES
1254 * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP
1255 *
1256 *
1257 * @param priv A pointer to struct lbs_private
1258 * @param index Index in scantable to check against current driver settings
1259 * @param mode Network mode: Infrastructure or IBSS
1260 *
1261 * @return Index in scantable, or error code if negative
1262 */
1263static int is_network_compatible(struct lbs_private *priv,
1264 struct bss_descriptor *bss, uint8_t mode)
1265{
1266 int matched = 0;
1267
1268 lbs_deb_enter(LBS_DEB_SCAN);
1269
1270 if (bss->mode != mode)
1271 goto done;
1272
1273 matched = match_bss_no_security(&priv->secinfo, bss);
1274 if (matched)
1275 goto done;
1276 matched = match_bss_static_wep(&priv->secinfo, bss);
1277 if (matched)
1278 goto done;
1279 matched = match_bss_wpa(&priv->secinfo, bss);
1280 if (matched) {
1281 lbs_deb_scan("is_network_compatible() WPA: wpa_ie 0x%x "
1282 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
1283 "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
1284 priv->secinfo.wep_enabled ? "e" : "d",
1285 priv->secinfo.WPAenabled ? "e" : "d",
1286 priv->secinfo.WPA2enabled ? "e" : "d",
1287 (bss->capability & WLAN_CAPABILITY_PRIVACY));
1288 goto done;
1289 }
1290 matched = match_bss_wpa2(&priv->secinfo, bss);
1291 if (matched) {
1292 lbs_deb_scan("is_network_compatible() WPA2: wpa_ie 0x%x "
1293 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
1294 "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
1295 priv->secinfo.wep_enabled ? "e" : "d",
1296 priv->secinfo.WPAenabled ? "e" : "d",
1297 priv->secinfo.WPA2enabled ? "e" : "d",
1298 (bss->capability & WLAN_CAPABILITY_PRIVACY));
1299 goto done;
1300 }
1301 matched = match_bss_dynamic_wep(&priv->secinfo, bss);
1302 if (matched) {
1303 lbs_deb_scan("is_network_compatible() dynamic WEP: "
1304 "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n",
1305 bss->wpa_ie[0], bss->rsn_ie[0],
1306 (bss->capability & WLAN_CAPABILITY_PRIVACY));
1307 goto done;
1308 }
1309
1310 /* bss security settings don't match those configured on card */
1311 lbs_deb_scan("is_network_compatible() FAILED: wpa_ie 0x%x "
1312 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n",
1313 bss->wpa_ie[0], bss->rsn_ie[0],
1314 priv->secinfo.wep_enabled ? "e" : "d",
1315 priv->secinfo.WPAenabled ? "e" : "d",
1316 priv->secinfo.WPA2enabled ? "e" : "d",
1317 (bss->capability & WLAN_CAPABILITY_PRIVACY));
1318
1319done:
1320 lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched);
1321 return matched;
1322}
1323
1324/**
1325 * @brief This function finds a specific compatible BSSID in the scan list
1326 *
1327 * Used in association code
1328 *
1329 * @param priv A pointer to struct lbs_private
1330 * @param bssid BSSID to find in the scan list
1331 * @param mode Network mode: Infrastructure or IBSS
1332 *
1333 * @return index in BSSID list, or error return code (< 0)
1334 */
1335static struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv,
1336 uint8_t *bssid, uint8_t mode)
1337{
1338 struct bss_descriptor *iter_bss;
1339 struct bss_descriptor *found_bss = NULL;
1340
1341 lbs_deb_enter(LBS_DEB_SCAN);
1342
1343 if (!bssid)
1344 goto out;
1345
1346 lbs_deb_hex(LBS_DEB_SCAN, "looking for", bssid, ETH_ALEN);
1347
1348 /* Look through the scan table for a compatible match. The loop will
1349 * continue past a matched bssid that is not compatible in case there
1350 * is an AP with multiple SSIDs assigned to the same BSSID
1351 */
1352 mutex_lock(&priv->lock);
1353 list_for_each_entry(iter_bss, &priv->network_list, list) {
1354 if (compare_ether_addr(iter_bss->bssid, bssid))
1355 continue; /* bssid doesn't match */
1356 switch (mode) {
1357 case IW_MODE_INFRA:
1358 case IW_MODE_ADHOC:
1359 if (!is_network_compatible(priv, iter_bss, mode))
1360 break;
1361 found_bss = iter_bss;
1362 break;
1363 default:
1364 found_bss = iter_bss;
1365 break;
1366 }
1367 }
1368 mutex_unlock(&priv->lock);
1369
1370out:
1371 lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss);
1372 return found_bss;
1373}
1374
1375/**
1376 * @brief This function finds ssid in ssid list.
1377 *
1378 * Used in association code
1379 *
1380 * @param priv A pointer to struct lbs_private
1381 * @param ssid SSID to find in the list
1382 * @param bssid BSSID to qualify the SSID selection (if provided)
1383 * @param mode Network mode: Infrastructure or IBSS
1384 *
1385 * @return index in BSSID list
1386 */
1387static struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
1388 uint8_t *ssid, uint8_t ssid_len,
1389 uint8_t *bssid, uint8_t mode,
1390 int channel)
1391{
1392 u32 bestrssi = 0;
1393 struct bss_descriptor *iter_bss = NULL;
1394 struct bss_descriptor *found_bss = NULL;
1395 struct bss_descriptor *tmp_oldest = NULL;
1396
1397 lbs_deb_enter(LBS_DEB_SCAN);
1398
1399 mutex_lock(&priv->lock);
1400
1401 list_for_each_entry(iter_bss, &priv->network_list, list) {
1402 if (!tmp_oldest ||
1403 (iter_bss->last_scanned < tmp_oldest->last_scanned))
1404 tmp_oldest = iter_bss;
1405
1406 if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
1407 ssid, ssid_len) != 0)
1408 continue; /* ssid doesn't match */
1409 if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
1410 continue; /* bssid doesn't match */
1411 if ((channel > 0) && (iter_bss->channel != channel))
1412 continue; /* channel doesn't match */
1413
1414 switch (mode) {
1415 case IW_MODE_INFRA:
1416 case IW_MODE_ADHOC:
1417 if (!is_network_compatible(priv, iter_bss, mode))
1418 break;
1419
1420 if (bssid) {
1421 /* Found requested BSSID */
1422 found_bss = iter_bss;
1423 goto out;
1424 }
1425
1426 if (SCAN_RSSI(iter_bss->rssi) > bestrssi) {
1427 bestrssi = SCAN_RSSI(iter_bss->rssi);
1428 found_bss = iter_bss;
1429 }
1430 break;
1431 case IW_MODE_AUTO:
1432 default:
1433 if (SCAN_RSSI(iter_bss->rssi) > bestrssi) {
1434 bestrssi = SCAN_RSSI(iter_bss->rssi);
1435 found_bss = iter_bss;
1436 }
1437 break;
1438 }
1439 }
1440
1441out:
1442 mutex_unlock(&priv->lock);
1443 lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss);
1444 return found_bss;
1445}
1446
1447static int assoc_helper_essid(struct lbs_private *priv,
1448 struct assoc_request * assoc_req)
1449{
1450 int ret = 0;
1451 struct bss_descriptor * bss;
1452 int channel = -1;
1453 DECLARE_SSID_BUF(ssid);
1454
1455 lbs_deb_enter(LBS_DEB_ASSOC);
1456
1457 /* FIXME: take channel into account when picking SSIDs if a channel
1458 * is set.
1459 */
1460
1461 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
1462 channel = assoc_req->channel;
1463
1464 lbs_deb_assoc("SSID '%s' requested\n",
1465 print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len));
1466 if (assoc_req->mode == IW_MODE_INFRA) {
1467 lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
1468 assoc_req->ssid_len);
1469
1470 bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
1471 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
1472 if (bss != NULL) {
1473 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
1474 ret = lbs_try_associate(priv, assoc_req);
1475 } else {
1476 lbs_deb_assoc("SSID not found; cannot associate\n");
1477 }
1478 } else if (assoc_req->mode == IW_MODE_ADHOC) {
1479 /* Scan for the network, do not save previous results. Stale
1480 * scan data will cause us to join a non-existant adhoc network
1481 */
1482 lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
1483 assoc_req->ssid_len);
1484
1485 /* Search for the requested SSID in the scan table */
1486 bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
1487 assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel);
1488 if (bss != NULL) {
1489 lbs_deb_assoc("SSID found, will join\n");
1490 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
1491 lbs_adhoc_join(priv, assoc_req);
1492 } else {
1493 /* else send START command */
1494 lbs_deb_assoc("SSID not found, creating adhoc network\n");
1495 memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
1496 IEEE80211_MAX_SSID_LEN);
1497 assoc_req->bss.ssid_len = assoc_req->ssid_len;
1498 lbs_adhoc_start(priv, assoc_req);
1499 }
1500 }
1501
1502 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1503 return ret;
1504}
1505
1506
1507static int assoc_helper_bssid(struct lbs_private *priv,
1508 struct assoc_request * assoc_req)
1509{
1510 int ret = 0;
1511 struct bss_descriptor * bss;
1512
1513 lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %pM", assoc_req->bssid);
1514
1515 /* Search for index position in list for requested MAC */
1516 bss = lbs_find_bssid_in_list(priv, assoc_req->bssid,
1517 assoc_req->mode);
1518 if (bss == NULL) {
1519 lbs_deb_assoc("ASSOC: WAP: BSSID %pM not found, "
1520 "cannot associate.\n", assoc_req->bssid);
1521 goto out;
1522 }
1523
1524 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
1525 if (assoc_req->mode == IW_MODE_INFRA) {
1526 ret = lbs_try_associate(priv, assoc_req);
1527 lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n",
1528 ret);
1529 } else if (assoc_req->mode == IW_MODE_ADHOC) {
1530 lbs_adhoc_join(priv, assoc_req);
1531 }
1532
1533out:
1534 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1535 return ret;
1536}
1537
1538
1539static int assoc_helper_associate(struct lbs_private *priv,
1540 struct assoc_request * assoc_req)
1541{
1542 int ret = 0, done = 0;
1543
1544 lbs_deb_enter(LBS_DEB_ASSOC);
1545
1546 /* If we're given and 'any' BSSID, try associating based on SSID */
1547
1548 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1549 if (compare_ether_addr(bssid_any, assoc_req->bssid) &&
1550 compare_ether_addr(bssid_off, assoc_req->bssid)) {
1551 ret = assoc_helper_bssid(priv, assoc_req);
1552 done = 1;
1553 }
1554 }
1555
1556 if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
1557 ret = assoc_helper_essid(priv, assoc_req);
1558 }
1559
1560 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1561 return ret;
1562}
1563
1564
1565static int assoc_helper_mode(struct lbs_private *priv,
1566 struct assoc_request * assoc_req)
1567{
1568 int ret = 0;
1569
1570 lbs_deb_enter(LBS_DEB_ASSOC);
1571
1572 if (assoc_req->mode == priv->mode)
1573 goto done;
1574
1575 if (assoc_req->mode == IW_MODE_INFRA) {
1576 if (priv->psstate != PS_STATE_FULL_POWER)
1577 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1578 priv->psmode = LBS802_11POWERMODECAM;
1579 }
1580
1581 priv->mode = assoc_req->mode;
1582 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE,
1583 assoc_req->mode == IW_MODE_ADHOC ? 2 : 1);
1584
1585done:
1586 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1587 return ret;
1588}
1589
1590static int assoc_helper_channel(struct lbs_private *priv,
1591 struct assoc_request * assoc_req)
1592{
1593 int ret = 0;
1594
1595 lbs_deb_enter(LBS_DEB_ASSOC);
1596
1597 ret = lbs_update_channel(priv);
1598 if (ret) {
1599 lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
1600 goto done;
1601 }
1602
1603 if (assoc_req->channel == priv->channel)
1604 goto done;
1605
1606 if (priv->mesh_dev) {
1607 /* Change mesh channel first; 21.p21 firmware won't let
1608 you change channel otherwise (even though it'll return
1609 an error to this */
1610 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
1611 assoc_req->channel);
1612 }
1613
1614 lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
1615 priv->channel, assoc_req->channel);
1616
1617 ret = lbs_set_channel(priv, assoc_req->channel);
1618 if (ret < 0)
1619 lbs_deb_assoc("ASSOC: channel: error setting channel.\n");
1620
1621 /* FIXME: shouldn't need to grab the channel _again_ after setting
1622 * it since the firmware is supposed to return the new channel, but
1623 * whatever... */
1624 ret = lbs_update_channel(priv);
1625 if (ret) {
1626 lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
1627 goto done;
1628 }
1629
1630 if (assoc_req->channel != priv->channel) {
1631 lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
1632 assoc_req->channel);
1633 goto restore_mesh;
1634 }
1635
1636 if (assoc_req->secinfo.wep_enabled &&
1637 (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
1638 assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) {
1639 /* Make sure WEP keys are re-sent to firmware */
1640 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1641 }
1642
1643 /* Must restart/rejoin adhoc networks after channel change */
1644 set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
1645
1646 restore_mesh:
1647 if (priv->mesh_dev)
1648 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1649 priv->channel);
1650
1651 done:
1652 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1653 return ret;
1654}
1655
1656
1657static int assoc_helper_wep_keys(struct lbs_private *priv,
1658 struct assoc_request *assoc_req)
1659{
1660 int i;
1661 int ret = 0;
1662
1663 lbs_deb_enter(LBS_DEB_ASSOC);
1664
1665 /* Set or remove WEP keys */
1666 if (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
1667 assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)
1668 ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_ADD, assoc_req);
1669 else
1670 ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_REMOVE, assoc_req);
1671
1672 if (ret)
1673 goto out;
1674
1675 /* enable/disable the MAC's WEP packet filter */
1676 if (assoc_req->secinfo.wep_enabled)
1677 priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
1678 else
1679 priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
1680
1681 lbs_set_mac_control(priv);
1682
1683 mutex_lock(&priv->lock);
1684
1685 /* Copy WEP keys into priv wep key fields */
1686 for (i = 0; i < 4; i++) {
1687 memcpy(&priv->wep_keys[i], &assoc_req->wep_keys[i],
1688 sizeof(struct enc_key));
1689 }
1690 priv->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
1691
1692 mutex_unlock(&priv->lock);
1693
1694out:
1695 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1696 return ret;
1697}
1698
1699static int assoc_helper_secinfo(struct lbs_private *priv,
1700 struct assoc_request * assoc_req)
1701{
1702 int ret = 0;
1703 uint16_t do_wpa;
1704 uint16_t rsn = 0;
1705
1706 lbs_deb_enter(LBS_DEB_ASSOC);
1707
1708 memcpy(&priv->secinfo, &assoc_req->secinfo,
1709 sizeof(struct lbs_802_11_security));
1710
1711 lbs_set_mac_control(priv);
1712
1713 /* If RSN is already enabled, don't try to enable it again, since
1714 * ENABLE_RSN resets internal state machines and will clobber the
1715 * 4-way WPA handshake.
1716 */
1717
1718 /* Get RSN enabled/disabled */
1719 ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_GET, &rsn);
1720 if (ret) {
1721 lbs_deb_assoc("Failed to get RSN status: %d\n", ret);
1722 goto out;
1723 }
1724
1725 /* Don't re-enable RSN if it's already enabled */
1726 do_wpa = assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled;
1727 if (do_wpa == rsn)
1728 goto out;
1729
1730 /* Set RSN enabled/disabled */
1731 ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_SET, &do_wpa);
1732
1733out:
1734 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1735 return ret;
1736}
1737
1738
1739static int assoc_helper_wpa_keys(struct lbs_private *priv,
1740 struct assoc_request * assoc_req)
1741{
1742 int ret = 0;
1743 unsigned int flags = assoc_req->flags;
1744
1745 lbs_deb_enter(LBS_DEB_ASSOC);
1746
1747 /* Work around older firmware bug where WPA unicast and multicast
1748 * keys must be set independently. Seen in SDIO parts with firmware
1749 * version 5.0.11p0.
1750 */
1751
1752 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
1753 clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
1754 ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
1755 assoc_req->flags = flags;
1756 }
1757
1758 if (ret)
1759 goto out;
1760
1761 memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_unicast_key,
1762 sizeof(struct enc_key));
1763
1764 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
1765 clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
1766
1767 ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
1768 assoc_req->flags = flags;
1769
1770 memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key,
1771 sizeof(struct enc_key));
1772 }
1773
1774out:
1775 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1776 return ret;
1777}
1778
1779
1780static int assoc_helper_wpa_ie(struct lbs_private *priv,
1781 struct assoc_request * assoc_req)
1782{
1783 int ret = 0;
1784
1785 lbs_deb_enter(LBS_DEB_ASSOC);
1786
1787 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
1788 memcpy(&priv->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
1789 priv->wpa_ie_len = assoc_req->wpa_ie_len;
1790 } else {
1791 memset(&priv->wpa_ie, 0, MAX_WPA_IE_LEN);
1792 priv->wpa_ie_len = 0;
1793 }
1794
1795 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1796 return ret;
1797}
1798
1799
1800static int should_deauth_infrastructure(struct lbs_private *priv,
1801 struct assoc_request * assoc_req)
1802{
1803 int ret = 0;
1804
1805 if (priv->connect_status != LBS_CONNECTED)
1806 return 0;
1807
1808 lbs_deb_enter(LBS_DEB_ASSOC);
1809 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
1810 lbs_deb_assoc("Deauthenticating due to new SSID\n");
1811 ret = 1;
1812 goto out;
1813 }
1814
1815 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
1816 if (priv->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
1817 lbs_deb_assoc("Deauthenticating due to new security\n");
1818 ret = 1;
1819 goto out;
1820 }
1821 }
1822
1823 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1824 lbs_deb_assoc("Deauthenticating due to new BSSID\n");
1825 ret = 1;
1826 goto out;
1827 }
1828
1829 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
1830 lbs_deb_assoc("Deauthenticating due to channel switch\n");
1831 ret = 1;
1832 goto out;
1833 }
1834
1835 /* FIXME: deal with 'auto' mode somehow */
1836 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
1837 if (assoc_req->mode != IW_MODE_INFRA) {
1838 lbs_deb_assoc("Deauthenticating due to leaving "
1839 "infra mode\n");
1840 ret = 1;
1841 goto out;
1842 }
1843 }
1844
1845out:
1846 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1847 return ret;
1848}
1849
1850
1851static int should_stop_adhoc(struct lbs_private *priv,
1852 struct assoc_request * assoc_req)
1853{
1854 lbs_deb_enter(LBS_DEB_ASSOC);
1855
1856 if (priv->connect_status != LBS_CONNECTED)
1857 return 0;
1858
1859 if (lbs_ssid_cmp(priv->curbssparams.ssid,
1860 priv->curbssparams.ssid_len,
1861 assoc_req->ssid, assoc_req->ssid_len) != 0)
1862 return 1;
1863
1864 /* FIXME: deal with 'auto' mode somehow */
1865 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
1866 if (assoc_req->mode != IW_MODE_ADHOC)
1867 return 1;
1868 }
1869
1870 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
1871 if (assoc_req->channel != priv->channel)
1872 return 1;
1873 }
1874
1875 lbs_deb_leave(LBS_DEB_ASSOC);
1876 return 0;
1877}
1878
1879
1880/**
1881 * @brief This function finds the best SSID in the Scan List
1882 *
1883 * Search the scan table for the best SSID that also matches the current
1884 * adapter network preference (infrastructure or adhoc)
1885 *
1886 * @param priv A pointer to struct lbs_private
1887 *
1888 * @return index in BSSID list
1889 */
1890static struct bss_descriptor *lbs_find_best_ssid_in_list(
1891 struct lbs_private *priv, uint8_t mode)
1892{
1893 uint8_t bestrssi = 0;
1894 struct bss_descriptor *iter_bss;
1895 struct bss_descriptor *best_bss = NULL;
1896
1897 lbs_deb_enter(LBS_DEB_SCAN);
1898
1899 mutex_lock(&priv->lock);
1900
1901 list_for_each_entry(iter_bss, &priv->network_list, list) {
1902 switch (mode) {
1903 case IW_MODE_INFRA:
1904 case IW_MODE_ADHOC:
1905 if (!is_network_compatible(priv, iter_bss, mode))
1906 break;
1907 if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
1908 break;
1909 bestrssi = SCAN_RSSI(iter_bss->rssi);
1910 best_bss = iter_bss;
1911 break;
1912 case IW_MODE_AUTO:
1913 default:
1914 if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
1915 break;
1916 bestrssi = SCAN_RSSI(iter_bss->rssi);
1917 best_bss = iter_bss;
1918 break;
1919 }
1920 }
1921
1922 mutex_unlock(&priv->lock);
1923 lbs_deb_leave_args(LBS_DEB_SCAN, "best_bss %p", best_bss);
1924 return best_bss;
1925}
1926
1927/**
1928 * @brief Find the best AP
1929 *
1930 * Used from association worker.
1931 *
1932 * @param priv A pointer to struct lbs_private structure
1933 * @param pSSID A pointer to AP's ssid
1934 *
1935 * @return 0--success, otherwise--fail
1936 */
1937static int lbs_find_best_network_ssid(struct lbs_private *priv,
1938 uint8_t *out_ssid, uint8_t *out_ssid_len, uint8_t preferred_mode,
1939 uint8_t *out_mode)
1940{
1941 int ret = -1;
1942 struct bss_descriptor *found;
1943
1944 lbs_deb_enter(LBS_DEB_SCAN);
1945
1946 priv->scan_ssid_len = 0;
1947 lbs_scan_networks(priv, 1);
1948 if (priv->surpriseremoved)
1949 goto out;
1950
1951 found = lbs_find_best_ssid_in_list(priv, preferred_mode);
1952 if (found && (found->ssid_len > 0)) {
1953 memcpy(out_ssid, &found->ssid, IEEE80211_MAX_SSID_LEN);
1954 *out_ssid_len = found->ssid_len;
1955 *out_mode = found->mode;
1956 ret = 0;
1957 }
1958
1959out:
1960 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
1961 return ret;
1962}
1963
1964
1965void lbs_association_worker(struct work_struct *work)
1966{
1967 struct lbs_private *priv = container_of(work, struct lbs_private,
1968 assoc_work.work);
1969 struct assoc_request * assoc_req = NULL;
1970 int ret = 0;
1971 int find_any_ssid = 0;
1972 DECLARE_SSID_BUF(ssid);
1973
1974 lbs_deb_enter(LBS_DEB_ASSOC);
1975
1976 mutex_lock(&priv->lock);
1977 assoc_req = priv->pending_assoc_req;
1978 priv->pending_assoc_req = NULL;
1979 priv->in_progress_assoc_req = assoc_req;
1980 mutex_unlock(&priv->lock);
1981
1982 if (!assoc_req)
1983 goto done;
1984
1985 lbs_deb_assoc(
1986 "Association Request:\n"
1987 " flags: 0x%08lx\n"
1988 " SSID: '%s'\n"
1989 " chann: %d\n"
1990 " band: %d\n"
1991 " mode: %d\n"
1992 " BSSID: %pM\n"
1993 " secinfo: %s%s%s\n"
1994 " auth_mode: %d\n",
1995 assoc_req->flags,
1996 print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len),
1997 assoc_req->channel, assoc_req->band, assoc_req->mode,
1998 assoc_req->bssid,
1999 assoc_req->secinfo.WPAenabled ? " WPA" : "",
2000 assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
2001 assoc_req->secinfo.wep_enabled ? " WEP" : "",
2002 assoc_req->secinfo.auth_mode);
2003
2004 /* If 'any' SSID was specified, find an SSID to associate with */
2005 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) &&
2006 !assoc_req->ssid_len)
2007 find_any_ssid = 1;
2008
2009 /* But don't use 'any' SSID if there's a valid locked BSSID to use */
2010 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
2011 if (compare_ether_addr(assoc_req->bssid, bssid_any) &&
2012 compare_ether_addr(assoc_req->bssid, bssid_off))
2013 find_any_ssid = 0;
2014 }
2015
2016 if (find_any_ssid) {
2017 u8 new_mode = assoc_req->mode;
2018
2019 ret = lbs_find_best_network_ssid(priv, assoc_req->ssid,
2020 &assoc_req->ssid_len, assoc_req->mode, &new_mode);
2021 if (ret) {
2022 lbs_deb_assoc("Could not find best network\n");
2023 ret = -ENETUNREACH;
2024 goto out;
2025 }
2026
2027 /* Ensure we switch to the mode of the AP */
2028 if (assoc_req->mode == IW_MODE_AUTO) {
2029 set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
2030 assoc_req->mode = new_mode;
2031 }
2032 }
2033
2034 /*
2035 * Check if the attributes being changing require deauthentication
2036 * from the currently associated infrastructure access point.
2037 */
2038 if (priv->mode == IW_MODE_INFRA) {
2039 if (should_deauth_infrastructure(priv, assoc_req)) {
2040 ret = lbs_cmd_80211_deauthenticate(priv,
2041 priv->curbssparams.bssid,
2042 WLAN_REASON_DEAUTH_LEAVING);
2043 if (ret) {
2044 lbs_deb_assoc("Deauthentication due to new "
2045 "configuration request failed: %d\n",
2046 ret);
2047 }
2048 }
2049 } else if (priv->mode == IW_MODE_ADHOC) {
2050 if (should_stop_adhoc(priv, assoc_req)) {
2051 ret = lbs_adhoc_stop(priv);
2052 if (ret) {
2053 lbs_deb_assoc("Teardown of AdHoc network due to "
2054 "new configuration request failed: %d\n",
2055 ret);
2056 }
2057
2058 }
2059 }
2060
2061 /* Send the various configuration bits to the firmware */
2062 if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
2063 ret = assoc_helper_mode(priv, assoc_req);
2064 if (ret)
2065 goto out;
2066 }
2067
2068 if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
2069 ret = assoc_helper_channel(priv, assoc_req);
2070 if (ret)
2071 goto out;
2072 }
2073
2074 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
2075 ret = assoc_helper_secinfo(priv, assoc_req);
2076 if (ret)
2077 goto out;
2078 }
2079
2080 if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
2081 ret = assoc_helper_wpa_ie(priv, assoc_req);
2082 if (ret)
2083 goto out;
2084 }
2085
2086 /*
2087 * v10 FW wants WPA keys to be set/cleared before WEP key operations,
2088 * otherwise it will fail to correctly associate to WEP networks.
2089 * Other firmware versions don't appear to care.
2090 */
2091 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) ||
2092 test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
2093 ret = assoc_helper_wpa_keys(priv, assoc_req);
2094 if (ret)
2095 goto out;
2096 }
2097
2098 if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) ||
2099 test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
2100 ret = assoc_helper_wep_keys(priv, assoc_req);
2101 if (ret)
2102 goto out;
2103 }
2104
2105
2106 /* SSID/BSSID should be the _last_ config option set, because they
2107 * trigger the association attempt.
2108 */
2109 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) ||
2110 test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
2111 int success = 1;
2112
2113 ret = assoc_helper_associate(priv, assoc_req);
2114 if (ret) {
2115 lbs_deb_assoc("ASSOC: association unsuccessful: %d\n",
2116 ret);
2117 success = 0;
2118 }
2119
2120 if (priv->connect_status != LBS_CONNECTED) {
2121 lbs_deb_assoc("ASSOC: association unsuccessful, "
2122 "not connected\n");
2123 success = 0;
2124 }
2125
2126 if (success) {
2127 lbs_deb_assoc("associated to %pM\n",
2128 priv->curbssparams.bssid);
2129 lbs_prepare_and_send_command(priv,
2130 CMD_802_11_RSSI,
2131 0, CMD_OPTION_WAITFORRSP, 0, NULL);
2132 } else {
2133 ret = -1;
2134 }
2135 }
2136
2137out:
2138 if (ret) {
2139 lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n",
2140 ret);
2141 }
2142
2143 mutex_lock(&priv->lock);
2144 priv->in_progress_assoc_req = NULL;
2145 mutex_unlock(&priv->lock);
2146 kfree(assoc_req);
2147
2148done:
2149 lbs_deb_leave(LBS_DEB_ASSOC);
2150}
2151
2152
2153/*
2154 * Caller MUST hold any necessary locks
2155 */
2156struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
2157{
2158 struct assoc_request * assoc_req;
2159
2160 lbs_deb_enter(LBS_DEB_ASSOC);
2161 if (!priv->pending_assoc_req) {
2162 priv->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
2163 GFP_KERNEL);
2164 if (!priv->pending_assoc_req) {
2165 lbs_pr_info("Not enough memory to allocate association"
2166 " request!\n");
2167 return NULL;
2168 }
2169 }
2170
2171 /* Copy current configuration attributes to the association request,
2172 * but don't overwrite any that are already set.
2173 */
2174 assoc_req = priv->pending_assoc_req;
2175 if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
2176 memcpy(&assoc_req->ssid, &priv->curbssparams.ssid,
2177 IEEE80211_MAX_SSID_LEN);
2178 assoc_req->ssid_len = priv->curbssparams.ssid_len;
2179 }
2180
2181 if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
2182 assoc_req->channel = priv->channel;
2183
2184 if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
2185 assoc_req->band = priv->curbssparams.band;
2186
2187 if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
2188 assoc_req->mode = priv->mode;
2189
2190 if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
2191 memcpy(&assoc_req->bssid, priv->curbssparams.bssid,
2192 ETH_ALEN);
2193 }
2194
2195 if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) {
2196 int i;
2197 for (i = 0; i < 4; i++) {
2198 memcpy(&assoc_req->wep_keys[i], &priv->wep_keys[i],
2199 sizeof(struct enc_key));
2200 }
2201 }
2202
2203 if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags))
2204 assoc_req->wep_tx_keyidx = priv->wep_tx_keyidx;
2205
2206 if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
2207 memcpy(&assoc_req->wpa_mcast_key, &priv->wpa_mcast_key,
2208 sizeof(struct enc_key));
2209 }
2210
2211 if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
2212 memcpy(&assoc_req->wpa_unicast_key, &priv->wpa_unicast_key,
2213 sizeof(struct enc_key));
2214 }
2215
2216 if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
2217 memcpy(&assoc_req->secinfo, &priv->secinfo,
2218 sizeof(struct lbs_802_11_security));
2219 }
2220
2221 if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
2222 memcpy(&assoc_req->wpa_ie, &priv->wpa_ie,
2223 MAX_WPA_IE_LEN);
2224 assoc_req->wpa_ie_len = priv->wpa_ie_len;
2225 }
2226
2227 lbs_deb_leave(LBS_DEB_ASSOC);
2228 return assoc_req;
2229}
2230
2231
2232/**
2233 * @brief Deauthenticate from a specific BSS
2234 *
2235 * @param priv A pointer to struct lbs_private structure
2236 * @param bssid The specific BSS to deauthenticate from
2237 * @param reason The 802.11 sec. 7.3.1.7 Reason Code for deauthenticating
2238 *
2239 * @return 0 on success, error on failure
2240 */
2241int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
2242 u16 reason)
2243{
2244 struct cmd_ds_802_11_deauthenticate cmd;
2245 int ret;
2246
2247 lbs_deb_enter(LBS_DEB_JOIN);
2248
2249 memset(&cmd, 0, sizeof(cmd));
2250 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2251 memcpy(cmd.macaddr, &bssid[0], ETH_ALEN);
2252 cmd.reasoncode = cpu_to_le16(reason);
2253
2254 ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
2255
2256 /* Clean up everything even if there was an error; can't assume that
2257 * we're still authenticated to the AP after trying to deauth.
2258 */
2259 lbs_mac_event_disconnected(priv);
2260
2261 lbs_deb_leave(LBS_DEB_JOIN);
2262 return ret;
2263}
2264
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
deleted file mode 100644
index 40621b789fc5..000000000000
--- a/drivers/net/wireless/libertas/assoc.h
+++ /dev/null
@@ -1,155 +0,0 @@
1/* Copyright (C) 2006, Red Hat, Inc. */
2
3#ifndef _LBS_ASSOC_H_
4#define _LBS_ASSOC_H_
5
6
7#include "defs.h"
8#include "host.h"
9
10
11struct lbs_private;
12
13/*
14 * In theory, the IE is limited to the IE length, 255,
15 * but in practice 64 bytes are enough.
16 */
17#define MAX_WPA_IE_LEN 64
18
19
20
21struct lbs_802_11_security {
22 u8 WPAenabled;
23 u8 WPA2enabled;
24 u8 wep_enabled;
25 u8 auth_mode;
26 u32 key_mgmt;
27};
28
29/** Current Basic Service Set State Structure */
30struct current_bss_params {
31 /** bssid */
32 u8 bssid[ETH_ALEN];
33 /** ssid */
34 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
35 u8 ssid_len;
36
37 /** band */
38 u8 band;
39 /** channel is directly in priv->channel */
40 /** zero-terminated array of supported data rates */
41 u8 rates[MAX_RATES + 1];
42};
43
44/**
45 * @brief Structure used to store information for each beacon/probe response
46 */
47struct bss_descriptor {
48 u8 bssid[ETH_ALEN];
49
50 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
51 u8 ssid_len;
52
53 u16 capability;
54 u32 rssi;
55 u32 channel;
56 u16 beaconperiod;
57 __le16 atimwindow;
58
59 /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
60 u8 mode;
61
62 /* zero-terminated array of supported data rates */
63 u8 rates[MAX_RATES + 1];
64
65 unsigned long last_scanned;
66
67 union ieee_phy_param_set phy;
68 union ieee_ss_param_set ss;
69
70 u8 wpa_ie[MAX_WPA_IE_LEN];
71 size_t wpa_ie_len;
72 u8 rsn_ie[MAX_WPA_IE_LEN];
73 size_t rsn_ie_len;
74
75 u8 mesh;
76
77 struct list_head list;
78};
79
80/** Association request
81 *
82 * Encapsulates all the options that describe a specific assocation request
83 * or configuration of the wireless card's radio, mode, and security settings.
84 */
85struct assoc_request {
86#define ASSOC_FLAG_SSID 1
87#define ASSOC_FLAG_CHANNEL 2
88#define ASSOC_FLAG_BAND 3
89#define ASSOC_FLAG_MODE 4
90#define ASSOC_FLAG_BSSID 5
91#define ASSOC_FLAG_WEP_KEYS 6
92#define ASSOC_FLAG_WEP_TX_KEYIDX 7
93#define ASSOC_FLAG_WPA_MCAST_KEY 8
94#define ASSOC_FLAG_WPA_UCAST_KEY 9
95#define ASSOC_FLAG_SECINFO 10
96#define ASSOC_FLAG_WPA_IE 11
97 unsigned long flags;
98
99 u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
100 u8 ssid_len;
101 u8 channel;
102 u8 band;
103 u8 mode;
104 u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
105
106 /** WEP keys */
107 struct enc_key wep_keys[4];
108 u16 wep_tx_keyidx;
109
110 /** WPA keys */
111 struct enc_key wpa_mcast_key;
112 struct enc_key wpa_unicast_key;
113
114 struct lbs_802_11_security secinfo;
115
116 /** WPA Information Elements*/
117 u8 wpa_ie[MAX_WPA_IE_LEN];
118 u8 wpa_ie_len;
119
120 /* BSS to associate with for infrastructure of Ad-Hoc join */
121 struct bss_descriptor bss;
122};
123
124
125extern u8 lbs_bg_rates[MAX_RATES];
126
127void lbs_association_worker(struct work_struct *work);
128struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
129
130int lbs_adhoc_stop(struct lbs_private *priv);
131
132int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
133 u8 bssid[ETH_ALEN], u16 reason);
134
135int lbs_cmd_802_11_rssi(struct lbs_private *priv,
136 struct cmd_ds_command *cmd);
137int lbs_ret_802_11_rssi(struct lbs_private *priv,
138 struct cmd_ds_command *resp);
139
140int lbs_cmd_bcn_ctrl(struct lbs_private *priv,
141 struct cmd_ds_command *cmd,
142 u16 cmd_action);
143int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv,
144 struct cmd_ds_command *resp);
145
146int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
147 struct assoc_request *assoc);
148
149int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
150 uint16_t *enable);
151
152int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
153 struct assoc_request *assoc);
154
155#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 9d5d3ccf08c8..f36cc970ad1b 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -7,8 +7,12 @@
7 */ 7 */
8 8
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/if_arp.h>
11#include <linux/ieee80211.h>
10#include <net/cfg80211.h> 12#include <net/cfg80211.h>
13#include <asm/unaligned.h>
11 14
15#include "decl.h"
12#include "cfg.h" 16#include "cfg.h"
13#include "cmd.h" 17#include "cmd.h"
14 18
@@ -39,26 +43,27 @@ static struct ieee80211_channel lbs_2ghz_channels[] = {
39 CHAN2G(14, 2484, 0), 43 CHAN2G(14, 2484, 0),
40}; 44};
41 45
42#define RATETAB_ENT(_rate, _rateid, _flags) { \ 46#define RATETAB_ENT(_rate, _hw_value, _flags) { \
43 .bitrate = (_rate), \ 47 .bitrate = (_rate), \
44 .hw_value = (_rateid), \ 48 .hw_value = (_hw_value), \
45 .flags = (_flags), \ 49 .flags = (_flags), \
46} 50}
47 51
48 52
53/* Table 6 in section 3.2.1.1 */
49static struct ieee80211_rate lbs_rates[] = { 54static struct ieee80211_rate lbs_rates[] = {
50 RATETAB_ENT(10, 0x1, 0), 55 RATETAB_ENT(10, 0, 0),
51 RATETAB_ENT(20, 0x2, 0), 56 RATETAB_ENT(20, 1, 0),
52 RATETAB_ENT(55, 0x4, 0), 57 RATETAB_ENT(55, 2, 0),
53 RATETAB_ENT(110, 0x8, 0), 58 RATETAB_ENT(110, 3, 0),
54 RATETAB_ENT(60, 0x10, 0), 59 RATETAB_ENT(60, 9, 0),
55 RATETAB_ENT(90, 0x20, 0), 60 RATETAB_ENT(90, 6, 0),
56 RATETAB_ENT(120, 0x40, 0), 61 RATETAB_ENT(120, 7, 0),
57 RATETAB_ENT(180, 0x80, 0), 62 RATETAB_ENT(180, 8, 0),
58 RATETAB_ENT(240, 0x100, 0), 63 RATETAB_ENT(240, 9, 0),
59 RATETAB_ENT(360, 0x200, 0), 64 RATETAB_ENT(360, 10, 0),
60 RATETAB_ENT(480, 0x400, 0), 65 RATETAB_ENT(480, 11, 0),
61 RATETAB_ENT(540, 0x800, 0), 66 RATETAB_ENT(540, 12, 0),
62}; 67};
63 68
64static struct ieee80211_supported_band lbs_band_2ghz = { 69static struct ieee80211_supported_band lbs_band_2ghz = {
@@ -76,22 +81,639 @@ static const u32 cipher_suites[] = {
76 WLAN_CIPHER_SUITE_CCMP, 81 WLAN_CIPHER_SUITE_CCMP,
77}; 82};
78 83
84/* Time to stay on the channel */
85#define LBS_DWELL_PASSIVE 100
86#define LBS_DWELL_ACTIVE 40
79 87
80 88
89/***************************************************************************
90 * Misc utility functions
91 *
92 * TLVs are Marvell specific. They are very similar to IEs, they have the
93 * same structure: type, length, data*. The only difference: for IEs, the
94 * type and length are u8, but for TLVs they're __le16.
95 */
96
97/*
98 * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1
99 * in the firmware spec
100 */
101static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
102{
103 int ret = -ENOTSUPP;
104
105 switch (auth_type) {
106 case NL80211_AUTHTYPE_OPEN_SYSTEM:
107 case NL80211_AUTHTYPE_SHARED_KEY:
108 ret = auth_type;
109 break;
110 case NL80211_AUTHTYPE_AUTOMATIC:
111 ret = NL80211_AUTHTYPE_OPEN_SYSTEM;
112 break;
113 case NL80211_AUTHTYPE_NETWORK_EAP:
114 ret = 0x80;
115 break;
116 default:
117 /* silence compiler */
118 break;
119 }
120 return ret;
121}
122
123
124/* Various firmware commands need the list of supported rates, but with
125 the hight-bit set for basic rates */
126static int lbs_add_rates(u8 *rates)
127{
128 size_t i;
129
130 for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
131 u8 rate = lbs_rates[i].bitrate / 5;
132 if (rate == 0x02 || rate == 0x04 ||
133 rate == 0x0b || rate == 0x16)
134 rate |= 0x80;
135 rates[i] = rate;
136 }
137 return ARRAY_SIZE(lbs_rates);
138}
139
140
141/***************************************************************************
142 * TLV utility functions
143 *
144 * TLVs are Marvell specific. They are very similar to IEs, they have the
145 * same structure: type, length, data*. The only difference: for IEs, the
146 * type and length are u8, but for TLVs they're __le16.
147 */
148
149
150/*
151 * Add ssid TLV
152 */
153#define LBS_MAX_SSID_TLV_SIZE \
154 (sizeof(struct mrvl_ie_header) \
155 + IEEE80211_MAX_SSID_LEN)
156
157static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len)
158{
159 struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
160
161 /*
162 * TLV-ID SSID 00 00
163 * length 06 00
164 * ssid 4d 4e 54 45 53 54
165 */
166 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
167 ssid_tlv->header.len = cpu_to_le16(ssid_len);
168 memcpy(ssid_tlv->ssid, ssid, ssid_len);
169 return sizeof(ssid_tlv->header) + ssid_len;
170}
171
172
173/*
174 * Add channel list TLV (section 8.4.2)
175 *
176 * Actual channel data comes from priv->wdev->wiphy->channels.
177 */
178#define LBS_MAX_CHANNEL_LIST_TLV_SIZE \
179 (sizeof(struct mrvl_ie_header) \
180 + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset)))
181
182static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv,
183 int last_channel, int active_scan)
184{
185 int chanscanparamsize = sizeof(struct chanscanparamset) *
186 (last_channel - priv->scan_channel);
187
188 struct mrvl_ie_header *header = (void *) tlv;
189
190 /*
191 * TLV-ID CHANLIST 01 01
192 * length 0e 00
193 * channel 00 01 00 00 00 64 00
194 * radio type 00
195 * channel 01
196 * scan type 00
197 * min scan time 00 00
198 * max scan time 64 00
199 * channel 2 00 02 00 00 00 64 00
200 *
201 */
202
203 header->type = cpu_to_le16(TLV_TYPE_CHANLIST);
204 header->len = cpu_to_le16(chanscanparamsize);
205 tlv += sizeof(struct mrvl_ie_header);
206
207 /* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel,
208 last_channel); */
209 memset(tlv, 0, chanscanparamsize);
210
211 while (priv->scan_channel < last_channel) {
212 struct chanscanparamset *param = (void *) tlv;
213
214 param->radiotype = CMD_SCAN_RADIO_TYPE_BG;
215 param->channumber =
216 priv->scan_req->channels[priv->scan_channel]->hw_value;
217 if (active_scan) {
218 param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE);
219 } else {
220 param->chanscanmode.passivescan = 1;
221 param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE);
222 }
223 tlv += sizeof(struct chanscanparamset);
224 priv->scan_channel++;
225 }
226 return sizeof(struct mrvl_ie_header) + chanscanparamsize;
227}
228
229
230/*
231 * Add rates TLV
232 *
233 * The rates are in lbs_bg_rates[], but for the 802.11b
234 * rates the high bit is set. We add this TLV only because
235 * there's a firmware which otherwise doesn't report all
236 * APs in range.
237 */
238#define LBS_MAX_RATES_TLV_SIZE \
239 (sizeof(struct mrvl_ie_header) \
240 + (ARRAY_SIZE(lbs_rates)))
241
242/* Adds a TLV with all rates the hardware supports */
243static int lbs_add_supported_rates_tlv(u8 *tlv)
244{
245 size_t i;
246 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
247
248 /*
249 * TLV-ID RATES 01 00
250 * length 0e 00
251 * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c
252 */
253 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
254 tlv += sizeof(rate_tlv->header);
255 i = lbs_add_rates(tlv);
256 tlv += i;
257 rate_tlv->header.len = cpu_to_le16(i);
258 return sizeof(rate_tlv->header) + i;
259}
260
261
262/*
263 * Adds a TLV with all rates the hardware *and* BSS supports.
264 */
265static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
266{
267 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
268 const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
269 int n;
270
271 /*
272 * 01 00 TLV_TYPE_RATES
273 * 04 00 len
274 * 82 84 8b 96 rates
275 */
276 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
277 tlv += sizeof(rate_tlv->header);
278
279 if (!rates_eid) {
280 /* Fallback: add basic 802.11b rates */
281 *tlv++ = 0x82;
282 *tlv++ = 0x84;
283 *tlv++ = 0x8b;
284 *tlv++ = 0x96;
285 n = 4;
286 } else {
287 int hw, ap;
288 u8 ap_max = rates_eid[1];
289 n = 0;
290 for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
291 u8 hw_rate = lbs_rates[hw].bitrate / 5;
292 for (ap = 0; ap < ap_max; ap++) {
293 if (hw_rate == (rates_eid[ap+2] & 0x7f)) {
294 *tlv++ = rates_eid[ap+2];
295 n++;
296 }
297 }
298 }
299 }
300
301 rate_tlv->header.len = cpu_to_le16(n);
302 return sizeof(rate_tlv->header) + n;
303}
304
305
306/*
307 * Add auth type TLV.
308 *
309 * This is only needed for newer firmware (V9 and up).
310 */
311#define LBS_MAX_AUTH_TYPE_TLV_SIZE \
312 sizeof(struct mrvl_ie_auth_type)
313
314static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type)
315{
316 struct mrvl_ie_auth_type *auth = (void *) tlv;
317
318 /*
319 * 1f 01 TLV_TYPE_AUTH_TYPE
320 * 01 00 len
321 * 01 auth type
322 */
323 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
324 auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header));
325 auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type));
326 return sizeof(*auth);
327}
328
329
330/*
331 * Add channel (phy ds) TLV
332 */
333#define LBS_MAX_CHANNEL_TLV_SIZE \
334 sizeof(struct mrvl_ie_header)
335
336static int lbs_add_channel_tlv(u8 *tlv, u8 channel)
337{
338 struct mrvl_ie_ds_param_set *ds = (void *) tlv;
339
340 /*
341 * 03 00 TLV_TYPE_PHY_DS
342 * 01 00 len
343 * 06 channel
344 */
345 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
346 ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header));
347 ds->channel = channel;
348 return sizeof(*ds);
349}
350
351
352/*
353 * Add (empty) CF param TLV of the form:
354 */
355#define LBS_MAX_CF_PARAM_TLV_SIZE \
356 sizeof(struct mrvl_ie_header)
357
358static int lbs_add_cf_param_tlv(u8 *tlv)
359{
360 struct mrvl_ie_cf_param_set *cf = (void *)tlv;
361
362 /*
363 * 04 00 TLV_TYPE_CF
364 * 06 00 len
365 * 00 cfpcnt
366 * 00 cfpperiod
367 * 00 00 cfpmaxduration
368 * 00 00 cfpdurationremaining
369 */
370 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
371 cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header));
372 return sizeof(*cf);
373}
374
375/*
376 * Add WPA TLV
377 */
378#define LBS_MAX_WPA_TLV_SIZE \
379 (sizeof(struct mrvl_ie_header) \
380 + 128 /* TODO: I guessed the size */)
381
382static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
383{
384 size_t tlv_len;
385
386 /*
387 * We need just convert an IE to an TLV. IEs use u8 for the header,
388 * u8 type
389 * u8 len
390 * u8[] data
391 * but TLVs use __le16 instead:
392 * __le16 type
393 * __le16 len
394 * u8[] data
395 */
396 *tlv++ = *ie++;
397 *tlv++ = 0;
398 tlv_len = *tlv++ = *ie++;
399 *tlv++ = 0;
400 while (tlv_len--)
401 *tlv++ = *ie++;
402 /* the TLV is two bytes larger than the IE */
403 return ie_len + 2;
404}
405
406/***************************************************************************
407 * Set Channel
408 */
409
81static int lbs_cfg_set_channel(struct wiphy *wiphy, 410static int lbs_cfg_set_channel(struct wiphy *wiphy,
82 struct net_device *netdev, 411 struct net_device *netdev,
83 struct ieee80211_channel *chan, 412 struct ieee80211_channel *channel,
84 enum nl80211_channel_type channel_type) 413 enum nl80211_channel_type channel_type)
85{ 414{
86 struct lbs_private *priv = wiphy_priv(wiphy); 415 struct lbs_private *priv = wiphy_priv(wiphy);
87 int ret = -ENOTSUPP; 416 int ret = -ENOTSUPP;
88 417
89 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", chan->center_freq, channel_type); 418 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
419 channel->center_freq, channel_type);
90 420
91 if (channel_type != NL80211_CHAN_NO_HT) 421 if (channel_type != NL80211_CHAN_NO_HT)
92 goto out; 422 goto out;
93 423
94 ret = lbs_set_channel(priv, chan->hw_value); 424 ret = lbs_set_channel(priv, channel->hw_value);
425
426 out:
427 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
428 return ret;
429}
430
431
432
433/***************************************************************************
434 * Scanning
435 */
436
437/*
438 * When scanning, the firmware doesn't send a nul packet with the power-safe
439 * bit to the AP. So we cannot stay away from our current channel too long,
440 * otherwise we loose data. So take a "nap" while scanning every other
441 * while.
442 */
443#define LBS_SCAN_BEFORE_NAP 4
444
445
446/*
447 * When the firmware reports back a scan-result, it gives us an "u8 rssi",
448 * which isn't really an RSSI, as it becomes larger when moving away from
449 * the AP. Anyway, we need to convert that into mBm.
450 */
451#define LBS_SCAN_RSSI_TO_MBM(rssi) \
452 ((-(int)rssi + 3)*100)
453
454static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
455 struct cmd_header *resp)
456{
457 struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
458 int bsssize;
459 const u8 *pos;
460 u16 nr_sets;
461 const u8 *tsfdesc;
462 int tsfsize;
463 int i;
464 int ret = -EILSEQ;
465
466 lbs_deb_enter(LBS_DEB_CFG80211);
467
468 bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
469 nr_sets = le16_to_cpu(resp->size);
470
471 /*
472 * The general layout of the scan response is described in chapter
473 * 5.7.1. Basically we have a common part, then any number of BSS
474 * descriptor sections. Finally we have section with the same number
475 * of TSFs.
476 *
477 * cmd_ds_802_11_scan_rsp
478 * cmd_header
479 * pos_size
480 * nr_sets
481 * bssdesc 1
482 * bssid
483 * rssi
484 * timestamp
485 * intvl
486 * capa
487 * IEs
488 * bssdesc 2
489 * bssdesc n
490 * MrvlIEtypes_TsfFimestamp_t
491 * TSF for BSS 1
492 * TSF for BSS 2
493 * TSF for BSS n
494 */
495
496 pos = scanresp->bssdesc_and_tlvbuffer;
497
498 tsfdesc = pos + bsssize;
499 tsfsize = 4 + 8 * scanresp->nr_sets;
500
501 /* Validity check: we expect a Marvell-Local TLV */
502 i = get_unaligned_le16(tsfdesc);
503 tsfdesc += 2;
504 if (i != TLV_TYPE_TSFTIMESTAMP)
505 goto done;
506 /* Validity check: the TLV holds TSF values with 8 bytes each, so
507 * the size in the TLV must match the nr_sets value */
508 i = get_unaligned_le16(tsfdesc);
509 tsfdesc += 2;
510 if (i / 8 != scanresp->nr_sets)
511 goto done;
512
513 for (i = 0; i < scanresp->nr_sets; i++) {
514 const u8 *bssid;
515 const u8 *ie;
516 int left;
517 int ielen;
518 int rssi;
519 u16 intvl;
520 u16 capa;
521 int chan_no = -1;
522 const u8 *ssid = NULL;
523 u8 ssid_len = 0;
524 DECLARE_SSID_BUF(ssid_buf);
525
526 int len = get_unaligned_le16(pos);
527 pos += 2;
528
529 /* BSSID */
530 bssid = pos;
531 pos += ETH_ALEN;
532 /* RSSI */
533 rssi = *pos++;
534 /* Packet time stamp */
535 pos += 8;
536 /* Beacon interval */
537 intvl = get_unaligned_le16(pos);
538 pos += 2;
539 /* Capabilities */
540 capa = get_unaligned_le16(pos);
541 pos += 2;
542
543 /* To find out the channel, we must parse the IEs */
544 ie = pos;
545 /* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
546 interval, capabilities */
547 ielen = left = len - (6 + 1 + 8 + 2 + 2);
548 while (left >= 2) {
549 u8 id, elen;
550 id = *pos++;
551 elen = *pos++;
552 left -= 2;
553 if (elen > left || elen == 0)
554 goto done;
555 if (id == WLAN_EID_DS_PARAMS)
556 chan_no = *pos;
557 if (id == WLAN_EID_SSID) {
558 ssid = pos;
559 ssid_len = elen;
560 }
561 left -= elen;
562 pos += elen;
563 }
564
565 /* No channel, no luck */
566 if (chan_no != -1) {
567 struct wiphy *wiphy = priv->wdev->wiphy;
568 int freq = ieee80211_channel_to_frequency(chan_no);
569 struct ieee80211_channel *channel =
570 ieee80211_get_channel(wiphy, freq);
571
572 lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, "
573 "%d dBm\n",
574 bssid, capa, chan_no,
575 print_ssid(ssid_buf, ssid, ssid_len),
576 LBS_SCAN_RSSI_TO_MBM(rssi)/100);
577
578 if (channel ||
579 !(channel->flags & IEEE80211_CHAN_DISABLED))
580 cfg80211_inform_bss(wiphy, channel,
581 bssid, le64_to_cpu(*(__le64 *)tsfdesc),
582 capa, intvl, ie, ielen,
583 LBS_SCAN_RSSI_TO_MBM(rssi),
584 GFP_KERNEL);
585 }
586 tsfdesc += 8;
587 }
588 ret = 0;
589
590 done:
591 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
592 return ret;
593}
594
595
596/*
597 * Our scan command contains a TLV, consting of a SSID TLV, a channel list
598 * TLV and a rates TLV. Determine the maximum size of them:
599 */
600#define LBS_SCAN_MAX_CMD_SIZE \
601 (sizeof(struct cmd_ds_802_11_scan) \
602 + LBS_MAX_SSID_TLV_SIZE \
603 + LBS_MAX_CHANNEL_LIST_TLV_SIZE \
604 + LBS_MAX_RATES_TLV_SIZE)
605
606/*
607 * Assumes priv->scan_req is initialized and valid
608 * Assumes priv->scan_channel is initialized
609 */
610static void lbs_scan_worker(struct work_struct *work)
611{
612 struct lbs_private *priv =
613 container_of(work, struct lbs_private, scan_work.work);
614 struct cmd_ds_802_11_scan *scan_cmd;
615 u8 *tlv; /* pointer into our current, growing TLV storage area */
616 int last_channel;
617 int running, carrier;
618
619 lbs_deb_enter(LBS_DEB_SCAN);
620
621 scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
622 if (scan_cmd == NULL)
623 goto out_no_scan_cmd;
624
625 /* prepare fixed part of scan command */
626 scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
627
628 /* stop network while we're away from our main channel */
629 running = !netif_queue_stopped(priv->dev);
630 carrier = netif_carrier_ok(priv->dev);
631 if (running)
632 netif_stop_queue(priv->dev);
633 if (carrier)
634 netif_carrier_off(priv->dev);
635
636 /* prepare fixed part of scan command */
637 tlv = scan_cmd->tlvbuffer;
638
639 /* add SSID TLV */
640 if (priv->scan_req->n_ssids)
641 tlv += lbs_add_ssid_tlv(tlv,
642 priv->scan_req->ssids[0].ssid,
643 priv->scan_req->ssids[0].ssid_len);
644
645 /* add channel TLVs */
646 last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP;
647 if (last_channel > priv->scan_req->n_channels)
648 last_channel = priv->scan_req->n_channels;
649 tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel,
650 priv->scan_req->n_ssids);
651
652 /* add rates TLV */
653 tlv += lbs_add_supported_rates_tlv(tlv);
654
655 if (priv->scan_channel < priv->scan_req->n_channels) {
656 cancel_delayed_work(&priv->scan_work);
657 queue_delayed_work(priv->work_thread, &priv->scan_work,
658 msecs_to_jiffies(300));
659 }
660
661 /* This is the final data we are about to send */
662 scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd);
663 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
664 sizeof(*scan_cmd));
665 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
666 tlv - scan_cmd->tlvbuffer);
667
668 __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
669 le16_to_cpu(scan_cmd->hdr.size),
670 lbs_ret_scan, 0);
671
672 if (priv->scan_channel >= priv->scan_req->n_channels) {
673 /* Mark scan done */
674 cfg80211_scan_done(priv->scan_req, false);
675 priv->scan_req = NULL;
676 }
677
678 /* Restart network */
679 if (carrier)
680 netif_carrier_on(priv->dev);
681 if (running && !priv->tx_pending_len)
682 netif_wake_queue(priv->dev);
683
684 kfree(scan_cmd);
685
686 out_no_scan_cmd:
687 lbs_deb_leave(LBS_DEB_SCAN);
688}
689
690
691static int lbs_cfg_scan(struct wiphy *wiphy,
692 struct net_device *dev,
693 struct cfg80211_scan_request *request)
694{
695 struct lbs_private *priv = wiphy_priv(wiphy);
696 int ret = 0;
697
698 lbs_deb_enter(LBS_DEB_CFG80211);
699
700 if (priv->scan_req || delayed_work_pending(&priv->scan_work)) {
701 /* old scan request not yet processed */
702 ret = -EAGAIN;
703 goto out;
704 }
705
706 lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
707 request->n_ssids, request->n_channels, request->ie_len);
708
709 priv->scan_channel = 0;
710 queue_delayed_work(priv->work_thread, &priv->scan_work,
711 msecs_to_jiffies(50));
712
713 if (priv->surpriseremoved)
714 ret = -EIO;
715
716 priv->scan_req = request;
95 717
96 out: 718 out:
97 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 719 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
@@ -101,8 +723,1228 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy,
101 723
102 724
103 725
726/***************************************************************************
727 * Events
728 */
729
730void lbs_send_disconnect_notification(struct lbs_private *priv)
731{
732 lbs_deb_enter(LBS_DEB_CFG80211);
733
734 cfg80211_disconnected(priv->dev,
735 0,
736 NULL, 0,
737 GFP_KERNEL);
738
739 lbs_deb_leave(LBS_DEB_CFG80211);
740}
741
742void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
743{
744 lbs_deb_enter(LBS_DEB_CFG80211);
745
746 cfg80211_michael_mic_failure(priv->dev,
747 priv->assoc_bss,
748 event == MACREG_INT_CODE_MIC_ERR_MULTICAST ?
749 NL80211_KEYTYPE_GROUP :
750 NL80211_KEYTYPE_PAIRWISE,
751 -1,
752 NULL,
753 GFP_KERNEL);
754
755 lbs_deb_leave(LBS_DEB_CFG80211);
756}
757
758
759
760
761/***************************************************************************
762 * Connect/disconnect
763 */
764
765
766/*
767 * This removes all WEP keys
768 */
769static int lbs_remove_wep_keys(struct lbs_private *priv)
770{
771 struct cmd_ds_802_11_set_wep cmd;
772 int ret;
773
774 lbs_deb_enter(LBS_DEB_CFG80211);
775
776 memset(&cmd, 0, sizeof(cmd));
777 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
778 cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
779 cmd.action = cpu_to_le16(CMD_ACT_REMOVE);
780
781 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
782
783 lbs_deb_leave(LBS_DEB_CFG80211);
784 return ret;
785}
786
787/*
788 * Set WEP keys
789 */
790static int lbs_set_wep_keys(struct lbs_private *priv)
791{
792 struct cmd_ds_802_11_set_wep cmd;
793 int i;
794 int ret;
795
796 lbs_deb_enter(LBS_DEB_CFG80211);
797
798 /*
799 * command 13 00
800 * size 50 00
801 * sequence xx xx
802 * result 00 00
803 * action 02 00 ACT_ADD
804 * transmit key 00 00
805 * type for key 1 01 WEP40
806 * type for key 2 00
807 * type for key 3 00
808 * type for key 4 00
809 * key 1 39 39 39 39 39 00 00 00
810 * 00 00 00 00 00 00 00 00
811 * key 2 00 00 00 00 00 00 00 00
812 * 00 00 00 00 00 00 00 00
813 * key 3 00 00 00 00 00 00 00 00
814 * 00 00 00 00 00 00 00 00
815 * key 4 00 00 00 00 00 00 00 00
816 */
817 if (priv->wep_key_len[0] || priv->wep_key_len[1] ||
818 priv->wep_key_len[2] || priv->wep_key_len[3]) {
819 /* Only set wep keys if we have at least one of them */
820 memset(&cmd, 0, sizeof(cmd));
821 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
822 cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
823 cmd.action = cpu_to_le16(CMD_ACT_ADD);
824
825 for (i = 0; i < 4; i++) {
826 switch (priv->wep_key_len[i]) {
827 case WLAN_KEY_LEN_WEP40:
828 cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
829 break;
830 case WLAN_KEY_LEN_WEP104:
831 cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
832 break;
833 default:
834 cmd.keytype[i] = 0;
835 break;
836 }
837 memcpy(cmd.keymaterial[i], priv->wep_key[i],
838 priv->wep_key_len[i]);
839 }
840
841 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
842 } else {
843 /* Otherwise remove all wep keys */
844 ret = lbs_remove_wep_keys(priv);
845 }
846
847 lbs_deb_leave(LBS_DEB_CFG80211);
848 return ret;
849}
850
851
852/*
853 * Enable/Disable RSN status
854 */
855static int lbs_enable_rsn(struct lbs_private *priv, int enable)
856{
857 struct cmd_ds_802_11_enable_rsn cmd;
858 int ret;
859
860 lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", enable);
861
862 /*
863 * cmd 2f 00
864 * size 0c 00
865 * sequence xx xx
866 * result 00 00
867 * action 01 00 ACT_SET
868 * enable 01 00
869 */
870 memset(&cmd, 0, sizeof(cmd));
871 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
872 cmd.action = cpu_to_le16(CMD_ACT_SET);
873 cmd.enable = cpu_to_le16(enable);
874
875 ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
876
877 lbs_deb_leave(LBS_DEB_CFG80211);
878 return ret;
879}
880
881
882/*
883 * Set WPA/WPA key material
884 */
885
886/* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
887 * get rid of WEXT, this should go into host.h */
888
889struct cmd_key_material {
890 struct cmd_header hdr;
891
892 __le16 action;
893 struct MrvlIEtype_keyParamSet param;
894} __attribute__ ((packed));
895
896static int lbs_set_key_material(struct lbs_private *priv,
897 int key_type,
898 int key_info,
899 u8 *key, u16 key_len)
900{
901 struct cmd_key_material cmd;
902 int ret;
903
904 lbs_deb_enter(LBS_DEB_CFG80211);
905
906 /*
907 * Example for WPA (TKIP):
908 *
909 * cmd 5e 00
910 * size 34 00
911 * sequence xx xx
912 * result 00 00
913 * action 01 00
914 * TLV type 00 01 key param
915 * length 00 26
916 * key type 01 00 TKIP
917 * key info 06 00 UNICAST | ENABLED
918 * key len 20 00
919 * key 32 bytes
920 */
921 memset(&cmd, 0, sizeof(cmd));
922 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
923 cmd.action = cpu_to_le16(CMD_ACT_SET);
924 cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
925 cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4);
926 cmd.param.keytypeid = cpu_to_le16(key_type);
927 cmd.param.keyinfo = cpu_to_le16(key_info);
928 cmd.param.keylen = cpu_to_le16(key_len);
929 if (key && key_len)
930 memcpy(cmd.param.key, key, key_len);
931
932 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
933
934 lbs_deb_leave(LBS_DEB_CFG80211);
935 return ret;
936}
937
938
939/*
940 * Sets the auth type (open, shared, etc) in the firmware. That
941 * we use CMD_802_11_AUTHENTICATE is misleading, this firmware
942 * command doesn't send an authentication frame at all, it just
943 * stores the auth_type.
944 */
945static int lbs_set_authtype(struct lbs_private *priv,
946 struct cfg80211_connect_params *sme)
947{
948 struct cmd_ds_802_11_authenticate cmd;
949 int ret;
950
951 lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type);
952
953 /*
954 * cmd 11 00
955 * size 19 00
956 * sequence xx xx
957 * result 00 00
958 * BSS id 00 13 19 80 da 30
959 * auth type 00
960 * reserved 00 00 00 00 00 00 00 00 00 00
961 */
962 memset(&cmd, 0, sizeof(cmd));
963 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
964 if (sme->bssid)
965 memcpy(cmd.bssid, sme->bssid, ETH_ALEN);
966 /* convert auth_type */
967 ret = lbs_auth_to_authtype(sme->auth_type);
968 if (ret < 0)
969 goto done;
970
971 cmd.authtype = ret;
972 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
973
974 done:
975 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
976 return ret;
977}
978
979
980/*
981 * Create association request
982 */
983#define LBS_ASSOC_MAX_CMD_SIZE \
984 (sizeof(struct cmd_ds_802_11_associate) \
985 - 512 /* cmd_ds_802_11_associate.iebuf */ \
986 + LBS_MAX_SSID_TLV_SIZE \
987 + LBS_MAX_CHANNEL_TLV_SIZE \
988 + LBS_MAX_CF_PARAM_TLV_SIZE \
989 + LBS_MAX_AUTH_TYPE_TLV_SIZE \
990 + LBS_MAX_WPA_TLV_SIZE)
991
992static int lbs_associate(struct lbs_private *priv,
993 struct cfg80211_bss *bss,
994 struct cfg80211_connect_params *sme)
995{
996 struct cmd_ds_802_11_associate_response *resp;
997 struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE,
998 GFP_KERNEL);
999 const u8 *ssid_eid;
1000 size_t len, resp_ie_len;
1001 int status;
1002 int ret;
1003 u8 *pos = &(cmd->iebuf[0]);
1004
1005 lbs_deb_enter(LBS_DEB_CFG80211);
1006
1007 if (!cmd) {
1008 ret = -ENOMEM;
1009 goto done;
1010 }
1011
1012 /*
1013 * cmd 50 00
1014 * length 34 00
1015 * sequence xx xx
1016 * result 00 00
1017 * BSS id 00 13 19 80 da 30
1018 * capabilities 11 00
1019 * listen interval 0a 00
1020 * beacon interval 00 00
1021 * DTIM period 00
1022 * TLVs xx (up to 512 bytes)
1023 */
1024 cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1025
1026 /* Fill in static fields */
1027 memcpy(cmd->bssid, bss->bssid, ETH_ALEN);
1028 cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1029 cmd->capability = cpu_to_le16(bss->capability);
1030
1031 /* add SSID TLV */
1032 ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1033 if (ssid_eid)
1034 pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
1035 else
1036 lbs_deb_assoc("no SSID\n");
1037
1038 /* add DS param TLV */
1039 if (bss->channel)
1040 pos += lbs_add_channel_tlv(pos, bss->channel->hw_value);
1041 else
1042 lbs_deb_assoc("no channel\n");
1043
1044 /* add (empty) CF param TLV */
1045 pos += lbs_add_cf_param_tlv(pos);
1046
1047 /* add rates TLV */
1048 pos += lbs_add_common_rates_tlv(pos, bss);
1049
1050 /* add auth type TLV */
1051 if (priv->fwrelease >= 0x09000000)
1052 pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
1053
1054 /* add WPA/WPA2 TLV */
1055 if (sme->ie && sme->ie_len)
1056 pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len);
1057
1058 len = (sizeof(*cmd) - sizeof(cmd->iebuf)) +
1059 (u16)(pos - (u8 *) &cmd->iebuf);
1060 cmd->hdr.size = cpu_to_le16(len);
1061
1062 /* store for later use */
1063 memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
1064
1065 ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd);
1066 if (ret)
1067 goto done;
1068
1069
1070 /* generate connect message to cfg80211 */
1071
1072 resp = (void *) cmd; /* recast for easier field access */
1073 status = le16_to_cpu(resp->statuscode);
1074
1075 /* Convert statis code of old firmware */
1076 if (priv->fwrelease < 0x09000000)
1077 switch (status) {
1078 case 0:
1079 break;
1080 case 1:
1081 lbs_deb_assoc("invalid association parameters\n");
1082 status = WLAN_STATUS_CAPS_UNSUPPORTED;
1083 break;
1084 case 2:
1085 lbs_deb_assoc("timer expired while waiting for AP\n");
1086 status = WLAN_STATUS_AUTH_TIMEOUT;
1087 break;
1088 case 3:
1089 lbs_deb_assoc("association refused by AP\n");
1090 status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1091 break;
1092 case 4:
1093 lbs_deb_assoc("authentication refused by AP\n");
1094 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1095 break;
1096 default:
1097 lbs_deb_assoc("association failure %d\n", status);
1098 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1099 }
1100
1101 lbs_deb_assoc("status %d, capability 0x%04x\n", status,
1102 le16_to_cpu(resp->capability));
1103
1104 resp_ie_len = le16_to_cpu(resp->hdr.size)
1105 - sizeof(resp->hdr)
1106 - 6;
1107 cfg80211_connect_result(priv->dev,
1108 priv->assoc_bss,
1109 sme->ie, sme->ie_len,
1110 resp->iebuf, resp_ie_len,
1111 status,
1112 GFP_KERNEL);
1113
1114 if (status == 0) {
1115 /* TODO: get rid of priv->connect_status */
1116 priv->connect_status = LBS_CONNECTED;
1117 netif_carrier_on(priv->dev);
1118 if (!priv->tx_pending_len)
1119 netif_tx_wake_all_queues(priv->dev);
1120 }
1121
1122
1123done:
1124 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1125 return ret;
1126}
1127
1128
1129
1130static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1131 struct cfg80211_connect_params *sme)
1132{
1133 struct lbs_private *priv = wiphy_priv(wiphy);
1134 struct cfg80211_bss *bss = NULL;
1135 int ret = 0;
1136 u8 preamble = RADIO_PREAMBLE_SHORT;
1137
1138 lbs_deb_enter(LBS_DEB_CFG80211);
1139
1140 if (sme->bssid) {
1141 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
1142 sme->ssid, sme->ssid_len,
1143 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1144 } else {
1145 /*
1146 * Here we have an impedance mismatch. The firmware command
1147 * CMD_802_11_ASSOCIATE always needs a BSSID, it cannot
1148 * connect otherwise. However, for the connect-API of
1149 * cfg80211 the bssid is purely optional. We don't get one,
1150 * except the user specifies one on the "iw" command line.
1151 *
1152 * If we don't got one, we could initiate a scan and look
1153 * for the best matching cfg80211_bss entry.
1154 *
1155 * Or, better yet, net/wireless/sme.c get's rewritten into
1156 * something more generally useful.
1157 */
1158 lbs_pr_err("TODO: no BSS specified\n");
1159 ret = -ENOTSUPP;
1160 goto done;
1161 }
1162
1163
1164 if (!bss) {
1165 lbs_pr_err("assicate: bss %pM not in scan results\n",
1166 sme->bssid);
1167 ret = -ENOENT;
1168 goto done;
1169 }
1170 lbs_deb_assoc("trying %pM", sme->bssid);
1171 lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
1172 sme->crypto.cipher_group,
1173 sme->key_idx, sme->key_len);
1174
1175 /* As this is a new connection, clear locally stored WEP keys */
1176 priv->wep_tx_key = 0;
1177 memset(priv->wep_key, 0, sizeof(priv->wep_key));
1178 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1179
1180 /* set/remove WEP keys */
1181 switch (sme->crypto.cipher_group) {
1182 case WLAN_CIPHER_SUITE_WEP40:
1183 case WLAN_CIPHER_SUITE_WEP104:
1184 /* Store provided WEP keys in priv-> */
1185 priv->wep_tx_key = sme->key_idx;
1186 priv->wep_key_len[sme->key_idx] = sme->key_len;
1187 memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len);
1188 /* Set WEP keys and WEP mode */
1189 lbs_set_wep_keys(priv);
1190 priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
1191 lbs_set_mac_control(priv);
1192 /* No RSN mode for WEP */
1193 lbs_enable_rsn(priv, 0);
1194 break;
1195 case 0: /* there's no WLAN_CIPHER_SUITE_NONE definition */
1196 /*
1197 * If we don't have no WEP, no WPA and no WPA2,
1198 * we remove all keys like in the WPA/WPA2 setup,
1199 * we just don't set RSN.
1200 *
1201 * Therefore: fall-throught
1202 */
1203 case WLAN_CIPHER_SUITE_TKIP:
1204 case WLAN_CIPHER_SUITE_CCMP:
1205 /* Remove WEP keys and WEP mode */
1206 lbs_remove_wep_keys(priv);
1207 priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
1208 lbs_set_mac_control(priv);
1209
1210 /* clear the WPA/WPA2 keys */
1211 lbs_set_key_material(priv,
1212 KEY_TYPE_ID_WEP, /* doesn't matter */
1213 KEY_INFO_WPA_UNICAST,
1214 NULL, 0);
1215 lbs_set_key_material(priv,
1216 KEY_TYPE_ID_WEP, /* doesn't matter */
1217 KEY_INFO_WPA_MCAST,
1218 NULL, 0);
1219 /* RSN mode for WPA/WPA2 */
1220 lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
1221 break;
1222 default:
1223 lbs_pr_err("unsupported cipher group 0x%x\n",
1224 sme->crypto.cipher_group);
1225 ret = -ENOTSUPP;
1226 goto done;
1227 }
1228
1229 lbs_set_authtype(priv, sme);
1230 lbs_set_radio(priv, preamble, 1);
1231
1232 /* Do the actual association */
1233 lbs_associate(priv, bss, sme);
1234
1235 done:
1236 if (bss)
1237 cfg80211_put_bss(bss);
1238 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1239 return ret;
1240}
1241
1242static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1243 u16 reason_code)
1244{
1245 struct lbs_private *priv = wiphy_priv(wiphy);
1246 struct cmd_ds_802_11_deauthenticate cmd;
1247
1248 lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
1249
1250 /* store for lbs_cfg_ret_disconnect() */
1251 priv->disassoc_reason = reason_code;
1252
1253 memset(&cmd, 0, sizeof(cmd));
1254 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1255 /* Mildly ugly to use a locally store my own BSSID ... */
1256 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
1257 cmd.reasoncode = cpu_to_le16(reason_code);
1258
1259 if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd))
1260 return -EFAULT;
1261
1262 cfg80211_disconnected(priv->dev,
1263 priv->disassoc_reason,
1264 NULL, 0,
1265 GFP_KERNEL);
1266 priv->connect_status = LBS_DISCONNECTED;
1267
1268 return 0;
1269}
1270
1271
1272static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1273 struct net_device *netdev,
1274 u8 key_index)
1275{
1276 struct lbs_private *priv = wiphy_priv(wiphy);
1277
1278 lbs_deb_enter(LBS_DEB_CFG80211);
1279
1280 if (key_index != priv->wep_tx_key) {
1281 lbs_deb_assoc("set_default_key: to %d\n", key_index);
1282 priv->wep_tx_key = key_index;
1283 lbs_set_wep_keys(priv);
1284 }
1285
1286 return 0;
1287}
1288
1289
1290static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1291 u8 idx, const u8 *mac_addr,
1292 struct key_params *params)
1293{
1294 struct lbs_private *priv = wiphy_priv(wiphy);
1295 u16 key_info;
1296 u16 key_type;
1297 int ret = 0;
1298
1299 lbs_deb_enter(LBS_DEB_CFG80211);
1300
1301 lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
1302 params->cipher, mac_addr);
1303 lbs_deb_assoc("add_key: key index %d, key len %d\n",
1304 idx, params->key_len);
1305 if (params->key_len)
1306 lbs_deb_hex(LBS_DEB_CFG80211, "KEY",
1307 params->key, params->key_len);
1308
1309 lbs_deb_assoc("add_key: seq len %d\n", params->seq_len);
1310 if (params->seq_len)
1311 lbs_deb_hex(LBS_DEB_CFG80211, "SEQ",
1312 params->seq, params->seq_len);
1313
1314 switch (params->cipher) {
1315 case WLAN_CIPHER_SUITE_WEP40:
1316 case WLAN_CIPHER_SUITE_WEP104:
1317 /* actually compare if something has changed ... */
1318 if ((priv->wep_key_len[idx] != params->key_len) ||
1319 memcmp(priv->wep_key[idx],
1320 params->key, params->key_len) != 0) {
1321 priv->wep_key_len[idx] = params->key_len;
1322 memcpy(priv->wep_key[idx],
1323 params->key, params->key_len);
1324 lbs_set_wep_keys(priv);
1325 }
1326 break;
1327 case WLAN_CIPHER_SUITE_TKIP:
1328 case WLAN_CIPHER_SUITE_CCMP:
1329 key_info = KEY_INFO_WPA_ENABLED | ((idx == 0)
1330 ? KEY_INFO_WPA_UNICAST
1331 : KEY_INFO_WPA_MCAST);
1332 key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1333 ? KEY_TYPE_ID_TKIP
1334 : KEY_TYPE_ID_AES;
1335 lbs_set_key_material(priv,
1336 key_type,
1337 key_info,
1338 params->key, params->key_len);
1339 break;
1340 default:
1341 lbs_pr_err("unhandled cipher 0x%x\n", params->cipher);
1342 ret = -ENOTSUPP;
1343 break;
1344 }
1345
1346 return ret;
1347}
1348
1349
1350static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
1351 u8 key_index, const u8 *mac_addr)
1352{
1353
1354 lbs_deb_enter(LBS_DEB_CFG80211);
1355
1356 lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n",
1357 key_index, mac_addr);
1358
1359#ifdef TODO
1360 struct lbs_private *priv = wiphy_priv(wiphy);
1361 /*
1362 * I think can keep this a NO-OP, because:
1363
1364 * - we clear all keys whenever we do lbs_cfg_connect() anyway
1365 * - neither "iw" nor "wpa_supplicant" won't call this during
1366 * an ongoing connection
1367 * - TODO: but I have to check if this is still true when
1368 * I set the AP to periodic re-keying
1369 * - we've not kzallec() something when we've added a key at
1370 * lbs_cfg_connect() or lbs_cfg_add_key().
1371 *
1372 * This causes lbs_cfg_del_key() only called at disconnect time,
1373 * where we'd just waste time deleting a key that is not going
1374 * to be used anyway.
1375 */
1376 if (key_index < 3 && priv->wep_key_len[key_index]) {
1377 priv->wep_key_len[key_index] = 0;
1378 lbs_set_wep_keys(priv);
1379 }
1380#endif
1381
1382 return 0;
1383}
1384
1385
1386
1387/***************************************************************************
1388 * Monitor mode
1389 */
1390
1391/* like "struct cmd_ds_802_11_monitor_mode", but with cmd_header. Once we
1392 * get rid of WEXT, this should go into host.h */
1393struct cmd_monitor_mode {
1394 struct cmd_header hdr;
1395
1396 __le16 action;
1397 __le16 mode;
1398} __attribute__ ((packed));
1399
1400static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode)
1401{
1402 struct cmd_monitor_mode cmd;
1403 int ret;
1404
1405 lbs_deb_enter(LBS_DEB_CFG80211);
1406
1407 /*
1408 * cmd 98 00
1409 * size 0c 00
1410 * sequence xx xx
1411 * result 00 00
1412 * action 01 00 ACT_SET
1413 * enable 01 00
1414 */
1415 memset(&cmd, 0, sizeof(cmd));
1416 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1417 cmd.action = cpu_to_le16(CMD_ACT_SET);
1418 cmd.mode = cpu_to_le16(mode);
1419
1420 ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
1421
1422 if (ret == 0)
1423 priv->dev->type = ARPHRD_IEEE80211_RADIOTAP;
1424 else
1425 priv->dev->type = ARPHRD_ETHER;
1426
1427 lbs_deb_leave(LBS_DEB_CFG80211);
1428 return ret;
1429}
1430
1431
1432
1433
1434
1435
1436/***************************************************************************
1437 * Get station
1438 */
1439
1440/*
1441 * Returns the signal or 0 in case of an error.
1442 */
1443
1444/* like "struct cmd_ds_802_11_rssi", but with cmd_header. Once we get rid
1445 * of WEXT, this should go into host.h */
1446struct cmd_rssi {
1447 struct cmd_header hdr;
1448
1449 __le16 n_or_snr;
1450 __le16 nf;
1451 __le16 avg_snr;
1452 __le16 avg_nf;
1453} __attribute__ ((packed));
1454
1455static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise)
1456{
1457 struct cmd_rssi cmd;
1458 int ret;
1459
1460 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1461 cmd.n_or_snr = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
1462 ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
1463
1464 if (ret == 0) {
1465 *signal = CAL_RSSI(le16_to_cpu(cmd.n_or_snr),
1466 le16_to_cpu(cmd.nf));
1467 *noise = CAL_NF(le16_to_cpu(cmd.nf));
1468 }
1469 return ret;
1470}
1471
1472
1473static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
1474 u8 *mac, struct station_info *sinfo)
1475{
1476 struct lbs_private *priv = wiphy_priv(wiphy);
1477 s8 signal, noise;
1478 int ret;
1479 size_t i;
1480
1481 lbs_deb_enter(LBS_DEB_CFG80211);
1482
1483 sinfo->filled |= STATION_INFO_TX_BYTES |
1484 STATION_INFO_TX_PACKETS |
1485 STATION_INFO_RX_BYTES |
1486 STATION_INFO_RX_PACKETS;
1487 sinfo->tx_bytes = priv->dev->stats.tx_bytes;
1488 sinfo->tx_packets = priv->dev->stats.tx_packets;
1489 sinfo->rx_bytes = priv->dev->stats.rx_bytes;
1490 sinfo->rx_packets = priv->dev->stats.rx_packets;
1491
1492 /* Get current RSSI */
1493 ret = lbs_get_signal(priv, &signal, &noise);
1494 if (ret == 0) {
1495 sinfo->signal = signal;
1496 sinfo->filled |= STATION_INFO_SIGNAL;
1497 }
1498
1499 /* Convert priv->cur_rate from hw_value to NL80211 value */
1500 for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
1501 if (priv->cur_rate == lbs_rates[i].hw_value) {
1502 sinfo->txrate.legacy = lbs_rates[i].bitrate;
1503 sinfo->filled |= STATION_INFO_TX_BITRATE;
1504 break;
1505 }
1506 }
1507
1508 return 0;
1509}
1510
1511
1512
1513
1514/***************************************************************************
1515 * "Site survey", here just current channel and noise level
1516 */
1517
1518static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
1519 int idx, struct survey_info *survey)
1520{
1521 struct lbs_private *priv = wiphy_priv(wiphy);
1522 s8 signal, noise;
1523 int ret;
1524
1525 if (idx != 0)
1526 ret = -ENOENT;
1527
1528 lbs_deb_enter(LBS_DEB_CFG80211);
1529
1530 survey->channel = ieee80211_get_channel(wiphy,
1531 ieee80211_channel_to_frequency(priv->channel));
1532
1533 ret = lbs_get_signal(priv, &signal, &noise);
1534 if (ret == 0) {
1535 survey->filled = SURVEY_INFO_NOISE_DBM;
1536 survey->noise = noise;
1537 }
1538
1539 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1540 return ret;
1541}
1542
1543
1544
1545
1546/***************************************************************************
1547 * Change interface
1548 */
1549
1550static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1551 enum nl80211_iftype type, u32 *flags,
1552 struct vif_params *params)
1553{
1554 struct lbs_private *priv = wiphy_priv(wiphy);
1555 int ret = 0;
1556
1557 lbs_deb_enter(LBS_DEB_CFG80211);
1558
1559 switch (type) {
1560 case NL80211_IFTYPE_MONITOR:
1561 ret = lbs_enable_monitor_mode(priv, 1);
1562 break;
1563 case NL80211_IFTYPE_STATION:
1564 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
1565 ret = lbs_enable_monitor_mode(priv, 0);
1566 if (!ret)
1567 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
1568 break;
1569 case NL80211_IFTYPE_ADHOC:
1570 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
1571 ret = lbs_enable_monitor_mode(priv, 0);
1572 if (!ret)
1573 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
1574 break;
1575 default:
1576 ret = -ENOTSUPP;
1577 }
1578
1579 if (!ret)
1580 priv->wdev->iftype = type;
1581
1582 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1583 return ret;
1584}
1585
1586
1587
1588/***************************************************************************
1589 * IBSS (Ad-Hoc)
1590 */
1591
1592/* The firmware needs the following bits masked out of the beacon-derived
1593 * capability field when associating/joining to a BSS:
1594 * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
1595 */
1596#define CAPINFO_MASK (~(0xda00))
1597
1598
1599static void lbs_join_post(struct lbs_private *priv,
1600 struct cfg80211_ibss_params *params,
1601 u8 *bssid, u16 capability)
1602{
1603 u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN + /* ssid */
1604 2 + 4 + /* basic rates */
1605 2 + 1 + /* DS parameter */
1606 2 + 2 + /* atim */
1607 2 + 8]; /* extended rates */
1608 u8 *fake = fake_ie;
1609
1610 lbs_deb_enter(LBS_DEB_CFG80211);
1611
1612 /*
1613 * For cfg80211_inform_bss, we'll need a fake IE, as we can't get
1614 * the real IE from the firmware. So we fabricate a fake IE based on
1615 * what the firmware actually sends (sniffed with wireshark).
1616 */
1617 /* Fake SSID IE */
1618 *fake++ = WLAN_EID_SSID;
1619 *fake++ = params->ssid_len;
1620 memcpy(fake, params->ssid, params->ssid_len);
1621 fake += params->ssid_len;
1622 /* Fake supported basic rates IE */
1623 *fake++ = WLAN_EID_SUPP_RATES;
1624 *fake++ = 4;
1625 *fake++ = 0x82;
1626 *fake++ = 0x84;
1627 *fake++ = 0x8b;
1628 *fake++ = 0x96;
1629 /* Fake DS channel IE */
1630 *fake++ = WLAN_EID_DS_PARAMS;
1631 *fake++ = 1;
1632 *fake++ = params->channel->hw_value;
1633 /* Fake IBSS params IE */
1634 *fake++ = WLAN_EID_IBSS_PARAMS;
1635 *fake++ = 2;
1636 *fake++ = 0; /* ATIM=0 */
1637 *fake++ = 0;
1638 /* Fake extended rates IE, TODO: don't add this for 802.11b only,
1639 * but I don't know how this could be checked */
1640 *fake++ = WLAN_EID_EXT_SUPP_RATES;
1641 *fake++ = 8;
1642 *fake++ = 0x0c;
1643 *fake++ = 0x12;
1644 *fake++ = 0x18;
1645 *fake++ = 0x24;
1646 *fake++ = 0x30;
1647 *fake++ = 0x48;
1648 *fake++ = 0x60;
1649 *fake++ = 0x6c;
1650 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1651
1652 cfg80211_inform_bss(priv->wdev->wiphy,
1653 params->channel,
1654 bssid,
1655 0,
1656 capability,
1657 params->beacon_interval,
1658 fake_ie, fake - fake_ie,
1659 0, GFP_KERNEL);
1660
1661 memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
1662 priv->wdev->ssid_len = params->ssid_len;
1663
1664 cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
1665
1666 /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
1667 priv->connect_status = LBS_CONNECTED;
1668 netif_carrier_on(priv->dev);
1669 if (!priv->tx_pending_len)
1670 netif_wake_queue(priv->dev);
1671
1672 lbs_deb_leave(LBS_DEB_CFG80211);
1673}
1674
1675static int lbs_ibss_join_existing(struct lbs_private *priv,
1676 struct cfg80211_ibss_params *params,
1677 struct cfg80211_bss *bss)
1678{
1679 const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1680 struct cmd_ds_802_11_ad_hoc_join cmd;
1681 u8 preamble = RADIO_PREAMBLE_SHORT;
1682 int ret = 0;
1683
1684 lbs_deb_enter(LBS_DEB_CFG80211);
1685
1686 /* TODO: set preamble based on scan result */
1687 ret = lbs_set_radio(priv, preamble, 1);
1688 if (ret)
1689 goto out;
1690
1691 /*
1692 * Example CMD_802_11_AD_HOC_JOIN command:
1693 *
1694 * command 2c 00 CMD_802_11_AD_HOC_JOIN
1695 * size 65 00
1696 * sequence xx xx
1697 * result 00 00
1698 * bssid 02 27 27 97 2f 96
1699 * ssid 49 42 53 53 00 00 00 00
1700 * 00 00 00 00 00 00 00 00
1701 * 00 00 00 00 00 00 00 00
1702 * 00 00 00 00 00 00 00 00
1703 * type 02 CMD_BSS_TYPE_IBSS
1704 * beacon period 64 00
1705 * dtim period 00
1706 * timestamp 00 00 00 00 00 00 00 00
1707 * localtime 00 00 00 00 00 00 00 00
1708 * IE DS 03
1709 * IE DS len 01
1710 * IE DS channel 01
1711 * reserveed 00 00 00 00
1712 * IE IBSS 06
1713 * IE IBSS len 02
1714 * IE IBSS atim 00 00
1715 * reserved 00 00 00 00
1716 * capability 02 00
1717 * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c 00
1718 * fail timeout ff 00
1719 * probe delay 00 00
1720 */
1721 memset(&cmd, 0, sizeof(cmd));
1722 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1723
1724 memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN);
1725 memcpy(cmd.bss.ssid, params->ssid, params->ssid_len);
1726 cmd.bss.type = CMD_BSS_TYPE_IBSS;
1727 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1728 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1729 cmd.bss.ds.header.len = 1;
1730 cmd.bss.ds.channel = params->channel->hw_value;
1731 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1732 cmd.bss.ibss.header.len = 2;
1733 cmd.bss.ibss.atimwindow = 0;
1734 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
1735
1736 /* set rates to the intersection of our rates and the rates in the
1737 bss */
1738 if (!rates_eid) {
1739 lbs_add_rates(cmd.bss.rates);
1740 } else {
1741 int hw, i;
1742 u8 rates_max = rates_eid[1];
1743 u8 *rates = cmd.bss.rates;
1744 for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
1745 u8 hw_rate = lbs_rates[hw].bitrate / 5;
1746 for (i = 0; i < rates_max; i++) {
1747 if (hw_rate == (rates_eid[i+2] & 0x7f)) {
1748 u8 rate = rates_eid[i+2];
1749 if (rate == 0x02 || rate == 0x04 ||
1750 rate == 0x0b || rate == 0x16)
1751 rate |= 0x80;
1752 *rates++ = rate;
1753 }
1754 }
1755 }
1756 }
1757
1758 /* Only v8 and below support setting this */
1759 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1760 cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1761 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1762 }
1763 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
1764 if (ret)
1765 goto out;
1766
1767 /*
1768 * This is a sample response to CMD_802_11_AD_HOC_JOIN:
1769 *
1770 * response 2c 80
1771 * size 09 00
1772 * sequence xx xx
1773 * result 00 00
1774 * reserved 00
1775 */
1776 lbs_join_post(priv, params, bss->bssid, bss->capability);
1777
1778 out:
1779 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1780 return ret;
1781}
1782
1783
1784
1785static int lbs_ibss_start_new(struct lbs_private *priv,
1786 struct cfg80211_ibss_params *params)
1787{
1788 struct cmd_ds_802_11_ad_hoc_start cmd;
1789 struct cmd_ds_802_11_ad_hoc_result *resp =
1790 (struct cmd_ds_802_11_ad_hoc_result *) &cmd;
1791 u8 preamble = RADIO_PREAMBLE_SHORT;
1792 int ret = 0;
1793 u16 capability;
1794
1795 lbs_deb_enter(LBS_DEB_CFG80211);
1796
1797 ret = lbs_set_radio(priv, preamble, 1);
1798 if (ret)
1799 goto out;
1800
1801 /*
1802 * Example CMD_802_11_AD_HOC_START command:
1803 *
1804 * command 2b 00 CMD_802_11_AD_HOC_START
1805 * size b1 00
1806 * sequence xx xx
1807 * result 00 00
1808 * ssid 54 45 53 54 00 00 00 00
1809 * 00 00 00 00 00 00 00 00
1810 * 00 00 00 00 00 00 00 00
1811 * 00 00 00 00 00 00 00 00
1812 * bss type 02
1813 * beacon period 64 00
1814 * dtim period 00
1815 * IE IBSS 06
1816 * IE IBSS len 02
1817 * IE IBSS atim 00 00
1818 * reserved 00 00 00 00
1819 * IE DS 03
1820 * IE DS len 01
1821 * IE DS channel 01
1822 * reserved 00 00 00 00
1823 * probe delay 00 00
1824 * capability 02 00
1825 * rates 82 84 8b 96 (basic rates with have bit 7 set)
1826 * 0c 12 18 24 30 48 60 6c
1827 * padding 100 bytes
1828 */
1829 memset(&cmd, 0, sizeof(cmd));
1830 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1831 memcpy(cmd.ssid, params->ssid, params->ssid_len);
1832 cmd.bsstype = CMD_BSS_TYPE_IBSS;
1833 cmd.beaconperiod = cpu_to_le16(params->beacon_interval);
1834 cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1835 cmd.ibss.header.len = 2;
1836 cmd.ibss.atimwindow = 0;
1837 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1838 cmd.ds.header.len = 1;
1839 cmd.ds.channel = params->channel->hw_value;
1840 /* Only v8 and below support setting probe delay */
1841 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1842 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1843 /* TODO: mix in WLAN_CAPABILITY_PRIVACY */
1844 capability = WLAN_CAPABILITY_IBSS;
1845 cmd.capability = cpu_to_le16(capability);
1846 lbs_add_rates(cmd.rates);
1847
1848
1849 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
1850 if (ret)
1851 goto out;
1852
1853 /*
1854 * This is a sample response to CMD_802_11_AD_HOC_JOIN:
1855 *
1856 * response 2b 80
1857 * size 14 00
1858 * sequence xx xx
1859 * result 00 00
1860 * reserved 00
1861 * bssid 02 2b 7b 0f 86 0e
1862 */
1863 lbs_join_post(priv, params, resp->bssid, capability);
1864
1865 out:
1866 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1867 return ret;
1868}
1869
1870
1871static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1872 struct cfg80211_ibss_params *params)
1873{
1874 struct lbs_private *priv = wiphy_priv(wiphy);
1875 int ret = 0;
1876 struct cfg80211_bss *bss;
1877 DECLARE_SSID_BUF(ssid_buf);
1878
1879 lbs_deb_enter(LBS_DEB_CFG80211);
1880
1881 if (!params->channel) {
1882 ret = -ENOTSUPP;
1883 goto out;
1884 }
1885
1886 ret = lbs_set_channel(priv, params->channel->hw_value);
1887 if (ret)
1888 goto out;
1889
1890 /* Search if someone is beaconing. This assumes that the
1891 * bss list is populated already */
1892 bss = cfg80211_get_bss(wiphy, params->channel, params->bssid,
1893 params->ssid, params->ssid_len,
1894 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
1895
1896 if (bss) {
1897 ret = lbs_ibss_join_existing(priv, params, bss);
1898 cfg80211_put_bss(bss);
1899 } else
1900 ret = lbs_ibss_start_new(priv, params);
1901
1902
1903 out:
1904 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1905 return ret;
1906}
1907
1908
1909static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1910{
1911 struct lbs_private *priv = wiphy_priv(wiphy);
1912 struct cmd_ds_802_11_ad_hoc_stop cmd;
1913 int ret = 0;
1914
1915 lbs_deb_enter(LBS_DEB_CFG80211);
1916
1917 memset(&cmd, 0, sizeof(cmd));
1918 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1919 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
1920
1921 /* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */
1922 lbs_mac_event_disconnected(priv);
1923
1924 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1925 return ret;
1926}
1927
1928
1929
1930
1931/***************************************************************************
1932 * Initialization
1933 */
1934
104static struct cfg80211_ops lbs_cfg80211_ops = { 1935static struct cfg80211_ops lbs_cfg80211_ops = {
105 .set_channel = lbs_cfg_set_channel, 1936 .set_channel = lbs_cfg_set_channel,
1937 .scan = lbs_cfg_scan,
1938 .connect = lbs_cfg_connect,
1939 .disconnect = lbs_cfg_disconnect,
1940 .add_key = lbs_cfg_add_key,
1941 .del_key = lbs_cfg_del_key,
1942 .set_default_key = lbs_cfg_set_default_key,
1943 .get_station = lbs_cfg_get_station,
1944 .dump_survey = lbs_get_survey,
1945 .change_virtual_intf = lbs_change_intf,
1946 .join_ibss = lbs_join_ibss,
1947 .leave_ibss = lbs_leave_ibss,
106}; 1948};
107 1949
108 1950
@@ -142,6 +1984,36 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev)
142} 1984}
143 1985
144 1986
1987static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
1988{
1989 struct region_code_mapping {
1990 const char *cn;
1991 int code;
1992 };
1993
1994 /* Section 5.17.2 */
1995 static struct region_code_mapping regmap[] = {
1996 {"US ", 0x10}, /* US FCC */
1997 {"CA ", 0x20}, /* Canada */
1998 {"EU ", 0x30}, /* ETSI */
1999 {"ES ", 0x31}, /* Spain */
2000 {"FR ", 0x32}, /* France */
2001 {"JP ", 0x40}, /* Japan */
2002 };
2003 size_t i;
2004
2005 lbs_deb_enter(LBS_DEB_CFG80211);
2006
2007 for (i = 0; i < ARRAY_SIZE(regmap); i++)
2008 if (regmap[i].code == priv->regioncode) {
2009 regulatory_hint(priv->wdev->wiphy, regmap[i].cn);
2010 break;
2011 }
2012
2013 lbs_deb_leave(LBS_DEB_CFG80211);
2014}
2015
2016
145/* 2017/*
146 * This function get's called after lbs_setup_firmware() determined the 2018 * This function get's called after lbs_setup_firmware() determined the
147 * firmware capabities. So we can setup the wiphy according to our 2019 * firmware capabities. So we can setup the wiphy according to our
@@ -157,10 +2029,12 @@ int lbs_cfg_register(struct lbs_private *priv)
157 wdev->wiphy->max_scan_ssids = 1; 2029 wdev->wiphy->max_scan_ssids = 1;
158 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 2030 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
159 2031
160 /* TODO: BIT(NL80211_IFTYPE_ADHOC); */ 2032 wdev->wiphy->interface_modes =
161 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 2033 BIT(NL80211_IFTYPE_STATION) |
2034 BIT(NL80211_IFTYPE_ADHOC);
2035 if (lbs_rtap_supported(priv))
2036 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
162 2037
163 /* TODO: honor priv->regioncode */
164 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz; 2038 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
165 2039
166 /* 2040 /*
@@ -169,6 +2043,7 @@ int lbs_cfg_register(struct lbs_private *priv)
169 */ 2043 */
170 wdev->wiphy->cipher_suites = cipher_suites; 2044 wdev->wiphy->cipher_suites = cipher_suites;
171 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 2045 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2046 wdev->wiphy->reg_notifier = lbs_reg_notifier;
172 2047
173 ret = wiphy_register(wdev->wiphy); 2048 ret = wiphy_register(wdev->wiphy);
174 if (ret < 0) 2049 if (ret < 0)
@@ -180,10 +2055,129 @@ int lbs_cfg_register(struct lbs_private *priv)
180 if (ret) 2055 if (ret)
181 lbs_pr_err("cannot register network device\n"); 2056 lbs_pr_err("cannot register network device\n");
182 2057
2058 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
2059
2060 lbs_cfg_set_regulatory_hint(priv);
2061
183 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 2062 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
184 return ret; 2063 return ret;
185} 2064}
186 2065
2066/**
2067 * @brief This function sets DOMAIN INFO to FW
2068 * @param priv pointer to struct lbs_private
2069 * @return 0; -1
2070*/
2071static int lbs_11d_set_domain_info(struct lbs_private *priv)
2072{
2073 int ret;
2074
2075 ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
2076 CMD_ACT_SET,
2077 CMD_OPTION_WAITFORRSP, 0, NULL);
2078 if (ret)
2079 lbs_deb_11d("fail to dnld domain info\n");
2080
2081 return ret;
2082}
2083
2084static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy,
2085 struct regulatory_request *request)
2086{
2087 u8 no_of_triplet = 0;
2088 u8 no_of_parsed_chan = 0;
2089 u8 first_channel = 0, next_chan = 0, max_pwr = 0;
2090 u8 i, flag = 0;
2091 enum ieee80211_band band;
2092 struct ieee80211_supported_band *sband;
2093 struct ieee80211_channel *ch;
2094 struct lbs_private *priv = wiphy_priv(wiphy);
2095 struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg;
2096 int ret = 0;
2097
2098 lbs_deb_enter(LBS_DEB_CFG80211);
2099
2100 /* Set country code */
2101 domain_info->country_code[0] = request->alpha2[0];
2102 domain_info->country_code[1] = request->alpha2[1];
2103 domain_info->country_code[2] = ' ';
2104
2105 for (band = 0; band < IEEE80211_NUM_BANDS ; band++) {
2106
2107 if (!wiphy->bands[band])
2108 continue;
2109
2110 sband = wiphy->bands[band];
2111
2112 for (i = 0; i < sband->n_channels ; i++) {
2113 ch = &sband->channels[i];
2114 if (ch->flags & IEEE80211_CHAN_DISABLED)
2115 continue;
2116
2117 if (!flag) {
2118 flag = 1;
2119 next_chan = first_channel = (u32) ch->hw_value;
2120 max_pwr = ch->max_power;
2121 no_of_parsed_chan = 1;
2122 continue;
2123 }
2124
2125 if (ch->hw_value == next_chan + 1 &&
2126 ch->max_power == max_pwr) {
2127 next_chan++;
2128 no_of_parsed_chan++;
2129 } else {
2130 domain_info->triplet[no_of_triplet]
2131 .chans.first_channel = first_channel;
2132 domain_info->triplet[no_of_triplet]
2133 .chans.num_channels = no_of_parsed_chan;
2134 domain_info->triplet[no_of_triplet]
2135 .chans.max_power = max_pwr;
2136 no_of_triplet++;
2137 flag = 0;
2138 }
2139 }
2140 if (flag) {
2141 domain_info->triplet[no_of_triplet]
2142 .chans.first_channel = first_channel;
2143 domain_info->triplet[no_of_triplet]
2144 .chans.num_channels = no_of_parsed_chan;
2145 domain_info->triplet[no_of_triplet]
2146 .chans.max_power = max_pwr;
2147 no_of_triplet++;
2148 }
2149 }
2150
2151 domain_info->no_triplet = no_of_triplet;
2152
2153 /* Set domain info */
2154 ret = lbs_11d_set_domain_info(priv);
2155 if (ret)
2156 lbs_pr_err("11D: error setting domain info in FW\n");
2157
2158 lbs_deb_leave(LBS_DEB_CFG80211);
2159}
2160
2161int lbs_reg_notifier(struct wiphy *wiphy,
2162 struct regulatory_request *request)
2163{
2164 lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
2165 "callback for domain %c%c\n", request->alpha2[0],
2166 request->alpha2[1]);
2167
2168 lbs_send_domain_info_cmd_fw(wiphy, request);
2169
2170 lbs_deb_leave(LBS_DEB_CFG80211);
2171
2172 return 0;
2173}
2174
2175void lbs_scan_deinit(struct lbs_private *priv)
2176{
2177 lbs_deb_enter(LBS_DEB_CFG80211);
2178 cancel_delayed_work_sync(&priv->scan_work);
2179}
2180
187 2181
188void lbs_cfg_free(struct lbs_private *priv) 2182void lbs_cfg_free(struct lbs_private *priv)
189{ 2183{
diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h
index e09a193a34d6..756fb98f9f05 100644
--- a/drivers/net/wireless/libertas/cfg.h
+++ b/drivers/net/wireless/libertas/cfg.h
@@ -1,16 +1,27 @@
1#ifndef __LBS_CFG80211_H__ 1#ifndef __LBS_CFG80211_H__
2#define __LBS_CFG80211_H__ 2#define __LBS_CFG80211_H__
3 3
4#include "dev.h" 4struct device;
5struct lbs_private;
6struct regulatory_request;
7struct wiphy;
5 8
6struct wireless_dev *lbs_cfg_alloc(struct device *dev); 9struct wireless_dev *lbs_cfg_alloc(struct device *dev);
7int lbs_cfg_register(struct lbs_private *priv); 10int lbs_cfg_register(struct lbs_private *priv);
8void lbs_cfg_free(struct lbs_private *priv); 11void lbs_cfg_free(struct lbs_private *priv);
9 12
10int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, 13int lbs_reg_notifier(struct wiphy *wiphy,
11 u8 ssid_len); 14 struct regulatory_request *request);
12int lbs_scan_networks(struct lbs_private *priv, int full_scan);
13void lbs_cfg_scan_worker(struct work_struct *work);
14 15
16/* All of those are TODOs: */
17#define lbs_cmd_802_11_rssi(priv, cmdptr) (0)
18#define lbs_ret_802_11_rssi(priv, resp) (0)
19#define lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action) (0)
20#define lbs_ret_802_11_bcn_ctrl(priv, resp) (0)
21
22void lbs_send_disconnect_notification(struct lbs_private *priv);
23void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
24
25void lbs_scan_deinit(struct lbs_private *priv);
15 26
16#endif 27#endif
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index cdb9b9650d73..6c8a9d952a01 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -7,13 +7,8 @@
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/slab.h> 8#include <linux/slab.h>
9 9
10#include "host.h"
11#include "decl.h" 10#include "decl.h"
12#include "defs.h" 11#include "cfg.h"
13#include "dev.h"
14#include "assoc.h"
15#include "wext.h"
16#include "scan.h"
17#include "cmd.h" 12#include "cmd.h"
18 13
19 14
@@ -70,6 +65,8 @@ static u8 is_command_allowed_in_ps(u16 cmd)
70 switch (cmd) { 65 switch (cmd) {
71 case CMD_802_11_RSSI: 66 case CMD_802_11_RSSI:
72 return 1; 67 return 1;
68 case CMD_802_11_HOST_SLEEP_CFG:
69 return 1;
73 default: 70 default:
74 break; 71 break;
75 } 72 }
@@ -175,16 +172,28 @@ int lbs_update_hw_spec(struct lbs_private *priv)
175 if (priv->mesh_dev) 172 if (priv->mesh_dev)
176 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN); 173 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
177 174
178 if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
179 ret = -1;
180 goto out;
181 }
182
183out: 175out:
184 lbs_deb_leave(LBS_DEB_CMD); 176 lbs_deb_leave(LBS_DEB_CMD);
185 return ret; 177 return ret;
186} 178}
187 179
180static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
181 struct cmd_header *resp)
182{
183 lbs_deb_enter(LBS_DEB_CMD);
184 if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
185 priv->is_host_sleep_configured = 0;
186 if (priv->psstate == PS_STATE_FULL_POWER) {
187 priv->is_host_sleep_activated = 0;
188 wake_up_interruptible(&priv->host_sleep_q);
189 }
190 } else {
191 priv->is_host_sleep_configured = 1;
192 }
193 lbs_deb_leave(LBS_DEB_CMD);
194 return 0;
195}
196
188int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, 197int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
189 struct wol_config *p_wol_config) 198 struct wol_config *p_wol_config)
190{ 199{
@@ -202,12 +211,11 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
202 else 211 else
203 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE; 212 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
204 213
205 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config); 214 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
215 le16_to_cpu(cmd_config.hdr.size),
216 lbs_ret_host_sleep_cfg, 0);
206 if (!ret) { 217 if (!ret) {
207 if (criteria) { 218 if (p_wol_config)
208 lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
209 priv->wol_criteria = criteria;
210 } else
211 memcpy((uint8_t *) p_wol_config, 219 memcpy((uint8_t *) p_wol_config,
212 (uint8_t *)&cmd_config.wol_conf, 220 (uint8_t *)&cmd_config.wol_conf,
213 sizeof(struct wol_config)); 221 sizeof(struct wol_config));
@@ -712,6 +720,10 @@ static void lbs_queue_cmd(struct lbs_private *priv,
712 } 720 }
713 } 721 }
714 722
723 if (le16_to_cpu(cmdnode->cmdbuf->command) ==
724 CMD_802_11_WAKEUP_CONFIRM)
725 addtail = 0;
726
715 spin_lock_irqsave(&priv->driver_lock, flags); 727 spin_lock_irqsave(&priv->driver_lock, flags);
716 728
717 if (addtail) 729 if (addtail)
@@ -887,6 +899,66 @@ void lbs_set_mac_control(struct lbs_private *priv)
887} 899}
888 900
889/** 901/**
902 * @brief This function implements command CMD_802_11D_DOMAIN_INFO
903 * @param priv pointer to struct lbs_private
904 * @param cmd pointer to cmd buffer
905 * @param cmdno cmd ID
906 * @param cmdOption cmd action
907 * @return 0
908*/
909int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
910 struct cmd_ds_command *cmd,
911 u16 cmdoption)
912{
913 struct cmd_ds_802_11d_domain_info *pdomaininfo =
914 &cmd->params.domaininfo;
915 struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
916 u8 nr_triplet = priv->domain_reg.no_triplet;
917
918 lbs_deb_enter(LBS_DEB_11D);
919
920 lbs_deb_11d("nr_triplet=%x\n", nr_triplet);
921
922 pdomaininfo->action = cpu_to_le16(cmdoption);
923 if (cmdoption == CMD_ACT_GET) {
924 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
925 sizeof(struct cmd_header));
926 lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
927 le16_to_cpu(cmd->size));
928 goto done;
929 }
930
931 domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
932 memcpy(domain->countrycode, priv->domain_reg.country_code,
933 sizeof(domain->countrycode));
934
935 domain->header.len = cpu_to_le16(nr_triplet
936 * sizeof(struct ieee80211_country_ie_triplet)
937 + sizeof(domain->countrycode));
938
939 if (nr_triplet) {
940 memcpy(domain->triplet, priv->domain_reg.triplet,
941 nr_triplet *
942 sizeof(struct ieee80211_country_ie_triplet));
943
944 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
945 le16_to_cpu(domain->header.len) +
946 sizeof(struct mrvl_ie_header) +
947 sizeof(struct cmd_header));
948 } else {
949 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
950 sizeof(struct cmd_header));
951 }
952
953 lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
954 le16_to_cpu(cmd->size));
955
956done:
957 lbs_deb_enter(LBS_DEB_11D);
958 return 0;
959}
960
961/**
890 * @brief This function prepare the command before send to firmware. 962 * @brief This function prepare the command before send to firmware.
891 * 963 *
892 * @param priv A pointer to struct lbs_private structure 964 * @param priv A pointer to struct lbs_private structure
@@ -984,6 +1056,11 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
984 ret = 0; 1056 ret = 0;
985 goto done; 1057 goto done;
986 1058
1059 case CMD_802_11D_DOMAIN_INFO:
1060 cmdptr->command = cpu_to_le16(cmd_no);
1061 ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action);
1062 break;
1063
987 case CMD_802_11_TPC_CFG: 1064 case CMD_802_11_TPC_CFG:
988 cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG); 1065 cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
989 cmdptr->size = 1066 cmdptr->size =
@@ -1303,6 +1380,15 @@ int lbs_execute_next_command(struct lbs_private *priv)
1303 * check if in power save mode, if yes, put the device back 1380 * check if in power save mode, if yes, put the device back
1304 * to PS mode 1381 * to PS mode
1305 */ 1382 */
1383#ifdef TODO
1384 /*
1385 * This was the old code for libertas+wext. Someone that
1386 * understands this beast should re-code it in a sane way.
1387 *
1388 * I actually don't understand why this is related to WPA
1389 * and to connection status, shouldn't powering should be
1390 * independ of such things?
1391 */
1306 if ((priv->psmode != LBS802_11POWERMODECAM) && 1392 if ((priv->psmode != LBS802_11POWERMODECAM) &&
1307 (priv->psstate == PS_STATE_FULL_POWER) && 1393 (priv->psstate == PS_STATE_FULL_POWER) &&
1308 ((priv->connect_status == LBS_CONNECTED) || 1394 ((priv->connect_status == LBS_CONNECTED) ||
@@ -1324,6 +1410,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
1324 lbs_ps_sleep(priv, 0); 1410 lbs_ps_sleep(priv, 0);
1325 } 1411 }
1326 } 1412 }
1413#endif
1327 } 1414 }
1328 1415
1329 ret = 0; 1416 ret = 0;
@@ -1353,6 +1440,11 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
1353 /* We don't get a response on the sleep-confirmation */ 1440 /* We don't get a response on the sleep-confirmation */
1354 priv->dnld_sent = DNLD_RES_RECEIVED; 1441 priv->dnld_sent = DNLD_RES_RECEIVED;
1355 1442
1443 if (priv->is_host_sleep_configured) {
1444 priv->is_host_sleep_activated = 1;
1445 wake_up_interruptible(&priv->host_sleep_q);
1446 }
1447
1356 /* If nothing to do, go back to sleep (?) */ 1448 /* If nothing to do, go back to sleep (?) */
1357 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) 1449 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1358 priv->psstate = PS_STATE_SLEEP; 1450 priv->psstate = PS_STATE_SLEEP;
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 88f7131d66e9..a0d9482ef5e2 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -5,18 +5,11 @@
5#include <linux/slab.h> 5#include <linux/slab.h>
6#include <linux/delay.h> 6#include <linux/delay.h>
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/if_arp.h>
9#include <linux/netdevice.h>
10#include <asm/unaligned.h> 8#include <asm/unaligned.h>
11#include <net/iw_handler.h> 9#include <net/cfg80211.h>
12 10
13#include "host.h" 11#include "cfg.h"
14#include "decl.h"
15#include "cmd.h" 12#include "cmd.h"
16#include "defs.h"
17#include "dev.h"
18#include "assoc.h"
19#include "wext.h"
20 13
21/** 14/**
22 * @brief This function handles disconnect event. it 15 * @brief This function handles disconnect event. it
@@ -38,7 +31,9 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
38 * It causes problem in the Supplicant 31 * It causes problem in the Supplicant
39 */ 32 */
40 msleep_interruptible(1000); 33 msleep_interruptible(1000);
41 lbs_send_disconnect_notification(priv); 34
35 if (priv->wdev->iftype == NL80211_IFTYPE_STATION)
36 lbs_send_disconnect_notification(priv);
42 37
43 /* report disconnect to upper layer */ 38 /* report disconnect to upper layer */
44 netif_stop_queue(priv->dev); 39 netif_stop_queue(priv->dev);
@@ -49,23 +44,8 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
49 priv->currenttxskb = NULL; 44 priv->currenttxskb = NULL;
50 priv->tx_pending_len = 0; 45 priv->tx_pending_len = 0;
51 46
52 /* reset SNR/NF/RSSI values */
53 memset(priv->SNR, 0x00, sizeof(priv->SNR));
54 memset(priv->NF, 0x00, sizeof(priv->NF));
55 memset(priv->RSSI, 0x00, sizeof(priv->RSSI));
56 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
57 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
58 priv->nextSNRNF = 0;
59 priv->numSNRNF = 0;
60 priv->connect_status = LBS_DISCONNECTED; 47 priv->connect_status = LBS_DISCONNECTED;
61 48
62 /* Clear out associated SSID and BSSID since connection is
63 * no longer valid.
64 */
65 memset(&priv->curbssparams.bssid, 0, ETH_ALEN);
66 memset(&priv->curbssparams.ssid, 0, IEEE80211_MAX_SSID_LEN);
67 priv->curbssparams.ssid_len = 0;
68
69 if (priv->psstate != PS_STATE_FULL_POWER) { 49 if (priv->psstate != PS_STATE_FULL_POWER) {
70 /* make firmware to exit PS mode */ 50 /* make firmware to exit PS mode */
71 lbs_deb_cmd("disconnected, so exit PS mode\n"); 51 lbs_deb_cmd("disconnected, so exit PS mode\n");
@@ -117,6 +97,52 @@ static int lbs_ret_reg_access(struct lbs_private *priv,
117 return ret; 97 return ret;
118} 98}
119 99
100/**
101 * @brief This function parses countryinfo from AP and download country info to FW
102 * @param priv pointer to struct lbs_private
103 * @param resp pointer to command response buffer
104 * @return 0; -1
105 */
106static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
107{
108 struct cmd_ds_802_11d_domain_info *domaininfo =
109 &resp->params.domaininforesp;
110 struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
111 u16 action = le16_to_cpu(domaininfo->action);
112 s16 ret = 0;
113 u8 nr_triplet = 0;
114
115 lbs_deb_enter(LBS_DEB_11D);
116
117 lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp,
118 (int)le16_to_cpu(resp->size));
119
120 nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
121 sizeof(struct ieee80211_country_ie_triplet);
122
123 lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet);
124
125 if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) {
126 lbs_deb_11d("invalid number of triplets returned!!\n");
127 return -1;
128 }
129
130 switch (action) {
131 case CMD_ACT_SET: /*Proc set action */
132 break;
133
134 case CMD_ACT_GET:
135 break;
136 default:
137 lbs_deb_11d("invalid action:%d\n", domaininfo->action);
138 ret = -1;
139 break;
140 }
141
142 lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
143 return ret;
144}
145
120static inline int handle_cmd_response(struct lbs_private *priv, 146static inline int handle_cmd_response(struct lbs_private *priv,
121 struct cmd_header *cmd_response) 147 struct cmd_header *cmd_response)
122{ 148{
@@ -150,6 +176,10 @@ static inline int handle_cmd_response(struct lbs_private *priv,
150 ret = lbs_ret_802_11_rssi(priv, resp); 176 ret = lbs_ret_802_11_rssi(priv, resp);
151 break; 177 break;
152 178
179 case CMD_RET(CMD_802_11D_DOMAIN_INFO):
180 ret = lbs_ret_802_11d_domain_info(resp);
181 break;
182
153 case CMD_RET(CMD_802_11_TPC_CFG): 183 case CMD_RET(CMD_802_11_TPC_CFG):
154 spin_lock_irqsave(&priv->driver_lock, flags); 184 spin_lock_irqsave(&priv->driver_lock, flags);
155 memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg, 185 memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
@@ -261,7 +291,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
261 * ad-hoc mode. It takes place in 291 * ad-hoc mode. It takes place in
262 * lbs_execute_next_command(). 292 * lbs_execute_next_command().
263 */ 293 */
264 if (priv->mode == IW_MODE_ADHOC && 294 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
265 action == CMD_SUBCMD_ENTER_PS) 295 action == CMD_SUBCMD_ENTER_PS)
266 priv->psmode = LBS802_11POWERMODECAM; 296 priv->psmode = LBS802_11POWERMODECAM;
267 } else if (action == CMD_SUBCMD_ENTER_PS) { 297 } else if (action == CMD_SUBCMD_ENTER_PS) {
@@ -341,32 +371,10 @@ done:
341 return ret; 371 return ret;
342} 372}
343 373
344static int lbs_send_confirmwake(struct lbs_private *priv)
345{
346 struct cmd_header cmd;
347 int ret = 0;
348
349 lbs_deb_enter(LBS_DEB_HOST);
350
351 cmd.command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM);
352 cmd.size = cpu_to_le16(sizeof(cmd));
353 cmd.seqnum = cpu_to_le16(++priv->seqnum);
354 cmd.result = 0;
355
356 lbs_deb_hex(LBS_DEB_HOST, "wake confirm", (u8 *) &cmd,
357 sizeof(cmd));
358
359 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &cmd, sizeof(cmd));
360 if (ret)
361 lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n");
362
363 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
364 return ret;
365}
366
367int lbs_process_event(struct lbs_private *priv, u32 event) 374int lbs_process_event(struct lbs_private *priv, u32 event)
368{ 375{
369 int ret = 0; 376 int ret = 0;
377 struct cmd_header cmd;
370 378
371 lbs_deb_enter(LBS_DEB_CMD); 379 lbs_deb_enter(LBS_DEB_CMD);
372 380
@@ -410,7 +418,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
410 if (priv->reset_deep_sleep_wakeup) 418 if (priv->reset_deep_sleep_wakeup)
411 priv->reset_deep_sleep_wakeup(priv); 419 priv->reset_deep_sleep_wakeup(priv);
412 priv->is_deep_sleep = 0; 420 priv->is_deep_sleep = 0;
413 lbs_send_confirmwake(priv); 421 lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
422 sizeof(cmd));
423 priv->is_host_sleep_activated = 0;
424 wake_up_interruptible(&priv->host_sleep_q);
414 break; 425 break;
415 426
416 case MACREG_INT_CODE_DEEP_SLEEP_AWAKE: 427 case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index de2caac11dd6..17367463c855 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -1,18 +1,13 @@
1#include <linux/module.h>
2#include <linux/dcache.h> 1#include <linux/dcache.h>
3#include <linux/debugfs.h> 2#include <linux/debugfs.h>
4#include <linux/delay.h> 3#include <linux/delay.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
6#include <linux/string.h> 5#include <linux/string.h>
7#include <linux/slab.h> 6#include <linux/slab.h>
8#include <net/iw_handler.h>
9#include <net/lib80211.h>
10 7
11#include "dev.h"
12#include "decl.h" 8#include "decl.h"
13#include "host.h"
14#include "debugfs.h"
15#include "cmd.h" 9#include "cmd.h"
10#include "debugfs.h"
16 11
17static struct dentry *lbs_dir; 12static struct dentry *lbs_dir;
18static char *szStates[] = { 13static char *szStates[] = {
@@ -60,51 +55,6 @@ static ssize_t lbs_dev_info(struct file *file, char __user *userbuf,
60 return res; 55 return res;
61} 56}
62 57
63
64static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
65 size_t count, loff_t *ppos)
66{
67 struct lbs_private *priv = file->private_data;
68 size_t pos = 0;
69 int numscansdone = 0, res;
70 unsigned long addr = get_zeroed_page(GFP_KERNEL);
71 char *buf = (char *)addr;
72 DECLARE_SSID_BUF(ssid);
73 struct bss_descriptor * iter_bss;
74 if (!buf)
75 return -ENOMEM;
76
77 pos += snprintf(buf+pos, len-pos,
78 "# | ch | rssi | bssid | cap | Qual | SSID\n");
79
80 mutex_lock(&priv->lock);
81 list_for_each_entry (iter_bss, &priv->network_list, list) {
82 u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS);
83 u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY);
84 u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT);
85
86 pos += snprintf(buf+pos, len-pos, "%02u| %03d | %04d | %pM |",
87 numscansdone, iter_bss->channel, iter_bss->rssi,
88 iter_bss->bssid);
89 pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability);
90 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
91 ibss ? 'A' : 'I', privacy ? 'P' : ' ',
92 spectrum_mgmt ? 'S' : ' ');
93 pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi));
94 pos += snprintf(buf+pos, len-pos, " %s\n",
95 print_ssid(ssid, iter_bss->ssid,
96 iter_bss->ssid_len));
97
98 numscansdone++;
99 }
100 mutex_unlock(&priv->lock);
101
102 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
103
104 free_page(addr);
105 return res;
106}
107
108static ssize_t lbs_sleepparams_write(struct file *file, 58static ssize_t lbs_sleepparams_write(struct file *file,
109 const char __user *user_buf, size_t count, 59 const char __user *user_buf, size_t count,
110 loff_t *ppos) 60 loff_t *ppos)
@@ -723,8 +673,6 @@ struct lbs_debugfs_files {
723 673
724static const struct lbs_debugfs_files debugfs_files[] = { 674static const struct lbs_debugfs_files debugfs_files[] = {
725 { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), }, 675 { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
726 { "getscantable", 0444, FOPS(lbs_getscantable,
727 write_file_dummy), },
728 { "sleepparams", 0644, FOPS(lbs_sleepparams_read, 676 { "sleepparams", 0644, FOPS(lbs_sleepparams_read,
729 lbs_sleepparams_write), }, 677 lbs_sleepparams_write), },
730}; 678};
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 709ffcad22ad..ba5438a7ba17 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -1,3 +1,4 @@
1
1/** 2/**
2 * This file contains declaration referring to 3 * This file contains declaration referring to
3 * functions defined in other source files 4 * functions defined in other source files
@@ -12,6 +13,7 @@
12struct lbs_private; 13struct lbs_private;
13struct sk_buff; 14struct sk_buff;
14struct net_device; 15struct net_device;
16struct cmd_ds_command;
15 17
16 18
17/* ethtool.c */ 19/* ethtool.c */
@@ -34,11 +36,13 @@ int lbs_start_card(struct lbs_private *priv);
34void lbs_stop_card(struct lbs_private *priv); 36void lbs_stop_card(struct lbs_private *priv);
35void lbs_host_to_card_done(struct lbs_private *priv); 37void lbs_host_to_card_done(struct lbs_private *priv);
36 38
39int lbs_rtap_supported(struct lbs_private *priv);
40
37int lbs_set_mac_address(struct net_device *dev, void *addr); 41int lbs_set_mac_address(struct net_device *dev, void *addr);
38void lbs_set_multicast_list(struct net_device *dev); 42void lbs_set_multicast_list(struct net_device *dev);
39 43
40int lbs_suspend(struct lbs_private *priv); 44int lbs_suspend(struct lbs_private *priv);
41void lbs_resume(struct lbs_private *priv); 45int lbs_resume(struct lbs_private *priv);
42 46
43void lbs_queue_event(struct lbs_private *priv, u32 event); 47void lbs_queue_event(struct lbs_private *priv, u32 event);
44void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx); 48void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
@@ -49,5 +53,9 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
49u32 lbs_fw_index_to_data_rate(u8 index); 53u32 lbs_fw_index_to_data_rate(u8 index);
50u8 lbs_data_rate_to_fw_index(u32 rate); 54u8 lbs_data_rate_to_fw_index(u32 rate);
51 55
56int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
57 struct cmd_ds_command *cmd, u16 cmdoption);
58
59int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp);
52 60
53#endif 61#endif
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index a54880e4ad2b..4536d9c0ad87 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -7,8 +7,8 @@
7#define _LBS_DEV_H_ 7#define _LBS_DEV_H_
8 8
9#include "mesh.h" 9#include "mesh.h"
10#include "scan.h" 10#include "defs.h"
11#include "assoc.h" 11#include "host.h"
12 12
13#include <linux/kfifo.h> 13#include <linux/kfifo.h>
14 14
@@ -29,7 +29,6 @@ struct lbs_private {
29 /* Basic networking */ 29 /* Basic networking */
30 struct net_device *dev; 30 struct net_device *dev;
31 u32 connect_status; 31 u32 connect_status;
32 int infra_open;
33 struct work_struct mcast_work; 32 struct work_struct mcast_work;
34 u32 nr_of_multicastmacaddr; 33 u32 nr_of_multicastmacaddr;
35 u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN]; 34 u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
@@ -37,6 +36,9 @@ struct lbs_private {
37 /* CFG80211 */ 36 /* CFG80211 */
38 struct wireless_dev *wdev; 37 struct wireless_dev *wdev;
39 bool wiphy_registered; 38 bool wiphy_registered;
39 struct cfg80211_scan_request *scan_req;
40 u8 assoc_bss[ETH_ALEN];
41 u8 disassoc_reason;
40 42
41 /* Mesh */ 43 /* Mesh */
42 struct net_device *mesh_dev; /* Virtual device */ 44 struct net_device *mesh_dev; /* Virtual device */
@@ -49,10 +51,6 @@ struct lbs_private {
49 u8 mesh_ssid_len; 51 u8 mesh_ssid_len;
50#endif 52#endif
51 53
52 /* Monitor mode */
53 struct net_device *rtap_net_dev;
54 u32 monitormode;
55
56 /* Debugfs */ 54 /* Debugfs */
57 struct dentry *debugfs_dir; 55 struct dentry *debugfs_dir;
58 struct dentry *debugfs_debug; 56 struct dentry *debugfs_debug;
@@ -62,6 +60,9 @@ struct lbs_private {
62 struct dentry *regs_dir; 60 struct dentry *regs_dir;
63 struct dentry *debugfs_regs_files[6]; 61 struct dentry *debugfs_regs_files[6];
64 62
63 /** 11D and domain regulatory data */
64 struct lbs_802_11d_domain_reg domain_reg;
65
65 /* Hardware debugging */ 66 /* Hardware debugging */
66 u32 mac_offset; 67 u32 mac_offset;
67 u32 bbp_offset; 68 u32 bbp_offset;
@@ -75,6 +76,7 @@ struct lbs_private {
75 76
76 /* Deep sleep */ 77 /* Deep sleep */
77 int is_deep_sleep; 78 int is_deep_sleep;
79 int deep_sleep_required;
78 int is_auto_deep_sleep_enabled; 80 int is_auto_deep_sleep_enabled;
79 int wakeup_dev_required; 81 int wakeup_dev_required;
80 int is_activity_detected; 82 int is_activity_detected;
@@ -82,6 +84,11 @@ struct lbs_private {
82 wait_queue_head_t ds_awake_q; 84 wait_queue_head_t ds_awake_q;
83 struct timer_list auto_deepsleep_timer; 85 struct timer_list auto_deepsleep_timer;
84 86
87 /* Host sleep*/
88 int is_host_sleep_configured;
89 int is_host_sleep_activated;
90 wait_queue_head_t host_sleep_q;
91
85 /* Hardware access */ 92 /* Hardware access */
86 void *card; 93 void *card;
87 u8 fw_ready; 94 u8 fw_ready;
@@ -127,14 +134,10 @@ struct lbs_private {
127 struct workqueue_struct *work_thread; 134 struct workqueue_struct *work_thread;
128 135
129 /** Encryption stuff */ 136 /** Encryption stuff */
130 struct lbs_802_11_security secinfo;
131 struct enc_key wpa_mcast_key;
132 struct enc_key wpa_unicast_key;
133 u8 wpa_ie[MAX_WPA_IE_LEN];
134 u8 wpa_ie_len;
135 u16 wep_tx_keyidx;
136 struct enc_key wep_keys[4];
137 u8 authtype_auto; 137 u8 authtype_auto;
138 u8 wep_tx_key;
139 u8 wep_key[4][WLAN_KEY_LEN_WEP104];
140 u8 wep_key_len[4];
138 141
139 /* Wake On LAN */ 142 /* Wake On LAN */
140 uint32_t wol_criteria; 143 uint32_t wol_criteria;
@@ -155,6 +158,7 @@ struct lbs_private {
155 /* NIC/link operation characteristics */ 158 /* NIC/link operation characteristics */
156 u16 mac_control; 159 u16 mac_control;
157 u8 radio_on; 160 u8 radio_on;
161 u8 cur_rate;
158 u8 channel; 162 u8 channel;
159 s16 txpower_cur; 163 s16 txpower_cur;
160 s16 txpower_min; 164 s16 txpower_min;
@@ -163,42 +167,6 @@ struct lbs_private {
163 /** Scanning */ 167 /** Scanning */
164 struct delayed_work scan_work; 168 struct delayed_work scan_work;
165 int scan_channel; 169 int scan_channel;
166 /* remember which channel was scanned last, != 0 if currently scanning */
167 u8 scan_ssid[IEEE80211_MAX_SSID_LEN + 1];
168 u8 scan_ssid_len;
169
170 /* Associating */
171 struct delayed_work assoc_work;
172 struct current_bss_params curbssparams;
173 u8 mode;
174 struct list_head network_list;
175 struct list_head network_free_list;
176 struct bss_descriptor *networks;
177 struct assoc_request * pending_assoc_req;
178 struct assoc_request * in_progress_assoc_req;
179 uint16_t enablehwauto;
180
181 /* ADHOC */
182 u16 beacon_period;
183 u8 beacon_enable;
184 u8 adhoccreate;
185
186 /* WEXT */
187 char name[DEV_NAME_LEN];
188 u8 nodename[16];
189 struct iw_statistics wstats;
190 u8 cur_rate;
191#define MAX_REGION_CHANNEL_NUM 2
192 struct region_channel region_channel[MAX_REGION_CHANNEL_NUM];
193
194 /** Requested Signal Strength*/
195 u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
196 u16 NF[MAX_TYPE_B][MAX_TYPE_AVG];
197 u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG];
198 u8 rawSNR[DEFAULT_DATA_AVG_FACTOR];
199 u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
200 u16 nextSNRNF;
201 u16 numSNRNF;
202}; 170};
203 171
204extern struct cmd_confirm_sleep confirm_sleep; 172extern struct cmd_confirm_sleep confirm_sleep;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 3804a58d7f4e..50193aac679e 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -2,13 +2,8 @@
2#include <linux/ethtool.h> 2#include <linux/ethtool.h>
3#include <linux/delay.h> 3#include <linux/delay.h>
4 4
5#include "host.h"
6#include "decl.h" 5#include "decl.h"
7#include "defs.h"
8#include "dev.h"
9#include "wext.h"
10#include "cmd.h" 6#include "cmd.h"
11#include "mesh.h"
12 7
13 8
14static void lbs_ethtool_get_drvinfo(struct net_device *dev, 9static void lbs_ethtool_get_drvinfo(struct net_device *dev,
@@ -69,14 +64,11 @@ static void lbs_ethtool_get_wol(struct net_device *dev,
69{ 64{
70 struct lbs_private *priv = dev->ml_priv; 65 struct lbs_private *priv = dev->ml_priv;
71 66
72 if (priv->wol_criteria == 0xffffffff) {
73 /* Interface driver didn't configure wake */
74 wol->supported = wol->wolopts = 0;
75 return;
76 }
77
78 wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY; 67 wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
79 68
69 if (priv->wol_criteria == EHS_REMOVE_WAKEUP)
70 return;
71
80 if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA) 72 if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA)
81 wol->wolopts |= WAKE_UCAST; 73 wol->wolopts |= WAKE_UCAST;
82 if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA) 74 if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA)
@@ -91,23 +83,22 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
91 struct ethtool_wolinfo *wol) 83 struct ethtool_wolinfo *wol)
92{ 84{
93 struct lbs_private *priv = dev->ml_priv; 85 struct lbs_private *priv = dev->ml_priv;
94 uint32_t criteria = 0;
95 86
96 if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) 87 if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
97 return -EOPNOTSUPP; 88 return -EOPNOTSUPP;
98 89
90 priv->wol_criteria = 0;
99 if (wol->wolopts & WAKE_UCAST) 91 if (wol->wolopts & WAKE_UCAST)
100 criteria |= EHS_WAKE_ON_UNICAST_DATA; 92 priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA;
101 if (wol->wolopts & WAKE_MCAST) 93 if (wol->wolopts & WAKE_MCAST)
102 criteria |= EHS_WAKE_ON_MULTICAST_DATA; 94 priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA;
103 if (wol->wolopts & WAKE_BCAST) 95 if (wol->wolopts & WAKE_BCAST)
104 criteria |= EHS_WAKE_ON_BROADCAST_DATA; 96 priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA;
105 if (wol->wolopts & WAKE_PHY) 97 if (wol->wolopts & WAKE_PHY)
106 criteria |= EHS_WAKE_ON_MAC_EVENT; 98 priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT;
107 if (wol->wolopts == 0) 99 if (wol->wolopts == 0)
108 criteria |= EHS_REMOVE_WAKEUP; 100 priv->wol_criteria |= EHS_REMOVE_WAKEUP;
109 101 return 0;
110 return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
111} 102}
112 103
113const struct ethtool_ops lbs_ethtool_ops = { 104const struct ethtool_ops lbs_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 3809c0b49464..112fbf167dc8 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -389,6 +389,30 @@ struct lbs_offset_value {
389 u32 value; 389 u32 value;
390} __attribute__ ((packed)); 390} __attribute__ ((packed));
391 391
392#define MRVDRV_MAX_TRIPLET_802_11D 83
393
394#define COUNTRY_CODE_LEN 3
395
396struct mrvl_ie_domain_param_set {
397 struct mrvl_ie_header header;
398
399 u8 countrycode[COUNTRY_CODE_LEN];
400 struct ieee80211_country_ie_triplet triplet[1];
401} __attribute__ ((packed));
402
403struct cmd_ds_802_11d_domain_info {
404 __le16 action;
405 struct mrvl_ie_domain_param_set domain;
406} __attribute__ ((packed));
407
408struct lbs_802_11d_domain_reg {
409 /** Country code*/
410 u8 country_code[COUNTRY_CODE_LEN];
411 /** No. of triplet*/
412 u8 no_triplet;
413 struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D];
414} __attribute__ ((packed));
415
392/* 416/*
393 * Define data structure for CMD_GET_HW_SPEC 417 * Define data structure for CMD_GET_HW_SPEC
394 * This structure defines the response for the GET_HW_SPEC command 418 * This structure defines the response for the GET_HW_SPEC command
@@ -949,6 +973,9 @@ struct cmd_ds_command {
949 struct cmd_ds_bbp_reg_access bbpreg; 973 struct cmd_ds_bbp_reg_access bbpreg;
950 struct cmd_ds_rf_reg_access rfreg; 974 struct cmd_ds_rf_reg_access rfreg;
951 975
976 struct cmd_ds_802_11d_domain_info domaininfo;
977 struct cmd_ds_802_11d_domain_info domaininforesp;
978
952 struct cmd_ds_802_11_tpc_cfg tpccfg; 979 struct cmd_ds_802_11_tpc_cfg tpccfg;
953 struct cmd_ds_802_11_afc afc; 980 struct cmd_ds_802_11_afc afc;
954 struct cmd_ds_802_11_led_ctrl ledgpio; 981 struct cmd_ds_802_11_led_ctrl ledgpio;
@@ -958,5 +985,4 @@ struct cmd_ds_command {
958 struct cmd_ds_802_11_beacon_control bcn_ctrl; 985 struct cmd_ds_802_11_beacon_control bcn_ctrl;
959 } params; 986 } params;
960} __attribute__ ((packed)); 987} __attribute__ ((packed));
961
962#endif 988#endif
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 64dd345d30f5..6e71346a7550 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1182,11 +1182,69 @@ static void if_sdio_remove(struct sdio_func *func)
1182 lbs_deb_leave(LBS_DEB_SDIO); 1182 lbs_deb_leave(LBS_DEB_SDIO);
1183} 1183}
1184 1184
1185static int if_sdio_suspend(struct device *dev)
1186{
1187 struct sdio_func *func = dev_to_sdio_func(dev);
1188 int ret;
1189 struct if_sdio_card *card = sdio_get_drvdata(func);
1190
1191 mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
1192
1193 lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
1194 sdio_func_id(func), flags);
1195
1196 /* If we aren't being asked to wake on anything, we should bail out
1197 * and let the SD stack power down the card.
1198 */
1199 if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
1200 lbs_pr_info("Suspend without wake params -- "
1201 "powering down card.");
1202 return -ENOSYS;
1203 }
1204
1205 if (!(flags & MMC_PM_KEEP_POWER)) {
1206 lbs_pr_err("%s: cannot remain alive while host is suspended\n",
1207 sdio_func_id(func));
1208 return -ENOSYS;
1209 }
1210
1211 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1212 if (ret)
1213 return ret;
1214
1215 ret = lbs_suspend(card->priv);
1216 if (ret)
1217 return ret;
1218
1219 return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
1220}
1221
1222static int if_sdio_resume(struct device *dev)
1223{
1224 struct sdio_func *func = dev_to_sdio_func(dev);
1225 struct if_sdio_card *card = sdio_get_drvdata(func);
1226 int ret;
1227
1228 lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));
1229
1230 ret = lbs_resume(card->priv);
1231
1232 return ret;
1233}
1234
1235static const struct dev_pm_ops if_sdio_pm_ops = {
1236 .suspend = if_sdio_suspend,
1237 .resume = if_sdio_resume,
1238};
1239
1185static struct sdio_driver if_sdio_driver = { 1240static struct sdio_driver if_sdio_driver = {
1186 .name = "libertas_sdio", 1241 .name = "libertas_sdio",
1187 .id_table = if_sdio_ids, 1242 .id_table = if_sdio_ids,
1188 .probe = if_sdio_probe, 1243 .probe = if_sdio_probe,
1189 .remove = if_sdio_remove, 1244 .remove = if_sdio_remove,
1245 .drv = {
1246 .pm = &if_sdio_pm_ops,
1247 },
1190}; 1248};
1191 1249
1192/*******************************************************************/ 1250/*******************************************************************/
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index f41594c7ac16..3678e532874f 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -613,16 +613,14 @@ static void if_usb_receive_fwload(struct urb *urb)
613 return; 613 return;
614 } 614 }
615 615
616 syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); 616 syncfwheader = kmemdup(skb->data + IPFIELD_ALIGN_OFFSET,
617 sizeof(struct fwsyncheader), GFP_ATOMIC);
617 if (!syncfwheader) { 618 if (!syncfwheader) {
618 lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); 619 lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
619 kfree_skb(skb); 620 kfree_skb(skb);
620 return; 621 return;
621 } 622 }
622 623
623 memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
624 sizeof(struct fwsyncheader));
625
626 if (!syncfwheader->cmd) { 624 if (!syncfwheader->cmd) {
627 lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); 625 lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
628 lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", 626 lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
@@ -1043,6 +1041,12 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
1043 if (priv->psstate != PS_STATE_FULL_POWER) 1041 if (priv->psstate != PS_STATE_FULL_POWER)
1044 return -1; 1042 return -1;
1045 1043
1044 if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
1045 lbs_pr_info("Suspend attempt without "
1046 "configuring wake params!\n");
1047 return -ENOSYS;
1048 }
1049
1046 ret = lbs_suspend(priv); 1050 ret = lbs_suspend(priv);
1047 if (ret) 1051 if (ret)
1048 goto out; 1052 goto out;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index d9b8ee130c45..b519fc70f04f 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -11,20 +11,14 @@
11#include <linux/if_arp.h> 11#include <linux/if_arp.h>
12#include <linux/kthread.h> 12#include <linux/kthread.h>
13#include <linux/kfifo.h> 13#include <linux/kfifo.h>
14#include <linux/stddef.h>
15#include <linux/ieee80211.h>
16#include <linux/slab.h> 14#include <linux/slab.h>
17#include <net/iw_handler.h>
18#include <net/cfg80211.h> 15#include <net/cfg80211.h>
19 16
20#include "host.h" 17#include "host.h"
21#include "decl.h" 18#include "decl.h"
22#include "dev.h" 19#include "dev.h"
23#include "wext.h"
24#include "cfg.h" 20#include "cfg.h"
25#include "debugfs.h" 21#include "debugfs.h"
26#include "scan.h"
27#include "assoc.h"
28#include "cmd.h" 22#include "cmd.h"
29 23
30#define DRIVER_RELEASE_VERSION "323.p0" 24#define DRIVER_RELEASE_VERSION "323.p0"
@@ -96,72 +90,6 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
96} 90}
97 91
98 92
99static int lbs_add_rtap(struct lbs_private *priv);
100static void lbs_remove_rtap(struct lbs_private *priv);
101
102
103/**
104 * Get function for sysfs attribute rtap
105 */
106static ssize_t lbs_rtap_get(struct device *dev,
107 struct device_attribute *attr, char * buf)
108{
109 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
110 return snprintf(buf, 5, "0x%X\n", priv->monitormode);
111}
112
113/**
114 * Set function for sysfs attribute rtap
115 */
116static ssize_t lbs_rtap_set(struct device *dev,
117 struct device_attribute *attr, const char * buf, size_t count)
118{
119 int monitor_mode;
120 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
121
122 sscanf(buf, "%x", &monitor_mode);
123 if (monitor_mode) {
124 if (priv->monitormode == monitor_mode)
125 return strlen(buf);
126 if (!priv->monitormode) {
127 if (priv->infra_open || lbs_mesh_open(priv))
128 return -EBUSY;
129 if (priv->mode == IW_MODE_INFRA)
130 lbs_cmd_80211_deauthenticate(priv,
131 priv->curbssparams.bssid,
132 WLAN_REASON_DEAUTH_LEAVING);
133 else if (priv->mode == IW_MODE_ADHOC)
134 lbs_adhoc_stop(priv);
135 lbs_add_rtap(priv);
136 }
137 priv->monitormode = monitor_mode;
138 } else {
139 if (!priv->monitormode)
140 return strlen(buf);
141 priv->monitormode = 0;
142 lbs_remove_rtap(priv);
143
144 if (priv->currenttxskb) {
145 dev_kfree_skb_any(priv->currenttxskb);
146 priv->currenttxskb = NULL;
147 }
148
149 /* Wake queues, command thread, etc. */
150 lbs_host_to_card_done(priv);
151 }
152
153 lbs_prepare_and_send_command(priv,
154 CMD_802_11_MONITOR_MODE, CMD_ACT_SET,
155 CMD_OPTION_WAITFORRSP, 0, &priv->monitormode);
156 return strlen(buf);
157}
158
159/**
160 * lbs_rtap attribute to be exported per ethX interface
161 * through sysfs (/sys/class/net/ethX/lbs_rtap)
162 */
163static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
164
165/** 93/**
166 * @brief This function opens the ethX interface 94 * @brief This function opens the ethX interface
167 * 95 *
@@ -177,13 +105,6 @@ static int lbs_dev_open(struct net_device *dev)
177 105
178 spin_lock_irq(&priv->driver_lock); 106 spin_lock_irq(&priv->driver_lock);
179 107
180 if (priv->monitormode) {
181 ret = -EBUSY;
182 goto out;
183 }
184
185 priv->infra_open = 1;
186
187 if (priv->connect_status == LBS_CONNECTED) 108 if (priv->connect_status == LBS_CONNECTED)
188 netif_carrier_on(dev); 109 netif_carrier_on(dev);
189 else 110 else
@@ -191,7 +112,6 @@ static int lbs_dev_open(struct net_device *dev)
191 112
192 if (!priv->tx_pending_len) 113 if (!priv->tx_pending_len)
193 netif_wake_queue(dev); 114 netif_wake_queue(dev);
194 out:
195 115
196 spin_unlock_irq(&priv->driver_lock); 116 spin_unlock_irq(&priv->driver_lock);
197 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 117 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
@@ -211,7 +131,6 @@ static int lbs_eth_stop(struct net_device *dev)
211 lbs_deb_enter(LBS_DEB_NET); 131 lbs_deb_enter(LBS_DEB_NET);
212 132
213 spin_lock_irq(&priv->driver_lock); 133 spin_lock_irq(&priv->driver_lock);
214 priv->infra_open = 0;
215 netif_stop_queue(dev); 134 netif_stop_queue(dev);
216 spin_unlock_irq(&priv->driver_lock); 135 spin_unlock_irq(&priv->driver_lock);
217 136
@@ -625,16 +544,13 @@ static int lbs_thread(void *data)
625 return 0; 544 return 0;
626} 545}
627 546
628static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy, 547static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
629 struct cmd_header *cmd) 548 unsigned long dummy,
549 struct cmd_header *cmd)
630{ 550{
631 lbs_deb_enter(LBS_DEB_FW); 551 lbs_deb_enter(LBS_DEB_FW);
632 552 priv->is_host_sleep_activated = 1;
633 netif_device_detach(priv->dev); 553 wake_up_interruptible(&priv->host_sleep_q);
634 if (priv->mesh_dev)
635 netif_device_detach(priv->mesh_dev);
636
637 priv->fw_ready = 0;
638 lbs_deb_leave(LBS_DEB_FW); 554 lbs_deb_leave(LBS_DEB_FW);
639 return 0; 555 return 0;
640} 556}
@@ -646,39 +562,65 @@ int lbs_suspend(struct lbs_private *priv)
646 562
647 lbs_deb_enter(LBS_DEB_FW); 563 lbs_deb_enter(LBS_DEB_FW);
648 564
649 if (priv->wol_criteria == 0xffffffff) { 565 if (priv->is_deep_sleep) {
650 lbs_pr_info("Suspend attempt without configuring wake params!\n"); 566 ret = lbs_set_deep_sleep(priv, 0);
651 return -EINVAL; 567 if (ret) {
568 lbs_pr_err("deep sleep cancellation failed: %d\n", ret);
569 return ret;
570 }
571 priv->deep_sleep_required = 1;
652 } 572 }
653 573
654 memset(&cmd, 0, sizeof(cmd)); 574 memset(&cmd, 0, sizeof(cmd));
575 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
576 (struct wol_config *)NULL);
577 if (ret) {
578 lbs_pr_info("Host sleep configuration failed: %d\n", ret);
579 return ret;
580 }
581 if (priv->psstate == PS_STATE_FULL_POWER) {
582 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
583 sizeof(cmd), lbs_ret_host_sleep_activate, 0);
584 if (ret)
585 lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
586 }
655 587
656 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd, 588 if (!wait_event_interruptible_timeout(priv->host_sleep_q,
657 sizeof(cmd), lbs_suspend_callback, 0); 589 priv->is_host_sleep_activated, (10 * HZ))) {
658 if (ret) 590 lbs_pr_err("host_sleep_q: timer expired\n");
659 lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret); 591 ret = -1;
592 }
593 netif_device_detach(priv->dev);
594 if (priv->mesh_dev)
595 netif_device_detach(priv->mesh_dev);
660 596
661 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 597 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
662 return ret; 598 return ret;
663} 599}
664EXPORT_SYMBOL_GPL(lbs_suspend); 600EXPORT_SYMBOL_GPL(lbs_suspend);
665 601
666void lbs_resume(struct lbs_private *priv) 602int lbs_resume(struct lbs_private *priv)
667{ 603{
668 lbs_deb_enter(LBS_DEB_FW); 604 int ret;
605 uint32_t criteria = EHS_REMOVE_WAKEUP;
669 606
670 priv->fw_ready = 1; 607 lbs_deb_enter(LBS_DEB_FW);
671 608
672 /* Firmware doesn't seem to give us RX packets any more 609 ret = lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
673 until we send it some command. Might as well update */
674 lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
675 0, 0, NULL);
676 610
677 netif_device_attach(priv->dev); 611 netif_device_attach(priv->dev);
678 if (priv->mesh_dev) 612 if (priv->mesh_dev)
679 netif_device_attach(priv->mesh_dev); 613 netif_device_attach(priv->mesh_dev);
680 614
681 lbs_deb_leave(LBS_DEB_FW); 615 if (priv->deep_sleep_required) {
616 priv->deep_sleep_required = 0;
617 ret = lbs_set_deep_sleep(priv, 1);
618 if (ret)
619 lbs_pr_err("deep sleep activation failed: %d\n", ret);
620 }
621
622 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
623 return ret;
682} 624}
683EXPORT_SYMBOL_GPL(lbs_resume); 625EXPORT_SYMBOL_GPL(lbs_resume);
684 626
@@ -710,6 +652,9 @@ static int lbs_setup_firmware(struct lbs_private *priv)
710 priv->txpower_max = maxlevel; 652 priv->txpower_max = maxlevel;
711 } 653 }
712 654
655 /* Send cmd to FW to enable 11D function */
656 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
657
713 lbs_set_mac_control(priv); 658 lbs_set_mac_control(priv);
714done: 659done:
715 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 660 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
@@ -799,45 +744,27 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
799 744
800static int lbs_init_adapter(struct lbs_private *priv) 745static int lbs_init_adapter(struct lbs_private *priv)
801{ 746{
802 size_t bufsize; 747 int ret;
803 int i, ret = 0;
804 748
805 lbs_deb_enter(LBS_DEB_MAIN); 749 lbs_deb_enter(LBS_DEB_MAIN);
806 750
807 /* Allocate buffer to store the BSSID list */
808 bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
809 priv->networks = kzalloc(bufsize, GFP_KERNEL);
810 if (!priv->networks) {
811 lbs_pr_err("Out of memory allocating beacons\n");
812 ret = -1;
813 goto out;
814 }
815
816 /* Initialize scan result lists */
817 INIT_LIST_HEAD(&priv->network_free_list);
818 INIT_LIST_HEAD(&priv->network_list);
819 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
820 list_add_tail(&priv->networks[i].list,
821 &priv->network_free_list);
822 }
823
824 memset(priv->current_addr, 0xff, ETH_ALEN); 751 memset(priv->current_addr, 0xff, ETH_ALEN);
825 752
826 priv->connect_status = LBS_DISCONNECTED; 753 priv->connect_status = LBS_DISCONNECTED;
827 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
828 priv->mode = IW_MODE_INFRA;
829 priv->channel = DEFAULT_AD_HOC_CHANNEL; 754 priv->channel = DEFAULT_AD_HOC_CHANNEL;
830 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 755 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
831 priv->radio_on = 1; 756 priv->radio_on = 1;
832 priv->enablehwauto = 1;
833 priv->psmode = LBS802_11POWERMODECAM; 757 priv->psmode = LBS802_11POWERMODECAM;
834 priv->psstate = PS_STATE_FULL_POWER; 758 priv->psstate = PS_STATE_FULL_POWER;
835 priv->is_deep_sleep = 0; 759 priv->is_deep_sleep = 0;
836 priv->is_auto_deep_sleep_enabled = 0; 760 priv->is_auto_deep_sleep_enabled = 0;
761 priv->deep_sleep_required = 0;
837 priv->wakeup_dev_required = 0; 762 priv->wakeup_dev_required = 0;
838 init_waitqueue_head(&priv->ds_awake_q); 763 init_waitqueue_head(&priv->ds_awake_q);
839 priv->authtype_auto = 1; 764 priv->authtype_auto = 1;
840 765 priv->is_host_sleep_configured = 0;
766 priv->is_host_sleep_activated = 0;
767 init_waitqueue_head(&priv->host_sleep_q);
841 mutex_init(&priv->lock); 768 mutex_init(&priv->lock);
842 769
843 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, 770 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
@@ -881,8 +808,6 @@ static void lbs_free_adapter(struct lbs_private *priv)
881 kfifo_free(&priv->event_fifo); 808 kfifo_free(&priv->event_fifo);
882 del_timer(&priv->command_timer); 809 del_timer(&priv->command_timer);
883 del_timer(&priv->auto_deepsleep_timer); 810 del_timer(&priv->auto_deepsleep_timer);
884 kfree(priv->networks);
885 priv->networks = NULL;
886 811
887 lbs_deb_leave(LBS_DEB_MAIN); 812 lbs_deb_leave(LBS_DEB_MAIN);
888} 813}
@@ -919,7 +844,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
919 lbs_pr_err("cfg80211 init failed\n"); 844 lbs_pr_err("cfg80211 init failed\n");
920 goto done; 845 goto done;
921 } 846 }
922 /* TODO? */ 847
923 wdev->iftype = NL80211_IFTYPE_STATION; 848 wdev->iftype = NL80211_IFTYPE_STATION;
924 priv = wdev_priv(wdev); 849 priv = wdev_priv(wdev);
925 priv->wdev = wdev; 850 priv->wdev = wdev;
@@ -929,7 +854,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
929 goto err_wdev; 854 goto err_wdev;
930 } 855 }
931 856
932 //TODO? dev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
933 dev = alloc_netdev(0, "wlan%d", ether_setup); 857 dev = alloc_netdev(0, "wlan%d", ether_setup);
934 if (!dev) { 858 if (!dev) {
935 dev_err(dmdev, "no memory for network device instance\n"); 859 dev_err(dmdev, "no memory for network device instance\n");
@@ -945,20 +869,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
945 dev->netdev_ops = &lbs_netdev_ops; 869 dev->netdev_ops = &lbs_netdev_ops;
946 dev->watchdog_timeo = 5 * HZ; 870 dev->watchdog_timeo = 5 * HZ;
947 dev->ethtool_ops = &lbs_ethtool_ops; 871 dev->ethtool_ops = &lbs_ethtool_ops;
948#ifdef WIRELESS_EXT
949 dev->wireless_handlers = &lbs_handler_def;
950#endif
951 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 872 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
952 873
953
954 // TODO: kzalloc + iwm_init_default_profile(iwm, iwm->umac_profile); ??
955
956
957 priv->card = card; 874 priv->card = card;
958 priv->infra_open = 0;
959 875
960
961 priv->rtap_net_dev = NULL;
962 strcpy(dev->name, "wlan%d"); 876 strcpy(dev->name, "wlan%d");
963 877
964 lbs_deb_thread("Starting main thread...\n"); 878 lbs_deb_thread("Starting main thread...\n");
@@ -970,12 +884,11 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
970 } 884 }
971 885
972 priv->work_thread = create_singlethread_workqueue("lbs_worker"); 886 priv->work_thread = create_singlethread_workqueue("lbs_worker");
973 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
974 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
975 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); 887 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
976 888
977 priv->wol_criteria = 0xffffffff; 889 priv->wol_criteria = 0xffffffff;
978 priv->wol_gpio = 0xff; 890 priv->wol_gpio = 0xff;
891 priv->wol_gap = 20;
979 892
980 goto done; 893 goto done;
981 894
@@ -1004,12 +917,10 @@ void lbs_remove_card(struct lbs_private *priv)
1004 lbs_deb_enter(LBS_DEB_MAIN); 917 lbs_deb_enter(LBS_DEB_MAIN);
1005 918
1006 lbs_remove_mesh(priv); 919 lbs_remove_mesh(priv);
1007 lbs_remove_rtap(priv); 920 lbs_scan_deinit(priv);
1008 921
1009 dev = priv->dev; 922 dev = priv->dev;
1010 923
1011 cancel_delayed_work_sync(&priv->scan_work);
1012 cancel_delayed_work_sync(&priv->assoc_work);
1013 cancel_work_sync(&priv->mcast_work); 924 cancel_work_sync(&priv->mcast_work);
1014 925
1015 /* worker thread destruction blocks on the in-flight command which 926 /* worker thread destruction blocks on the in-flight command which
@@ -1024,13 +935,15 @@ void lbs_remove_card(struct lbs_private *priv)
1024 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); 935 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1025 } 936 }
1026 937
1027 lbs_send_disconnect_notification(priv);
1028
1029 if (priv->is_deep_sleep) { 938 if (priv->is_deep_sleep) {
1030 priv->is_deep_sleep = 0; 939 priv->is_deep_sleep = 0;
1031 wake_up_interruptible(&priv->ds_awake_q); 940 wake_up_interruptible(&priv->ds_awake_q);
1032 } 941 }
1033 942
943 priv->is_host_sleep_configured = 0;
944 priv->is_host_sleep_activated = 0;
945 wake_up_interruptible(&priv->host_sleep_q);
946
1034 /* Stop the thread servicing the interrupts */ 947 /* Stop the thread servicing the interrupts */
1035 priv->surpriseremoved = 1; 948 priv->surpriseremoved = 1;
1036 kthread_stop(priv->main_thread); 949 kthread_stop(priv->main_thread);
@@ -1046,7 +959,7 @@ void lbs_remove_card(struct lbs_private *priv)
1046EXPORT_SYMBOL_GPL(lbs_remove_card); 959EXPORT_SYMBOL_GPL(lbs_remove_card);
1047 960
1048 961
1049static int lbs_rtap_supported(struct lbs_private *priv) 962int lbs_rtap_supported(struct lbs_private *priv)
1050{ 963{
1051 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) 964 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
1052 return 1; 965 return 1;
@@ -1078,16 +991,6 @@ int lbs_start_card(struct lbs_private *priv)
1078 991
1079 lbs_init_mesh(priv); 992 lbs_init_mesh(priv);
1080 993
1081 /*
1082 * While rtap isn't related to mesh, only mesh-enabled
1083 * firmware implements the rtap functionality via
1084 * CMD_802_11_MONITOR_MODE.
1085 */
1086 if (lbs_rtap_supported(priv)) {
1087 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
1088 lbs_pr_err("cannot register lbs_rtap attribute\n");
1089 }
1090
1091 lbs_debugfs_init_one(priv, dev); 994 lbs_debugfs_init_one(priv, dev);
1092 995
1093 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); 996 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
@@ -1119,9 +1022,6 @@ void lbs_stop_card(struct lbs_private *priv)
1119 lbs_debugfs_remove_one(priv); 1022 lbs_debugfs_remove_one(priv);
1120 lbs_deinit_mesh(priv); 1023 lbs_deinit_mesh(priv);
1121 1024
1122 if (lbs_rtap_supported(priv))
1123 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1124
1125 /* Delete the timeout of the currently processing command */ 1025 /* Delete the timeout of the currently processing command */
1126 del_timer_sync(&priv->command_timer); 1026 del_timer_sync(&priv->command_timer);
1127 del_timer_sync(&priv->auto_deepsleep_timer); 1027 del_timer_sync(&priv->auto_deepsleep_timer);
@@ -1208,87 +1108,6 @@ static void __exit lbs_exit_module(void)
1208 lbs_deb_leave(LBS_DEB_MAIN); 1108 lbs_deb_leave(LBS_DEB_MAIN);
1209} 1109}
1210 1110
1211/*
1212 * rtap interface support fuctions
1213 */
1214
1215static int lbs_rtap_open(struct net_device *dev)
1216{
1217 /* Yes, _stop_ the queue. Because we don't support injection */
1218 lbs_deb_enter(LBS_DEB_MAIN);
1219 netif_carrier_off(dev);
1220 netif_stop_queue(dev);
1221 lbs_deb_leave(LBS_DEB_LEAVE);
1222 return 0;
1223}
1224
1225static int lbs_rtap_stop(struct net_device *dev)
1226{
1227 lbs_deb_enter(LBS_DEB_MAIN);
1228 lbs_deb_leave(LBS_DEB_MAIN);
1229 return 0;
1230}
1231
1232static netdev_tx_t lbs_rtap_hard_start_xmit(struct sk_buff *skb,
1233 struct net_device *dev)
1234{
1235 netif_stop_queue(dev);
1236 return NETDEV_TX_BUSY;
1237}
1238
1239static void lbs_remove_rtap(struct lbs_private *priv)
1240{
1241 lbs_deb_enter(LBS_DEB_MAIN);
1242 if (priv->rtap_net_dev == NULL)
1243 goto out;
1244 unregister_netdev(priv->rtap_net_dev);
1245 free_netdev(priv->rtap_net_dev);
1246 priv->rtap_net_dev = NULL;
1247out:
1248 lbs_deb_leave(LBS_DEB_MAIN);
1249}
1250
1251static const struct net_device_ops rtap_netdev_ops = {
1252 .ndo_open = lbs_rtap_open,
1253 .ndo_stop = lbs_rtap_stop,
1254 .ndo_start_xmit = lbs_rtap_hard_start_xmit,
1255};
1256
1257static int lbs_add_rtap(struct lbs_private *priv)
1258{
1259 int ret = 0;
1260 struct net_device *rtap_dev;
1261
1262 lbs_deb_enter(LBS_DEB_MAIN);
1263 if (priv->rtap_net_dev) {
1264 ret = -EPERM;
1265 goto out;
1266 }
1267
1268 rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
1269 if (rtap_dev == NULL) {
1270 ret = -ENOMEM;
1271 goto out;
1272 }
1273
1274 memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
1275 rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
1276 rtap_dev->netdev_ops = &rtap_netdev_ops;
1277 rtap_dev->ml_priv = priv;
1278 SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
1279
1280 ret = register_netdev(rtap_dev);
1281 if (ret) {
1282 free_netdev(rtap_dev);
1283 goto out;
1284 }
1285 priv->rtap_net_dev = rtap_dev;
1286
1287out:
1288 lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1289 return ret;
1290}
1291
1292module_init(lbs_init_module); 1111module_init(lbs_init_module);
1293module_exit(lbs_exit_module); 1112module_exit(lbs_exit_module);
1294 1113
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index e385af1f4583..bc5bc1384c35 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -5,6 +5,7 @@
5#include <linux/if_arp.h> 5#include <linux/if_arp.h>
6#include <linux/kthread.h> 6#include <linux/kthread.h>
7#include <linux/kfifo.h> 7#include <linux/kfifo.h>
8#include <net/cfg80211.h>
8 9
9#include "mesh.h" 10#include "mesh.h"
10#include "decl.h" 11#include "decl.h"
@@ -314,7 +315,7 @@ static int lbs_mesh_dev_open(struct net_device *dev)
314 315
315 spin_lock_irq(&priv->driver_lock); 316 spin_lock_irq(&priv->driver_lock);
316 317
317 if (priv->monitormode) { 318 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
318 ret = -EBUSY; 319 ret = -EBUSY;
319 goto out; 320 goto out;
320 } 321 }
@@ -369,9 +370,6 @@ int lbs_add_mesh(struct lbs_private *priv)
369 370
370 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); 371 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
371 372
372#ifdef WIRELESS_EXT
373 mesh_dev->wireless_handlers = &mesh_handler_def;
374#endif
375 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 373 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
376 /* Register virtual mesh interface */ 374 /* Register virtual mesh interface */
377 ret = register_netdev(mesh_dev); 375 ret = register_netdev(mesh_dev);
diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h
index e2573303a328..84ea2481ff20 100644
--- a/drivers/net/wireless/libertas/mesh.h
+++ b/drivers/net/wireless/libertas/mesh.h
@@ -70,11 +70,6 @@ void lbs_persist_config_init(struct net_device *net);
70void lbs_persist_config_remove(struct net_device *net); 70void lbs_persist_config_remove(struct net_device *net);
71 71
72 72
73/* WEXT handler */
74
75extern struct iw_handler_def mesh_handler_def;
76
77
78/* Ethtool statistics */ 73/* Ethtool statistics */
79 74
80struct ethtool_stats; 75struct ethtool_stats;
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 7a377f5b7662..2163df01caed 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -4,12 +4,13 @@
4#include <linux/etherdevice.h> 4#include <linux/etherdevice.h>
5#include <linux/slab.h> 5#include <linux/slab.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <net/cfg80211.h>
7 8
9#include "defs.h"
8#include "host.h" 10#include "host.h"
9#include "radiotap.h" 11#include "radiotap.h"
10#include "decl.h" 12#include "decl.h"
11#include "dev.h" 13#include "dev.h"
12#include "wext.h"
13 14
14struct eth803hdr { 15struct eth803hdr {
15 u8 dest_addr[6]; 16 u8 dest_addr[6];
@@ -39,98 +40,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
39 struct sk_buff *skb); 40 struct sk_buff *skb);
40 41
41/** 42/**
42 * @brief This function computes the avgSNR .
43 *
44 * @param priv A pointer to struct lbs_private structure
45 * @return avgSNR
46 */
47static u8 lbs_getavgsnr(struct lbs_private *priv)
48{
49 u8 i;
50 u16 temp = 0;
51 if (priv->numSNRNF == 0)
52 return 0;
53 for (i = 0; i < priv->numSNRNF; i++)
54 temp += priv->rawSNR[i];
55 return (u8) (temp / priv->numSNRNF);
56
57}
58
59/**
60 * @brief This function computes the AvgNF
61 *
62 * @param priv A pointer to struct lbs_private structure
63 * @return AvgNF
64 */
65static u8 lbs_getavgnf(struct lbs_private *priv)
66{
67 u8 i;
68 u16 temp = 0;
69 if (priv->numSNRNF == 0)
70 return 0;
71 for (i = 0; i < priv->numSNRNF; i++)
72 temp += priv->rawNF[i];
73 return (u8) (temp / priv->numSNRNF);
74
75}
76
77/**
78 * @brief This function save the raw SNR/NF to our internel buffer
79 *
80 * @param priv A pointer to struct lbs_private structure
81 * @param prxpd A pointer to rxpd structure of received packet
82 * @return n/a
83 */
84static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
85{
86 if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR)
87 priv->numSNRNF++;
88 priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr;
89 priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf;
90 priv->nextSNRNF++;
91 if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
92 priv->nextSNRNF = 0;
93}
94
95/**
96 * @brief This function computes the RSSI in received packet.
97 *
98 * @param priv A pointer to struct lbs_private structure
99 * @param prxpd A pointer to rxpd structure of received packet
100 * @return n/a
101 */
102static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
103{
104
105 lbs_deb_enter(LBS_DEB_RX);
106
107 lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
108 lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
109 priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
110 priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
111
112 priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
113 priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
114 lbs_save_rawSNRNF(priv, p_rx_pd);
115
116 priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE;
117 priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE;
118 lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
119 priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
120 priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
121
122 priv->RSSI[TYPE_RXPD][TYPE_NOAVG] =
123 CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG],
124 priv->NF[TYPE_RXPD][TYPE_NOAVG]);
125
126 priv->RSSI[TYPE_RXPD][TYPE_AVG] =
127 CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
128 priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
129
130 lbs_deb_leave(LBS_DEB_RX);
131}
132
133/**
134 * @brief This function processes received packet and forwards it 43 * @brief This function processes received packet and forwards it
135 * to kernel/upper layer 44 * to kernel/upper layer
136 * 45 *
@@ -154,7 +63,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
154 63
155 skb->ip_summed = CHECKSUM_NONE; 64 skb->ip_summed = CHECKSUM_NONE;
156 65
157 if (priv->monitormode) 66 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
158 return process_rxed_802_11_packet(priv, skb); 67 return process_rxed_802_11_packet(priv, skb);
159 68
160 p_rx_pd = (struct rxpd *) skb->data; 69 p_rx_pd = (struct rxpd *) skb->data;
@@ -225,13 +134,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
225 */ 134 */
226 skb_pull(skb, hdrchop); 135 skb_pull(skb, hdrchop);
227 136
228 /* Take the data rate from the rxpd structure 137 priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
229 * only if the rate is auto
230 */
231 if (priv->enablehwauto)
232 priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
233
234 lbs_compute_rssi(priv, p_rx_pd);
235 138
236 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); 139 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
237 dev->stats.rx_bytes += skb->len; 140 dev->stats.rx_bytes += skb->len;
@@ -352,20 +255,18 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
352 pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr)); 255 pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
353 memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr)); 256 memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr));
354 257
355 /* Take the data rate from the rxpd structure 258 priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
356 * only if the rate is auto
357 */
358 if (priv->enablehwauto)
359 priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
360
361 lbs_compute_rssi(priv, prxpd);
362 259
363 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); 260 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
364 dev->stats.rx_bytes += skb->len; 261 dev->stats.rx_bytes += skb->len;
365 dev->stats.rx_packets++; 262 dev->stats.rx_packets++;
366 263
367 skb->protocol = eth_type_trans(skb, priv->rtap_net_dev); 264 skb->protocol = eth_type_trans(skb, priv->dev);
368 netif_rx(skb); 265
266 if (in_interrupt())
267 netif_rx(skb);
268 else
269 netif_rx_ni(skb);
369 270
370 ret = 0; 271 ret = 0;
371 272
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
deleted file mode 100644
index 24cd54b3a806..000000000000
--- a/drivers/net/wireless/libertas/scan.c
+++ /dev/null
@@ -1,1354 +0,0 @@
1/**
2 * Functions implementing wlan scan IOCTL and firmware command APIs
3 *
4 * IOCTL handlers as well as command preperation and response routines
5 * for sending scan commands to the firmware.
6 */
7#include <linux/slab.h>
8#include <linux/types.h>
9#include <linux/kernel.h>
10#include <linux/etherdevice.h>
11#include <linux/if_arp.h>
12#include <asm/unaligned.h>
13#include <net/lib80211.h>
14
15#include "host.h"
16#include "dev.h"
17#include "scan.h"
18#include "assoc.h"
19#include "wext.h"
20#include "cmd.h"
21
22//! Approximate amount of data needed to pass a scan result back to iwlist
23#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \
24 + IEEE80211_MAX_SSID_LEN \
25 + IW_EV_UINT_LEN \
26 + IW_EV_FREQ_LEN \
27 + IW_EV_QUAL_LEN \
28 + IEEE80211_MAX_SSID_LEN \
29 + IW_EV_PARAM_LEN \
30 + 40) /* 40 for WPAIE */
31
32//! Memory needed to store a max sized channel List TLV for a firmware scan
33#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \
34 + (MRVDRV_MAX_CHANNELS_PER_SCAN \
35 * sizeof(struct chanscanparamset)))
36
37//! Memory needed to store a max number/size SSID TLV for a firmware scan
38#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set))
39
40//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
41#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \
42 + CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE)
43
44//! The maximum number of channels the firmware can scan per command
45#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
46
47/**
48 * @brief Number of channels to scan per firmware scan command issuance.
49 *
50 * Number restricted to prevent hitting the limit on the amount of scan data
51 * returned in a single firmware scan command.
52 */
53#define MRVDRV_CHANNELS_PER_SCAN_CMD 4
54
55//! Scan time specified in the channel TLV for each channel for passive scans
56#define MRVDRV_PASSIVE_SCAN_CHAN_TIME 100
57
58//! Scan time specified in the channel TLV for each channel for active scans
59#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
60
61#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
62
63static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
64 struct cmd_header *resp);
65
66/*********************************************************************/
67/* */
68/* Misc helper functions */
69/* */
70/*********************************************************************/
71
72/**
73 * @brief Unsets the MSB on basic rates
74 *
75 * Scan through an array and unset the MSB for basic data rates.
76 *
77 * @param rates buffer of data rates
78 * @param len size of buffer
79 */
80static void lbs_unset_basic_rate_flags(u8 *rates, size_t len)
81{
82 int i;
83
84 for (i = 0; i < len; i++)
85 rates[i] &= 0x7f;
86}
87
88
89static inline void clear_bss_descriptor(struct bss_descriptor *bss)
90{
91 /* Don't blow away ->list, just BSS data */
92 memset(bss, 0, offsetof(struct bss_descriptor, list));
93}
94
95/**
96 * @brief Compare two SSIDs
97 *
98 * @param ssid1 A pointer to ssid to compare
99 * @param ssid2 A pointer to ssid to compare
100 *
101 * @return 0: ssid is same, otherwise is different
102 */
103int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2,
104 uint8_t ssid2_len)
105{
106 if (ssid1_len != ssid2_len)
107 return -1;
108
109 return memcmp(ssid1, ssid2, ssid1_len);
110}
111
112static inline int is_same_network(struct bss_descriptor *src,
113 struct bss_descriptor *dst)
114{
115 /* A network is only a duplicate if the channel, BSSID, and ESSID
116 * all match. We treat all <hidden> with the same BSSID and channel
117 * as one network */
118 return ((src->ssid_len == dst->ssid_len) &&
119 (src->channel == dst->channel) &&
120 !compare_ether_addr(src->bssid, dst->bssid) &&
121 !memcmp(src->ssid, dst->ssid, src->ssid_len));
122}
123
124
125
126/*********************************************************************/
127/* */
128/* Region channel support */
129/* */
130/*********************************************************************/
131
132#define LBS_TX_PWR_DEFAULT 20 /*100mW */
133#define LBS_TX_PWR_US_DEFAULT 20 /*100mW */
134#define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */
135#define LBS_TX_PWR_FR_DEFAULT 20 /*100mW */
136#define LBS_TX_PWR_EMEA_DEFAULT 20 /*100mW */
137
138/* Format { channel, frequency (MHz), maxtxpower } */
139/* band: 'B/G', region: USA FCC/Canada IC */
140static struct chan_freq_power channel_freq_power_US_BG[] = {
141 {1, 2412, LBS_TX_PWR_US_DEFAULT},
142 {2, 2417, LBS_TX_PWR_US_DEFAULT},
143 {3, 2422, LBS_TX_PWR_US_DEFAULT},
144 {4, 2427, LBS_TX_PWR_US_DEFAULT},
145 {5, 2432, LBS_TX_PWR_US_DEFAULT},
146 {6, 2437, LBS_TX_PWR_US_DEFAULT},
147 {7, 2442, LBS_TX_PWR_US_DEFAULT},
148 {8, 2447, LBS_TX_PWR_US_DEFAULT},
149 {9, 2452, LBS_TX_PWR_US_DEFAULT},
150 {10, 2457, LBS_TX_PWR_US_DEFAULT},
151 {11, 2462, LBS_TX_PWR_US_DEFAULT}
152};
153
154/* band: 'B/G', region: Europe ETSI */
155static struct chan_freq_power channel_freq_power_EU_BG[] = {
156 {1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
157 {2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
158 {3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
159 {4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
160 {5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
161 {6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
162 {7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
163 {8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
164 {9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
165 {10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
166 {11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
167 {12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
168 {13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
169};
170
171/* band: 'B/G', region: Spain */
172static struct chan_freq_power channel_freq_power_SPN_BG[] = {
173 {10, 2457, LBS_TX_PWR_DEFAULT},
174 {11, 2462, LBS_TX_PWR_DEFAULT}
175};
176
177/* band: 'B/G', region: France */
178static struct chan_freq_power channel_freq_power_FR_BG[] = {
179 {10, 2457, LBS_TX_PWR_FR_DEFAULT},
180 {11, 2462, LBS_TX_PWR_FR_DEFAULT},
181 {12, 2467, LBS_TX_PWR_FR_DEFAULT},
182 {13, 2472, LBS_TX_PWR_FR_DEFAULT}
183};
184
185/* band: 'B/G', region: Japan */
186static struct chan_freq_power channel_freq_power_JPN_BG[] = {
187 {1, 2412, LBS_TX_PWR_JP_DEFAULT},
188 {2, 2417, LBS_TX_PWR_JP_DEFAULT},
189 {3, 2422, LBS_TX_PWR_JP_DEFAULT},
190 {4, 2427, LBS_TX_PWR_JP_DEFAULT},
191 {5, 2432, LBS_TX_PWR_JP_DEFAULT},
192 {6, 2437, LBS_TX_PWR_JP_DEFAULT},
193 {7, 2442, LBS_TX_PWR_JP_DEFAULT},
194 {8, 2447, LBS_TX_PWR_JP_DEFAULT},
195 {9, 2452, LBS_TX_PWR_JP_DEFAULT},
196 {10, 2457, LBS_TX_PWR_JP_DEFAULT},
197 {11, 2462, LBS_TX_PWR_JP_DEFAULT},
198 {12, 2467, LBS_TX_PWR_JP_DEFAULT},
199 {13, 2472, LBS_TX_PWR_JP_DEFAULT},
200 {14, 2484, LBS_TX_PWR_JP_DEFAULT}
201};
202
203/**
204 * the structure for channel, frequency and power
205 */
206struct region_cfp_table {
207 u8 region;
208 struct chan_freq_power *cfp_BG;
209 int cfp_no_BG;
210};
211
212/**
213 * the structure for the mapping between region and CFP
214 */
215static struct region_cfp_table region_cfp_table[] = {
216 {0x10, /*US FCC */
217 channel_freq_power_US_BG,
218 ARRAY_SIZE(channel_freq_power_US_BG),
219 }
220 ,
221 {0x20, /*CANADA IC */
222 channel_freq_power_US_BG,
223 ARRAY_SIZE(channel_freq_power_US_BG),
224 }
225 ,
226 {0x30, /*EU*/ channel_freq_power_EU_BG,
227 ARRAY_SIZE(channel_freq_power_EU_BG),
228 }
229 ,
230 {0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
231 ARRAY_SIZE(channel_freq_power_SPN_BG),
232 }
233 ,
234 {0x32, /*FRANCE*/ channel_freq_power_FR_BG,
235 ARRAY_SIZE(channel_freq_power_FR_BG),
236 }
237 ,
238 {0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
239 ARRAY_SIZE(channel_freq_power_JPN_BG),
240 }
241 ,
242/*Add new region here */
243};
244
245/**
246 * @brief This function finds the CFP in
247 * region_cfp_table based on region and band parameter.
248 *
249 * @param region The region code
250 * @param band The band
251 * @param cfp_no A pointer to CFP number
252 * @return A pointer to CFP
253 */
254static struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no)
255{
256 int i, end;
257
258 lbs_deb_enter(LBS_DEB_MAIN);
259
260 end = ARRAY_SIZE(region_cfp_table);
261
262 for (i = 0; i < end ; i++) {
263 lbs_deb_main("region_cfp_table[i].region=%d\n",
264 region_cfp_table[i].region);
265 if (region_cfp_table[i].region == region) {
266 *cfp_no = region_cfp_table[i].cfp_no_BG;
267 lbs_deb_leave(LBS_DEB_MAIN);
268 return region_cfp_table[i].cfp_BG;
269 }
270 }
271
272 lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
273 return NULL;
274}
275
276int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
277{
278 int ret = 0;
279 int i = 0;
280
281 struct chan_freq_power *cfp;
282 int cfp_no;
283
284 lbs_deb_enter(LBS_DEB_MAIN);
285
286 memset(priv->region_channel, 0, sizeof(priv->region_channel));
287
288 cfp = lbs_get_region_cfp_table(region, &cfp_no);
289 if (cfp != NULL) {
290 priv->region_channel[i].nrcfp = cfp_no;
291 priv->region_channel[i].CFP = cfp;
292 } else {
293 lbs_deb_main("wrong region code %#x in band B/G\n",
294 region);
295 ret = -1;
296 goto out;
297 }
298 priv->region_channel[i].valid = 1;
299 priv->region_channel[i].region = region;
300 priv->region_channel[i].band = band;
301 i++;
302out:
303 lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
304 return ret;
305}
306
307
308
309
310/*********************************************************************/
311/* */
312/* Main scanning support */
313/* */
314/*********************************************************************/
315
316/**
317 * @brief Create a channel list for the driver to scan based on region info
318 *
319 * Only used from lbs_scan_setup_scan_config()
320 *
321 * Use the driver region/band information to construct a comprehensive list
322 * of channels to scan. This routine is used for any scan that is not
323 * provided a specific channel list to scan.
324 *
325 * @param priv A pointer to struct lbs_private structure
326 * @param scanchanlist Output parameter: resulting channel list to scan
327 *
328 * @return void
329 */
330static int lbs_scan_create_channel_list(struct lbs_private *priv,
331 struct chanscanparamset *scanchanlist)
332{
333 struct region_channel *scanregion;
334 struct chan_freq_power *cfp;
335 int rgnidx;
336 int chanidx;
337 int nextchan;
338 uint8_t scantype;
339
340 chanidx = 0;
341
342 /* Set the default scan type to the user specified type, will later
343 * be changed to passive on a per channel basis if restricted by
344 * regulatory requirements (11d or 11h)
345 */
346 scantype = CMD_SCAN_TYPE_ACTIVE;
347
348 for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) {
349 if (!priv->region_channel[rgnidx].valid)
350 continue;
351 scanregion = &priv->region_channel[rgnidx];
352
353 for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) {
354 struct chanscanparamset *chan = &scanchanlist[chanidx];
355
356 cfp = scanregion->CFP + nextchan;
357
358 if (scanregion->band == BAND_B || scanregion->band == BAND_G)
359 chan->radiotype = CMD_SCAN_RADIO_TYPE_BG;
360
361 if (scantype == CMD_SCAN_TYPE_PASSIVE) {
362 chan->maxscantime = cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
363 chan->chanscanmode.passivescan = 1;
364 } else {
365 chan->maxscantime = cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
366 chan->chanscanmode.passivescan = 0;
367 }
368
369 chan->channumber = cfp->channel;
370 }
371 }
372 return chanidx;
373}
374
375/*
376 * Add SSID TLV of the form:
377 *
378 * TLV-ID SSID 00 00
379 * length 06 00
380 * ssid 4d 4e 54 45 53 54
381 */
382static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
383{
384 struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
385
386 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
387 ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len);
388 memcpy(ssid_tlv->ssid, priv->scan_ssid, priv->scan_ssid_len);
389 return sizeof(ssid_tlv->header) + priv->scan_ssid_len;
390}
391
392/*
393 * Add CHANLIST TLV of the form
394 *
395 * TLV-ID CHANLIST 01 01
396 * length 5b 00
397 * channel 1 00 01 00 00 00 64 00
398 * radio type 00
399 * channel 01
400 * scan type 00
401 * min scan time 00 00
402 * max scan time 64 00
403 * channel 2 00 02 00 00 00 64 00
404 * channel 3 00 03 00 00 00 64 00
405 * channel 4 00 04 00 00 00 64 00
406 * channel 5 00 05 00 00 00 64 00
407 * channel 6 00 06 00 00 00 64 00
408 * channel 7 00 07 00 00 00 64 00
409 * channel 8 00 08 00 00 00 64 00
410 * channel 9 00 09 00 00 00 64 00
411 * channel 10 00 0a 00 00 00 64 00
412 * channel 11 00 0b 00 00 00 64 00
413 * channel 12 00 0c 00 00 00 64 00
414 * channel 13 00 0d 00 00 00 64 00
415 *
416 */
417static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
418 struct chanscanparamset *chan_list,
419 int chan_count)
420{
421 size_t size = sizeof(struct chanscanparamset) *chan_count;
422 struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv;
423
424 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
425 memcpy(chan_tlv->chanscanparam, chan_list, size);
426 chan_tlv->header.len = cpu_to_le16(size);
427 return sizeof(chan_tlv->header) + size;
428}
429
430/*
431 * Add RATES TLV of the form
432 *
433 * TLV-ID RATES 01 00
434 * length 0e 00
435 * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c
436 *
437 * The rates are in lbs_bg_rates[], but for the 802.11b
438 * rates the high bit isn't set.
439 */
440static int lbs_scan_add_rates_tlv(uint8_t *tlv)
441{
442 int i;
443 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
444
445 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
446 tlv += sizeof(rate_tlv->header);
447 for (i = 0; i < MAX_RATES; i++) {
448 *tlv = lbs_bg_rates[i];
449 if (*tlv == 0)
450 break;
451 /* This code makes sure that the 802.11b rates (1 MBit/s, 2
452 MBit/s, 5.5 MBit/s and 11 MBit/s get's the high bit set.
453 Note that the values are MBit/s * 2, to mark them as
454 basic rates so that the firmware likes it better */
455 if (*tlv == 0x02 || *tlv == 0x04 ||
456 *tlv == 0x0b || *tlv == 0x16)
457 *tlv |= 0x80;
458 tlv++;
459 }
460 rate_tlv->header.len = cpu_to_le16(i);
461 return sizeof(rate_tlv->header) + i;
462}
463
464/*
465 * Generate the CMD_802_11_SCAN command with the proper tlv
466 * for a bunch of channels.
467 */
468static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype,
469 struct chanscanparamset *chan_list, int chan_count)
470{
471 int ret = -ENOMEM;
472 struct cmd_ds_802_11_scan *scan_cmd;
473 uint8_t *tlv; /* pointer into our current, growing TLV storage area */
474
475 lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d",
476 bsstype, chan_list ? chan_list[0].channumber : -1,
477 chan_count);
478
479 /* create the fixed part for scan command */
480 scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
481 if (scan_cmd == NULL)
482 goto out;
483
484 tlv = scan_cmd->tlvbuffer;
485 /* TODO: do we need to scan for a specific BSSID?
486 memcpy(scan_cmd->bssid, priv->scan_bssid, ETH_ALEN); */
487 scan_cmd->bsstype = bsstype;
488
489 /* add TLVs */
490 if (priv->scan_ssid_len)
491 tlv += lbs_scan_add_ssid_tlv(priv, tlv);
492 if (chan_list && chan_count)
493 tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count);
494 tlv += lbs_scan_add_rates_tlv(tlv);
495
496 /* This is the final data we are about to send */
497 scan_cmd->hdr.size = cpu_to_le16(tlv - (uint8_t *)scan_cmd);
498 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
499 sizeof(*scan_cmd));
500 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
501 tlv - scan_cmd->tlvbuffer);
502
503 ret = __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
504 le16_to_cpu(scan_cmd->hdr.size),
505 lbs_ret_80211_scan, 0);
506
507out:
508 kfree(scan_cmd);
509 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
510 return ret;
511}
512
513/**
514 * @brief Internal function used to start a scan based on an input config
515 *
516 * Use the input user scan configuration information when provided in
517 * order to send the appropriate scan commands to firmware to populate or
518 * update the internal driver scan table
519 *
520 * @param priv A pointer to struct lbs_private structure
521 * @param full_scan Do a full-scan (blocking)
522 *
523 * @return 0 or < 0 if error
524 */
525int lbs_scan_networks(struct lbs_private *priv, int full_scan)
526{
527 int ret = -ENOMEM;
528 struct chanscanparamset *chan_list;
529 struct chanscanparamset *curr_chans;
530 int chan_count;
531 uint8_t bsstype = CMD_BSS_TYPE_ANY;
532 int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD;
533 union iwreq_data wrqu;
534#ifdef CONFIG_LIBERTAS_DEBUG
535 struct bss_descriptor *iter;
536 int i = 0;
537 DECLARE_SSID_BUF(ssid);
538#endif
539
540 lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan);
541
542 /* Cancel any partial outstanding partial scans if this scan
543 * is a full scan.
544 */
545 if (full_scan && delayed_work_pending(&priv->scan_work))
546 cancel_delayed_work(&priv->scan_work);
547
548 /* User-specified bsstype or channel list
549 TODO: this can be implemented if some user-space application
550 need the feature. Formerly, it was accessible from debugfs,
551 but then nowhere used.
552 if (user_cfg) {
553 if (user_cfg->bsstype)
554 bsstype = user_cfg->bsstype;
555 } */
556
557 lbs_deb_scan("numchannels %d, bsstype %d\n", numchannels, bsstype);
558
559 /* Create list of channels to scan */
560 chan_list = kzalloc(sizeof(struct chanscanparamset) *
561 LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
562 if (!chan_list) {
563 lbs_pr_alert("SCAN: chan_list empty\n");
564 goto out;
565 }
566
567 /* We want to scan all channels */
568 chan_count = lbs_scan_create_channel_list(priv, chan_list);
569
570 netif_stop_queue(priv->dev);
571 if (priv->mesh_dev)
572 netif_stop_queue(priv->mesh_dev);
573
574 /* Prepare to continue an interrupted scan */
575 lbs_deb_scan("chan_count %d, scan_channel %d\n",
576 chan_count, priv->scan_channel);
577 curr_chans = chan_list;
578 /* advance channel list by already-scanned-channels */
579 if (priv->scan_channel > 0) {
580 curr_chans += priv->scan_channel;
581 chan_count -= priv->scan_channel;
582 }
583
584 /* Send scan command(s)
585 * numchannels contains the number of channels we should maximally scan
586 * chan_count is the total number of channels to scan
587 */
588
589 while (chan_count) {
590 int to_scan = min(numchannels, chan_count);
591 lbs_deb_scan("scanning %d of %d channels\n",
592 to_scan, chan_count);
593 ret = lbs_do_scan(priv, bsstype, curr_chans,
594 to_scan);
595 if (ret) {
596 lbs_pr_err("SCAN_CMD failed\n");
597 goto out2;
598 }
599 curr_chans += to_scan;
600 chan_count -= to_scan;
601
602 /* somehow schedule the next part of the scan */
603 if (chan_count && !full_scan &&
604 !priv->surpriseremoved) {
605 /* -1 marks just that we're currently scanning */
606 if (priv->scan_channel < 0)
607 priv->scan_channel = to_scan;
608 else
609 priv->scan_channel += to_scan;
610 cancel_delayed_work(&priv->scan_work);
611 queue_delayed_work(priv->work_thread, &priv->scan_work,
612 msecs_to_jiffies(300));
613 /* skip over GIWSCAN event */
614 goto out;
615 }
616
617 }
618 memset(&wrqu, 0, sizeof(union iwreq_data));
619 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
620
621#ifdef CONFIG_LIBERTAS_DEBUG
622 /* Dump the scan table */
623 mutex_lock(&priv->lock);
624 lbs_deb_scan("scan table:\n");
625 list_for_each_entry(iter, &priv->network_list, list)
626 lbs_deb_scan("%02d: BSSID %pM, RSSI %d, SSID '%s'\n",
627 i++, iter->bssid, iter->rssi,
628 print_ssid(ssid, iter->ssid, iter->ssid_len));
629 mutex_unlock(&priv->lock);
630#endif
631
632out2:
633 priv->scan_channel = 0;
634
635out:
636 if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len)
637 netif_wake_queue(priv->dev);
638
639 if (priv->mesh_dev && lbs_mesh_connected(priv) &&
640 !priv->tx_pending_len)
641 netif_wake_queue(priv->mesh_dev);
642
643 kfree(chan_list);
644
645 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
646 return ret;
647}
648
649void lbs_scan_worker(struct work_struct *work)
650{
651 struct lbs_private *priv =
652 container_of(work, struct lbs_private, scan_work.work);
653
654 lbs_deb_enter(LBS_DEB_SCAN);
655 lbs_scan_networks(priv, 0);
656 lbs_deb_leave(LBS_DEB_SCAN);
657}
658
659
660/*********************************************************************/
661/* */
662/* Result interpretation */
663/* */
664/*********************************************************************/
665
666/**
667 * @brief Interpret a BSS scan response returned from the firmware
668 *
669 * Parse the various fixed fields and IEs passed back for a a BSS probe
670 * response or beacon from the scan command. Record information as needed
671 * in the scan table struct bss_descriptor for that entry.
672 *
673 * @param bss Output parameter: Pointer to the BSS Entry
674 *
675 * @return 0 or -1
676 */
677static int lbs_process_bss(struct bss_descriptor *bss,
678 uint8_t **pbeaconinfo, int *bytesleft)
679{
680 struct ieee_ie_fh_param_set *fh;
681 struct ieee_ie_ds_param_set *ds;
682 struct ieee_ie_cf_param_set *cf;
683 struct ieee_ie_ibss_param_set *ibss;
684 DECLARE_SSID_BUF(ssid);
685 uint8_t *pos, *end, *p;
686 uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
687 uint16_t beaconsize = 0;
688 int ret;
689
690 lbs_deb_enter(LBS_DEB_SCAN);
691
692 if (*bytesleft >= sizeof(beaconsize)) {
693 /* Extract & convert beacon size from the command buffer */
694 beaconsize = get_unaligned_le16(*pbeaconinfo);
695 *bytesleft -= sizeof(beaconsize);
696 *pbeaconinfo += sizeof(beaconsize);
697 }
698
699 if (beaconsize == 0 || beaconsize > *bytesleft) {
700 *pbeaconinfo += *bytesleft;
701 *bytesleft = 0;
702 ret = -1;
703 goto done;
704 }
705
706 /* Initialize the current working beacon pointer for this BSS iteration */
707 pos = *pbeaconinfo;
708 end = pos + beaconsize;
709
710 /* Advance the return beacon pointer past the current beacon */
711 *pbeaconinfo += beaconsize;
712 *bytesleft -= beaconsize;
713
714 memcpy(bss->bssid, pos, ETH_ALEN);
715 lbs_deb_scan("process_bss: BSSID %pM\n", bss->bssid);
716 pos += ETH_ALEN;
717
718 if ((end - pos) < 12) {
719 lbs_deb_scan("process_bss: Not enough bytes left\n");
720 ret = -1;
721 goto done;
722 }
723
724 /*
725 * next 4 fields are RSSI, time stamp, beacon interval,
726 * and capability information
727 */
728
729 /* RSSI is 1 byte long */
730 bss->rssi = *pos;
731 lbs_deb_scan("process_bss: RSSI %d\n", *pos);
732 pos++;
733
734 /* time stamp is 8 bytes long */
735 pos += 8;
736
737 /* beacon interval is 2 bytes long */
738 bss->beaconperiod = get_unaligned_le16(pos);
739 pos += 2;
740
741 /* capability information is 2 bytes long */
742 bss->capability = get_unaligned_le16(pos);
743 lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability);
744 pos += 2;
745
746 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
747 lbs_deb_scan("process_bss: WEP enabled\n");
748 if (bss->capability & WLAN_CAPABILITY_IBSS)
749 bss->mode = IW_MODE_ADHOC;
750 else
751 bss->mode = IW_MODE_INFRA;
752
753 /* rest of the current buffer are IE's */
754 lbs_deb_scan("process_bss: IE len %zd\n", end - pos);
755 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: IE info", pos, end - pos);
756
757 /* process variable IE */
758 while (pos <= end - 2) {
759 if (pos + pos[1] > end) {
760 lbs_deb_scan("process_bss: error in processing IE, "
761 "bytes left < IE length\n");
762 break;
763 }
764
765 switch (pos[0]) {
766 case WLAN_EID_SSID:
767 bss->ssid_len = min_t(int, IEEE80211_MAX_SSID_LEN, pos[1]);
768 memcpy(bss->ssid, pos + 2, bss->ssid_len);
769 lbs_deb_scan("got SSID IE: '%s', len %u\n",
770 print_ssid(ssid, bss->ssid, bss->ssid_len),
771 bss->ssid_len);
772 break;
773
774 case WLAN_EID_SUPP_RATES:
775 n_basic_rates = min_t(uint8_t, MAX_RATES, pos[1]);
776 memcpy(bss->rates, pos + 2, n_basic_rates);
777 got_basic_rates = 1;
778 lbs_deb_scan("got RATES IE\n");
779 break;
780
781 case WLAN_EID_FH_PARAMS:
782 fh = (struct ieee_ie_fh_param_set *) pos;
783 memcpy(&bss->phy.fh, fh, sizeof(*fh));
784 lbs_deb_scan("got FH IE\n");
785 break;
786
787 case WLAN_EID_DS_PARAMS:
788 ds = (struct ieee_ie_ds_param_set *) pos;
789 bss->channel = ds->channel;
790 memcpy(&bss->phy.ds, ds, sizeof(*ds));
791 lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
792 break;
793
794 case WLAN_EID_CF_PARAMS:
795 cf = (struct ieee_ie_cf_param_set *) pos;
796 memcpy(&bss->ss.cf, cf, sizeof(*cf));
797 lbs_deb_scan("got CF IE\n");
798 break;
799
800 case WLAN_EID_IBSS_PARAMS:
801 ibss = (struct ieee_ie_ibss_param_set *) pos;
802 bss->atimwindow = ibss->atimwindow;
803 memcpy(&bss->ss.ibss, ibss, sizeof(*ibss));
804 lbs_deb_scan("got IBSS IE\n");
805 break;
806
807 case WLAN_EID_EXT_SUPP_RATES:
808 /* only process extended supported rate if data rate is
809 * already found. Data rate IE should come before
810 * extended supported rate IE
811 */
812 lbs_deb_scan("got RATESEX IE\n");
813 if (!got_basic_rates) {
814 lbs_deb_scan("... but ignoring it\n");
815 break;
816 }
817
818 n_ex_rates = pos[1];
819 if (n_basic_rates + n_ex_rates > MAX_RATES)
820 n_ex_rates = MAX_RATES - n_basic_rates;
821
822 p = bss->rates + n_basic_rates;
823 memcpy(p, pos + 2, n_ex_rates);
824 break;
825
826 case WLAN_EID_GENERIC:
827 if (pos[1] >= 4 &&
828 pos[2] == 0x00 && pos[3] == 0x50 &&
829 pos[4] == 0xf2 && pos[5] == 0x01) {
830 bss->wpa_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN);
831 memcpy(bss->wpa_ie, pos, bss->wpa_ie_len);
832 lbs_deb_scan("got WPA IE\n");
833 lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie,
834 bss->wpa_ie_len);
835 } else if (pos[1] >= MARVELL_MESH_IE_LENGTH &&
836 pos[2] == 0x00 && pos[3] == 0x50 &&
837 pos[4] == 0x43 && pos[5] == 0x04) {
838 lbs_deb_scan("got mesh IE\n");
839 bss->mesh = 1;
840 } else {
841 lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n",
842 pos[2], pos[3],
843 pos[4], pos[5],
844 pos[1]);
845 }
846 break;
847
848 case WLAN_EID_RSN:
849 lbs_deb_scan("got RSN IE\n");
850 bss->rsn_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN);
851 memcpy(bss->rsn_ie, pos, bss->rsn_ie_len);
852 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE",
853 bss->rsn_ie, bss->rsn_ie_len);
854 break;
855
856 default:
857 lbs_deb_scan("got IE 0x%04x, len %d\n",
858 pos[0], pos[1]);
859 break;
860 }
861
862 pos += pos[1] + 2;
863 }
864
865 /* Timestamp */
866 bss->last_scanned = jiffies;
867 lbs_unset_basic_rate_flags(bss->rates, sizeof(bss->rates));
868
869 ret = 0;
870
871done:
872 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
873 return ret;
874}
875
876/**
877 * @brief Send a scan command for all available channels filtered on a spec
878 *
879 * Used in association code and from debugfs
880 *
881 * @param priv A pointer to struct lbs_private structure
882 * @param ssid A pointer to the SSID to scan for
883 * @param ssid_len Length of the SSID
884 *
885 * @return 0-success, otherwise fail
886 */
887int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid,
888 uint8_t ssid_len)
889{
890 DECLARE_SSID_BUF(ssid_buf);
891 int ret = 0;
892
893 lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n",
894 print_ssid(ssid_buf, ssid, ssid_len));
895
896 if (!ssid_len)
897 goto out;
898
899 memcpy(priv->scan_ssid, ssid, ssid_len);
900 priv->scan_ssid_len = ssid_len;
901
902 lbs_scan_networks(priv, 1);
903 if (priv->surpriseremoved) {
904 ret = -1;
905 goto out;
906 }
907
908out:
909 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
910 return ret;
911}
912
913
914
915
916/*********************************************************************/
917/* */
918/* Support for Wireless Extensions */
919/* */
920/*********************************************************************/
921
922
923#define MAX_CUSTOM_LEN 64
924
925static inline char *lbs_translate_scan(struct lbs_private *priv,
926 struct iw_request_info *info,
927 char *start, char *stop,
928 struct bss_descriptor *bss)
929{
930 struct chan_freq_power *cfp;
931 char *current_val; /* For rates */
932 struct iw_event iwe; /* Temporary buffer */
933 int j;
934#define PERFECT_RSSI ((uint8_t)50)
935#define WORST_RSSI ((uint8_t)0)
936#define RSSI_DIFF ((uint8_t)(PERFECT_RSSI - WORST_RSSI))
937 uint8_t rssi;
938
939 lbs_deb_enter(LBS_DEB_SCAN);
940
941 cfp = lbs_find_cfp_by_band_and_channel(priv, 0, bss->channel);
942 if (!cfp) {
943 lbs_deb_scan("Invalid channel number %d\n", bss->channel);
944 start = NULL;
945 goto out;
946 }
947
948 /* First entry *MUST* be the BSSID */
949 iwe.cmd = SIOCGIWAP;
950 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
951 memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
952 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
953
954 /* SSID */
955 iwe.cmd = SIOCGIWESSID;
956 iwe.u.data.flags = 1;
957 iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IEEE80211_MAX_SSID_LEN);
958 start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
959
960 /* Mode */
961 iwe.cmd = SIOCGIWMODE;
962 iwe.u.mode = bss->mode;
963 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
964
965 /* Frequency */
966 iwe.cmd = SIOCGIWFREQ;
967 iwe.u.freq.m = (long)cfp->freq * 100000;
968 iwe.u.freq.e = 1;
969 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
970
971 /* Add quality statistics */
972 iwe.cmd = IWEVQUAL;
973 iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
974 iwe.u.qual.level = SCAN_RSSI(bss->rssi);
975
976 rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;
977 iwe.u.qual.qual =
978 (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) *
979 (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) /
980 (RSSI_DIFF * RSSI_DIFF);
981 if (iwe.u.qual.qual > 100)
982 iwe.u.qual.qual = 100;
983
984 if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
985 iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
986 } else {
987 iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
988 }
989
990 /* Locally created ad-hoc BSSs won't have beacons if this is the
991 * only station in the adhoc network; so get signal strength
992 * from receive statistics.
993 */
994 if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate
995 && !lbs_ssid_cmp(priv->curbssparams.ssid,
996 priv->curbssparams.ssid_len,
997 bss->ssid, bss->ssid_len)) {
998 int snr, nf;
999 snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
1000 nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
1001 iwe.u.qual.level = CAL_RSSI(snr, nf);
1002 }
1003 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
1004
1005 /* Add encryption capability */
1006 iwe.cmd = SIOCGIWENCODE;
1007 if (bss->capability & WLAN_CAPABILITY_PRIVACY) {
1008 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1009 } else {
1010 iwe.u.data.flags = IW_ENCODE_DISABLED;
1011 }
1012 iwe.u.data.length = 0;
1013 start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
1014
1015 current_val = start + iwe_stream_lcp_len(info);
1016
1017 iwe.cmd = SIOCGIWRATE;
1018 iwe.u.bitrate.fixed = 0;
1019 iwe.u.bitrate.disabled = 0;
1020 iwe.u.bitrate.value = 0;
1021
1022 for (j = 0; j < ARRAY_SIZE(bss->rates) && bss->rates[j]; j++) {
1023 /* Bit rate given in 500 kb/s units */
1024 iwe.u.bitrate.value = bss->rates[j] * 500000;
1025 current_val = iwe_stream_add_value(info, start, current_val,
1026 stop, &iwe, IW_EV_PARAM_LEN);
1027 }
1028 if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
1029 && !lbs_ssid_cmp(priv->curbssparams.ssid,
1030 priv->curbssparams.ssid_len,
1031 bss->ssid, bss->ssid_len)) {
1032 iwe.u.bitrate.value = 22 * 500000;
1033 current_val = iwe_stream_add_value(info, start, current_val,
1034 stop, &iwe, IW_EV_PARAM_LEN);
1035 }
1036 /* Check if we added any event */
1037 if ((current_val - start) > iwe_stream_lcp_len(info))
1038 start = current_val;
1039
1040 memset(&iwe, 0, sizeof(iwe));
1041 if (bss->wpa_ie_len) {
1042 char buf[MAX_WPA_IE_LEN];
1043 memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
1044 iwe.cmd = IWEVGENIE;
1045 iwe.u.data.length = bss->wpa_ie_len;
1046 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
1047 }
1048
1049 memset(&iwe, 0, sizeof(iwe));
1050 if (bss->rsn_ie_len) {
1051 char buf[MAX_WPA_IE_LEN];
1052 memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
1053 iwe.cmd = IWEVGENIE;
1054 iwe.u.data.length = bss->rsn_ie_len;
1055 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
1056 }
1057
1058 if (bss->mesh) {
1059 char custom[MAX_CUSTOM_LEN];
1060 char *p = custom;
1061
1062 iwe.cmd = IWEVCUSTOM;
1063 p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
1064 iwe.u.data.length = p - custom;
1065 if (iwe.u.data.length)
1066 start = iwe_stream_add_point(info, start, stop,
1067 &iwe, custom);
1068 }
1069
1070out:
1071 lbs_deb_leave_args(LBS_DEB_SCAN, "start %p", start);
1072 return start;
1073}
1074
1075
1076/**
1077 * @brief Handle Scan Network ioctl
1078 *
1079 * @param dev A pointer to net_device structure
1080 * @param info A pointer to iw_request_info structure
1081 * @param vwrq A pointer to iw_param structure
1082 * @param extra A pointer to extra data buf
1083 *
1084 * @return 0 --success, otherwise fail
1085 */
1086int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
1087 union iwreq_data *wrqu, char *extra)
1088{
1089 DECLARE_SSID_BUF(ssid);
1090 struct lbs_private *priv = dev->ml_priv;
1091 int ret = 0;
1092
1093 lbs_deb_enter(LBS_DEB_WEXT);
1094
1095 if (!priv->radio_on) {
1096 ret = -EINVAL;
1097 goto out;
1098 }
1099
1100 if (!netif_running(dev)) {
1101 ret = -ENETDOWN;
1102 goto out;
1103 }
1104
1105 /* mac80211 does this:
1106 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1107 if (sdata->type != IEEE80211_IF_TYPE_xxx) {
1108 ret = -EOPNOTSUPP;
1109 goto out;
1110 }
1111 */
1112
1113 if (wrqu->data.length == sizeof(struct iw_scan_req) &&
1114 wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1115 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1116 priv->scan_ssid_len = req->essid_len;
1117 memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len);
1118 lbs_deb_wext("set_scan, essid '%s'\n",
1119 print_ssid(ssid, priv->scan_ssid, priv->scan_ssid_len));
1120 } else {
1121 priv->scan_ssid_len = 0;
1122 }
1123
1124 if (!delayed_work_pending(&priv->scan_work))
1125 queue_delayed_work(priv->work_thread, &priv->scan_work,
1126 msecs_to_jiffies(50));
1127 /* set marker that currently a scan is taking place */
1128 priv->scan_channel = -1;
1129
1130 if (priv->surpriseremoved)
1131 ret = -EIO;
1132
1133out:
1134 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1135 return ret;
1136}
1137
1138
1139/**
1140 * @brief Handle Retrieve scan table ioctl
1141 *
1142 * @param dev A pointer to net_device structure
1143 * @param info A pointer to iw_request_info structure
1144 * @param dwrq A pointer to iw_point structure
1145 * @param extra A pointer to extra data buf
1146 *
1147 * @return 0 --success, otherwise fail
1148 */
1149int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1150 struct iw_point *dwrq, char *extra)
1151{
1152#define SCAN_ITEM_SIZE 128
1153 struct lbs_private *priv = dev->ml_priv;
1154 int err = 0;
1155 char *ev = extra;
1156 char *stop = ev + dwrq->length;
1157 struct bss_descriptor *iter_bss;
1158 struct bss_descriptor *safe;
1159
1160 lbs_deb_enter(LBS_DEB_WEXT);
1161
1162 /* iwlist should wait until the current scan is finished */
1163 if (priv->scan_channel)
1164 return -EAGAIN;
1165
1166 /* Update RSSI if current BSS is a locally created ad-hoc BSS */
1167 if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) {
1168 err = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
1169 CMD_OPTION_WAITFORRSP, 0, NULL);
1170 if (err)
1171 goto out;
1172 }
1173
1174 mutex_lock(&priv->lock);
1175 list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
1176 char *next_ev;
1177 unsigned long stale_time;
1178
1179 if (stop - ev < SCAN_ITEM_SIZE) {
1180 err = -E2BIG;
1181 break;
1182 }
1183
1184 /* For mesh device, list only mesh networks */
1185 if (dev == priv->mesh_dev && !iter_bss->mesh)
1186 continue;
1187
1188 /* Prune old an old scan result */
1189 stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
1190 if (time_after(jiffies, stale_time)) {
1191 list_move_tail(&iter_bss->list, &priv->network_free_list);
1192 clear_bss_descriptor(iter_bss);
1193 continue;
1194 }
1195
1196 /* Translate to WE format this entry */
1197 next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss);
1198 if (next_ev == NULL)
1199 continue;
1200 ev = next_ev;
1201 }
1202 mutex_unlock(&priv->lock);
1203
1204 dwrq->length = (ev - extra);
1205 dwrq->flags = 0;
1206out:
1207 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err);
1208 return err;
1209}
1210
1211
1212
1213
1214/*********************************************************************/
1215/* */
1216/* Command execution */
1217/* */
1218/*********************************************************************/
1219
1220
1221/**
1222 * @brief This function handles the command response of scan
1223 *
1224 * Called from handle_cmd_response() in cmdrespc.
1225 *
1226 * The response buffer for the scan command has the following
1227 * memory layout:
1228 *
1229 * .-----------------------------------------------------------.
1230 * | header (4 * sizeof(u16)): Standard command response hdr |
1231 * .-----------------------------------------------------------.
1232 * | bufsize (u16) : sizeof the BSS Description data |
1233 * .-----------------------------------------------------------.
1234 * | NumOfSet (u8) : Number of BSS Descs returned |
1235 * .-----------------------------------------------------------.
1236 * | BSSDescription data (variable, size given in bufsize) |
1237 * .-----------------------------------------------------------.
1238 * | TLV data (variable, size calculated using header->size, |
1239 * | bufsize and sizeof the fixed fields above) |
1240 * .-----------------------------------------------------------.
1241 *
1242 * @param priv A pointer to struct lbs_private structure
1243 * @param resp A pointer to cmd_ds_command
1244 *
1245 * @return 0 or -1
1246 */
1247static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
1248 struct cmd_header *resp)
1249{
1250 struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
1251 struct bss_descriptor *iter_bss;
1252 struct bss_descriptor *safe;
1253 uint8_t *bssinfo;
1254 uint16_t scanrespsize;
1255 int bytesleft;
1256 int idx;
1257 int tlvbufsize;
1258 int ret;
1259
1260 lbs_deb_enter(LBS_DEB_SCAN);
1261
1262 /* Prune old entries from scan table */
1263 list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
1264 unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
1265 if (time_before(jiffies, stale_time))
1266 continue;
1267 list_move_tail (&iter_bss->list, &priv->network_free_list);
1268 clear_bss_descriptor(iter_bss);
1269 }
1270
1271 if (scanresp->nr_sets > MAX_NETWORK_COUNT) {
1272 lbs_deb_scan("SCAN_RESP: too many scan results (%d, max %d)\n",
1273 scanresp->nr_sets, MAX_NETWORK_COUNT);
1274 ret = -1;
1275 goto done;
1276 }
1277
1278 bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize);
1279 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
1280
1281 scanrespsize = le16_to_cpu(resp->size);
1282 lbs_deb_scan("SCAN_RESP: scan results %d\n", scanresp->nr_sets);
1283
1284 bssinfo = scanresp->bssdesc_and_tlvbuffer;
1285
1286 /* The size of the TLV buffer is equal to the entire command response
1287 * size (scanrespsize) minus the fixed fields (sizeof()'s), the
1288 * BSS Descriptions (bssdescriptsize as bytesLef) and the command
1289 * response header (sizeof(struct cmd_header))
1290 */
1291 tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize)
1292 + sizeof(scanresp->nr_sets)
1293 + sizeof(struct cmd_header));
1294
1295 /*
1296 * Process each scan response returned (scanresp->nr_sets). Save
1297 * the information in the newbssentry and then insert into the
1298 * driver scan table either as an update to an existing entry
1299 * or as an addition at the end of the table
1300 */
1301 for (idx = 0; idx < scanresp->nr_sets && bytesleft; idx++) {
1302 struct bss_descriptor new;
1303 struct bss_descriptor *found = NULL;
1304 struct bss_descriptor *oldest = NULL;
1305
1306 /* Process the data fields and IEs returned for this BSS */
1307 memset(&new, 0, sizeof (struct bss_descriptor));
1308 if (lbs_process_bss(&new, &bssinfo, &bytesleft) != 0) {
1309 /* error parsing the scan response, skipped */
1310 lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
1311 continue;
1312 }
1313
1314 /* Try to find this bss in the scan table */
1315 list_for_each_entry (iter_bss, &priv->network_list, list) {
1316 if (is_same_network(iter_bss, &new)) {
1317 found = iter_bss;
1318 break;
1319 }
1320
1321 if ((oldest == NULL) ||
1322 (iter_bss->last_scanned < oldest->last_scanned))
1323 oldest = iter_bss;
1324 }
1325
1326 if (found) {
1327 /* found, clear it */
1328 clear_bss_descriptor(found);
1329 } else if (!list_empty(&priv->network_free_list)) {
1330 /* Pull one from the free list */
1331 found = list_entry(priv->network_free_list.next,
1332 struct bss_descriptor, list);
1333 list_move_tail(&found->list, &priv->network_list);
1334 } else if (oldest) {
1335 /* If there are no more slots, expire the oldest */
1336 found = oldest;
1337 clear_bss_descriptor(found);
1338 list_move_tail(&found->list, &priv->network_list);
1339 } else {
1340 continue;
1341 }
1342
1343 lbs_deb_scan("SCAN_RESP: BSSID %pM\n", new.bssid);
1344
1345 /* Copy the locally created newbssentry to the scan table */
1346 memcpy(found, &new, offsetof(struct bss_descriptor, list));
1347 }
1348
1349 ret = 0;
1350
1351done:
1352 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
1353 return ret;
1354}
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
deleted file mode 100644
index 8fb1706d7526..000000000000
--- a/drivers/net/wireless/libertas/scan.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/**
2 * Interface for the wlan network scan routines
3 *
4 * Driver interface functions and type declarations for the scan module
5 * implemented in scan.c.
6 */
7#ifndef _LBS_SCAN_H
8#define _LBS_SCAN_H
9
10#include <net/iw_handler.h>
11
12struct lbs_private;
13
14#define MAX_NETWORK_COUNT 128
15
16/** Chan-freq-TxPower mapping table*/
17struct chan_freq_power {
18 /** channel Number */
19 u16 channel;
20 /** frequency of this channel */
21 u32 freq;
22 /** Max allowed Tx power level */
23 u16 maxtxpower;
24 /** TRUE:channel unsupported; FLASE:supported*/
25 u8 unsupported;
26};
27
28/** region-band mapping table*/
29struct region_channel {
30 /** TRUE if this entry is valid */
31 u8 valid;
32 /** region code for US, Japan ... */
33 u8 region;
34 /** band B/G/A, used for BAND_CONFIG cmd */
35 u8 band;
36 /** Actual No. of elements in the array below */
37 u8 nrcfp;
38 /** chan-freq-txpower mapping table*/
39 struct chan_freq_power *CFP;
40};
41
42/**
43 * @brief Maximum number of channels that can be sent in a setuserscan ioctl
44 */
45#define LBS_IOCTL_USER_SCAN_CHAN_MAX 50
46
47int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
48
49int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
50
51int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
52 u8 ssid_len);
53
54int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
55 struct iw_point *dwrq, char *extra);
56int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
57 union iwreq_data *wrqu, char *extra);
58
59int lbs_scan_networks(struct lbs_private *priv, int full_scan);
60
61void lbs_scan_worker(struct work_struct *work);
62
63#endif
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index a9bf658659eb..411a3bbf035e 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -4,13 +4,13 @@
4#include <linux/netdevice.h> 4#include <linux/netdevice.h>
5#include <linux/etherdevice.h> 5#include <linux/etherdevice.h>
6#include <linux/sched.h> 6#include <linux/sched.h>
7#include <net/cfg80211.h>
7 8
8#include "host.h" 9#include "host.h"
9#include "radiotap.h" 10#include "radiotap.h"
10#include "decl.h" 11#include "decl.h"
11#include "defs.h" 12#include "defs.h"
12#include "dev.h" 13#include "dev.h"
13#include "wext.h"
14 14
15/** 15/**
16 * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE 16 * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
@@ -111,7 +111,7 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
111 p802x_hdr = skb->data; 111 p802x_hdr = skb->data;
112 pkt_len = skb->len; 112 pkt_len = skb->len;
113 113
114 if (dev == priv->rtap_net_dev) { 114 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
115 struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data; 115 struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
116 116
117 /* set txpd fields from the radiotap header */ 117 /* set txpd fields from the radiotap header */
@@ -147,7 +147,7 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
147 dev->stats.tx_packets++; 147 dev->stats.tx_packets++;
148 dev->stats.tx_bytes += skb->len; 148 dev->stats.tx_bytes += skb->len;
149 149
150 if (priv->monitormode) { 150 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
151 /* Keep the skb to echo it back once Tx feedback is 151 /* Keep the skb to echo it back once Tx feedback is
152 received from FW */ 152 received from FW */
153 skb_orphan(skb); 153 skb_orphan(skb);
@@ -158,6 +158,7 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
158 free: 158 free:
159 dev_kfree_skb_any(skb); 159 dev_kfree_skb_any(skb);
160 } 160 }
161
161 unlock: 162 unlock:
162 spin_unlock_irqrestore(&priv->driver_lock, flags); 163 spin_unlock_irqrestore(&priv->driver_lock, flags);
163 wake_up(&priv->waitq); 164 wake_up(&priv->waitq);
@@ -179,7 +180,8 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
179{ 180{
180 struct tx_radiotap_hdr *radiotap_hdr; 181 struct tx_radiotap_hdr *radiotap_hdr;
181 182
182 if (!priv->monitormode || priv->currenttxskb == NULL) 183 if (!priv->wdev->iftype == NL80211_IFTYPE_MONITOR ||
184 priv->currenttxskb == NULL)
183 return; 185 return;
184 186
185 radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data; 187 radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data;
@@ -188,7 +190,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
188 (1 + priv->txretrycount - try_count) : 0; 190 (1 + priv->txretrycount - try_count) : 0;
189 191
190 priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb, 192 priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb,
191 priv->rtap_net_dev); 193 priv->dev);
192 netif_rx(priv->currenttxskb); 194 netif_rx(priv->currenttxskb);
193 195
194 priv->currenttxskb = NULL; 196 priv->currenttxskb = NULL;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
deleted file mode 100644
index f96a96031a50..000000000000
--- a/drivers/net/wireless/libertas/wext.c
+++ /dev/null
@@ -1,2353 +0,0 @@
1/**
2 * This file contains ioctl functions
3 */
4#include <linux/ctype.h>
5#include <linux/slab.h>
6#include <linux/delay.h>
7#include <linux/if.h>
8#include <linux/if_arp.h>
9#include <linux/wireless.h>
10#include <linux/bitops.h>
11
12#include <net/lib80211.h>
13#include <net/iw_handler.h>
14
15#include "host.h"
16#include "radiotap.h"
17#include "decl.h"
18#include "defs.h"
19#include "dev.h"
20#include "wext.h"
21#include "scan.h"
22#include "assoc.h"
23#include "cmd.h"
24
25
26static inline void lbs_postpone_association_work(struct lbs_private *priv)
27{
28 if (priv->surpriseremoved)
29 return;
30 cancel_delayed_work(&priv->assoc_work);
31 queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2);
32}
33
34static inline void lbs_do_association_work(struct lbs_private *priv)
35{
36 if (priv->surpriseremoved)
37 return;
38 cancel_delayed_work(&priv->assoc_work);
39 queue_delayed_work(priv->work_thread, &priv->assoc_work, 0);
40}
41
42static inline void lbs_cancel_association_work(struct lbs_private *priv)
43{
44 cancel_delayed_work(&priv->assoc_work);
45 kfree(priv->pending_assoc_req);
46 priv->pending_assoc_req = NULL;
47}
48
49void lbs_send_disconnect_notification(struct lbs_private *priv)
50{
51 union iwreq_data wrqu;
52
53 memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
54 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
55 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
56}
57
58static void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
59{
60 union iwreq_data iwrq;
61 u8 buf[50];
62
63 lbs_deb_enter(LBS_DEB_WEXT);
64
65 memset(&iwrq, 0, sizeof(union iwreq_data));
66 memset(buf, 0, sizeof(buf));
67
68 snprintf(buf, sizeof(buf) - 1, "%s", str);
69
70 iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
71
72 /* Send Event to upper layer */
73 lbs_deb_wext("event indication string %s\n", (char *)buf);
74 lbs_deb_wext("event indication length %d\n", iwrq.data.length);
75 lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str);
76
77 wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
78
79 lbs_deb_leave(LBS_DEB_WEXT);
80}
81
82/**
83 * @brief This function handles MIC failure event.
84 *
85 * @param priv A pointer to struct lbs_private structure
86 * @para event the event id
87 * @return n/a
88 */
89void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
90{
91 char buf[50];
92
93 lbs_deb_enter(LBS_DEB_CMD);
94 memset(buf, 0, sizeof(buf));
95
96 sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");
97
98 if (event == MACREG_INT_CODE_MIC_ERR_UNICAST)
99 strcat(buf, "unicast ");
100 else
101 strcat(buf, "multicast ");
102
103 lbs_send_iwevcustom_event(priv, buf);
104 lbs_deb_leave(LBS_DEB_CMD);
105}
106
107/**
108 * @brief Find the channel frequency power info with specific channel
109 *
110 * @param priv A pointer to struct lbs_private structure
111 * @param band it can be BAND_A, BAND_G or BAND_B
112 * @param channel the channel for looking
113 * @return A pointer to struct chan_freq_power structure or NULL if not find.
114 */
115struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
116 struct lbs_private *priv,
117 u8 band,
118 u16 channel)
119{
120 struct chan_freq_power *cfp = NULL;
121 struct region_channel *rc;
122 int i, j;
123
124 for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
125 rc = &priv->region_channel[j];
126
127 if (!rc->valid || !rc->CFP)
128 continue;
129 if (rc->band != band)
130 continue;
131 for (i = 0; i < rc->nrcfp; i++) {
132 if (rc->CFP[i].channel == channel) {
133 cfp = &rc->CFP[i];
134 break;
135 }
136 }
137 }
138
139 if (!cfp && channel)
140 lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find "
141 "cfp by band %d / channel %d\n", band, channel);
142
143 return cfp;
144}
145
146/**
147 * @brief Find the channel frequency power info with specific frequency
148 *
149 * @param priv A pointer to struct lbs_private structure
150 * @param band it can be BAND_A, BAND_G or BAND_B
151 * @param freq the frequency for looking
152 * @return A pointer to struct chan_freq_power structure or NULL if not find.
153 */
154static struct chan_freq_power *find_cfp_by_band_and_freq(
155 struct lbs_private *priv,
156 u8 band,
157 u32 freq)
158{
159 struct chan_freq_power *cfp = NULL;
160 struct region_channel *rc;
161 int i, j;
162
163 for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
164 rc = &priv->region_channel[j];
165
166 if (!rc->valid || !rc->CFP)
167 continue;
168 if (rc->band != band)
169 continue;
170 for (i = 0; i < rc->nrcfp; i++) {
171 if (rc->CFP[i].freq == freq) {
172 cfp = &rc->CFP[i];
173 break;
174 }
175 }
176 }
177
178 if (!cfp && freq)
179 lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by "
180 "band %d / freq %d\n", band, freq);
181
182 return cfp;
183}
184
185/**
186 * @brief Copy active data rates based on adapter mode and status
187 *
188 * @param priv A pointer to struct lbs_private structure
189 * @param rate The buf to return the active rates
190 */
191static void copy_active_data_rates(struct lbs_private *priv, u8 *rates)
192{
193 lbs_deb_enter(LBS_DEB_WEXT);
194
195 if ((priv->connect_status != LBS_CONNECTED) &&
196 !lbs_mesh_connected(priv))
197 memcpy(rates, lbs_bg_rates, MAX_RATES);
198 else
199 memcpy(rates, priv->curbssparams.rates, MAX_RATES);
200
201 lbs_deb_leave(LBS_DEB_WEXT);
202}
203
204static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
205 char *cwrq, char *extra)
206{
207
208 lbs_deb_enter(LBS_DEB_WEXT);
209
210 /* We could add support for 802.11n here as needed. Jean II */
211 snprintf(cwrq, IFNAMSIZ, "IEEE 802.11b/g");
212
213 lbs_deb_leave(LBS_DEB_WEXT);
214 return 0;
215}
216
217static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
218 struct iw_freq *fwrq, char *extra)
219{
220 struct lbs_private *priv = dev->ml_priv;
221 struct chan_freq_power *cfp;
222
223 lbs_deb_enter(LBS_DEB_WEXT);
224
225 cfp = lbs_find_cfp_by_band_and_channel(priv, 0,
226 priv->channel);
227
228 if (!cfp) {
229 if (priv->channel)
230 lbs_deb_wext("invalid channel %d\n",
231 priv->channel);
232 return -EINVAL;
233 }
234
235 fwrq->m = (long)cfp->freq * 100000;
236 fwrq->e = 1;
237
238 lbs_deb_wext("freq %u\n", fwrq->m);
239 lbs_deb_leave(LBS_DEB_WEXT);
240 return 0;
241}
242
243static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
244 struct sockaddr *awrq, char *extra)
245{
246 struct lbs_private *priv = dev->ml_priv;
247
248 lbs_deb_enter(LBS_DEB_WEXT);
249
250 if (priv->connect_status == LBS_CONNECTED) {
251 memcpy(awrq->sa_data, priv->curbssparams.bssid, ETH_ALEN);
252 } else {
253 memset(awrq->sa_data, 0, ETH_ALEN);
254 }
255 awrq->sa_family = ARPHRD_ETHER;
256
257 lbs_deb_leave(LBS_DEB_WEXT);
258 return 0;
259}
260
261static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
262 struct iw_point *dwrq, char *extra)
263{
264 struct lbs_private *priv = dev->ml_priv;
265
266 lbs_deb_enter(LBS_DEB_WEXT);
267
268 /*
269 * Check the size of the string
270 */
271
272 if (dwrq->length > 16) {
273 return -E2BIG;
274 }
275
276 mutex_lock(&priv->lock);
277 memset(priv->nodename, 0, sizeof(priv->nodename));
278 memcpy(priv->nodename, extra, dwrq->length);
279 mutex_unlock(&priv->lock);
280
281 lbs_deb_leave(LBS_DEB_WEXT);
282 return 0;
283}
284
285static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
286 struct iw_point *dwrq, char *extra)
287{
288 struct lbs_private *priv = dev->ml_priv;
289
290 lbs_deb_enter(LBS_DEB_WEXT);
291
292 dwrq->length = strlen(priv->nodename);
293 memcpy(extra, priv->nodename, dwrq->length);
294 extra[dwrq->length] = '\0';
295
296 dwrq->flags = 1; /* active */
297
298 lbs_deb_leave(LBS_DEB_WEXT);
299 return 0;
300}
301
302#ifdef CONFIG_LIBERTAS_MESH
303static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
304 struct iw_point *dwrq, char *extra)
305{
306 struct lbs_private *priv = dev->ml_priv;
307
308 lbs_deb_enter(LBS_DEB_WEXT);
309
310 /* Use nickname to indicate that mesh is on */
311
312 if (lbs_mesh_connected(priv)) {
313 strncpy(extra, "Mesh", 12);
314 extra[12] = '\0';
315 dwrq->length = strlen(extra);
316 }
317
318 else {
319 extra[0] = '\0';
320 dwrq->length = 0;
321 }
322
323 lbs_deb_leave(LBS_DEB_WEXT);
324 return 0;
325}
326#endif
327
328static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
329 struct iw_param *vwrq, char *extra)
330{
331 int ret = 0;
332 struct lbs_private *priv = dev->ml_priv;
333 u32 val = vwrq->value;
334
335 lbs_deb_enter(LBS_DEB_WEXT);
336
337 if (vwrq->disabled)
338 val = MRVDRV_RTS_MAX_VALUE;
339
340 if (val > MRVDRV_RTS_MAX_VALUE) /* min rts value is 0 */
341 return -EINVAL;
342
343 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, (u16) val);
344
345 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
346 return ret;
347}
348
349static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
350 struct iw_param *vwrq, char *extra)
351{
352 struct lbs_private *priv = dev->ml_priv;
353 int ret = 0;
354 u16 val = 0;
355
356 lbs_deb_enter(LBS_DEB_WEXT);
357
358 ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val);
359 if (ret)
360 goto out;
361
362 vwrq->value = val;
363 vwrq->disabled = val > MRVDRV_RTS_MAX_VALUE; /* min rts value is 0 */
364 vwrq->fixed = 1;
365
366out:
367 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
368 return ret;
369}
370
371static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
372 struct iw_param *vwrq, char *extra)
373{
374 struct lbs_private *priv = dev->ml_priv;
375 int ret = 0;
376 u32 val = vwrq->value;
377
378 lbs_deb_enter(LBS_DEB_WEXT);
379
380 if (vwrq->disabled)
381 val = MRVDRV_FRAG_MAX_VALUE;
382
383 if (val < MRVDRV_FRAG_MIN_VALUE || val > MRVDRV_FRAG_MAX_VALUE)
384 return -EINVAL;
385
386 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, (u16) val);
387
388 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
389 return ret;
390}
391
392static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
393 struct iw_param *vwrq, char *extra)
394{
395 struct lbs_private *priv = dev->ml_priv;
396 int ret = 0;
397 u16 val = 0;
398
399 lbs_deb_enter(LBS_DEB_WEXT);
400
401 ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val);
402 if (ret)
403 goto out;
404
405 vwrq->value = val;
406 vwrq->disabled = ((val < MRVDRV_FRAG_MIN_VALUE)
407 || (val > MRVDRV_FRAG_MAX_VALUE));
408 vwrq->fixed = 1;
409
410out:
411 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
412 return ret;
413}
414
415static int lbs_get_mode(struct net_device *dev,
416 struct iw_request_info *info, u32 * uwrq, char *extra)
417{
418 struct lbs_private *priv = dev->ml_priv;
419
420 lbs_deb_enter(LBS_DEB_WEXT);
421
422 *uwrq = priv->mode;
423
424 lbs_deb_leave(LBS_DEB_WEXT);
425 return 0;
426}
427
428#ifdef CONFIG_LIBERTAS_MESH
429static int mesh_wlan_get_mode(struct net_device *dev,
430 struct iw_request_info *info, u32 * uwrq,
431 char *extra)
432{
433 lbs_deb_enter(LBS_DEB_WEXT);
434
435 *uwrq = IW_MODE_REPEAT;
436
437 lbs_deb_leave(LBS_DEB_WEXT);
438 return 0;
439}
440#endif
441
442static int lbs_get_txpow(struct net_device *dev,
443 struct iw_request_info *info,
444 struct iw_param *vwrq, char *extra)
445{
446 struct lbs_private *priv = dev->ml_priv;
447 s16 curlevel = 0;
448 int ret = 0;
449
450 lbs_deb_enter(LBS_DEB_WEXT);
451
452 if (!priv->radio_on) {
453 lbs_deb_wext("tx power off\n");
454 vwrq->value = 0;
455 vwrq->disabled = 1;
456 goto out;
457 }
458
459 ret = lbs_get_tx_power(priv, &curlevel, NULL, NULL);
460 if (ret)
461 goto out;
462
463 lbs_deb_wext("tx power level %d dbm\n", curlevel);
464 priv->txpower_cur = curlevel;
465
466 vwrq->value = curlevel;
467 vwrq->fixed = 1;
468 vwrq->disabled = 0;
469 vwrq->flags = IW_TXPOW_DBM;
470
471out:
472 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
473 return ret;
474}
475
476static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
477 struct iw_param *vwrq, char *extra)
478{
479 struct lbs_private *priv = dev->ml_priv;
480 int ret = 0;
481 u16 slimit = 0, llimit = 0;
482
483 lbs_deb_enter(LBS_DEB_WEXT);
484
485 if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
486 return -EOPNOTSUPP;
487
488 /* The MAC has a 4-bit Total_Tx_Count register
489 Total_Tx_Count = 1 + Tx_Retry_Count */
490#define TX_RETRY_MIN 0
491#define TX_RETRY_MAX 14
492 if (vwrq->value < TX_RETRY_MIN || vwrq->value > TX_RETRY_MAX)
493 return -EINVAL;
494
495 /* Add 1 to convert retry count to try count */
496 if (vwrq->flags & IW_RETRY_SHORT)
497 slimit = (u16) (vwrq->value + 1);
498 else if (vwrq->flags & IW_RETRY_LONG)
499 llimit = (u16) (vwrq->value + 1);
500 else
501 slimit = llimit = (u16) (vwrq->value + 1); /* set both */
502
503 if (llimit) {
504 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_LONG_RETRY_LIMIT,
505 llimit);
506 if (ret)
507 goto out;
508 }
509
510 if (slimit) {
511 /* txretrycount follows the short retry limit */
512 priv->txretrycount = slimit;
513 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_SHORT_RETRY_LIMIT,
514 slimit);
515 if (ret)
516 goto out;
517 }
518
519out:
520 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
521 return ret;
522}
523
524static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
525 struct iw_param *vwrq, char *extra)
526{
527 struct lbs_private *priv = dev->ml_priv;
528 int ret = 0;
529 u16 val = 0;
530
531 lbs_deb_enter(LBS_DEB_WEXT);
532
533 vwrq->disabled = 0;
534
535 if (vwrq->flags & IW_RETRY_LONG) {
536 ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_LONG_RETRY_LIMIT, &val);
537 if (ret)
538 goto out;
539
540 /* Subtract 1 to convert try count to retry count */
541 vwrq->value = val - 1;
542 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
543 } else {
544 ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_SHORT_RETRY_LIMIT, &val);
545 if (ret)
546 goto out;
547
548 /* txretry count follows the short retry limit */
549 priv->txretrycount = val;
550 /* Subtract 1 to convert try count to retry count */
551 vwrq->value = val - 1;
552 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
553 }
554
555out:
556 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
557 return ret;
558}
559
560static inline void sort_channels(struct iw_freq *freq, int num)
561{
562 int i, j;
563 struct iw_freq temp;
564
565 for (i = 0; i < num; i++)
566 for (j = i + 1; j < num; j++)
567 if (freq[i].i > freq[j].i) {
568 temp.i = freq[i].i;
569 temp.m = freq[i].m;
570
571 freq[i].i = freq[j].i;
572 freq[i].m = freq[j].m;
573
574 freq[j].i = temp.i;
575 freq[j].m = temp.m;
576 }
577}
578
579/* data rate listing
580 MULTI_BANDS:
581 abg a b b/g
582 Infra G(12) A(8) B(4) G(12)
583 Adhoc A+B(12) A(8) B(4) B(4)
584
585 non-MULTI_BANDS:
586 b b/g
587 Infra B(4) G(12)
588 Adhoc B(4) B(4)
589 */
590/**
591 * @brief Get Range Info
592 *
593 * @param dev A pointer to net_device structure
594 * @param info A pointer to iw_request_info structure
595 * @param vwrq A pointer to iw_param structure
596 * @param extra A pointer to extra data buf
597 * @return 0 --success, otherwise fail
598 */
599static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
600 struct iw_point *dwrq, char *extra)
601{
602 int i, j;
603 struct lbs_private *priv = dev->ml_priv;
604 struct iw_range *range = (struct iw_range *)extra;
605 struct chan_freq_power *cfp;
606 u8 rates[MAX_RATES + 1];
607
608 lbs_deb_enter(LBS_DEB_WEXT);
609
610 dwrq->length = sizeof(struct iw_range);
611 memset(range, 0, sizeof(struct iw_range));
612
613 range->min_nwid = 0;
614 range->max_nwid = 0;
615
616 memset(rates, 0, sizeof(rates));
617 copy_active_data_rates(priv, rates);
618 range->num_bitrates = strnlen(rates, IW_MAX_BITRATES);
619 for (i = 0; i < range->num_bitrates; i++)
620 range->bitrate[i] = rates[i] * 500000;
621 range->num_bitrates = i;
622 lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES,
623 range->num_bitrates);
624
625 range->num_frequency = 0;
626
627 range->scan_capa = IW_SCAN_CAPA_ESSID;
628
629 for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
630 && (j < ARRAY_SIZE(priv->region_channel)); j++) {
631 cfp = priv->region_channel[j].CFP;
632 for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
633 && priv->region_channel[j].valid
634 && cfp
635 && (i < priv->region_channel[j].nrcfp); i++) {
636 range->freq[range->num_frequency].i =
637 (long)cfp->channel;
638 range->freq[range->num_frequency].m =
639 (long)cfp->freq * 100000;
640 range->freq[range->num_frequency].e = 1;
641 cfp++;
642 range->num_frequency++;
643 }
644 }
645
646 lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n",
647 IW_MAX_FREQUENCIES, range->num_frequency);
648
649 range->num_channels = range->num_frequency;
650
651 sort_channels(&range->freq[0], range->num_frequency);
652
653 /*
654 * Set an indication of the max TCP throughput in bit/s that we can
655 * expect using this interface
656 */
657 if (i > 2)
658 range->throughput = 5000 * 1000;
659 else
660 range->throughput = 1500 * 1000;
661
662 range->min_rts = MRVDRV_RTS_MIN_VALUE;
663 range->max_rts = MRVDRV_RTS_MAX_VALUE;
664 range->min_frag = MRVDRV_FRAG_MIN_VALUE;
665 range->max_frag = MRVDRV_FRAG_MAX_VALUE;
666
667 range->encoding_size[0] = 5;
668 range->encoding_size[1] = 13;
669 range->num_encoding_sizes = 2;
670 range->max_encoding_tokens = 4;
671
672 /*
673 * Right now we support only "iwconfig ethX power on|off"
674 */
675 range->pm_capa = IW_POWER_ON;
676
677 /*
678 * Minimum version we recommend
679 */
680 range->we_version_source = 15;
681
682 /*
683 * Version we are compiled with
684 */
685 range->we_version_compiled = WIRELESS_EXT;
686
687 range->retry_capa = IW_RETRY_LIMIT;
688 range->retry_flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
689
690 range->min_retry = TX_RETRY_MIN;
691 range->max_retry = TX_RETRY_MAX;
692
693 /*
694 * Set the qual, level and noise range values
695 */
696 range->max_qual.qual = 100;
697 range->max_qual.level = 0;
698 range->max_qual.noise = 0;
699 range->max_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
700
701 range->avg_qual.qual = 70;
702 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
703 range->avg_qual.level = 0;
704 range->avg_qual.noise = 0;
705 range->avg_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
706
707 range->sensitivity = 0;
708
709 /* Setup the supported power level ranges */
710 memset(range->txpower, 0, sizeof(range->txpower));
711 range->txpower_capa = IW_TXPOW_DBM | IW_TXPOW_RANGE;
712 range->txpower[0] = priv->txpower_min;
713 range->txpower[1] = priv->txpower_max;
714 range->num_txpower = 2;
715
716 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
717 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
718 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
719 range->event_capa[1] = IW_EVENT_CAPA_K_1;
720
721 if (priv->fwcapinfo & FW_CAPINFO_WPA) {
722 range->enc_capa = IW_ENC_CAPA_WPA
723 | IW_ENC_CAPA_WPA2
724 | IW_ENC_CAPA_CIPHER_TKIP
725 | IW_ENC_CAPA_CIPHER_CCMP;
726 }
727
728 lbs_deb_leave(LBS_DEB_WEXT);
729 return 0;
730}
731
732static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
733 struct iw_param *vwrq, char *extra)
734{
735 struct lbs_private *priv = dev->ml_priv;
736 int ret = 0;
737
738 lbs_deb_enter(LBS_DEB_WEXT);
739
740 if (!(priv->fwcapinfo & FW_CAPINFO_PS)) {
741 if (vwrq->disabled)
742 return 0;
743 else
744 return -EINVAL;
745 }
746
747 /* PS is currently supported only in Infrastructure mode
748 * Remove this check if it is to be supported in IBSS mode also
749 */
750
751 if (vwrq->disabled) {
752 priv->psmode = LBS802_11POWERMODECAM;
753 if (priv->psstate != PS_STATE_FULL_POWER) {
754 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
755 }
756
757 return 0;
758 }
759
760 if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
761 lbs_deb_wext(
762 "setting power timeout is not supported\n");
763 return -EINVAL;
764 } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
765 vwrq->value = vwrq->value / 1000;
766 if (!priv->enter_deep_sleep) {
767 lbs_pr_err("deep sleep feature is not implemented "
768 "for this interface driver\n");
769 return -EINVAL;
770 }
771
772 if (priv->connect_status == LBS_CONNECTED) {
773 if ((priv->is_auto_deep_sleep_enabled) &&
774 (vwrq->value == -1000)) {
775 lbs_exit_auto_deep_sleep(priv);
776 return 0;
777 } else {
778 lbs_pr_err("can't use deep sleep cmd in "
779 "connected state\n");
780 return -EINVAL;
781 }
782 }
783
784 if ((vwrq->value < 0) && (vwrq->value != -1000)) {
785 lbs_pr_err("unknown option\n");
786 return -EINVAL;
787 }
788
789 if (vwrq->value > 0) {
790 if (!priv->is_auto_deep_sleep_enabled) {
791 priv->is_activity_detected = 0;
792 priv->auto_deep_sleep_timeout = vwrq->value;
793 lbs_enter_auto_deep_sleep(priv);
794 } else {
795 priv->auto_deep_sleep_timeout = vwrq->value;
796 lbs_deb_debugfs("auto deep sleep: "
797 "already enabled\n");
798 }
799 return 0;
800 } else {
801 if (priv->is_auto_deep_sleep_enabled) {
802 lbs_exit_auto_deep_sleep(priv);
803 /* Try to exit deep sleep if auto */
804 /*deep sleep disabled */
805 ret = lbs_set_deep_sleep(priv, 0);
806 }
807 if (vwrq->value == 0)
808 ret = lbs_set_deep_sleep(priv, 1);
809 else if (vwrq->value == -1000)
810 ret = lbs_set_deep_sleep(priv, 0);
811 return ret;
812 }
813 }
814
815 if (priv->psmode != LBS802_11POWERMODECAM) {
816 return 0;
817 }
818
819 priv->psmode = LBS802_11POWERMODEMAX_PSP;
820
821 if (priv->connect_status == LBS_CONNECTED) {
822 lbs_ps_sleep(priv, CMD_OPTION_WAITFORRSP);
823 }
824
825 lbs_deb_leave(LBS_DEB_WEXT);
826
827 return 0;
828}
829
830static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
831 struct iw_param *vwrq, char *extra)
832{
833 struct lbs_private *priv = dev->ml_priv;
834
835 lbs_deb_enter(LBS_DEB_WEXT);
836
837 vwrq->value = 0;
838 vwrq->flags = 0;
839 vwrq->disabled = priv->psmode == LBS802_11POWERMODECAM
840 || priv->connect_status == LBS_DISCONNECTED;
841
842 lbs_deb_leave(LBS_DEB_WEXT);
843 return 0;
844}
845
846static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
847{
848 enum {
849 POOR = 30,
850 FAIR = 60,
851 GOOD = 80,
852 VERY_GOOD = 90,
853 EXCELLENT = 95,
854 PERFECT = 100
855 };
856 struct lbs_private *priv = dev->ml_priv;
857 u32 rssi_qual;
858 u32 tx_qual;
859 u32 quality = 0;
860 int ret, stats_valid = 0;
861 u8 rssi;
862 u32 tx_retries;
863 struct cmd_ds_802_11_get_log log;
864
865 lbs_deb_enter(LBS_DEB_WEXT);
866
867 priv->wstats.status = priv->mode;
868
869 /* If we're not associated, all quality values are meaningless */
870 if ((priv->connect_status != LBS_CONNECTED) &&
871 !lbs_mesh_connected(priv))
872 goto out;
873
874 /* Quality by RSSI */
875 priv->wstats.qual.level =
876 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
877 priv->NF[TYPE_BEACON][TYPE_NOAVG]);
878
879 if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
880 priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
881 } else {
882 priv->wstats.qual.noise =
883 CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
884 }
885
886 lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
887 lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise);
888
889 rssi = priv->wstats.qual.level - priv->wstats.qual.noise;
890 if (rssi < 15)
891 rssi_qual = rssi * POOR / 10;
892 else if (rssi < 20)
893 rssi_qual = (rssi - 15) * (FAIR - POOR) / 5 + POOR;
894 else if (rssi < 30)
895 rssi_qual = (rssi - 20) * (GOOD - FAIR) / 5 + FAIR;
896 else if (rssi < 40)
897 rssi_qual = (rssi - 30) * (VERY_GOOD - GOOD) /
898 10 + GOOD;
899 else
900 rssi_qual = (rssi - 40) * (PERFECT - VERY_GOOD) /
901 10 + VERY_GOOD;
902 quality = rssi_qual;
903
904 /* Quality by TX errors */
905 priv->wstats.discard.retries = dev->stats.tx_errors;
906
907 memset(&log, 0, sizeof(log));
908 log.hdr.size = cpu_to_le16(sizeof(log));
909 ret = lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log);
910 if (ret)
911 goto out;
912
913 tx_retries = le32_to_cpu(log.retry);
914
915 if (tx_retries > 75)
916 tx_qual = (90 - tx_retries) * POOR / 15;
917 else if (tx_retries > 70)
918 tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
919 else if (tx_retries > 65)
920 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
921 else if (tx_retries > 50)
922 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
923 15 + GOOD;
924 else
925 tx_qual = (50 - tx_retries) *
926 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
927 quality = min(quality, tx_qual);
928
929 priv->wstats.discard.code = le32_to_cpu(log.wepundecryptable);
930 priv->wstats.discard.retries = tx_retries;
931 priv->wstats.discard.misc = le32_to_cpu(log.ackfailure);
932
933 /* Calculate quality */
934 priv->wstats.qual.qual = min_t(u8, quality, 100);
935 priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
936 stats_valid = 1;
937
938 /* update stats asynchronously for future calls */
939 ret = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
940 0, 0, NULL);
941 if (ret)
942 lbs_pr_err("RSSI command failed\n");
943out:
944 if (!stats_valid) {
945 priv->wstats.miss.beacon = 0;
946 priv->wstats.discard.retries = 0;
947 priv->wstats.qual.qual = 0;
948 priv->wstats.qual.level = 0;
949 priv->wstats.qual.noise = 0;
950 priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED;
951 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID |
952 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
953 }
954
955 lbs_deb_leave(LBS_DEB_WEXT);
956 return &priv->wstats;
957
958
959}
960
961static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
962 struct iw_freq *fwrq, char *extra)
963{
964 int ret = -EINVAL;
965 struct lbs_private *priv = dev->ml_priv;
966 struct chan_freq_power *cfp;
967 struct assoc_request * assoc_req;
968
969 lbs_deb_enter(LBS_DEB_WEXT);
970
971 mutex_lock(&priv->lock);
972 assoc_req = lbs_get_association_request(priv);
973 if (!assoc_req) {
974 ret = -ENOMEM;
975 goto out;
976 }
977
978 /* If setting by frequency, convert to a channel */
979 if (fwrq->e == 1) {
980 long f = fwrq->m / 100000;
981
982 cfp = find_cfp_by_band_and_freq(priv, 0, f);
983 if (!cfp) {
984 lbs_deb_wext("invalid freq %ld\n", f);
985 goto out;
986 }
987
988 fwrq->e = 0;
989 fwrq->m = (int) cfp->channel;
990 }
991
992 /* Setting by channel number */
993 if (fwrq->m > 1000 || fwrq->e > 0) {
994 goto out;
995 }
996
997 cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
998 if (!cfp) {
999 goto out;
1000 }
1001
1002 assoc_req->channel = fwrq->m;
1003 ret = 0;
1004
1005out:
1006 if (ret == 0) {
1007 set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
1008 lbs_postpone_association_work(priv);
1009 } else {
1010 lbs_cancel_association_work(priv);
1011 }
1012 mutex_unlock(&priv->lock);
1013
1014 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1015 return ret;
1016}
1017
1018#ifdef CONFIG_LIBERTAS_MESH
1019static int lbs_mesh_set_freq(struct net_device *dev,
1020 struct iw_request_info *info,
1021 struct iw_freq *fwrq, char *extra)
1022{
1023 struct lbs_private *priv = dev->ml_priv;
1024 struct chan_freq_power *cfp;
1025 int ret = -EINVAL;
1026
1027 lbs_deb_enter(LBS_DEB_WEXT);
1028
1029 /* If setting by frequency, convert to a channel */
1030 if (fwrq->e == 1) {
1031 long f = fwrq->m / 100000;
1032
1033 cfp = find_cfp_by_band_and_freq(priv, 0, f);
1034 if (!cfp) {
1035 lbs_deb_wext("invalid freq %ld\n", f);
1036 goto out;
1037 }
1038
1039 fwrq->e = 0;
1040 fwrq->m = (int) cfp->channel;
1041 }
1042
1043 /* Setting by channel number */
1044 if (fwrq->m > 1000 || fwrq->e > 0) {
1045 goto out;
1046 }
1047
1048 cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
1049 if (!cfp) {
1050 goto out;
1051 }
1052
1053 if (fwrq->m != priv->channel) {
1054 lbs_deb_wext("mesh channel change forces eth disconnect\n");
1055 if (priv->mode == IW_MODE_INFRA)
1056 lbs_cmd_80211_deauthenticate(priv,
1057 priv->curbssparams.bssid,
1058 WLAN_REASON_DEAUTH_LEAVING);
1059 else if (priv->mode == IW_MODE_ADHOC)
1060 lbs_adhoc_stop(priv);
1061 }
1062 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
1063 lbs_update_channel(priv);
1064 ret = 0;
1065
1066out:
1067 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1068 return ret;
1069}
1070#endif
1071
1072static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
1073 struct iw_param *vwrq, char *extra)
1074{
1075 struct lbs_private *priv = dev->ml_priv;
1076 u8 new_rate = 0;
1077 int ret = -EINVAL;
1078 u8 rates[MAX_RATES + 1];
1079
1080 lbs_deb_enter(LBS_DEB_WEXT);
1081
1082 lbs_deb_wext("vwrq->value %d\n", vwrq->value);
1083 lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed);
1084
1085 if (vwrq->fixed && vwrq->value == -1)
1086 goto out;
1087
1088 /* Auto rate? */
1089 priv->enablehwauto = !vwrq->fixed;
1090
1091 if (vwrq->value == -1)
1092 priv->cur_rate = 0;
1093 else {
1094 if (vwrq->value % 100000)
1095 goto out;
1096
1097 new_rate = vwrq->value / 500000;
1098 priv->cur_rate = new_rate;
1099 /* the rest is only needed for lbs_set_data_rate() */
1100 memset(rates, 0, sizeof(rates));
1101 copy_active_data_rates(priv, rates);
1102 if (!memchr(rates, new_rate, sizeof(rates))) {
1103 lbs_pr_alert("fixed data rate 0x%X out of range\n",
1104 new_rate);
1105 goto out;
1106 }
1107 if (priv->fwrelease < 0x09000000) {
1108 ret = lbs_set_power_adapt_cfg(priv, 0,
1109 POW_ADAPT_DEFAULT_P0,
1110 POW_ADAPT_DEFAULT_P1,
1111 POW_ADAPT_DEFAULT_P2);
1112 if (ret)
1113 goto out;
1114 }
1115 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
1116 TPC_DEFAULT_P2, 1);
1117 if (ret)
1118 goto out;
1119 }
1120
1121 /* Try the newer command first (Firmware Spec 5.1 and above) */
1122 ret = lbs_cmd_802_11_rate_adapt_rateset(priv, CMD_ACT_SET);
1123
1124 /* Fallback to older version */
1125 if (ret)
1126 ret = lbs_set_data_rate(priv, new_rate);
1127
1128out:
1129 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1130 return ret;
1131}
1132
1133static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
1134 struct iw_param *vwrq, char *extra)
1135{
1136 struct lbs_private *priv = dev->ml_priv;
1137
1138 lbs_deb_enter(LBS_DEB_WEXT);
1139
1140 if (priv->connect_status == LBS_CONNECTED) {
1141 vwrq->value = priv->cur_rate * 500000;
1142
1143 if (priv->enablehwauto)
1144 vwrq->fixed = 0;
1145 else
1146 vwrq->fixed = 1;
1147
1148 } else {
1149 vwrq->fixed = 0;
1150 vwrq->value = 0;
1151 }
1152
1153 lbs_deb_leave(LBS_DEB_WEXT);
1154 return 0;
1155}
1156
1157static int lbs_set_mode(struct net_device *dev,
1158 struct iw_request_info *info, u32 * uwrq, char *extra)
1159{
1160 int ret = 0;
1161 struct lbs_private *priv = dev->ml_priv;
1162 struct assoc_request * assoc_req;
1163
1164 lbs_deb_enter(LBS_DEB_WEXT);
1165
1166 if ( (*uwrq != IW_MODE_ADHOC)
1167 && (*uwrq != IW_MODE_INFRA)
1168 && (*uwrq != IW_MODE_AUTO)) {
1169 lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq);
1170 ret = -EINVAL;
1171 goto out;
1172 }
1173
1174 mutex_lock(&priv->lock);
1175 assoc_req = lbs_get_association_request(priv);
1176 if (!assoc_req) {
1177 ret = -ENOMEM;
1178 lbs_cancel_association_work(priv);
1179 } else {
1180 assoc_req->mode = *uwrq;
1181 set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
1182 lbs_postpone_association_work(priv);
1183 lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);
1184 }
1185 mutex_unlock(&priv->lock);
1186
1187out:
1188 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1189 return ret;
1190}
1191
1192
1193/**
1194 * @brief Get Encryption key
1195 *
1196 * @param dev A pointer to net_device structure
1197 * @param info A pointer to iw_request_info structure
1198 * @param vwrq A pointer to iw_param structure
1199 * @param extra A pointer to extra data buf
1200 * @return 0 --success, otherwise fail
1201 */
1202static int lbs_get_encode(struct net_device *dev,
1203 struct iw_request_info *info,
1204 struct iw_point *dwrq, u8 * extra)
1205{
1206 struct lbs_private *priv = dev->ml_priv;
1207 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1208
1209 lbs_deb_enter(LBS_DEB_WEXT);
1210
1211 lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n",
1212 dwrq->flags, index, dwrq->length, priv->wep_tx_keyidx);
1213
1214 dwrq->flags = 0;
1215
1216 /* Authentication method */
1217 switch (priv->secinfo.auth_mode) {
1218 case IW_AUTH_ALG_OPEN_SYSTEM:
1219 dwrq->flags = IW_ENCODE_OPEN;
1220 break;
1221
1222 case IW_AUTH_ALG_SHARED_KEY:
1223 case IW_AUTH_ALG_LEAP:
1224 dwrq->flags = IW_ENCODE_RESTRICTED;
1225 break;
1226 default:
1227 dwrq->flags = IW_ENCODE_DISABLED | IW_ENCODE_OPEN;
1228 break;
1229 }
1230
1231 memset(extra, 0, 16);
1232
1233 mutex_lock(&priv->lock);
1234
1235 /* Default to returning current transmit key */
1236 if (index < 0)
1237 index = priv->wep_tx_keyidx;
1238
1239 if ((priv->wep_keys[index].len) && priv->secinfo.wep_enabled) {
1240 memcpy(extra, priv->wep_keys[index].key,
1241 priv->wep_keys[index].len);
1242 dwrq->length = priv->wep_keys[index].len;
1243
1244 dwrq->flags |= (index + 1);
1245 /* Return WEP enabled */
1246 dwrq->flags &= ~IW_ENCODE_DISABLED;
1247 } else if ((priv->secinfo.WPAenabled)
1248 || (priv->secinfo.WPA2enabled)) {
1249 /* return WPA enabled */
1250 dwrq->flags &= ~IW_ENCODE_DISABLED;
1251 dwrq->flags |= IW_ENCODE_NOKEY;
1252 } else {
1253 dwrq->flags |= IW_ENCODE_DISABLED;
1254 }
1255
1256 mutex_unlock(&priv->lock);
1257
1258 lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n",
1259 extra[0], extra[1], extra[2],
1260 extra[3], extra[4], extra[5], dwrq->length);
1261
1262 lbs_deb_wext("return flags 0x%x\n", dwrq->flags);
1263
1264 lbs_deb_leave(LBS_DEB_WEXT);
1265 return 0;
1266}
1267
1268/**
1269 * @brief Set Encryption key (internal)
1270 *
1271 * @param priv A pointer to private card structure
1272 * @param key_material A pointer to key material
1273 * @param key_length length of key material
1274 * @param index key index to set
1275 * @param set_tx_key Force set TX key (1 = yes, 0 = no)
1276 * @return 0 --success, otherwise fail
1277 */
1278static int lbs_set_wep_key(struct assoc_request *assoc_req,
1279 const char *key_material,
1280 u16 key_length,
1281 u16 index,
1282 int set_tx_key)
1283{
1284 int ret = 0;
1285 struct enc_key *pkey;
1286
1287 lbs_deb_enter(LBS_DEB_WEXT);
1288
1289 /* Paranoid validation of key index */
1290 if (index > 3) {
1291 ret = -EINVAL;
1292 goto out;
1293 }
1294
1295 /* validate max key length */
1296 if (key_length > KEY_LEN_WEP_104) {
1297 ret = -EINVAL;
1298 goto out;
1299 }
1300
1301 pkey = &assoc_req->wep_keys[index];
1302
1303 if (key_length > 0) {
1304 memset(pkey, 0, sizeof(struct enc_key));
1305 pkey->type = KEY_TYPE_ID_WEP;
1306
1307 /* Standardize the key length */
1308 pkey->len = (key_length > KEY_LEN_WEP_40) ?
1309 KEY_LEN_WEP_104 : KEY_LEN_WEP_40;
1310 memcpy(pkey->key, key_material, key_length);
1311 }
1312
1313 if (set_tx_key) {
1314 /* Ensure the chosen key is valid */
1315 if (!pkey->len) {
1316 lbs_deb_wext("key not set, so cannot enable it\n");
1317 ret = -EINVAL;
1318 goto out;
1319 }
1320 assoc_req->wep_tx_keyidx = index;
1321 }
1322
1323 assoc_req->secinfo.wep_enabled = 1;
1324
1325out:
1326 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1327 return ret;
1328}
1329
1330static int validate_key_index(u16 def_index, u16 raw_index,
1331 u16 *out_index, u16 *is_default)
1332{
1333 if (!out_index || !is_default)
1334 return -EINVAL;
1335
1336 /* Verify index if present, otherwise use default TX key index */
1337 if (raw_index > 0) {
1338 if (raw_index > 4)
1339 return -EINVAL;
1340 *out_index = raw_index - 1;
1341 } else {
1342 *out_index = def_index;
1343 *is_default = 1;
1344 }
1345 return 0;
1346}
1347
1348static void disable_wep(struct assoc_request *assoc_req)
1349{
1350 int i;
1351
1352 lbs_deb_enter(LBS_DEB_WEXT);
1353
1354 /* Set Open System auth mode */
1355 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1356
1357 /* Clear WEP keys and mark WEP as disabled */
1358 assoc_req->secinfo.wep_enabled = 0;
1359 for (i = 0; i < 4; i++)
1360 assoc_req->wep_keys[i].len = 0;
1361
1362 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1363 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1364
1365 lbs_deb_leave(LBS_DEB_WEXT);
1366}
1367
1368static void disable_wpa(struct assoc_request *assoc_req)
1369{
1370 lbs_deb_enter(LBS_DEB_WEXT);
1371
1372 memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct enc_key));
1373 assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST;
1374 set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
1375
1376 memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct enc_key));
1377 assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST;
1378 set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
1379
1380 assoc_req->secinfo.WPAenabled = 0;
1381 assoc_req->secinfo.WPA2enabled = 0;
1382 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1383
1384 lbs_deb_leave(LBS_DEB_WEXT);
1385}
1386
1387/**
1388 * @brief Set Encryption key
1389 *
1390 * @param dev A pointer to net_device structure
1391 * @param info A pointer to iw_request_info structure
1392 * @param vwrq A pointer to iw_param structure
1393 * @param extra A pointer to extra data buf
1394 * @return 0 --success, otherwise fail
1395 */
1396static int lbs_set_encode(struct net_device *dev,
1397 struct iw_request_info *info,
1398 struct iw_point *dwrq, char *extra)
1399{
1400 int ret = 0;
1401 struct lbs_private *priv = dev->ml_priv;
1402 struct assoc_request * assoc_req;
1403 u16 is_default = 0, index = 0, set_tx_key = 0;
1404
1405 lbs_deb_enter(LBS_DEB_WEXT);
1406
1407 mutex_lock(&priv->lock);
1408 assoc_req = lbs_get_association_request(priv);
1409 if (!assoc_req) {
1410 ret = -ENOMEM;
1411 goto out;
1412 }
1413
1414 if (dwrq->flags & IW_ENCODE_DISABLED) {
1415 disable_wep (assoc_req);
1416 disable_wpa (assoc_req);
1417 goto out;
1418 }
1419
1420 ret = validate_key_index(assoc_req->wep_tx_keyidx,
1421 (dwrq->flags & IW_ENCODE_INDEX),
1422 &index, &is_default);
1423 if (ret) {
1424 ret = -EINVAL;
1425 goto out;
1426 }
1427
1428 /* If WEP isn't enabled, or if there is no key data but a valid
1429 * index, set the TX key.
1430 */
1431 if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default))
1432 set_tx_key = 1;
1433
1434 ret = lbs_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
1435 if (ret)
1436 goto out;
1437
1438 if (dwrq->length)
1439 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1440 if (set_tx_key)
1441 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
1442
1443 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1444 priv->authtype_auto = 0;
1445 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1446 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1447 priv->authtype_auto = 0;
1448 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1449 }
1450
1451out:
1452 if (ret == 0) {
1453 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1454 lbs_postpone_association_work(priv);
1455 } else {
1456 lbs_cancel_association_work(priv);
1457 }
1458 mutex_unlock(&priv->lock);
1459
1460 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1461 return ret;
1462}
1463
1464/**
1465 * @brief Get Extended Encryption key (WPA/802.1x and WEP)
1466 *
1467 * @param dev A pointer to net_device structure
1468 * @param info A pointer to iw_request_info structure
1469 * @param vwrq A pointer to iw_param structure
1470 * @param extra A pointer to extra data buf
1471 * @return 0 on success, otherwise failure
1472 */
1473static int lbs_get_encodeext(struct net_device *dev,
1474 struct iw_request_info *info,
1475 struct iw_point *dwrq,
1476 char *extra)
1477{
1478 int ret = -EINVAL;
1479 struct lbs_private *priv = dev->ml_priv;
1480 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1481 int index, max_key_len;
1482
1483 lbs_deb_enter(LBS_DEB_WEXT);
1484
1485 max_key_len = dwrq->length - sizeof(*ext);
1486 if (max_key_len < 0)
1487 goto out;
1488
1489 index = dwrq->flags & IW_ENCODE_INDEX;
1490 if (index) {
1491 if (index < 1 || index > 4)
1492 goto out;
1493 index--;
1494 } else {
1495 index = priv->wep_tx_keyidx;
1496 }
1497
1498 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
1499 ext->alg != IW_ENCODE_ALG_WEP) {
1500 if (index != 0 || priv->mode != IW_MODE_INFRA)
1501 goto out;
1502 }
1503
1504 dwrq->flags = index + 1;
1505 memset(ext, 0, sizeof(*ext));
1506
1507 if ( !priv->secinfo.wep_enabled
1508 && !priv->secinfo.WPAenabled
1509 && !priv->secinfo.WPA2enabled) {
1510 ext->alg = IW_ENCODE_ALG_NONE;
1511 ext->key_len = 0;
1512 dwrq->flags |= IW_ENCODE_DISABLED;
1513 } else {
1514 u8 *key = NULL;
1515
1516 if ( priv->secinfo.wep_enabled
1517 && !priv->secinfo.WPAenabled
1518 && !priv->secinfo.WPA2enabled) {
1519 /* WEP */
1520 ext->alg = IW_ENCODE_ALG_WEP;
1521 ext->key_len = priv->wep_keys[index].len;
1522 key = &priv->wep_keys[index].key[0];
1523 } else if ( !priv->secinfo.wep_enabled
1524 && (priv->secinfo.WPAenabled ||
1525 priv->secinfo.WPA2enabled)) {
1526 /* WPA */
1527 struct enc_key * pkey = NULL;
1528
1529 if ( priv->wpa_mcast_key.len
1530 && (priv->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
1531 pkey = &priv->wpa_mcast_key;
1532 else if ( priv->wpa_unicast_key.len
1533 && (priv->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
1534 pkey = &priv->wpa_unicast_key;
1535
1536 if (pkey) {
1537 if (pkey->type == KEY_TYPE_ID_AES) {
1538 ext->alg = IW_ENCODE_ALG_CCMP;
1539 } else {
1540 ext->alg = IW_ENCODE_ALG_TKIP;
1541 }
1542 ext->key_len = pkey->len;
1543 key = &pkey->key[0];
1544 } else {
1545 ext->alg = IW_ENCODE_ALG_TKIP;
1546 ext->key_len = 0;
1547 }
1548 } else {
1549 goto out;
1550 }
1551
1552 if (ext->key_len > max_key_len) {
1553 ret = -E2BIG;
1554 goto out;
1555 }
1556
1557 if (ext->key_len)
1558 memcpy(ext->key, key, ext->key_len);
1559 else
1560 dwrq->flags |= IW_ENCODE_NOKEY;
1561 dwrq->flags |= IW_ENCODE_ENABLED;
1562 }
1563 ret = 0;
1564
1565out:
1566 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1567 return ret;
1568}
1569
1570/**
1571 * @brief Set Encryption key Extended (WPA/802.1x and WEP)
1572 *
1573 * @param dev A pointer to net_device structure
1574 * @param info A pointer to iw_request_info structure
1575 * @param vwrq A pointer to iw_param structure
1576 * @param extra A pointer to extra data buf
1577 * @return 0 --success, otherwise fail
1578 */
1579static int lbs_set_encodeext(struct net_device *dev,
1580 struct iw_request_info *info,
1581 struct iw_point *dwrq,
1582 char *extra)
1583{
1584 int ret = 0;
1585 struct lbs_private *priv = dev->ml_priv;
1586 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1587 int alg = ext->alg;
1588 struct assoc_request * assoc_req;
1589
1590 lbs_deb_enter(LBS_DEB_WEXT);
1591
1592 mutex_lock(&priv->lock);
1593 assoc_req = lbs_get_association_request(priv);
1594 if (!assoc_req) {
1595 ret = -ENOMEM;
1596 goto out;
1597 }
1598
1599 if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
1600 disable_wep (assoc_req);
1601 disable_wpa (assoc_req);
1602 } else if (alg == IW_ENCODE_ALG_WEP) {
1603 u16 is_default = 0, index, set_tx_key = 0;
1604
1605 ret = validate_key_index(assoc_req->wep_tx_keyidx,
1606 (dwrq->flags & IW_ENCODE_INDEX),
1607 &index, &is_default);
1608 if (ret)
1609 goto out;
1610
1611 /* If WEP isn't enabled, or if there is no key data but a valid
1612 * index, or if the set-TX-key flag was passed, set the TX key.
1613 */
1614 if ( !assoc_req->secinfo.wep_enabled
1615 || (dwrq->length == 0 && !is_default)
1616 || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY))
1617 set_tx_key = 1;
1618
1619 /* Copy key to driver */
1620 ret = lbs_set_wep_key(assoc_req, ext->key, ext->key_len, index,
1621 set_tx_key);
1622 if (ret)
1623 goto out;
1624
1625 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1626 priv->authtype_auto = 0;
1627 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1628 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1629 priv->authtype_auto = 0;
1630 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1631 }
1632
1633 /* Mark the various WEP bits as modified */
1634 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1635 if (dwrq->length)
1636 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1637 if (set_tx_key)
1638 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
1639 } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
1640 struct enc_key * pkey;
1641
1642 /* validate key length */
1643 if (((alg == IW_ENCODE_ALG_TKIP)
1644 && (ext->key_len != KEY_LEN_WPA_TKIP))
1645 || ((alg == IW_ENCODE_ALG_CCMP)
1646 && (ext->key_len != KEY_LEN_WPA_AES))) {
1647 lbs_deb_wext("invalid size %d for key of alg "
1648 "type %d\n",
1649 ext->key_len,
1650 alg);
1651 ret = -EINVAL;
1652 goto out;
1653 }
1654
1655 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1656 pkey = &assoc_req->wpa_mcast_key;
1657 set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
1658 } else {
1659 pkey = &assoc_req->wpa_unicast_key;
1660 set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
1661 }
1662
1663 memset(pkey, 0, sizeof (struct enc_key));
1664 memcpy(pkey->key, ext->key, ext->key_len);
1665 pkey->len = ext->key_len;
1666 if (pkey->len)
1667 pkey->flags |= KEY_INFO_WPA_ENABLED;
1668
1669 /* Do this after zeroing key structure */
1670 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1671 pkey->flags |= KEY_INFO_WPA_MCAST;
1672 } else {
1673 pkey->flags |= KEY_INFO_WPA_UNICAST;
1674 }
1675
1676 if (alg == IW_ENCODE_ALG_TKIP) {
1677 pkey->type = KEY_TYPE_ID_TKIP;
1678 } else if (alg == IW_ENCODE_ALG_CCMP) {
1679 pkey->type = KEY_TYPE_ID_AES;
1680 }
1681
1682 /* If WPA isn't enabled yet, do that now */
1683 if ( assoc_req->secinfo.WPAenabled == 0
1684 && assoc_req->secinfo.WPA2enabled == 0) {
1685 assoc_req->secinfo.WPAenabled = 1;
1686 assoc_req->secinfo.WPA2enabled = 1;
1687 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1688 }
1689
1690 /* Only disable wep if necessary: can't waste time here. */
1691 if (priv->mac_control & CMD_ACT_MAC_WEP_ENABLE)
1692 disable_wep(assoc_req);
1693 }
1694
1695out:
1696 if (ret == 0) {
1697 /* 802.1x and WPA rekeying must happen as quickly as possible,
1698 * especially during the 4-way handshake; thus if in
1699 * infrastructure mode, and either (a) 802.1x is enabled or
1700 * (b) WPA is being used, set the key right away.
1701 */
1702 if (assoc_req->mode == IW_MODE_INFRA &&
1703 ((assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_802_1X) ||
1704 (assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_PSK) ||
1705 assoc_req->secinfo.WPAenabled ||
1706 assoc_req->secinfo.WPA2enabled)) {
1707 lbs_do_association_work(priv);
1708 } else
1709 lbs_postpone_association_work(priv);
1710 } else {
1711 lbs_cancel_association_work(priv);
1712 }
1713 mutex_unlock(&priv->lock);
1714
1715 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1716 return ret;
1717}
1718
1719
1720static int lbs_set_genie(struct net_device *dev,
1721 struct iw_request_info *info,
1722 struct iw_point *dwrq,
1723 char *extra)
1724{
1725 struct lbs_private *priv = dev->ml_priv;
1726 int ret = 0;
1727 struct assoc_request * assoc_req;
1728
1729 lbs_deb_enter(LBS_DEB_WEXT);
1730
1731 mutex_lock(&priv->lock);
1732 assoc_req = lbs_get_association_request(priv);
1733 if (!assoc_req) {
1734 ret = -ENOMEM;
1735 goto out;
1736 }
1737
1738 if (dwrq->length > MAX_WPA_IE_LEN ||
1739 (dwrq->length && extra == NULL)) {
1740 ret = -EINVAL;
1741 goto out;
1742 }
1743
1744 if (dwrq->length) {
1745 memcpy(&assoc_req->wpa_ie[0], extra, dwrq->length);
1746 assoc_req->wpa_ie_len = dwrq->length;
1747 } else {
1748 memset(&assoc_req->wpa_ie[0], 0, sizeof(priv->wpa_ie));
1749 assoc_req->wpa_ie_len = 0;
1750 }
1751
1752out:
1753 if (ret == 0) {
1754 set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags);
1755 lbs_postpone_association_work(priv);
1756 } else {
1757 lbs_cancel_association_work(priv);
1758 }
1759 mutex_unlock(&priv->lock);
1760
1761 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1762 return ret;
1763}
1764
1765static int lbs_get_genie(struct net_device *dev,
1766 struct iw_request_info *info,
1767 struct iw_point *dwrq,
1768 char *extra)
1769{
1770 int ret = 0;
1771 struct lbs_private *priv = dev->ml_priv;
1772
1773 lbs_deb_enter(LBS_DEB_WEXT);
1774
1775 if (priv->wpa_ie_len == 0) {
1776 dwrq->length = 0;
1777 goto out;
1778 }
1779
1780 if (dwrq->length < priv->wpa_ie_len) {
1781 ret = -E2BIG;
1782 goto out;
1783 }
1784
1785 dwrq->length = priv->wpa_ie_len;
1786 memcpy(extra, &priv->wpa_ie[0], priv->wpa_ie_len);
1787
1788out:
1789 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1790 return ret;
1791}
1792
1793
1794static int lbs_set_auth(struct net_device *dev,
1795 struct iw_request_info *info,
1796 struct iw_param *dwrq,
1797 char *extra)
1798{
1799 struct lbs_private *priv = dev->ml_priv;
1800 struct assoc_request * assoc_req;
1801 int ret = 0;
1802 int updated = 0;
1803
1804 lbs_deb_enter(LBS_DEB_WEXT);
1805
1806 mutex_lock(&priv->lock);
1807 assoc_req = lbs_get_association_request(priv);
1808 if (!assoc_req) {
1809 ret = -ENOMEM;
1810 goto out;
1811 }
1812
1813 switch (dwrq->flags & IW_AUTH_INDEX) {
1814 case IW_AUTH_PRIVACY_INVOKED:
1815 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1816 case IW_AUTH_TKIP_COUNTERMEASURES:
1817 case IW_AUTH_CIPHER_PAIRWISE:
1818 case IW_AUTH_CIPHER_GROUP:
1819 case IW_AUTH_DROP_UNENCRYPTED:
1820 /*
1821 * libertas does not use these parameters
1822 */
1823 break;
1824
1825 case IW_AUTH_KEY_MGMT:
1826 assoc_req->secinfo.key_mgmt = dwrq->value;
1827 updated = 1;
1828 break;
1829
1830 case IW_AUTH_WPA_VERSION:
1831 if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
1832 assoc_req->secinfo.WPAenabled = 0;
1833 assoc_req->secinfo.WPA2enabled = 0;
1834 disable_wpa (assoc_req);
1835 }
1836 if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
1837 assoc_req->secinfo.WPAenabled = 1;
1838 assoc_req->secinfo.wep_enabled = 0;
1839 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1840 }
1841 if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) {
1842 assoc_req->secinfo.WPA2enabled = 1;
1843 assoc_req->secinfo.wep_enabled = 0;
1844 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1845 }
1846 updated = 1;
1847 break;
1848
1849 case IW_AUTH_80211_AUTH_ALG:
1850 if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
1851 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1852 } else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1853 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1854 } else if (dwrq->value & IW_AUTH_ALG_LEAP) {
1855 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP;
1856 } else {
1857 ret = -EINVAL;
1858 }
1859 updated = 1;
1860 break;
1861
1862 case IW_AUTH_WPA_ENABLED:
1863 if (dwrq->value) {
1864 if (!assoc_req->secinfo.WPAenabled &&
1865 !assoc_req->secinfo.WPA2enabled) {
1866 assoc_req->secinfo.WPAenabled = 1;
1867 assoc_req->secinfo.WPA2enabled = 1;
1868 assoc_req->secinfo.wep_enabled = 0;
1869 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1870 }
1871 } else {
1872 assoc_req->secinfo.WPAenabled = 0;
1873 assoc_req->secinfo.WPA2enabled = 0;
1874 disable_wpa (assoc_req);
1875 }
1876 updated = 1;
1877 break;
1878
1879 default:
1880 ret = -EOPNOTSUPP;
1881 break;
1882 }
1883
1884out:
1885 if (ret == 0) {
1886 if (updated)
1887 set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
1888 lbs_postpone_association_work(priv);
1889 } else if (ret != -EOPNOTSUPP) {
1890 lbs_cancel_association_work(priv);
1891 }
1892 mutex_unlock(&priv->lock);
1893
1894 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1895 return ret;
1896}
1897
1898static int lbs_get_auth(struct net_device *dev,
1899 struct iw_request_info *info,
1900 struct iw_param *dwrq,
1901 char *extra)
1902{
1903 int ret = 0;
1904 struct lbs_private *priv = dev->ml_priv;
1905
1906 lbs_deb_enter(LBS_DEB_WEXT);
1907
1908 switch (dwrq->flags & IW_AUTH_INDEX) {
1909 case IW_AUTH_KEY_MGMT:
1910 dwrq->value = priv->secinfo.key_mgmt;
1911 break;
1912
1913 case IW_AUTH_WPA_VERSION:
1914 dwrq->value = 0;
1915 if (priv->secinfo.WPAenabled)
1916 dwrq->value |= IW_AUTH_WPA_VERSION_WPA;
1917 if (priv->secinfo.WPA2enabled)
1918 dwrq->value |= IW_AUTH_WPA_VERSION_WPA2;
1919 if (!dwrq->value)
1920 dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
1921 break;
1922
1923 case IW_AUTH_80211_AUTH_ALG:
1924 dwrq->value = priv->secinfo.auth_mode;
1925 break;
1926
1927 case IW_AUTH_WPA_ENABLED:
1928 if (priv->secinfo.WPAenabled && priv->secinfo.WPA2enabled)
1929 dwrq->value = 1;
1930 break;
1931
1932 default:
1933 ret = -EOPNOTSUPP;
1934 }
1935
1936 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1937 return ret;
1938}
1939
1940
1941static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1942 struct iw_param *vwrq, char *extra)
1943{
1944 int ret = 0;
1945 struct lbs_private *priv = dev->ml_priv;
1946 s16 dbm = (s16) vwrq->value;
1947
1948 lbs_deb_enter(LBS_DEB_WEXT);
1949
1950 if (vwrq->disabled) {
1951 lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0);
1952 goto out;
1953 }
1954
1955 if (vwrq->fixed == 0) {
1956 /* User requests automatic tx power control, however there are
1957 * many auto tx settings. For now use firmware defaults until
1958 * we come up with a good way to expose these to the user. */
1959 if (priv->fwrelease < 0x09000000) {
1960 ret = lbs_set_power_adapt_cfg(priv, 1,
1961 POW_ADAPT_DEFAULT_P0,
1962 POW_ADAPT_DEFAULT_P1,
1963 POW_ADAPT_DEFAULT_P2);
1964 if (ret)
1965 goto out;
1966 }
1967 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
1968 TPC_DEFAULT_P2, 1);
1969 if (ret)
1970 goto out;
1971 dbm = priv->txpower_max;
1972 } else {
1973 /* Userspace check in iwrange if it should use dBm or mW,
1974 * therefore this should never happen... Jean II */
1975 if ((vwrq->flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
1976 ret = -EOPNOTSUPP;
1977 goto out;
1978 }
1979
1980 /* Validate requested power level against firmware allowed
1981 * levels */
1982 if (priv->txpower_min && (dbm < priv->txpower_min)) {
1983 ret = -EINVAL;
1984 goto out;
1985 }
1986
1987 if (priv->txpower_max && (dbm > priv->txpower_max)) {
1988 ret = -EINVAL;
1989 goto out;
1990 }
1991 if (priv->fwrelease < 0x09000000) {
1992 ret = lbs_set_power_adapt_cfg(priv, 0,
1993 POW_ADAPT_DEFAULT_P0,
1994 POW_ADAPT_DEFAULT_P1,
1995 POW_ADAPT_DEFAULT_P2);
1996 if (ret)
1997 goto out;
1998 }
1999 ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
2000 TPC_DEFAULT_P2, 1);
2001 if (ret)
2002 goto out;
2003 }
2004
2005 /* If the radio was off, turn it on */
2006 if (!priv->radio_on) {
2007 ret = lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 1);
2008 if (ret)
2009 goto out;
2010 }
2011
2012 lbs_deb_wext("txpower set %d dBm\n", dbm);
2013
2014 ret = lbs_set_tx_power(priv, dbm);
2015
2016out:
2017 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
2018 return ret;
2019}
2020
2021static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
2022 struct iw_point *dwrq, char *extra)
2023{
2024 struct lbs_private *priv = dev->ml_priv;
2025
2026 lbs_deb_enter(LBS_DEB_WEXT);
2027
2028 /*
2029 * Note : if dwrq->flags != 0, we should get the relevant SSID from
2030 * the SSID list...
2031 */
2032
2033 /*
2034 * Get the current SSID
2035 */
2036 if (priv->connect_status == LBS_CONNECTED) {
2037 memcpy(extra, priv->curbssparams.ssid,
2038 priv->curbssparams.ssid_len);
2039 } else {
2040 memset(extra, 0, 32);
2041 }
2042 /*
2043 * If none, we may want to get the one that was set
2044 */
2045
2046 dwrq->length = priv->curbssparams.ssid_len;
2047
2048 dwrq->flags = 1; /* active */
2049
2050 lbs_deb_leave(LBS_DEB_WEXT);
2051 return 0;
2052}
2053
2054static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
2055 struct iw_point *dwrq, char *extra)
2056{
2057 struct lbs_private *priv = dev->ml_priv;
2058 int ret = 0;
2059 u8 ssid[IEEE80211_MAX_SSID_LEN];
2060 u8 ssid_len = 0;
2061 struct assoc_request * assoc_req;
2062 int in_ssid_len = dwrq->length;
2063 DECLARE_SSID_BUF(ssid_buf);
2064
2065 lbs_deb_enter(LBS_DEB_WEXT);
2066
2067 if (!priv->radio_on) {
2068 ret = -EINVAL;
2069 goto out;
2070 }
2071
2072 /* Check the size of the string */
2073 if (in_ssid_len > IEEE80211_MAX_SSID_LEN) {
2074 ret = -E2BIG;
2075 goto out;
2076 }
2077
2078 memset(&ssid, 0, sizeof(ssid));
2079
2080 if (!dwrq->flags || !in_ssid_len) {
2081 /* "any" SSID requested; leave SSID blank */
2082 } else {
2083 /* Specific SSID requested */
2084 memcpy(&ssid, extra, in_ssid_len);
2085 ssid_len = in_ssid_len;
2086 }
2087
2088 if (!ssid_len) {
2089 lbs_deb_wext("requested any SSID\n");
2090 } else {
2091 lbs_deb_wext("requested SSID '%s'\n",
2092 print_ssid(ssid_buf, ssid, ssid_len));
2093 }
2094
2095out:
2096 mutex_lock(&priv->lock);
2097 if (ret == 0) {
2098 /* Get or create the current association request */
2099 assoc_req = lbs_get_association_request(priv);
2100 if (!assoc_req) {
2101 ret = -ENOMEM;
2102 } else {
2103 /* Copy the SSID to the association request */
2104 memcpy(&assoc_req->ssid, &ssid, IEEE80211_MAX_SSID_LEN);
2105 assoc_req->ssid_len = ssid_len;
2106 set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
2107 lbs_postpone_association_work(priv);
2108 }
2109 }
2110
2111 /* Cancel the association request if there was an error */
2112 if (ret != 0) {
2113 lbs_cancel_association_work(priv);
2114 }
2115
2116 mutex_unlock(&priv->lock);
2117
2118 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
2119 return ret;
2120}
2121
2122#ifdef CONFIG_LIBERTAS_MESH
2123static int lbs_mesh_get_essid(struct net_device *dev,
2124 struct iw_request_info *info,
2125 struct iw_point *dwrq, char *extra)
2126{
2127 struct lbs_private *priv = dev->ml_priv;
2128
2129 lbs_deb_enter(LBS_DEB_WEXT);
2130
2131 memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len);
2132
2133 dwrq->length = priv->mesh_ssid_len;
2134
2135 dwrq->flags = 1; /* active */
2136
2137 lbs_deb_leave(LBS_DEB_WEXT);
2138 return 0;
2139}
2140
2141static int lbs_mesh_set_essid(struct net_device *dev,
2142 struct iw_request_info *info,
2143 struct iw_point *dwrq, char *extra)
2144{
2145 struct lbs_private *priv = dev->ml_priv;
2146 int ret = 0;
2147
2148 lbs_deb_enter(LBS_DEB_WEXT);
2149
2150 if (!priv->radio_on) {
2151 ret = -EINVAL;
2152 goto out;
2153 }
2154
2155 /* Check the size of the string */
2156 if (dwrq->length > IEEE80211_MAX_SSID_LEN) {
2157 ret = -E2BIG;
2158 goto out;
2159 }
2160
2161 if (!dwrq->flags || !dwrq->length) {
2162 ret = -EINVAL;
2163 goto out;
2164 } else {
2165 /* Specific SSID requested */
2166 memcpy(priv->mesh_ssid, extra, dwrq->length);
2167 priv->mesh_ssid_len = dwrq->length;
2168 }
2169
2170 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
2171 priv->channel);
2172 out:
2173 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
2174 return ret;
2175}
2176#endif
2177
2178/**
2179 * @brief Connect to the AP or Ad-hoc Network with specific bssid
2180 *
2181 * @param dev A pointer to net_device structure
2182 * @param info A pointer to iw_request_info structure
2183 * @param awrq A pointer to iw_param structure
2184 * @param extra A pointer to extra data buf
2185 * @return 0 --success, otherwise fail
2186 */
2187static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
2188 struct sockaddr *awrq, char *extra)
2189{
2190 struct lbs_private *priv = dev->ml_priv;
2191 struct assoc_request * assoc_req;
2192 int ret = 0;
2193
2194 lbs_deb_enter(LBS_DEB_WEXT);
2195
2196 if (!priv->radio_on)
2197 return -EINVAL;
2198
2199 if (awrq->sa_family != ARPHRD_ETHER)
2200 return -EINVAL;
2201
2202 lbs_deb_wext("ASSOC: WAP: sa_data %pM\n", awrq->sa_data);
2203
2204 mutex_lock(&priv->lock);
2205
2206 /* Get or create the current association request */
2207 assoc_req = lbs_get_association_request(priv);
2208 if (!assoc_req) {
2209 lbs_cancel_association_work(priv);
2210 ret = -ENOMEM;
2211 } else {
2212 /* Copy the BSSID to the association request */
2213 memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN);
2214 set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags);
2215 lbs_postpone_association_work(priv);
2216 }
2217
2218 mutex_unlock(&priv->lock);
2219
2220 return ret;
2221}
2222
2223/*
2224 * iwconfig settable callbacks
2225 */
2226static const iw_handler lbs_handler[] = {
2227 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2228 (iw_handler) lbs_get_name, /* SIOCGIWNAME */
2229 (iw_handler) NULL, /* SIOCSIWNWID */
2230 (iw_handler) NULL, /* SIOCGIWNWID */
2231 (iw_handler) lbs_set_freq, /* SIOCSIWFREQ */
2232 (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */
2233 (iw_handler) lbs_set_mode, /* SIOCSIWMODE */
2234 (iw_handler) lbs_get_mode, /* SIOCGIWMODE */
2235 (iw_handler) NULL, /* SIOCSIWSENS */
2236 (iw_handler) NULL, /* SIOCGIWSENS */
2237 (iw_handler) NULL, /* SIOCSIWRANGE */
2238 (iw_handler) lbs_get_range, /* SIOCGIWRANGE */
2239 (iw_handler) NULL, /* SIOCSIWPRIV */
2240 (iw_handler) NULL, /* SIOCGIWPRIV */
2241 (iw_handler) NULL, /* SIOCSIWSTATS */
2242 (iw_handler) NULL, /* SIOCGIWSTATS */
2243 iw_handler_set_spy, /* SIOCSIWSPY */
2244 iw_handler_get_spy, /* SIOCGIWSPY */
2245 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
2246 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
2247 (iw_handler) lbs_set_wap, /* SIOCSIWAP */
2248 (iw_handler) lbs_get_wap, /* SIOCGIWAP */
2249 (iw_handler) NULL, /* SIOCSIWMLME */
2250 (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
2251 (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */
2252 (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */
2253 (iw_handler) lbs_set_essid, /* SIOCSIWESSID */
2254 (iw_handler) lbs_get_essid, /* SIOCGIWESSID */
2255 (iw_handler) lbs_set_nick, /* SIOCSIWNICKN */
2256 (iw_handler) lbs_get_nick, /* SIOCGIWNICKN */
2257 (iw_handler) NULL, /* -- hole -- */
2258 (iw_handler) NULL, /* -- hole -- */
2259 (iw_handler) lbs_set_rate, /* SIOCSIWRATE */
2260 (iw_handler) lbs_get_rate, /* SIOCGIWRATE */
2261 (iw_handler) lbs_set_rts, /* SIOCSIWRTS */
2262 (iw_handler) lbs_get_rts, /* SIOCGIWRTS */
2263 (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */
2264 (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */
2265 (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */
2266 (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */
2267 (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */
2268 (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */
2269 (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */
2270 (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */
2271 (iw_handler) lbs_set_power, /* SIOCSIWPOWER */
2272 (iw_handler) lbs_get_power, /* SIOCGIWPOWER */
2273 (iw_handler) NULL, /* -- hole -- */
2274 (iw_handler) NULL, /* -- hole -- */
2275 (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */
2276 (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */
2277 (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */
2278 (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */
2279 (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
2280 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
2281 (iw_handler) NULL, /* SIOCSIWPMKSA */
2282};
2283struct iw_handler_def lbs_handler_def = {
2284 .num_standard = ARRAY_SIZE(lbs_handler),
2285 .standard = (iw_handler *) lbs_handler,
2286 .get_wireless_stats = lbs_get_wireless_stats,
2287};
2288
2289#ifdef CONFIG_LIBERTAS_MESH
2290static const iw_handler mesh_wlan_handler[] = {
2291 (iw_handler) NULL, /* SIOCSIWCOMMIT */
2292 (iw_handler) lbs_get_name, /* SIOCGIWNAME */
2293 (iw_handler) NULL, /* SIOCSIWNWID */
2294 (iw_handler) NULL, /* SIOCGIWNWID */
2295 (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */
2296 (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */
2297 (iw_handler) NULL, /* SIOCSIWMODE */
2298 (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */
2299 (iw_handler) NULL, /* SIOCSIWSENS */
2300 (iw_handler) NULL, /* SIOCGIWSENS */
2301 (iw_handler) NULL, /* SIOCSIWRANGE */
2302 (iw_handler) lbs_get_range, /* SIOCGIWRANGE */
2303 (iw_handler) NULL, /* SIOCSIWPRIV */
2304 (iw_handler) NULL, /* SIOCGIWPRIV */
2305 (iw_handler) NULL, /* SIOCSIWSTATS */
2306 (iw_handler) NULL, /* SIOCGIWSTATS */
2307 iw_handler_set_spy, /* SIOCSIWSPY */
2308 iw_handler_get_spy, /* SIOCGIWSPY */
2309 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
2310 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
2311 (iw_handler) NULL, /* SIOCSIWAP */
2312 (iw_handler) NULL, /* SIOCGIWAP */
2313 (iw_handler) NULL, /* SIOCSIWMLME */
2314 (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
2315 (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */
2316 (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */
2317 (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
2318 (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
2319 (iw_handler) NULL, /* SIOCSIWNICKN */
2320 (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */
2321 (iw_handler) NULL, /* -- hole -- */
2322 (iw_handler) NULL, /* -- hole -- */
2323 (iw_handler) lbs_set_rate, /* SIOCSIWRATE */
2324 (iw_handler) lbs_get_rate, /* SIOCGIWRATE */
2325 (iw_handler) lbs_set_rts, /* SIOCSIWRTS */
2326 (iw_handler) lbs_get_rts, /* SIOCGIWRTS */
2327 (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */
2328 (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */
2329 (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */
2330 (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */
2331 (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */
2332 (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */
2333 (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */
2334 (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */
2335 (iw_handler) lbs_set_power, /* SIOCSIWPOWER */
2336 (iw_handler) lbs_get_power, /* SIOCGIWPOWER */
2337 (iw_handler) NULL, /* -- hole -- */
2338 (iw_handler) NULL, /* -- hole -- */
2339 (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */
2340 (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */
2341 (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */
2342 (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */
2343 (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
2344 (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
2345 (iw_handler) NULL, /* SIOCSIWPMKSA */
2346};
2347
2348struct iw_handler_def mesh_handler_def = {
2349 .num_standard = ARRAY_SIZE(mesh_wlan_handler),
2350 .standard = (iw_handler *) mesh_wlan_handler,
2351 .get_wireless_stats = lbs_get_wireless_stats,
2352};
2353#endif
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
deleted file mode 100644
index f3f19fe8c6c6..000000000000
--- a/drivers/net/wireless/libertas/wext.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/**
2 * This file contains definition for IOCTL call.
3 */
4#ifndef _LBS_WEXT_H_
5#define _LBS_WEXT_H_
6
7void lbs_send_disconnect_notification(struct lbs_private *priv);
8void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
9
10struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
11 struct lbs_private *priv,
12 u8 band,
13 u16 channel);
14
15extern struct iw_handler_def lbs_handler_def;
16
17#endif
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index c445500ffc61..b172f5d87a3b 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -538,7 +538,8 @@ static void if_usb_receive_fwload(struct urb *urb)
538 return; 538 return;
539 } 539 }
540 540
541 syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); 541 syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader),
542 GFP_ATOMIC);
542 if (!syncfwheader) { 543 if (!syncfwheader) {
543 lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); 544 lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
544 kfree_skb(skb); 545 kfree_skb(skb);
@@ -546,8 +547,6 @@ static void if_usb_receive_fwload(struct urb *urb)
546 return; 547 return;
547 } 548 }
548 549
549 memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader));
550
551 if (!syncfwheader->cmd) { 550 if (!syncfwheader->cmd) {
552 lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); 551 lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
553 lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", 552 lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 6f8cb3ee6fed..af50895e4bb0 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1291,6 +1291,11 @@ static int __init init_mac80211_hwsim(void)
1291 hw->wiphy->n_addresses = 2; 1291 hw->wiphy->n_addresses = 2;
1292 hw->wiphy->addresses = data->addresses; 1292 hw->wiphy->addresses = data->addresses;
1293 1293
1294 if (fake_hw_scan) {
1295 hw->wiphy->max_scan_ssids = 255;
1296 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
1297 }
1298
1294 hw->channel_change_time = 1; 1299 hw->channel_change_time = 1;
1295 hw->queues = 4; 1300 hw->queues = 4;
1296 hw->wiphy->interface_modes = 1301 hw->wiphy->interface_modes =
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 808adb909095..cd37b2ac5356 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -109,7 +109,7 @@ struct mwl8k_rx_queue {
109 dma_addr_t rxd_dma; 109 dma_addr_t rxd_dma;
110 struct { 110 struct {
111 struct sk_buff *skb; 111 struct sk_buff *skb;
112 DECLARE_PCI_UNMAP_ADDR(dma) 112 DEFINE_DMA_UNMAP_ADDR(dma);
113 } *buf; 113 } *buf;
114}; 114};
115 115
@@ -963,7 +963,7 @@ static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
963 if (rxq->tail == MWL8K_RX_DESCS) 963 if (rxq->tail == MWL8K_RX_DESCS)
964 rxq->tail = 0; 964 rxq->tail = 0;
965 rxq->buf[rx].skb = skb; 965 rxq->buf[rx].skb = skb;
966 pci_unmap_addr_set(&rxq->buf[rx], dma, addr); 966 dma_unmap_addr_set(&rxq->buf[rx], dma, addr);
967 967
968 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size); 968 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
969 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ); 969 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
@@ -984,9 +984,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
984 for (i = 0; i < MWL8K_RX_DESCS; i++) { 984 for (i = 0; i < MWL8K_RX_DESCS; i++) {
985 if (rxq->buf[i].skb != NULL) { 985 if (rxq->buf[i].skb != NULL) {
986 pci_unmap_single(priv->pdev, 986 pci_unmap_single(priv->pdev,
987 pci_unmap_addr(&rxq->buf[i], dma), 987 dma_unmap_addr(&rxq->buf[i], dma),
988 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 988 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
989 pci_unmap_addr_set(&rxq->buf[i], dma, 0); 989 dma_unmap_addr_set(&rxq->buf[i], dma, 0);
990 990
991 kfree_skb(rxq->buf[i].skb); 991 kfree_skb(rxq->buf[i].skb);
992 rxq->buf[i].skb = NULL; 992 rxq->buf[i].skb = NULL;
@@ -1060,9 +1060,9 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
1060 rxq->buf[rxq->head].skb = NULL; 1060 rxq->buf[rxq->head].skb = NULL;
1061 1061
1062 pci_unmap_single(priv->pdev, 1062 pci_unmap_single(priv->pdev,
1063 pci_unmap_addr(&rxq->buf[rxq->head], dma), 1063 dma_unmap_addr(&rxq->buf[rxq->head], dma),
1064 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 1064 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
1065 pci_unmap_addr_set(&rxq->buf[rxq->head], dma, 0); 1065 dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0);
1066 1066
1067 rxq->head++; 1067 rxq->head++;
1068 if (rxq->head == MWL8K_RX_DESCS) 1068 if (rxq->head == MWL8K_RX_DESCS)
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index 6da85e75fce0..f750f49bbd4e 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -68,7 +68,7 @@ struct dblock {
68} __attribute__ ((packed)); 68} __attribute__ ((packed));
69 69
70/* 70/*
71 * Plug Data References are located in in the image after the last data 71 * Plug Data References are located in the image after the last data
72 * block. They refer to areas in the adapter memory where the plug data 72 * block. They refer to areas in the adapter memory where the plug data
73 * items with matching ID should be written. 73 * items with matching ID should be written.
74 */ 74 */
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index 78f089baa8c9..020da76c9558 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -356,12 +356,10 @@ static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv,
356{ 356{
357 struct request_context *ctx; 357 struct request_context *ctx;
358 358
359 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); 359 ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
360 if (!ctx) 360 if (!ctx)
361 return NULL; 361 return NULL;
362 362
363 memset(ctx, 0, sizeof(*ctx));
364
365 ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC); 363 ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC);
366 if (!ctx->buf) { 364 if (!ctx->buf) {
367 kfree(ctx); 365 kfree(ctx);
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 5775124e2aee..a63108c6df7d 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -993,11 +993,9 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
993 return -EINVAL; 993 return -EINVAL;
994 994
995 if (wrqu->data.length) { 995 if (wrqu->data.length) {
996 buf = kmalloc(wrqu->data.length, GFP_KERNEL); 996 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
997 if (buf == NULL) 997 if (buf == NULL)
998 return -ENOMEM; 998 return -ENOMEM;
999
1000 memcpy(buf, extra, wrqu->data.length);
1001 } else 999 } else
1002 buf = NULL; 1000 buf = NULL;
1003 1001
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 187e263b045a..e51650ed49f2 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -599,13 +599,13 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
599 } 599 }
600 break; 600 break;
601 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: 601 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
602 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL); 602 priv->iq_autocal = kmemdup(entry->data, data_len,
603 GFP_KERNEL);
603 if (!priv->iq_autocal) { 604 if (!priv->iq_autocal) {
604 err = -ENOMEM; 605 err = -ENOMEM;
605 goto err; 606 goto err;
606 } 607 }
607 608
608 memcpy(priv->iq_autocal, entry->data, data_len);
609 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); 609 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
610 break; 610 break;
611 case PDR_DEFAULT_COUNTRY: 611 case PDR_DEFAULT_COUNTRY:
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index c8f09da1f84d..087bf0698a5a 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -697,9 +697,7 @@ static int __devexit p54spi_remove(struct spi_device *spi)
697 697
698static struct spi_driver p54spi_driver = { 698static struct spi_driver p54spi_driver = {
699 .driver = { 699 .driver = {
700 /* use cx3110x name because board-n800.c uses that for the 700 .name = "p54spi",
701 * SPI port */
702 .name = "cx3110x",
703 .bus = &spi_bus_type, 701 .bus = &spi_bus_type,
704 .owner = THIS_MODULE, 702 .owner = THIS_MODULE,
705 }, 703 },
@@ -733,3 +731,4 @@ module_exit(p54spi_exit);
733MODULE_LICENSE("GPL"); 731MODULE_LICENSE("GPL");
734MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); 732MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
735MODULE_ALIAS("spi:cx3110x"); 733MODULE_ALIAS("spi:cx3110x");
734MODULE_ALIAS("spi:p54spi");
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 73073259f508..ad595958b7df 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -69,7 +69,8 @@ static struct usb_device_id p54u_table[] __devinitdata = {
69 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ 69 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
70 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/ 70 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
71 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/ 71 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
72 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ 72 /* {USB_DEVICE(0x0cde, 0x0006)}, * Medion MD40900 already listed above,
73 * just noting it here for clarity */
73 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ 74 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
74 {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */ 75 {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */
75 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ 76 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
@@ -434,10 +435,9 @@ static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
434 u8 *buf; 435 u8 *buf;
435 int ret; 436 int ret;
436 437
437 buf = kmalloc(4, GFP_KERNEL); 438 buf = kmemdup(p54u_romboot_3887, 4, GFP_KERNEL);
438 if (!buf) 439 if (!buf)
439 return -ENOMEM; 440 return -ENOMEM;
440 memcpy(buf, p54u_romboot_3887, 4);
441 ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, 441 ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
442 buf, 4); 442 buf, 4);
443 kfree(buf); 443 kfree(buf);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 8d1190c0f062..236e37526d07 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -2751,14 +2751,9 @@ prism54_hostapd(struct net_device *ndev, struct iw_point *p)
2751 p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) 2751 p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
2752 return -EINVAL; 2752 return -EINVAL;
2753 2753
2754 param = kmalloc(p->length, GFP_KERNEL); 2754 param = memdup_user(p->pointer, p->length);
2755 if (param == NULL) 2755 if (IS_ERR(param))
2756 return -ENOMEM; 2756 return PTR_ERR(param);
2757
2758 if (copy_from_user(param, p->pointer, p->length)) {
2759 kfree(param);
2760 return -EFAULT;
2761 }
2762 2757
2763 switch (param->cmd) { 2758 switch (param->cmd) {
2764 case PRISM2_SET_ENCRYPTION: 2759 case PRISM2_SET_ENCRYPTION:
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 4bd61ee627c0..5e26edb57d82 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -520,8 +520,9 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
520 520
521static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); 521static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed);
522 522
523static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, 523static int rndis_set_tx_power(struct wiphy *wiphy,
524 int dbm); 524 enum nl80211_tx_power_setting type,
525 int mbm);
525static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); 526static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm);
526 527
527static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, 528static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
@@ -1856,20 +1857,25 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1856 return 0; 1857 return 0;
1857} 1858}
1858 1859
1859static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, 1860static int rndis_set_tx_power(struct wiphy *wiphy,
1860 int dbm) 1861 enum nl80211_tx_power_setting type,
1862 int mbm)
1861{ 1863{
1862 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 1864 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
1863 struct usbnet *usbdev = priv->usbdev; 1865 struct usbnet *usbdev = priv->usbdev;
1864 1866
1865 netdev_dbg(usbdev->net, "%s(): type:0x%x dbm:%i\n", 1867 netdev_dbg(usbdev->net, "%s(): type:0x%x mbm:%i\n",
1866 __func__, type, dbm); 1868 __func__, type, mbm);
1869
1870 if (mbm < 0 || (mbm % 100))
1871 return -ENOTSUPP;
1867 1872
1868 /* Device doesn't support changing txpower after initialization, only 1873 /* Device doesn't support changing txpower after initialization, only
1869 * turn off/on radio. Support 'auto' mode and setting same dBm that is 1874 * turn off/on radio. Support 'auto' mode and setting same dBm that is
1870 * currently used. 1875 * currently used.
1871 */ 1876 */
1872 if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) { 1877 if (type == NL80211_TX_POWER_AUTOMATIC ||
1878 MBM_TO_DBM(mbm) == get_bcm4320_power_dbm(priv)) {
1873 if (!priv->radio_on) 1879 if (!priv->radio_on)
1874 disassociate(usbdev, true); /* turn on radio */ 1880 disassociate(usbdev, true); /* turn on radio */
1875 1881
@@ -2495,8 +2501,7 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
2495static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) 2501static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2496{ 2502{
2497 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2503 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2498 struct ndis_80211_assoc_info *info; 2504 struct ndis_80211_assoc_info *info = NULL;
2499 u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32];
2500 u8 bssid[ETH_ALEN]; 2505 u8 bssid[ETH_ALEN];
2501 int resp_ie_len, req_ie_len; 2506 int resp_ie_len, req_ie_len;
2502 u8 *req_ie, *resp_ie; 2507 u8 *req_ie, *resp_ie;
@@ -2515,23 +2520,43 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2515 resp_ie = NULL; 2520 resp_ie = NULL;
2516 2521
2517 if (priv->infra_mode == NDIS_80211_INFRA_INFRA) { 2522 if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
2518 memset(assoc_buf, 0, sizeof(assoc_buf)); 2523 info = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
2519 info = (void *)assoc_buf; 2524 if (!info) {
2525 /* No memory? Try resume work later */
2526 set_bit(WORK_LINK_UP, &priv->work_pending);
2527 queue_work(priv->workqueue, &priv->work);
2528 return;
2529 }
2520 2530
2521 /* Get association info IEs from device and send them back to 2531 /* Get association info IEs from device. */
2522 * userspace. */ 2532 ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE);
2523 ret = get_association_info(usbdev, info, sizeof(assoc_buf));
2524 if (!ret) { 2533 if (!ret) {
2525 req_ie_len = le32_to_cpu(info->req_ie_length); 2534 req_ie_len = le32_to_cpu(info->req_ie_length);
2526 if (req_ie_len > 0) { 2535 if (req_ie_len > 0) {
2527 offset = le32_to_cpu(info->offset_req_ies); 2536 offset = le32_to_cpu(info->offset_req_ies);
2537
2538 if (offset > CONTROL_BUFFER_SIZE)
2539 offset = CONTROL_BUFFER_SIZE;
2540
2528 req_ie = (u8 *)info + offset; 2541 req_ie = (u8 *)info + offset;
2542
2543 if (offset + req_ie_len > CONTROL_BUFFER_SIZE)
2544 req_ie_len =
2545 CONTROL_BUFFER_SIZE - offset;
2529 } 2546 }
2530 2547
2531 resp_ie_len = le32_to_cpu(info->resp_ie_length); 2548 resp_ie_len = le32_to_cpu(info->resp_ie_length);
2532 if (resp_ie_len > 0) { 2549 if (resp_ie_len > 0) {
2533 offset = le32_to_cpu(info->offset_resp_ies); 2550 offset = le32_to_cpu(info->offset_resp_ies);
2551
2552 if (offset > CONTROL_BUFFER_SIZE)
2553 offset = CONTROL_BUFFER_SIZE;
2554
2534 resp_ie = (u8 *)info + offset; 2555 resp_ie = (u8 *)info + offset;
2556
2557 if (offset + resp_ie_len > CONTROL_BUFFER_SIZE)
2558 resp_ie_len =
2559 CONTROL_BUFFER_SIZE - offset;
2535 } 2560 }
2536 } 2561 }
2537 } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC)) 2562 } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC))
@@ -2563,6 +2588,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2563 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) 2588 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2564 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); 2589 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
2565 2590
2591 if (info != NULL)
2592 kfree(info);
2593
2566 priv->connected = true; 2594 priv->connected = true;
2567 memcpy(priv->bssid, bssid, ETH_ALEN); 2595 memcpy(priv->bssid, bssid, ETH_ALEN);
2568 2596
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index ad2c98af7e9d..1eb882e15fb4 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1076,9 +1076,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
1076 struct txentry_desc *txdesc) 1076 struct txentry_desc *txdesc)
1077{ 1077{
1078 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1078 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1079 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1080 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1081 u32 word;
1082 u32 reg; 1079 u32 reg;
1083 1080
1084 /* 1081 /*
@@ -1091,9 +1088,15 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
1091 1088
1092 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 1089 rt2x00queue_map_txskb(rt2x00dev, entry->skb);
1093 1090
1094 rt2x00_desc_read(entry_priv->desc, 1, &word); 1091 /*
1095 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 1092 * Write the TX descriptor for the beacon.
1096 rt2x00_desc_write(entry_priv->desc, 1, word); 1093 */
1094 rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
1095
1096 /*
1097 * Dump beacon to userspace through debugfs.
1098 */
1099 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1097 1100
1098 /* 1101 /*
1099 * Enable beaconing again. 1102 * Enable beaconing again.
@@ -1226,7 +1229,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
1226 } 1229 }
1227 txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); 1230 txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
1228 1231
1229 rt2x00lib_txdone(entry, &txdesc); 1232 rt2x00pci_txdone(entry, &txdesc);
1230 } 1233 }
1231} 1234}
1232 1235
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 41da3d218c65..a29cb212f89a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1233,9 +1233,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
1233 struct txentry_desc *txdesc) 1233 struct txentry_desc *txdesc)
1234{ 1234{
1235 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1235 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1236 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1237 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1238 u32 word;
1239 u32 reg; 1236 u32 reg;
1240 1237
1241 /* 1238 /*
@@ -1248,9 +1245,15 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
1248 1245
1249 rt2x00queue_map_txskb(rt2x00dev, entry->skb); 1246 rt2x00queue_map_txskb(rt2x00dev, entry->skb);
1250 1247
1251 rt2x00_desc_read(entry_priv->desc, 1, &word); 1248 /*
1252 rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 1249 * Write the TX descriptor for the beacon.
1253 rt2x00_desc_write(entry_priv->desc, 1, word); 1250 */
1251 rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
1252
1253 /*
1254 * Dump beacon to userspace through debugfs.
1255 */
1256 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1254 1257
1255 /* 1258 /*
1256 * Enable beaconing again. 1259 * Enable beaconing again.
@@ -1362,7 +1365,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
1362 } 1365 }
1363 txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); 1366 txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
1364 1367
1365 rt2x00lib_txdone(entry, &txdesc); 1368 rt2x00pci_txdone(entry, &txdesc);
1366 } 1369 }
1367} 1370}
1368 1371
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9ae96a626e6d..963238c89080 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -345,9 +345,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
345 struct rt2x00lib_crypto *crypto, 345 struct rt2x00lib_crypto *crypto,
346 struct ieee80211_key_conf *key) 346 struct ieee80211_key_conf *key)
347{ 347{
348 int timeout;
349 u32 mask; 348 u32 mask;
350 u16 reg; 349 u16 reg;
350 enum cipher curr_cipher;
351 351
352 if (crypto->cmd == SET_KEY) { 352 if (crypto->cmd == SET_KEY) {
353 /* 353 /*
@@ -358,6 +358,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
358 mask = TXRX_CSR0_KEY_ID.bit_mask; 358 mask = TXRX_CSR0_KEY_ID.bit_mask;
359 359
360 rt2500usb_register_read(rt2x00dev, TXRX_CSR0, &reg); 360 rt2500usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
361 curr_cipher = rt2x00_get_field16(reg, TXRX_CSR0_ALGORITHM);
361 reg &= mask; 362 reg &= mask;
362 363
363 if (reg && reg == mask) 364 if (reg && reg == mask)
@@ -366,19 +367,17 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
366 reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); 367 reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID);
367 368
368 key->hw_key_idx += reg ? ffz(reg) : 0; 369 key->hw_key_idx += reg ? ffz(reg) : 0;
369
370 /* 370 /*
371 * The encryption key doesn't fit within the CSR cache, 371 * Hardware requires that all keys use the same cipher
372 * this means we should allocate it separately and use 372 * (e.g. TKIP-only, AES-only, but not TKIP+AES).
373 * rt2x00usb_vendor_request() to send the key to the hardware. 373 * If this is not the first key, compare the cipher with the
374 * first one and fall back to SW crypto if not the same.
374 */ 375 */
375 reg = KEY_ENTRY(key->hw_key_idx); 376 if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher)
376 timeout = REGISTER_TIMEOUT32(sizeof(crypto->key)); 377 return -EOPNOTSUPP;
377 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, 378
378 USB_VENDOR_REQUEST_OUT, reg, 379 rt2500usb_register_multiwrite(rt2x00dev, reg,
379 crypto->key, 380 crypto->key, sizeof(crypto->key));
380 sizeof(crypto->key),
381 timeout);
382 381
383 /* 382 /*
384 * The driver does not support the IV/EIV generation 383 * The driver does not support the IV/EIV generation
@@ -1034,7 +1033,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1034 struct txentry_desc *txdesc) 1033 struct txentry_desc *txdesc)
1035{ 1034{
1036 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1035 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1037 __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); 1036 __le32 *txd = (__le32 *) skb->data;
1038 u32 word; 1037 u32 word;
1039 1038
1040 /* 1039 /*
@@ -1080,6 +1079,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1080 /* 1079 /*
1081 * Register descriptor details in skb frame descriptor. 1080 * Register descriptor details in skb frame descriptor.
1082 */ 1081 */
1082 skbdesc->flags |= SKBDESC_DESC_IN_SKB;
1083 skbdesc->desc = txd; 1083 skbdesc->desc = txd;
1084 skbdesc->desc_len = TXD_DESC_SIZE; 1084 skbdesc->desc_len = TXD_DESC_SIZE;
1085} 1085}
@@ -1108,9 +1108,20 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
1108 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); 1108 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
1109 1109
1110 /* 1110 /*
1111 * Take the descriptor in front of the skb into account. 1111 * Add space for the descriptor in front of the skb.
1112 */ 1112 */
1113 skb_push(entry->skb, TXD_DESC_SIZE); 1113 skb_push(entry->skb, TXD_DESC_SIZE);
1114 memset(entry->skb->data, 0, TXD_DESC_SIZE);
1115
1116 /*
1117 * Write the TX descriptor for the beacon.
1118 */
1119 rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
1120
1121 /*
1122 * Dump beacon to userspace through debugfs.
1123 */
1124 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1114 1125
1115 /* 1126 /*
1116 * USB devices cannot blindly pass the skb->len as the 1127 * USB devices cannot blindly pass the skb->len as the
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 2aa03751c341..3ed87badc2d3 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -63,7 +63,6 @@
63 */ 63 */
64#define REV_RT2860C 0x0100 64#define REV_RT2860C 0x0100
65#define REV_RT2860D 0x0101 65#define REV_RT2860D 0x0101
66#define REV_RT2870D 0x0101
67#define REV_RT2872E 0x0200 66#define REV_RT2872E 0x0200
68#define REV_RT3070E 0x0200 67#define REV_RT3070E 0x0200
69#define REV_RT3070F 0x0201 68#define REV_RT3070F 0x0201
@@ -99,6 +98,21 @@
99 */ 98 */
100 99
101/* 100/*
101 * E2PROM_CSR: PCI EEPROM control register.
102 * RELOAD: Write 1 to reload eeprom content.
103 * TYPE: 0: 93c46, 1:93c66.
104 * LOAD_STATUS: 1:loading, 0:done.
105 */
106#define E2PROM_CSR 0x0004
107#define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000001)
108#define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000002)
109#define E2PROM_CSR_DATA_IN FIELD32(0x00000004)
110#define E2PROM_CSR_DATA_OUT FIELD32(0x00000008)
111#define E2PROM_CSR_TYPE FIELD32(0x00000030)
112#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
113#define E2PROM_CSR_RELOAD FIELD32(0x00000080)
114
115/*
102 * OPT_14: Unknown register used by rt3xxx devices. 116 * OPT_14: Unknown register used by rt3xxx devices.
103 */ 117 */
104#define OPT_14_CSR 0x0114 118#define OPT_14_CSR 0x0114
@@ -322,6 +336,39 @@
322#define RX_DRX_IDX 0x029c 336#define RX_DRX_IDX 0x029c
323 337
324/* 338/*
339 * USB_DMA_CFG
340 * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
341 * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
342 * PHY_CLEAR: phy watch dog enable.
343 * TX_CLEAR: Clear USB DMA TX path.
344 * TXOP_HALT: Halt TXOP count down when TX buffer is full.
345 * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
346 * RX_BULK_EN: Enable USB DMA Rx.
347 * TX_BULK_EN: Enable USB DMA Tx.
348 * EP_OUT_VALID: OUT endpoint data valid.
349 * RX_BUSY: USB DMA RX FSM busy.
350 * TX_BUSY: USB DMA TX FSM busy.
351 */
352#define USB_DMA_CFG 0x02a0
353#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff)
354#define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00)
355#define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000)
356#define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000)
357#define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000)
358#define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000)
359#define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000)
360#define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000)
361#define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000)
362#define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000)
363#define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000)
364
365/*
366 * US_CYC_CNT
367 */
368#define US_CYC_CNT 0x02a4
369#define US_CYC_CNT_CLOCK_CYCLE FIELD32(0x000000ff)
370
371/*
325 * PBF_SYS_CTRL 372 * PBF_SYS_CTRL
326 * HOST_RAM_WRITE: enable Host program ram write selection 373 * HOST_RAM_WRITE: enable Host program ram write selection
327 */ 374 */
@@ -1389,6 +1436,10 @@ struct mac_iveiv_entry {
1389#define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e) 1436#define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e)
1390#define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070) 1437#define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070)
1391#define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380) 1438#define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380)
1439#define MAC_WCID_ATTRIBUTE_CIPHER_EXT FIELD32(0x00000400)
1440#define MAC_WCID_ATTRIBUTE_BSS_IDX_EXT FIELD32(0x00000800)
1441#define MAC_WCID_ATTRIBUTE_WAPI_MCBC FIELD32(0x00008000)
1442#define MAC_WCID_ATTRIBUTE_WAPI_KEY_IDX FIELD32(0xff000000)
1392 1443
1393/* 1444/*
1394 * SHARED_KEY_MODE: 1445 * SHARED_KEY_MODE:
@@ -1510,7 +1561,9 @@ struct mac_iveiv_entry {
1510 */ 1561 */
1511 1562
1512/* 1563/*
1513 * BBP 1: TX Antenna 1564 * BBP 1: TX Antenna & Power
1565 * POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm,
1566 * 3 - increase tx power by 6dBm
1514 */ 1567 */
1515#define BBP1_TX_POWER FIELD8(0x07) 1568#define BBP1_TX_POWER FIELD8(0x07)
1516#define BBP1_TX_ANTENNA FIELD8(0x18) 1569#define BBP1_TX_ANTENNA FIELD8(0x18)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index db4250d1c8b3..14c361ae87be 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1,9 +1,9 @@
1/* 1/*
2 Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com>
2 Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> 3 Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
3 Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> 4 Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com>
4 5
5 Based on the original rt2800pci.c and rt2800usb.c. 6 Based on the original rt2800pci.c and rt2800usb.c.
6 Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
7 Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> 7 Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
8 Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> 8 Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
9 Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> 9 Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
@@ -38,16 +38,8 @@
38#include <linux/slab.h> 38#include <linux/slab.h>
39 39
40#include "rt2x00.h" 40#include "rt2x00.h"
41#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
42#include "rt2x00usb.h"
43#endif
44#include "rt2800lib.h" 41#include "rt2800lib.h"
45#include "rt2800.h" 42#include "rt2800.h"
46#include "rt2800usb.h"
47
48MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
49MODULE_DESCRIPTION("rt2800 library");
50MODULE_LICENSE("GPL");
51 43
52/* 44/*
53 * Register access. 45 * Register access.
@@ -282,9 +274,8 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
282} 274}
283EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); 275EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
284 276
285void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc) 277void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
286{ 278{
287 __le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE);
288 u32 word; 279 u32 word;
289 280
290 /* 281 /*
@@ -380,6 +371,67 @@ void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc)
380} 371}
381EXPORT_SYMBOL_GPL(rt2800_process_rxwi); 372EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
382 373
374void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
375{
376 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
377 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
378 unsigned int beacon_base;
379 u32 reg;
380
381 /*
382 * Disable beaconing while we are reloading the beacon data,
383 * otherwise we might be sending out invalid data.
384 */
385 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
386 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
387 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
388
389 /*
390 * Add space for the TXWI in front of the skb.
391 */
392 skb_push(entry->skb, TXWI_DESC_SIZE);
393 memset(entry->skb, 0, TXWI_DESC_SIZE);
394
395 /*
396 * Register descriptor details in skb frame descriptor.
397 */
398 skbdesc->flags |= SKBDESC_DESC_IN_SKB;
399 skbdesc->desc = entry->skb->data;
400 skbdesc->desc_len = TXWI_DESC_SIZE;
401
402 /*
403 * Add the TXWI for the beacon to the skb.
404 */
405 rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
406
407 /*
408 * Dump beacon to userspace through debugfs.
409 */
410 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
411
412 /*
413 * Write entire beacon with TXWI to register.
414 */
415 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
416 rt2800_register_multiwrite(rt2x00dev, beacon_base,
417 entry->skb->data, entry->skb->len);
418
419 /*
420 * Enable beaconing again.
421 */
422 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
423 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
424 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
425 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
426
427 /*
428 * Clean up beacon skb.
429 */
430 dev_kfree_skb_any(entry->skb);
431 entry->skb = NULL;
432}
433EXPORT_SYMBOL(rt2800_write_beacon);
434
383#ifdef CONFIG_RT2X00_LIB_DEBUGFS 435#ifdef CONFIG_RT2X00_LIB_DEBUGFS
384const struct rt2x00debug rt2800_rt2x00debug = { 436const struct rt2x00debug rt2800_rt2x00debug = {
385 .owner = THIS_MODULE, 437 .owner = THIS_MODULE,
@@ -502,15 +554,28 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
502 554
503 offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); 555 offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
504 556
505 rt2800_register_read(rt2x00dev, offset, &reg); 557 if (crypto->cmd == SET_KEY) {
506 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB, 558 rt2800_register_read(rt2x00dev, offset, &reg);
507 !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); 559 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
508 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, 560 !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
509 (crypto->cmd == SET_KEY) * crypto->cipher); 561 /*
510 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, 562 * Both the cipher as the BSS Idx numbers are split in a main
511 (crypto->cmd == SET_KEY) * crypto->bssidx); 563 * value of 3 bits, and a extended field for adding one additional
512 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); 564 * bit to the value.
513 rt2800_register_write(rt2x00dev, offset, reg); 565 */
566 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
567 (crypto->cipher & 0x7));
568 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER_EXT,
569 (crypto->cipher & 0x8) >> 3);
570 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
571 (crypto->bssidx & 0x7));
572 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
573 (crypto->bssidx & 0x8) >> 3);
574 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
575 rt2800_register_write(rt2x00dev, offset, reg);
576 } else {
577 rt2800_register_write(rt2x00dev, offset, 0);
578 }
514 579
515 offset = MAC_IVEIV_ENTRY(key->hw_key_idx); 580 offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
516 581
@@ -1023,7 +1088,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1023 u8 r1; 1088 u8 r1;
1024 1089
1025 rt2800_bbp_read(rt2x00dev, 1, &r1); 1090 rt2800_bbp_read(rt2x00dev, 1, &r1);
1026 rt2x00_set_field8(&reg, BBP1_TX_POWER, 0); 1091 rt2x00_set_field8(&r1, BBP1_TX_POWER, 0);
1027 rt2800_bbp_write(rt2x00dev, 1, r1); 1092 rt2800_bbp_write(rt2x00dev, 1, r1);
1028 1093
1029 rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg); 1094 rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
@@ -1212,6 +1277,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1212 u32 reg; 1277 u32 reg;
1213 u16 eeprom; 1278 u16 eeprom;
1214 unsigned int i; 1279 unsigned int i;
1280 int ret;
1215 1281
1216 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg); 1282 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
1217 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); 1283 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
@@ -1221,59 +1287,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1221 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); 1287 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
1222 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); 1288 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
1223 1289
1224 if (rt2x00_is_usb(rt2x00dev)) { 1290 ret = rt2800_drv_init_registers(rt2x00dev);
1225 /* 1291 if (ret)
1226 * Wait until BBP and RF are ready. 1292 return ret;
1227 */
1228 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
1229 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
1230 if (reg && reg != ~0)
1231 break;
1232 msleep(1);
1233 }
1234
1235 if (i == REGISTER_BUSY_COUNT) {
1236 ERROR(rt2x00dev, "Unstable hardware.\n");
1237 return -EBUSY;
1238 }
1239
1240 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
1241 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
1242 reg & ~0x00002000);
1243 } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
1244 /*
1245 * Reset DMA indexes
1246 */
1247 rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
1248 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
1249 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
1250 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
1251 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
1252 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
1253 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
1254 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
1255 rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
1256
1257 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
1258 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
1259
1260 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
1261 }
1262
1263 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
1264 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
1265 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
1266 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
1267
1268 if (rt2x00_is_usb(rt2x00dev)) {
1269 rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
1270#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
1271 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
1272 USB_MODE_RESET, REGISTER_TIMEOUT);
1273#endif
1274 }
1275
1276 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
1277 1293
1278 rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg); 1294 rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
1279 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */ 1295 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
@@ -1328,7 +1344,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1328 } else { 1344 } else {
1329 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); 1345 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
1330 } 1346 }
1331 rt2800_register_write(rt2x00dev, TX_SW_CFG2, reg);
1332 } else if (rt2x00_rt(rt2x00dev, RT3070)) { 1347 } else if (rt2x00_rt(rt2x00dev, RT3070)) {
1333 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); 1348 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
1334 1349
@@ -1339,6 +1354,10 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1339 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); 1354 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
1340 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); 1355 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
1341 } 1356 }
1357 } else if (rt2800_is_305x_soc(rt2x00dev)) {
1358 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
1359 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
1360 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f);
1342 } else { 1361 } else {
1343 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); 1362 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
1344 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); 1363 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -1560,9 +1579,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1560 rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0); 1579 rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
1561 1580
1562 if (rt2x00_is_usb(rt2x00dev)) { 1581 if (rt2x00_is_usb(rt2x00dev)) {
1563 rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg); 1582 rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg);
1564 rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30); 1583 rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 30);
1565 rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg); 1584 rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
1566 } 1585 }
1567 1586
1568 rt2800_register_read(rt2x00dev, HT_FBK_CFG0, &reg); 1587 rt2800_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
@@ -1706,8 +1725,7 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
1706 rt2800_bbp_write(rt2x00dev, 82, 0x62); 1725 rt2800_bbp_write(rt2x00dev, 82, 0x62);
1707 rt2800_bbp_write(rt2x00dev, 83, 0x6a); 1726 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
1708 1727
1709 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D) || 1728 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
1710 rt2x00_rt_rev(rt2x00dev, RT2870, REV_RT2870D))
1711 rt2800_bbp_write(rt2x00dev, 84, 0x19); 1729 rt2800_bbp_write(rt2x00dev, 84, 0x19);
1712 else 1730 else
1713 rt2800_bbp_write(rt2x00dev, 84, 0x99); 1731 rt2800_bbp_write(rt2x00dev, 84, 0x99);
@@ -2013,8 +2031,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
2013 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || 2031 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
2014 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || 2032 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
2015 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { 2033 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
2016 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); 2034 if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
2017 if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
2018 rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); 2035 rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
2019 } 2036 }
2020 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); 2037 rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
@@ -2147,7 +2164,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
2147 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); 2164 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
2148 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); 2165 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
2149 } else if (rt2x00_rt(rt2x00dev, RT2860) || 2166 } else if (rt2x00_rt(rt2x00dev, RT2860) ||
2150 rt2x00_rt(rt2x00dev, RT2870) ||
2151 rt2x00_rt(rt2x00dev, RT2872)) { 2167 rt2x00_rt(rt2x00dev, RT2872)) {
2152 /* 2168 /*
2153 * There is a max of 2 RX streams for RT28x0 series 2169 * There is a max of 2 RX streams for RT28x0 series
@@ -2251,7 +2267,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
2251 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); 2267 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
2252 2268
2253 if (!rt2x00_rt(rt2x00dev, RT2860) && 2269 if (!rt2x00_rt(rt2x00dev, RT2860) &&
2254 !rt2x00_rt(rt2x00dev, RT2870) &&
2255 !rt2x00_rt(rt2x00dev, RT2872) && 2270 !rt2x00_rt(rt2x00dev, RT2872) &&
2256 !rt2x00_rt(rt2x00dev, RT2883) && 2271 !rt2x00_rt(rt2x00dev, RT2883) &&
2257 !rt2x00_rt(rt2x00dev, RT3070) && 2272 !rt2x00_rt(rt2x00dev, RT3070) &&
@@ -2491,6 +2506,18 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2491 rt2x00_eeprom_addr(rt2x00dev, 2506 rt2x00_eeprom_addr(rt2x00dev,
2492 EEPROM_MAC_ADDR_0)); 2507 EEPROM_MAC_ADDR_0));
2493 2508
2509 /*
2510 * As rt2800 has a global fallback table we cannot specify
2511 * more then one tx rate per frame but since the hw will
2512 * try several rates (based on the fallback table) we should
2513 * still initialize max_rates to the maximum number of rates
2514 * we are going to try. Otherwise mac80211 will truncate our
2515 * reported tx rates and the rc algortihm will end up with
2516 * incorrect data.
2517 */
2518 rt2x00dev->hw->max_rates = 7;
2519 rt2x00dev->hw->max_rate_tries = 1;
2520
2494 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 2521 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
2495 2522
2496 /* 2523 /*
@@ -2528,16 +2555,16 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2528 else 2555 else
2529 spec->ht.ht_supported = false; 2556 spec->ht.ht_supported = false;
2530 2557
2531 /*
2532 * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes
2533 * reception problems with HT40 capable 11n APs
2534 */
2535 spec->ht.cap = 2558 spec->ht.cap =
2559 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2536 IEEE80211_HT_CAP_GRN_FLD | 2560 IEEE80211_HT_CAP_GRN_FLD |
2537 IEEE80211_HT_CAP_SGI_20 | 2561 IEEE80211_HT_CAP_SGI_20 |
2538 IEEE80211_HT_CAP_SGI_40 | 2562 IEEE80211_HT_CAP_SGI_40 |
2539 IEEE80211_HT_CAP_TX_STBC |
2540 IEEE80211_HT_CAP_RX_STBC; 2563 IEEE80211_HT_CAP_RX_STBC;
2564
2565 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2)
2566 spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC;
2567
2541 spec->ht.ampdu_factor = 3; 2568 spec->ht.ampdu_factor = 3;
2542 spec->ht.ampdu_density = 4; 2569 spec->ht.ampdu_density = 4;
2543 spec->ht.mcs.tx_params = 2570 spec->ht.mcs.tx_params =
@@ -2743,3 +2770,8 @@ const struct ieee80211_ops rt2800_mac80211_ops = {
2743 .rfkill_poll = rt2x00mac_rfkill_poll, 2770 .rfkill_poll = rt2x00mac_rfkill_poll,
2744}; 2771};
2745EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); 2772EXPORT_SYMBOL_GPL(rt2800_mac80211_ops);
2773
2774MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz");
2775MODULE_VERSION(DRV_VERSION);
2776MODULE_DESCRIPTION("Ralink RT2800 library");
2777MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 94de999e2290..8313dbf441a5 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -40,6 +40,8 @@ struct rt2800_ops {
40 int (*regbusy_read)(struct rt2x00_dev *rt2x00dev, 40 int (*regbusy_read)(struct rt2x00_dev *rt2x00dev,
41 const unsigned int offset, 41 const unsigned int offset,
42 const struct rt2x00_field32 field, u32 *reg); 42 const struct rt2x00_field32 field, u32 *reg);
43
44 int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
43}; 45};
44 46
45static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, 47static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
@@ -107,13 +109,22 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev,
107 return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); 109 return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg);
108} 110}
109 111
112static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev)
113{
114 const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
115
116 return rt2800ops->drv_init_registers(rt2x00dev);
117}
118
110void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, 119void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
111 const u8 command, const u8 token, 120 const u8 command, const u8 token,
112 const u8 arg0, const u8 arg1); 121 const u8 arg0, const u8 arg1);
113 122
114void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc); 123void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc);
115void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc); 124void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc);
116 125
126void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
127
117extern const struct rt2x00debug rt2800_rt2x00debug; 128extern const struct rt2x00debug rt2800_rt2x00debug;
118 129
119int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev); 130int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b2f23272c3aa..e5ea670a18db 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -51,7 +51,7 @@
51/* 51/*
52 * Allow hardware encryption to be disabled. 52 * Allow hardware encryption to be disabled.
53 */ 53 */
54static int modparam_nohwcrypt = 1; 54static int modparam_nohwcrypt = 0;
55module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 55module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
56MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 56MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
57 57
@@ -446,6 +446,38 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
446 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); 446 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
447} 447}
448 448
449static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
450{
451 u32 reg;
452
453 /*
454 * Reset DMA indexes
455 */
456 rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
457 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
458 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
459 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
460 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
461 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
462 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
463 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
464 rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
465
466 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
467 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
468
469 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
470
471 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
472 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
473 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
474 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
475
476 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
477
478 return 0;
479}
480
449static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) 481static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
450{ 482{
451 u32 reg; 483 u32 reg;
@@ -465,7 +497,7 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
465 /* 497 /*
466 * Send signal to firmware during boot time. 498 * Send signal to firmware during boot time.
467 */ 499 */
468 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); 500 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
469 501
470 /* 502 /*
471 * Enable RX. 503 * Enable RX.
@@ -613,18 +645,10 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
613/* 645/*
614 * TX descriptor initialization 646 * TX descriptor initialization
615 */ 647 */
616static int rt2800pci_write_tx_data(struct queue_entry* entry, 648static void rt2800pci_write_tx_datadesc(struct queue_entry* entry,
617 struct txentry_desc *txdesc) 649 struct txentry_desc *txdesc)
618{ 650{
619 int ret; 651 rt2800_write_txwi((__le32 *) entry->skb->data, txdesc);
620
621 ret = rt2x00pci_write_tx_data(entry, txdesc);
622 if (ret)
623 return ret;
624
625 rt2800_write_txwi(entry->skb, txdesc);
626
627 return 0;
628} 652}
629 653
630 654
@@ -684,49 +708,6 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
684/* 708/*
685 * TX data initialization 709 * TX data initialization
686 */ 710 */
687static void rt2800pci_write_beacon(struct queue_entry *entry,
688 struct txentry_desc *txdesc)
689{
690 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
691 unsigned int beacon_base;
692 u32 reg;
693
694 /*
695 * Disable beaconing while we are reloading the beacon data,
696 * otherwise we might be sending out invalid data.
697 */
698 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
699 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
700 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
701
702 /*
703 * Add the TXWI for the beacon to the skb.
704 */
705 rt2800_write_txwi(entry->skb, txdesc);
706 skb_push(entry->skb, TXWI_DESC_SIZE);
707
708 /*
709 * Write entire beacon with TXWI to register.
710 */
711 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
712 rt2800_register_multiwrite(rt2x00dev, beacon_base,
713 entry->skb->data, entry->skb->len);
714
715 /*
716 * Enable beaconing again.
717 */
718 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
719 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
720 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
721 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
722
723 /*
724 * Clean up beacon skb.
725 */
726 dev_kfree_skb_any(entry->skb);
727 entry->skb = NULL;
728}
729
730static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, 711static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
731 const enum data_queue_qid queue_idx) 712 const enum data_queue_qid queue_idx)
732{ 713{
@@ -832,29 +813,24 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
832 struct txdone_entry_desc txdesc; 813 struct txdone_entry_desc txdesc;
833 u32 word; 814 u32 word;
834 u32 reg; 815 u32 reg;
835 u32 old_reg;
836 int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; 816 int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
837 u16 mcs, real_mcs; 817 u16 mcs, real_mcs;
818 int i;
838 819
839 /* 820 /*
840 * During each loop we will compare the freshly read 821 * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
841 * TX_STA_FIFO register value with the value read from 822 * at most X times and also stop processing once the TX_STA_FIFO_VALID
842 * the previous loop. If the 2 values are equal then 823 * flag is not set anymore.
843 * we should stop processing because the chance it 824 *
844 * quite big that the device has been unplugged and 825 * The legacy drivers use X=TX_RING_SIZE but state in a comment
845 * we risk going into an endless loop. 826 * that the TX_STA_FIFO stack has a size of 16. We stick to our
827 * tx ring size for now.
846 */ 828 */
847 old_reg = 0; 829 for (i = 0; i < TX_ENTRIES; i++) {
848
849 while (1) {
850 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg); 830 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
851 if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) 831 if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
852 break; 832 break;
853 833
854 if (old_reg == reg)
855 break;
856 old_reg = reg;
857
858 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); 834 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
859 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); 835 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
860 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); 836 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
@@ -880,8 +856,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
880 856
881 /* Check if we got a match by looking at WCID/ACK/PID 857 /* Check if we got a match by looking at WCID/ACK/PID
882 * fields */ 858 * fields */
883 txwi = (__le32 *)(entry->skb->data - 859 txwi = (__le32 *) entry->skb->data;
884 rt2x00dev->ops->extra_tx_headroom);
885 860
886 rt2x00_desc_read(txwi, 1, &word); 861 rt2x00_desc_read(txwi, 1, &word);
887 tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); 862 tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
@@ -923,10 +898,14 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
923 txdesc.retry = 7; 898 txdesc.retry = 7;
924 } 899 }
925 900
926 __set_bit(TXDONE_FALLBACK, &txdesc.flags); 901 /*
927 902 * the frame was retried at least once
903 * -> hw used fallback rates
904 */
905 if (txdesc.retry)
906 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
928 907
929 rt2x00lib_txdone(entry, &txdesc); 908 rt2x00pci_txdone(entry, &txdesc);
930 } 909 }
931} 910}
932 911
@@ -996,6 +975,8 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
996 .register_multiwrite = rt2x00pci_register_multiwrite, 975 .register_multiwrite = rt2x00pci_register_multiwrite,
997 976
998 .regbusy_read = rt2x00pci_regbusy_read, 977 .regbusy_read = rt2x00pci_regbusy_read,
978
979 .drv_init_registers = rt2800pci_init_registers,
999}; 980};
1000 981
1001static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) 982static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1063,8 +1044,9 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
1063 .reset_tuner = rt2800_reset_tuner, 1044 .reset_tuner = rt2800_reset_tuner,
1064 .link_tuner = rt2800_link_tuner, 1045 .link_tuner = rt2800_link_tuner,
1065 .write_tx_desc = rt2800pci_write_tx_desc, 1046 .write_tx_desc = rt2800pci_write_tx_desc,
1066 .write_tx_data = rt2800pci_write_tx_data, 1047 .write_tx_data = rt2x00pci_write_tx_data,
1067 .write_beacon = rt2800pci_write_beacon, 1048 .write_tx_datadesc = rt2800pci_write_tx_datadesc,
1049 .write_beacon = rt2800_write_beacon,
1068 .kick_tx_queue = rt2800pci_kick_tx_queue, 1050 .kick_tx_queue = rt2800pci_kick_tx_queue,
1069 .kill_tx_queue = rt2800pci_kill_tx_queue, 1051 .kill_tx_queue = rt2800pci_kill_tx_queue,
1070 .fill_rxdone = rt2800pci_fill_rxdone, 1052 .fill_rxdone = rt2800pci_fill_rxdone,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index afc8e7da27cb..5a8dda9b5b5a 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -35,25 +35,6 @@
35#define RT2800PCI_H 35#define RT2800PCI_H
36 36
37/* 37/*
38 * PCI registers.
39 */
40
41/*
42 * E2PROM_CSR: EEPROM control register.
43 * RELOAD: Write 1 to reload eeprom content.
44 * TYPE: 0: 93c46, 1:93c66.
45 * LOAD_STATUS: 1:loading, 0:done.
46 */
47#define E2PROM_CSR 0x0004
48#define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000001)
49#define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000002)
50#define E2PROM_CSR_DATA_IN FIELD32(0x00000004)
51#define E2PROM_CSR_DATA_OUT FIELD32(0x00000008)
52#define E2PROM_CSR_TYPE FIELD32(0x00000030)
53#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
54#define E2PROM_CSR_RELOAD FIELD32(0x00000080)
55
56/*
57 * Queue register offset macros 38 * Queue register offset macros
58 */ 39 */
59#define TX_QUEUE_REG_OFFSET 0x10 40#define TX_QUEUE_REG_OFFSET 0x10
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 0f8b84b7224c..f18c12a19cc9 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -45,7 +45,7 @@
45/* 45/*
46 * Allow hardware encryption to be disabled. 46 * Allow hardware encryption to be disabled.
47 */ 47 */
48static int modparam_nohwcrypt = 1; 48static int modparam_nohwcrypt = 0;
49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
51 51
@@ -169,11 +169,8 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
169 /* 169 /*
170 * Write firmware to device. 170 * Write firmware to device.
171 */ 171 */
172 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, 172 rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
173 USB_VENDOR_REQUEST_OUT, 173 data + offset, length);
174 FIRMWARE_IMAGE_BASE,
175 data + offset, length,
176 REGISTER_TIMEOUT32(length));
177 174
178 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); 175 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
179 rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); 176 rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
@@ -196,7 +193,7 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
196 /* 193 /*
197 * Send signal to firmware during boot time. 194 * Send signal to firmware during boot time.
198 */ 195 */
199 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); 196 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
200 197
201 if (rt2x00_rt(rt2x00dev, RT3070) || 198 if (rt2x00_rt(rt2x00dev, RT3070) ||
202 rt2x00_rt(rt2x00dev, RT3071) || 199 rt2x00_rt(rt2x00dev, RT3071) ||
@@ -246,6 +243,44 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
246 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 243 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
247} 244}
248 245
246static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
247{
248 u32 reg;
249 int i;
250
251 /*
252 * Wait until BBP and RF are ready.
253 */
254 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
255 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
256 if (reg && reg != ~0)
257 break;
258 msleep(1);
259 }
260
261 if (i == REGISTER_BUSY_COUNT) {
262 ERROR(rt2x00dev, "Unstable hardware.\n");
263 return -EBUSY;
264 }
265
266 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
267 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
268
269 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
270 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
271 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
272 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
273
274 rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
275
276 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
277 USB_MODE_RESET, REGISTER_TIMEOUT);
278
279 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
280
281 return 0;
282}
283
249static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) 284static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
250{ 285{
251 u32 reg; 286 u32 reg;
@@ -400,20 +435,21 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
400 struct txentry_desc *txdesc) 435 struct txentry_desc *txdesc)
401{ 436{
402 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 437 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
403 __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE); 438 __le32 *txi = (__le32 *) skb->data;
439 __le32 *txwi = (__le32 *) (skb->data + TXINFO_DESC_SIZE);
404 u32 word; 440 u32 word;
405 441
406 /* 442 /*
407 * Initialize TXWI descriptor 443 * Initialize TXWI descriptor
408 */ 444 */
409 rt2800_write_txwi(skb, txdesc); 445 rt2800_write_txwi(txwi, txdesc);
410 446
411 /* 447 /*
412 * Initialize TXINFO descriptor 448 * Initialize TXINFO descriptor
413 */ 449 */
414 rt2x00_desc_read(txi, 0, &word); 450 rt2x00_desc_read(txi, 0, &word);
415 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, 451 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
416 skb->len + TXWI_DESC_SIZE); 452 skb->len - TXINFO_DESC_SIZE);
417 rt2x00_set_field32(&word, TXINFO_W0_WIV, 453 rt2x00_set_field32(&word, TXINFO_W0_WIV,
418 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); 454 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
419 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); 455 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
@@ -426,6 +462,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
426 /* 462 /*
427 * Register descriptor details in skb frame descriptor. 463 * Register descriptor details in skb frame descriptor.
428 */ 464 */
465 skbdesc->flags |= SKBDESC_DESC_IN_SKB;
429 skbdesc->desc = txi; 466 skbdesc->desc = txi;
430 skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; 467 skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
431} 468}
@@ -433,51 +470,6 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
433/* 470/*
434 * TX data initialization 471 * TX data initialization
435 */ 472 */
436static void rt2800usb_write_beacon(struct queue_entry *entry,
437 struct txentry_desc *txdesc)
438{
439 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
440 unsigned int beacon_base;
441 u32 reg;
442
443 /*
444 * Disable beaconing while we are reloading the beacon data,
445 * otherwise we might be sending out invalid data.
446 */
447 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
448 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
449 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
450
451 /*
452 * Add the TXWI for the beacon to the skb.
453 */
454 rt2800_write_txwi(entry->skb, txdesc);
455 skb_push(entry->skb, TXWI_DESC_SIZE);
456
457 /*
458 * Write entire beacon with descriptor to register.
459 */
460 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
461 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
462 USB_VENDOR_REQUEST_OUT, beacon_base,
463 entry->skb->data, entry->skb->len,
464 REGISTER_TIMEOUT32(entry->skb->len));
465
466 /*
467 * Enable beaconing again.
468 */
469 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
470 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
471 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
472 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
473
474 /*
475 * Clean up the beacon skb.
476 */
477 dev_kfree_skb(entry->skb);
478 entry->skb = NULL;
479}
480
481static int rt2800usb_get_tx_data_len(struct queue_entry *entry) 473static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
482{ 474{
483 int length; 475 int length;
@@ -595,6 +587,8 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
595 .register_multiwrite = rt2x00usb_register_multiwrite, 587 .register_multiwrite = rt2x00usb_register_multiwrite,
596 588
597 .regbusy_read = rt2x00usb_regbusy_read, 589 .regbusy_read = rt2x00usb_regbusy_read,
590
591 .drv_init_registers = rt2800usb_init_registers,
598}; 592};
599 593
600static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) 594static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -659,7 +653,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
659 .link_tuner = rt2800_link_tuner, 653 .link_tuner = rt2800_link_tuner,
660 .write_tx_desc = rt2800usb_write_tx_desc, 654 .write_tx_desc = rt2800usb_write_tx_desc,
661 .write_tx_data = rt2x00usb_write_tx_data, 655 .write_tx_data = rt2x00usb_write_tx_data,
662 .write_beacon = rt2800usb_write_beacon, 656 .write_beacon = rt2800_write_beacon,
663 .get_tx_data_len = rt2800usb_get_tx_data_len, 657 .get_tx_data_len = rt2800usb_get_tx_data_len,
664 .kick_tx_queue = rt2x00usb_kick_tx_queue, 658 .kick_tx_queue = rt2x00usb_kick_tx_queue,
665 .kill_tx_queue = rt2x00usb_kill_tx_queue, 659 .kill_tx_queue = rt2x00usb_kill_tx_queue,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 2bca6a71a7f5..0722badccf86 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -32,43 +32,6 @@
32#define RT2800USB_H 32#define RT2800USB_H
33 33
34/* 34/*
35 * USB registers.
36 */
37
38/*
39 * USB_DMA_CFG
40 * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
41 * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
42 * PHY_CLEAR: phy watch dog enable.
43 * TX_CLEAR: Clear USB DMA TX path.
44 * TXOP_HALT: Halt TXOP count down when TX buffer is full.
45 * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
46 * RX_BULK_EN: Enable USB DMA Rx.
47 * TX_BULK_EN: Enable USB DMA Tx.
48 * EP_OUT_VALID: OUT endpoint data valid.
49 * RX_BUSY: USB DMA RX FSM busy.
50 * TX_BUSY: USB DMA TX FSM busy.
51 */
52#define USB_DMA_CFG 0x02a0
53#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff)
54#define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00)
55#define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000)
56#define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000)
57#define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000)
58#define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000)
59#define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000)
60#define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000)
61#define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000)
62#define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000)
63#define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000)
64
65/*
66 * USB_CYC_CFG
67 */
68#define USB_CYC_CFG 0x02a4
69#define USB_CYC_CFG_CLOCK_CYCLE FIELD32(0x000000ff)
70
71/*
72 * 8051 firmware image. 35 * 8051 firmware image.
73 */ 36 */
74#define FIRMWARE_RT2870 "rt2870.bin" 37#define FIRMWARE_RT2870 "rt2870.bin"
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 6c1ff4c15c84..e7acc6abfd89 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -39,6 +39,7 @@
39#include <net/mac80211.h> 39#include <net/mac80211.h>
40 40
41#include "rt2x00debug.h" 41#include "rt2x00debug.h"
42#include "rt2x00dump.h"
42#include "rt2x00leds.h" 43#include "rt2x00leds.h"
43#include "rt2x00reg.h" 44#include "rt2x00reg.h"
44#include "rt2x00queue.h" 45#include "rt2x00queue.h"
@@ -159,6 +160,7 @@ struct avg_val {
159 160
160enum rt2x00_chip_intf { 161enum rt2x00_chip_intf {
161 RT2X00_CHIP_INTF_PCI, 162 RT2X00_CHIP_INTF_PCI,
163 RT2X00_CHIP_INTF_PCIE,
162 RT2X00_CHIP_INTF_USB, 164 RT2X00_CHIP_INTF_USB,
163 RT2X00_CHIP_INTF_SOC, 165 RT2X00_CHIP_INTF_SOC,
164}; 166};
@@ -175,8 +177,7 @@ struct rt2x00_chip {
175#define RT2570 0x2570 177#define RT2570 0x2570
176#define RT2661 0x2661 178#define RT2661 0x2661
177#define RT2573 0x2573 179#define RT2573 0x2573
178#define RT2860 0x2860 /* 2.4GHz PCI/CB */ 180#define RT2860 0x2860 /* 2.4GHz */
179#define RT2870 0x2870
180#define RT2872 0x2872 /* WSOC */ 181#define RT2872 0x2872 /* WSOC */
181#define RT2883 0x2883 /* WSOC */ 182#define RT2883 0x2883 /* WSOC */
182#define RT3070 0x3070 183#define RT3070 0x3070
@@ -551,6 +552,8 @@ struct rt2x00lib_ops {
551 struct txentry_desc *txdesc); 552 struct txentry_desc *txdesc);
552 int (*write_tx_data) (struct queue_entry *entry, 553 int (*write_tx_data) (struct queue_entry *entry,
553 struct txentry_desc *txdesc); 554 struct txentry_desc *txdesc);
555 void (*write_tx_datadesc) (struct queue_entry *entry,
556 struct txentry_desc *txdesc);
554 void (*write_beacon) (struct queue_entry *entry, 557 void (*write_beacon) (struct queue_entry *entry,
555 struct txentry_desc *txdesc); 558 struct txentry_desc *txdesc);
556 int (*get_tx_data_len) (struct queue_entry *entry); 559 int (*get_tx_data_len) (struct queue_entry *entry);
@@ -978,7 +981,13 @@ static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev,
978 981
979static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev) 982static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev)
980{ 983{
981 return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); 984 return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI) ||
985 rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
986}
987
988static inline bool rt2x00_is_pcie(struct rt2x00_dev *rt2x00dev)
989{
990 return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
982} 991}
983 992
984static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev) 993static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev)
@@ -999,6 +1008,13 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
999void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 1008void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
1000 1009
1001/** 1010/**
1011 * rt2x00queue_unmap_skb - Unmap a skb from DMA.
1012 * @rt2x00dev: Pointer to &struct rt2x00_dev.
1013 * @skb: The skb to unmap.
1014 */
1015void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
1016
1017/**
1002 * rt2x00queue_get_queue - Convert queue index to queue pointer 1018 * rt2x00queue_get_queue - Convert queue index to queue pointer
1003 * @rt2x00dev: Pointer to &struct rt2x00_dev. 1019 * @rt2x00dev: Pointer to &struct rt2x00_dev.
1004 * @queue: rt2x00 queue index (see &enum data_queue_qid). 1020 * @queue: rt2x00 queue index (see &enum data_queue_qid).
@@ -1015,6 +1031,26 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
1015 enum queue_index index); 1031 enum queue_index index);
1016 1032
1017/* 1033/*
1034 * Debugfs handlers.
1035 */
1036/**
1037 * rt2x00debug_dump_frame - Dump a frame to userspace through debugfs.
1038 * @rt2x00dev: Pointer to &struct rt2x00_dev.
1039 * @type: The type of frame that is being dumped.
1040 * @skb: The skb containing the frame to be dumped.
1041 */
1042#ifdef CONFIG_RT2X00_LIB_DEBUGFS
1043void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
1044 enum rt2x00_dump_type type, struct sk_buff *skb);
1045#else
1046static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
1047 enum rt2x00_dump_type type,
1048 struct sk_buff *skb)
1049{
1050}
1051#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
1052
1053/*
1018 * Interrupt context handlers. 1054 * Interrupt context handlers.
1019 */ 1055 */
1020void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); 1056void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 098315a271ca..8dbd634dae27 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -170,23 +170,27 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
170 unsigned int ieee80211_flags) 170 unsigned int ieee80211_flags)
171{ 171{
172 struct rt2x00lib_conf libconf; 172 struct rt2x00lib_conf libconf;
173 u16 hw_value;
173 174
174 memset(&libconf, 0, sizeof(libconf)); 175 memset(&libconf, 0, sizeof(libconf));
175 176
176 libconf.conf = conf; 177 libconf.conf = conf;
177 178
178 if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { 179 if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
179 if (conf_is_ht40(conf)) 180 if (conf_is_ht40(conf)) {
180 __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); 181 __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
181 else 182 hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
183 } else {
182 __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); 184 __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
185 hw_value = conf->channel->hw_value;
186 }
183 187
184 memcpy(&libconf.rf, 188 memcpy(&libconf.rf,
185 &rt2x00dev->spec.channels[conf->channel->hw_value], 189 &rt2x00dev->spec.channels[hw_value],
186 sizeof(libconf.rf)); 190 sizeof(libconf.rf));
187 191
188 memcpy(&libconf.channel, 192 memcpy(&libconf.channel,
189 &rt2x00dev->spec.channels_info[conf->channel->hw_value], 193 &rt2x00dev->spec.channels_info[hw_value],
190 sizeof(libconf.channel)); 194 sizeof(libconf.channel));
191 } 195 }
192 196
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index e9fe93fd8042..b0498e7e7aae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -211,6 +211,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
211 if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) 211 if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
212 skb_queue_purge(&intf->frame_dump_skbqueue); 212 skb_queue_purge(&intf->frame_dump_skbqueue);
213} 213}
214EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame);
214 215
215static int rt2x00debug_file_open(struct inode *inode, struct file *file) 216static int rt2x00debug_file_open(struct inode *inode, struct file *file)
216{ 217{
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 3ae468c4d760..339cc84bf4fb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -211,11 +211,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
211 bool success; 211 bool success;
212 212
213 /* 213 /*
214 * Unmap the skb.
215 */
216 rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
217
218 /*
219 * Remove L2 padding which was added during 214 * Remove L2 padding which was added during
220 */ 215 */
221 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) 216 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
@@ -224,7 +219,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
224 /* 219 /*
225 * If the IV/EIV data was stripped from the frame before it was 220 * If the IV/EIV data was stripped from the frame before it was
226 * passed to the hardware, we should now reinsert it again because 221 * passed to the hardware, we should now reinsert it again because
227 * mac80211 will expect the the same data to be present it the 222 * mac80211 will expect the same data to be present it the
228 * frame as it was passed to us. 223 * frame as it was passed to us.
229 */ 224 */
230 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) 225 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
@@ -241,8 +236,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
241 */ 236 */
242 success = 237 success =
243 test_bit(TXDONE_SUCCESS, &txdesc->flags) || 238 test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
244 test_bit(TXDONE_UNKNOWN, &txdesc->flags) || 239 test_bit(TXDONE_UNKNOWN, &txdesc->flags);
245 test_bit(TXDONE_FALLBACK, &txdesc->flags);
246 240
247 /* 241 /*
248 * Update TX statistics. 242 * Update TX statistics.
@@ -264,11 +258,22 @@ void rt2x00lib_txdone(struct queue_entry *entry,
264 /* 258 /*
265 * Frame was send with retries, hardware tried 259 * Frame was send with retries, hardware tried
266 * different rates to send out the frame, at each 260 * different rates to send out the frame, at each
267 * retry it lowered the rate 1 step. 261 * retry it lowered the rate 1 step except when the
262 * lowest rate was used.
268 */ 263 */
269 for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) { 264 for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
270 tx_info->status.rates[i].idx = rate_idx - i; 265 tx_info->status.rates[i].idx = rate_idx - i;
271 tx_info->status.rates[i].flags = rate_flags; 266 tx_info->status.rates[i].flags = rate_flags;
267
268 if (rate_idx - i == 0) {
269 /*
270 * The lowest rate (index 0) was used until the
271 * number of max retries was reached.
272 */
273 tx_info->status.rates[i].count = retry_rates - i;
274 i++;
275 break;
276 }
272 tx_info->status.rates[i].count = 1; 277 tx_info->status.rates[i].count = 1;
273 } 278 }
274 if (i < (IEEE80211_TX_MAX_RATES - 1)) 279 if (i < (IEEE80211_TX_MAX_RATES - 1))
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h
index ed303b423e41..6df2e0b746b8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dump.h
+++ b/drivers/net/wireless/rt2x00/rt2x00dump.h
@@ -20,7 +20,12 @@
20 20
21/* 21/*
22 Module: rt2x00dump 22 Module: rt2x00dump
23 Abstract: Data structures for the rt2x00debug & userspace. 23 Abstract:
24 Data structures for the rt2x00debug & userspace.
25
26 The declarations in this file can be used by both rt2x00
27 and userspace and therefore should be kept together in
28 this file.
24 */ 29 */
25 30
26#ifndef RT2X00DUMP_H 31#ifndef RT2X00DUMP_H
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index 5a407602ce3e..c004cd3a8847 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -44,11 +44,22 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
44 txdesc->mpdu_density = 0; 44 txdesc->mpdu_density = 0;
45 45
46 txdesc->ba_size = 7; /* FIXME: What value is needed? */ 46 txdesc->ba_size = 7; /* FIXME: What value is needed? */
47 txdesc->stbc = 0; /* FIXME: What value is needed? */
48 47
49 txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); 48 txdesc->stbc =
50 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) 49 (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT;
51 txdesc->mcs |= 0x08; 50
51 /*
52 * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the
53 * mcs rate to be used
54 */
55 if (txrate->flags & IEEE80211_TX_RC_MCS) {
56 txdesc->mcs = txrate->idx;
57 } else {
58 txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
59 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
60 txdesc->mcs |= 0x08;
61 }
62
52 63
53 /* 64 /*
54 * Convert flags 65 * Convert flags
@@ -84,3 +95,31 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
84 else 95 else
85 txdesc->txop = TXOP_HTTXOP; 96 txdesc->txop = TXOP_HTTXOP;
86} 97}
98
99u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
100 struct ieee80211_conf *conf)
101{
102 struct hw_mode_spec *spec = &rt2x00dev->spec;
103 int center_channel;
104 u16 i;
105
106 /*
107 * Initialize center channel to current channel.
108 */
109 center_channel = spec->channels[conf->channel->hw_value].channel;
110
111 /*
112 * Adjust center channel to HT40+ and HT40- operation.
113 */
114 if (conf_is_ht40_plus(conf))
115 center_channel += 2;
116 else if (conf_is_ht40_minus(conf))
117 center_channel -= (center_channel == 14) ? 1 : 2;
118
119 for (i = 0; i < spec->num_channels; i++)
120 if (spec->channels[i].channel == center_channel)
121 return i;
122
123 WARN_ON(1);
124 return conf->channel->hw_value;
125}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index be2e37fb4071..ed27de1de57b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -27,8 +27,6 @@
27#ifndef RT2X00LIB_H 27#ifndef RT2X00LIB_H
28#define RT2X00LIB_H 28#define RT2X00LIB_H
29 29
30#include "rt2x00dump.h"
31
32/* 30/*
33 * Interval defines 31 * Interval defines
34 */ 32 */
@@ -107,13 +105,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
107 struct queue_entry *entry); 105 struct queue_entry *entry);
108 106
109/** 107/**
110 * rt2x00queue_unmap_skb - Unmap a skb from DMA.
111 * @rt2x00dev: Pointer to &struct rt2x00_dev.
112 * @skb: The skb to unmap.
113 */
114void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
115
116/**
117 * rt2x00queue_free_skb - free a skb 108 * rt2x00queue_free_skb - free a skb
118 * @rt2x00dev: Pointer to &struct rt2x00_dev. 109 * @rt2x00dev: Pointer to &struct rt2x00_dev.
119 * @skb: The skb to free. 110 * @skb: The skb to free.
@@ -296,8 +287,6 @@ static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
296#ifdef CONFIG_RT2X00_LIB_DEBUGFS 287#ifdef CONFIG_RT2X00_LIB_DEBUGFS
297void rt2x00debug_register(struct rt2x00_dev *rt2x00dev); 288void rt2x00debug_register(struct rt2x00_dev *rt2x00dev);
298void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); 289void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
299void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
300 enum rt2x00_dump_type type, struct sk_buff *skb);
301void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, 290void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
302 struct rxdone_entry_desc *rxdesc); 291 struct rxdone_entry_desc *rxdesc);
303#else 292#else
@@ -309,12 +298,6 @@ static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
309{ 298{
310} 299}
311 300
312static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
313 enum rt2x00_dump_type type,
314 struct sk_buff *skb)
315{
316}
317
318static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, 301static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
319 struct rxdone_entry_desc *rxdesc) 302 struct rxdone_entry_desc *rxdesc)
320{ 303{
@@ -384,12 +367,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
384void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, 367void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
385 struct txentry_desc *txdesc, 368 struct txentry_desc *txdesc,
386 const struct rt2x00_rate *hwrate); 369 const struct rt2x00_rate *hwrate);
370
371u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
372 struct ieee80211_conf *conf);
387#else 373#else
388static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, 374static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
389 struct txentry_desc *txdesc, 375 struct txentry_desc *txdesc,
390 const struct rt2x00_rate *hwrate) 376 const struct rt2x00_rate *hwrate)
391{ 377{
392} 378}
379
380static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
381 struct ieee80211_conf *conf)
382{
383 return conf->channel->hw_value;
384}
393#endif /* CONFIG_RT2X00_LIB_HT */ 385#endif /* CONFIG_RT2X00_LIB_HT */
394 386
395/* 387/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index f71eee67f977..10eaffd12b1b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -81,6 +81,24 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry,
81 return -EINVAL; 81 return -EINVAL;
82 } 82 }
83 83
84 /*
85 * Add the requested extra tx headroom in front of the skb.
86 */
87 skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom);
88 memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom);
89
90 /*
91 * Call the driver's write_tx_datadesc function, if it exists.
92 */
93 if (rt2x00dev->ops->lib->write_tx_datadesc)
94 rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc);
95
96 /*
97 * Map the skb to DMA.
98 */
99 if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
100 rt2x00queue_map_txskb(rt2x00dev, entry->skb);
101
84 return 0; 102 return 0;
85} 103}
86EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); 104EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
@@ -88,6 +106,34 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
88/* 106/*
89 * TX/RX data handlers. 107 * TX/RX data handlers.
90 */ 108 */
109void rt2x00pci_txdone(struct queue_entry *entry,
110 struct txdone_entry_desc *txdesc)
111{
112 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
113 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
114
115 /*
116 * Unmap the skb.
117 */
118 rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
119
120 /*
121 * Remove the extra tx headroom from the skb.
122 */
123 skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
124
125 /*
126 * Signal that the TX descriptor is no longer in the skb.
127 */
128 skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
129
130 /*
131 * Pass on to rt2x00lib.
132 */
133 rt2x00lib_txdone(entry, txdesc);
134}
135EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
136
91void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) 137void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
92{ 138{
93 struct data_queue *queue = rt2x00dev->rx; 139 struct data_queue *queue = rt2x00dev->rx;
@@ -305,7 +351,10 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
305 rt2x00dev->irq = pci_dev->irq; 351 rt2x00dev->irq = pci_dev->irq;
306 rt2x00dev->name = pci_name(pci_dev); 352 rt2x00dev->name = pci_name(pci_dev);
307 353
308 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); 354 if (pci_dev->is_pcie)
355 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
356 else
357 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
309 358
310 retval = rt2x00pci_alloc_reg(rt2x00dev); 359 retval = rt2x00pci_alloc_reg(rt2x00dev);
311 if (retval) 360 if (retval)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 51bcef3839ce..00528b8a754d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -109,6 +109,14 @@ struct queue_entry_priv_pci {
109}; 109};
110 110
111/** 111/**
112 * rt2x00pci_txdone - Handle TX done events.
113 * @entry: The queue entry for which a TX done event was received.
114 * @txdesc: The TX done descriptor for the entry.
115 */
116void rt2x00pci_txdone(struct queue_entry *entry,
117 struct txdone_entry_desc *txdesc);
118
119/**
112 * rt2x00pci_rxdone - Handle RX done events 120 * rt2x00pci_rxdone - Handle RX done events
113 * @rt2x00dev: Device pointer, see &struct rt2x00_dev. 121 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
114 */ 122 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 20dbdd6fb904..f91637147116 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -100,21 +100,8 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
100{ 100{
101 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 101 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
102 102
103 /*
104 * If device has requested headroom, we should make sure that
105 * is also mapped to the DMA so it can be used for transfering
106 * additional descriptor information to the hardware.
107 */
108 skb_push(skb, rt2x00dev->ops->extra_tx_headroom);
109
110 skbdesc->skb_dma = 103 skbdesc->skb_dma =
111 dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); 104 dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
112
113 /*
114 * Restore data pointer to original location again.
115 */
116 skb_pull(skb, rt2x00dev->ops->extra_tx_headroom);
117
118 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; 105 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
119} 106}
120EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); 107EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
@@ -130,16 +117,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
130 } 117 }
131 118
132 if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { 119 if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
133 /* 120 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
134 * Add headroom to the skb length, it has been removed
135 * by the driver, but it was actually mapped to DMA.
136 */
137 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
138 skb->len + rt2x00dev->ops->extra_tx_headroom,
139 DMA_TO_DEVICE); 121 DMA_TO_DEVICE);
140 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; 122 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
141 } 123 }
142} 124}
125EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
143 126
144void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) 127void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
145{ 128{
@@ -370,13 +353,18 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
370 /* 353 /*
371 * Check if more fragments are pending 354 * Check if more fragments are pending
372 */ 355 */
373 if (ieee80211_has_morefrags(hdr->frame_control) || 356 if (ieee80211_has_morefrags(hdr->frame_control)) {
374 (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES)) {
375 __set_bit(ENTRY_TXD_BURST, &txdesc->flags); 357 __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
376 __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); 358 __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags);
377 } 359 }
378 360
379 /* 361 /*
362 * Check if more frames (!= fragments) are pending
363 */
364 if (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES)
365 __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
366
367 /*
380 * Beacons and probe responses require the tsf timestamp 368 * Beacons and probe responses require the tsf timestamp
381 * to be inserted into the frame, except for a frame that has been injected 369 * to be inserted into the frame, except for a frame that has been injected
382 * through a monitor interface. This latter is needed for testing a 370 * through a monitor interface. This latter is needed for testing a
@@ -421,7 +409,6 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
421{ 409{
422 struct data_queue *queue = entry->queue; 410 struct data_queue *queue = entry->queue;
423 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 411 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
424 enum rt2x00_dump_type dump_type;
425 412
426 rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); 413 rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
427 414
@@ -429,9 +416,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
429 * All processing on the frame has been completed, this means 416 * All processing on the frame has been completed, this means
430 * it is now ready to be dumped to userspace through debugfs. 417 * it is now ready to be dumped to userspace through debugfs.
431 */ 418 */
432 dump_type = (txdesc->queue == QID_BEACON) ? 419 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
433 DUMP_FRAME_BEACON : DUMP_FRAME_TX;
434 rt2x00debug_dump_frame(rt2x00dev, dump_type, entry->skb);
435} 420}
436 421
437static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, 422static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
@@ -537,9 +522,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
537 return -EIO; 522 return -EIO;
538 } 523 }
539 524
540 if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
541 rt2x00queue_map_txskb(queue->rt2x00dev, skb);
542
543 set_bit(ENTRY_DATA_PENDING, &entry->flags); 525 set_bit(ENTRY_DATA_PENDING, &entry->flags);
544 526
545 rt2x00queue_index_inc(queue, Q_INDEX); 527 rt2x00queue_index_inc(queue, Q_INDEX);
@@ -595,11 +577,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
595 skbdesc->entry = intf->beacon; 577 skbdesc->entry = intf->beacon;
596 578
597 /* 579 /*
598 * Write TX descriptor into reserved room in front of the beacon.
599 */
600 rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
601
602 /*
603 * Send beacon to hardware and enable beacon genaration.. 580 * Send beacon to hardware and enable beacon genaration..
604 */ 581 */
605 rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); 582 rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index f79170849add..bd54f55a8cb9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -213,9 +213,16 @@ struct rxdone_entry_desc {
213/** 213/**
214 * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc 214 * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc
215 * 215 *
216 * Every txdone report has to contain the basic result of the
217 * transmission, either &TXDONE_UNKNOWN, &TXDONE_SUCCESS or
218 * &TXDONE_FAILURE. The flag &TXDONE_FALLBACK can be used in
219 * conjunction with all of these flags but should only be set
220 * if retires > 0. The flag &TXDONE_EXCESSIVE_RETRY can only be used
221 * in conjunction with &TXDONE_FAILURE.
222 *
216 * @TXDONE_UNKNOWN: Hardware could not determine success of transmission. 223 * @TXDONE_UNKNOWN: Hardware could not determine success of transmission.
217 * @TXDONE_SUCCESS: Frame was successfully send 224 * @TXDONE_SUCCESS: Frame was successfully send
218 * @TXDONE_FALLBACK: Frame was successfully send using a fallback rate. 225 * @TXDONE_FALLBACK: Hardware used fallback rates for retries
219 * @TXDONE_FAILURE: Frame was not successfully send 226 * @TXDONE_FAILURE: Frame was not successfully send
220 * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the 227 * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the
221 * frame transmission failed due to excessive retries. 228 * frame transmission failed due to excessive retries.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index bd1546ba7ad2..b45bc24c3dae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -113,26 +113,6 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
113 const u16 offset, void *buffer, 113 const u16 offset, void *buffer,
114 const u16 buffer_length, const int timeout) 114 const u16 buffer_length, const int timeout)
115{ 115{
116 int status;
117
118 mutex_lock(&rt2x00dev->csr_mutex);
119
120 status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
121 requesttype, offset, buffer,
122 buffer_length, timeout);
123
124 mutex_unlock(&rt2x00dev->csr_mutex);
125
126 return status;
127}
128EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
129
130int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
131 const u8 request, const u8 requesttype,
132 const u16 offset, const void *buffer,
133 const u16 buffer_length,
134 const int timeout)
135{
136 int status = 0; 116 int status = 0;
137 unsigned char *tb; 117 unsigned char *tb;
138 u16 off, len, bsize; 118 u16 off, len, bsize;
@@ -157,7 +137,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
157 137
158 return status; 138 return status;
159} 139}
160EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff); 140EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
161 141
162int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, 142int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
163 const unsigned int offset, 143 const unsigned int offset,
@@ -198,6 +178,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
198 return; 178 return;
199 179
200 /* 180 /*
181 * Remove the descriptor from the front of the skb.
182 */
183 skb_pull(entry->skb, entry->queue->desc_size);
184
185 /*
201 * Obtain the status about this packet. 186 * Obtain the status about this packet.
202 * Note that when the status is 0 it does not mean the 187 * Note that when the status is 0 it does not mean the
203 * frame was send out correctly. It only means the frame 188 * frame was send out correctly. It only means the frame
@@ -243,10 +228,10 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry,
243 rt2x00usb_interrupt_txdone, entry); 228 rt2x00usb_interrupt_txdone, entry);
244 229
245 /* 230 /*
246 * Make sure the skb->data pointer points to the frame, not the 231 * Call the driver's write_tx_datadesc function, if it exists.
247 * descriptor.
248 */ 232 */
249 skb_pull(entry->skb, entry->queue->desc_size); 233 if (rt2x00dev->ops->lib->write_tx_datadesc)
234 rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc);
250 235
251 return 0; 236 return 0;
252} 237}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 621d0f829251..255b81ef9530 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -167,25 +167,6 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
167 const u16 buffer_length, const int timeout); 167 const u16 buffer_length, const int timeout);
168 168
169/** 169/**
170 * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered)
171 * @rt2x00dev: Pointer to &struct rt2x00_dev
172 * @request: USB vendor command (See &enum rt2x00usb_vendor_request)
173 * @requesttype: Request type &USB_VENDOR_REQUEST_*
174 * @offset: Register start offset to perform action on
175 * @buffer: Buffer where information will be read/written to by device
176 * @buffer_length: Size of &buffer
177 * @timeout: Operation timeout
178 *
179 * This function is used to transfer register data in blocks larger
180 * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons.
181 */
182int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
183 const u8 request, const u8 requesttype,
184 const u16 offset, const void *buffer,
185 const u16 buffer_length,
186 const int timeout);
187
188/**
189 * rt2x00usb_vendor_request_sw - Send single register command to device 170 * rt2x00usb_vendor_request_sw - Send single register command to device
190 * @rt2x00dev: Pointer to &struct rt2x00_dev 171 * @rt2x00dev: Pointer to &struct rt2x00_dev
191 * @request: USB vendor command (See &enum rt2x00usb_vendor_request) 172 * @request: USB vendor command (See &enum rt2x00usb_vendor_request)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 6a74baf4e934..7ca383478eeb 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -931,6 +931,9 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
931 u32 reg; 931 u32 reg;
932 932
933 rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg); 933 rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
934 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1);
935 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_STEP, 0);
936 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0);
934 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, 937 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
935 libconf->conf->long_frame_max_tx_count); 938 libconf->conf->long_frame_max_tx_count);
936 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, 939 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
@@ -1874,6 +1877,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
1874 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); 1877 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
1875 1878
1876 /* 1879 /*
1880 * Write the TX descriptor for the beacon.
1881 */
1882 rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
1883
1884 /*
1885 * Dump beacon to userspace through debugfs.
1886 */
1887 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1888
1889 /*
1877 * Write entire beacon with descriptor to register. 1890 * Write entire beacon with descriptor to register.
1878 */ 1891 */
1879 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1892 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
@@ -2039,29 +2052,24 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2039 struct txdone_entry_desc txdesc; 2052 struct txdone_entry_desc txdesc;
2040 u32 word; 2053 u32 word;
2041 u32 reg; 2054 u32 reg;
2042 u32 old_reg;
2043 int type; 2055 int type;
2044 int index; 2056 int index;
2057 int i;
2045 2058
2046 /* 2059 /*
2047 * During each loop we will compare the freshly read 2060 * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
2048 * STA_CSR4 register value with the value read from 2061 * at most X times and also stop processing once the TX_STA_FIFO_VALID
2049 * the previous loop. If the 2 values are equal then 2062 * flag is not set anymore.
2050 * we should stop processing because the chance is 2063 *
2051 * quite big that the device has been unplugged and 2064 * The legacy drivers use X=TX_RING_SIZE but state in a comment
2052 * we risk going into an endless loop. 2065 * that the TX_STA_FIFO stack has a size of 16. We stick to our
2066 * tx ring size for now.
2053 */ 2067 */
2054 old_reg = 0; 2068 for (i = 0; i < TX_ENTRIES; i++) {
2055
2056 while (1) {
2057 rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg); 2069 rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg);
2058 if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) 2070 if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
2059 break; 2071 break;
2060 2072
2061 if (old_reg == reg)
2062 break;
2063 old_reg = reg;
2064
2065 /* 2073 /*
2066 * Skip this entry when it contains an invalid 2074 * Skip this entry when it contains an invalid
2067 * queue identication number. 2075 * queue identication number.
@@ -2100,7 +2108,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2100 __set_bit(TXDONE_UNKNOWN, &txdesc.flags); 2108 __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
2101 txdesc.retry = 0; 2109 txdesc.retry = 0;
2102 2110
2103 rt2x00lib_txdone(entry_done, &txdesc); 2111 rt2x00pci_txdone(entry_done, &txdesc);
2104 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 2112 entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
2105 } 2113 }
2106 2114
@@ -2120,7 +2128,14 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2120 } 2128 }
2121 txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); 2129 txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
2122 2130
2123 rt2x00lib_txdone(entry, &txdesc); 2131 /*
2132 * the frame was retried at least once
2133 * -> hw used fallback rates
2134 */
2135 if (txdesc.retry)
2136 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
2137
2138 rt2x00pci_txdone(entry, &txdesc);
2124 } 2139 }
2125} 2140}
2126 2141
@@ -2577,6 +2592,18 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2577 EEPROM_MAC_ADDR_0)); 2592 EEPROM_MAC_ADDR_0));
2578 2593
2579 /* 2594 /*
2595 * As rt61 has a global fallback table we cannot specify
2596 * more then one tx rate per frame but since the hw will
2597 * try several rates (based on the fallback table) we should
2598 * still initialize max_rates to the maximum number of rates
2599 * we are going to try. Otherwise mac80211 will truncate our
2600 * reported tx rates and the rc algortihm will end up with
2601 * incorrect data.
2602 */
2603 rt2x00dev->hw->max_rates = 7;
2604 rt2x00dev->hw->max_rate_tries = 1;
2605
2606 /*
2580 * Initialize hw_mode information. 2607 * Initialize hw_mode information.
2581 */ 2608 */
2582 spec->supported_bands = SUPPORT_BAND_2GHZ; 2609 spec->supported_bands = SUPPORT_BAND_2GHZ;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 6e0d82efe924..d06d90f003e7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -270,7 +270,6 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
270{ 270{
271 struct hw_key_entry key_entry; 271 struct hw_key_entry key_entry;
272 struct rt2x00_field32 field; 272 struct rt2x00_field32 field;
273 int timeout;
274 u32 mask; 273 u32 mask;
275 u32 reg; 274 u32 reg;
276 275
@@ -306,12 +305,8 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
306 sizeof(key_entry.rx_mic)); 305 sizeof(key_entry.rx_mic));
307 306
308 reg = SHARED_KEY_ENTRY(key->hw_key_idx); 307 reg = SHARED_KEY_ENTRY(key->hw_key_idx);
309 timeout = REGISTER_TIMEOUT32(sizeof(key_entry)); 308 rt2x00usb_register_multiwrite(rt2x00dev, reg,
310 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, 309 &key_entry, sizeof(key_entry));
311 USB_VENDOR_REQUEST_OUT, reg,
312 &key_entry,
313 sizeof(key_entry),
314 timeout);
315 310
316 /* 311 /*
317 * The cipher types are stored over 2 registers. 312 * The cipher types are stored over 2 registers.
@@ -372,7 +367,6 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
372{ 367{
373 struct hw_pairwise_ta_entry addr_entry; 368 struct hw_pairwise_ta_entry addr_entry;
374 struct hw_key_entry key_entry; 369 struct hw_key_entry key_entry;
375 int timeout;
376 u32 mask; 370 u32 mask;
377 u32 reg; 371 u32 reg;
378 372
@@ -407,17 +401,11 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
407 sizeof(key_entry.rx_mic)); 401 sizeof(key_entry.rx_mic));
408 402
409 reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); 403 reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
410 timeout = REGISTER_TIMEOUT32(sizeof(key_entry)); 404 rt2x00usb_register_multiwrite(rt2x00dev, reg,
411 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, 405 &key_entry, sizeof(key_entry));
412 USB_VENDOR_REQUEST_OUT, reg,
413 &key_entry,
414 sizeof(key_entry),
415 timeout);
416 406
417 /* 407 /*
418 * Send the address and cipher type to the hardware register. 408 * Send the address and cipher type to the hardware register.
419 * This data fits within the CSR cache size, so we can use
420 * rt2x00usb_register_multiwrite() directly.
421 */ 409 */
422 memset(&addr_entry, 0, sizeof(addr_entry)); 410 memset(&addr_entry, 0, sizeof(addr_entry));
423 memcpy(&addr_entry, crypto->address, ETH_ALEN); 411 memcpy(&addr_entry, crypto->address, ETH_ALEN);
@@ -828,6 +816,9 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
828 u32 reg; 816 u32 reg;
829 817
830 rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg); 818 rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
819 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1);
820 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_STEP, 0);
821 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0);
831 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, 822 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
832 libconf->conf->long_frame_max_tx_count); 823 libconf->conf->long_frame_max_tx_count);
833 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, 824 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
@@ -1092,11 +1083,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
1092 /* 1083 /*
1093 * Write firmware to device. 1084 * Write firmware to device.
1094 */ 1085 */
1095 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, 1086 rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, data, len);
1096 USB_VENDOR_REQUEST_OUT,
1097 FIRMWARE_IMAGE_BASE,
1098 data, len,
1099 REGISTER_TIMEOUT32(len));
1100 1087
1101 /* 1088 /*
1102 * Send firmware request to device to load firmware, 1089 * Send firmware request to device to load firmware,
@@ -1442,7 +1429,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1442 struct txentry_desc *txdesc) 1429 struct txentry_desc *txdesc)
1443{ 1430{
1444 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 1431 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
1445 __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); 1432 __le32 *txd = (__le32 *) skb->data;
1446 u32 word; 1433 u32 word;
1447 1434
1448 /* 1435 /*
@@ -1505,6 +1492,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1505 /* 1492 /*
1506 * Register descriptor details in skb frame descriptor. 1493 * Register descriptor details in skb frame descriptor.
1507 */ 1494 */
1495 skbdesc->flags |= SKBDESC_DESC_IN_SKB;
1508 skbdesc->desc = txd; 1496 skbdesc->desc = txd;
1509 skbdesc->desc_len = TXD_DESC_SIZE; 1497 skbdesc->desc_len = TXD_DESC_SIZE;
1510} 1498}
@@ -1528,18 +1516,27 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1528 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 1516 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1529 1517
1530 /* 1518 /*
1531 * Take the descriptor in front of the skb into account. 1519 * Add space for the descriptor in front of the skb.
1532 */ 1520 */
1533 skb_push(entry->skb, TXD_DESC_SIZE); 1521 skb_push(entry->skb, TXD_DESC_SIZE);
1522 memset(entry->skb->data, 0, TXD_DESC_SIZE);
1523
1524 /*
1525 * Write the TX descriptor for the beacon.
1526 */
1527 rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
1528
1529 /*
1530 * Dump beacon to userspace through debugfs.
1531 */
1532 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1534 1533
1535 /* 1534 /*
1536 * Write entire beacon with descriptor to register. 1535 * Write entire beacon with descriptor to register.
1537 */ 1536 */
1538 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1537 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1539 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, 1538 rt2x00usb_register_multiwrite(rt2x00dev, beacon_base,
1540 USB_VENDOR_REQUEST_OUT, beacon_base, 1539 entry->skb->data, entry->skb->len);
1541 entry->skb->data, entry->skb->len,
1542 REGISTER_TIMEOUT32(entry->skb->len));
1543 1540
1544 /* 1541 /*
1545 * Enable beaconing again. 1542 * Enable beaconing again.
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 515817de2905..42705028751d 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -671,7 +671,7 @@ static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
671 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; 671 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
672} 672}
673 673
674void rtl8180_beacon_work(struct work_struct *work) 674static void rtl8180_beacon_work(struct work_struct *work)
675{ 675{
676 struct rtl8180_vif *vif_priv = 676 struct rtl8180_vif *vif_priv =
677 container_of(work, struct rtl8180_vif, beacon_work.work); 677 container_of(work, struct rtl8180_vif, beacon_work.work);
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 337fc7bec5a5..2f98058be451 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -41,7 +41,7 @@ config WL1251_SDIO
41 41
42config WL1271 42config WL1271
43 tristate "TI wl1271 support" 43 tristate "TI wl1271 support"
44 depends on WL12XX && SPI_MASTER && GENERIC_HARDIRQS 44 depends on WL12XX && GENERIC_HARDIRQS
45 depends on INET 45 depends on INET
46 select FW_LOADER 46 select FW_LOADER
47 select CRC7 47 select CRC7
@@ -65,7 +65,7 @@ config WL1271_SPI
65 65
66config WL1271_SDIO 66config WL1271_SDIO
67 tristate "TI wl1271 SDIO support" 67 tristate "TI wl1271 SDIO support"
68 depends on WL1271 && MMC && ARM 68 depends on WL1271 && MMC
69 ---help--- 69 ---help---
70 This module adds support for the SDIO interface of adapters using 70 This module adds support for the SDIO interface of adapters using
71 TI wl1271 chipset. Select this if your platform is using 71 TI wl1271 chipset. Select this if your platform is using
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 00b24282fc73..c8f268951e10 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -124,7 +124,7 @@ static int wl1251_fetch_nvs(struct wl1251 *wl)
124 } 124 }
125 125
126 wl->nvs_len = fw->size; 126 wl->nvs_len = fw->size;
127 wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL); 127 wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL);
128 128
129 if (!wl->nvs) { 129 if (!wl->nvs) {
130 wl1251_error("could not allocate memory for the nvs file"); 130 wl1251_error("could not allocate memory for the nvs file");
@@ -132,8 +132,6 @@ static int wl1251_fetch_nvs(struct wl1251 *wl)
132 goto out; 132 goto out;
133 } 133 }
134 134
135 memcpy(wl->nvs, fw->data, wl->nvs_len);
136
137 ret = 0; 135 ret = 0;
138 136
139out: 137out:
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
index c561332e7009..b901b6135654 100644
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -37,11 +37,17 @@
37#define SDIO_DEVICE_ID_TI_WL1251 0x9066 37#define SDIO_DEVICE_ID_TI_WL1251 0x9066
38#endif 38#endif
39 39
40struct wl1251_sdio {
41 struct sdio_func *func;
42 u32 elp_val;
43};
44
40static struct wl12xx_platform_data *wl12xx_board_data; 45static struct wl12xx_platform_data *wl12xx_board_data;
41 46
42static struct sdio_func *wl_to_func(struct wl1251 *wl) 47static struct sdio_func *wl_to_func(struct wl1251 *wl)
43{ 48{
44 return wl->if_priv; 49 struct wl1251_sdio *wl_sdio = wl->if_priv;
50 return wl_sdio->func;
45} 51}
46 52
47static void wl1251_sdio_interrupt(struct sdio_func *func) 53static void wl1251_sdio_interrupt(struct sdio_func *func)
@@ -90,10 +96,17 @@ static void wl1251_sdio_write(struct wl1251 *wl, int addr,
90static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) 96static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
91{ 97{
92 int ret = 0; 98 int ret = 0;
93 struct sdio_func *func = wl_to_func(wl); 99 struct wl1251_sdio *wl_sdio = wl->if_priv;
94 100 struct sdio_func *func = wl_sdio->func;
101
102 /*
103 * The hardware only supports RAW (read after write) access for
104 * reading, regular sdio_readb won't work here (it interprets
105 * the unused bits of CMD52 as write data even if we send read
106 * request).
107 */
95 sdio_claim_host(func); 108 sdio_claim_host(func);
96 *val = sdio_readb(func, addr, &ret); 109 *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
97 sdio_release_host(func); 110 sdio_release_host(func);
98 111
99 if (ret) 112 if (ret)
@@ -103,7 +116,8 @@ static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
103static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) 116static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
104{ 117{
105 int ret = 0; 118 int ret = 0;
106 struct sdio_func *func = wl_to_func(wl); 119 struct wl1251_sdio *wl_sdio = wl->if_priv;
120 struct sdio_func *func = wl_sdio->func;
107 121
108 sdio_claim_host(func); 122 sdio_claim_host(func);
109 sdio_writeb(func, val, addr, &ret); 123 sdio_writeb(func, val, addr, &ret);
@@ -111,6 +125,8 @@ static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
111 125
112 if (ret) 126 if (ret)
113 wl1251_error("sdio_writeb failed (%d)", ret); 127 wl1251_error("sdio_writeb failed (%d)", ret);
128 else
129 wl_sdio->elp_val = val;
114} 130}
115 131
116static void wl1251_sdio_reset(struct wl1251 *wl) 132static void wl1251_sdio_reset(struct wl1251 *wl)
@@ -197,6 +213,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
197 int ret; 213 int ret;
198 struct wl1251 *wl; 214 struct wl1251 *wl;
199 struct ieee80211_hw *hw; 215 struct ieee80211_hw *hw;
216 struct wl1251_sdio *wl_sdio;
200 217
201 hw = wl1251_alloc_hw(); 218 hw = wl1251_alloc_hw();
202 if (IS_ERR(hw)) 219 if (IS_ERR(hw))
@@ -204,6 +221,12 @@ static int wl1251_sdio_probe(struct sdio_func *func,
204 221
205 wl = hw->priv; 222 wl = hw->priv;
206 223
224 wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
225 if (wl_sdio == NULL) {
226 ret = -ENOMEM;
227 goto out_free_hw;
228 }
229
207 sdio_claim_host(func); 230 sdio_claim_host(func);
208 ret = sdio_enable_func(func); 231 ret = sdio_enable_func(func);
209 if (ret) 232 if (ret)
@@ -213,7 +236,8 @@ static int wl1251_sdio_probe(struct sdio_func *func,
213 sdio_release_host(func); 236 sdio_release_host(func);
214 237
215 SET_IEEE80211_DEV(hw, &func->dev); 238 SET_IEEE80211_DEV(hw, &func->dev);
216 wl->if_priv = func; 239 wl_sdio->func = func;
240 wl->if_priv = wl_sdio;
217 wl->if_ops = &wl1251_sdio_ops; 241 wl->if_ops = &wl1251_sdio_ops;
218 wl->set_power = wl1251_sdio_set_power; 242 wl->set_power = wl1251_sdio_set_power;
219 243
@@ -259,6 +283,8 @@ disable:
259 sdio_disable_func(func); 283 sdio_disable_func(func);
260release: 284release:
261 sdio_release_host(func); 285 sdio_release_host(func);
286 kfree(wl_sdio);
287out_free_hw:
262 wl1251_free_hw(wl); 288 wl1251_free_hw(wl);
263 return ret; 289 return ret;
264} 290}
@@ -266,9 +292,11 @@ release:
266static void __devexit wl1251_sdio_remove(struct sdio_func *func) 292static void __devexit wl1251_sdio_remove(struct sdio_func *func)
267{ 293{
268 struct wl1251 *wl = sdio_get_drvdata(func); 294 struct wl1251 *wl = sdio_get_drvdata(func);
295 struct wl1251_sdio *wl_sdio = wl->if_priv;
269 296
270 if (wl->irq) 297 if (wl->irq)
271 free_irq(wl->irq, wl); 298 free_irq(wl->irq, wl);
299 kfree(wl_sdio);
272 wl1251_free_hw(wl); 300 wl1251_free_hw(wl);
273 301
274 sdio_claim_host(func); 302 sdio_claim_host(func);
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 6f1b6b5640c0..1b52ce6a84d7 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -33,6 +33,7 @@
33#include <net/mac80211.h> 33#include <net/mac80211.h>
34 34
35#include "wl1271_conf.h" 35#include "wl1271_conf.h"
36#include "wl1271_ini.h"
36 37
37#define DRIVER_NAME "wl1271" 38#define DRIVER_NAME "wl1271"
38#define DRIVER_PREFIX DRIVER_NAME ": " 39#define DRIVER_PREFIX DRIVER_NAME ": "
@@ -116,33 +117,6 @@ enum {
116#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) 117#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
117#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) 118#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
118 119
119/* NVS data structure */
120#define WL1271_NVS_SECTION_SIZE 468
121
122#define WL1271_NVS_GENERAL_PARAMS_SIZE 57
123#define WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED \
124 (WL1271_NVS_GENERAL_PARAMS_SIZE + 1)
125#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE 17
126#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED \
127 (WL1271_NVS_STAT_RADIO_PARAMS_SIZE + 1)
128#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE 65
129#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED \
130 (WL1271_NVS_DYN_RADIO_PARAMS_SIZE + 1)
131#define WL1271_NVS_FEM_COUNT 2
132#define WL1271_NVS_INI_SPARE_SIZE 124
133
134struct wl1271_nvs_file {
135 /* NVS section */
136 u8 nvs[WL1271_NVS_SECTION_SIZE];
137
138 /* INI section */
139 u8 general_params[WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED];
140 u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED];
141 u8 dyn_radio_params[WL1271_NVS_FEM_COUNT]
142 [WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED];
143 u8 ini_spare[WL1271_NVS_INI_SPARE_SIZE];
144} __attribute__ ((packed));
145
146/* 120/*
147 * Enable/disable 802.11a support for WL1273 121 * Enable/disable 802.11a support for WL1273
148 */ 122 */
@@ -325,6 +299,7 @@ struct wl1271_rx_mem_pool_addr {
325}; 299};
326 300
327struct wl1271_scan { 301struct wl1271_scan {
302 struct cfg80211_scan_request *req;
328 u8 state; 303 u8 state;
329 u8 ssid[IW_ESSID_MAX_SIZE+1]; 304 u8 ssid[IW_ESSID_MAX_SIZE+1];
330 size_t ssid_len; 305 size_t ssid_len;
@@ -375,6 +350,7 @@ struct wl1271 {
375#define WL1271_FLAG_IRQ_PENDING (9) 350#define WL1271_FLAG_IRQ_PENDING (9)
376#define WL1271_FLAG_IRQ_RUNNING (10) 351#define WL1271_FLAG_IRQ_RUNNING (10)
377#define WL1271_FLAG_IDLE (11) 352#define WL1271_FLAG_IDLE (11)
353#define WL1271_FLAG_IDLE_REQUESTED (12)
378 unsigned long flags; 354 unsigned long flags;
379 355
380 struct wl1271_partition_set part; 356 struct wl1271_partition_set part;
@@ -421,6 +397,7 @@ struct wl1271 {
421 397
422 /* Pending TX frames */ 398 /* Pending TX frames */
423 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; 399 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
400 int tx_frames_cnt;
424 401
425 /* Security sequence number counters */ 402 /* Security sequence number counters */
426 u8 tx_security_last_seq; 403 u8 tx_security_last_seq;
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 19393e236e2c..530678e45a13 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -212,8 +212,8 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
212 212
213 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; 213 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
214 214
215 memcpy(gen_parms->params, wl->nvs->general_params, 215 memcpy(&gen_parms->general_params, &wl->nvs->general_params,
216 WL1271_NVS_GENERAL_PARAMS_SIZE); 216 sizeof(struct wl1271_ini_general_params));
217 217
218 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); 218 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
219 if (ret < 0) 219 if (ret < 0)
@@ -238,13 +238,20 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
238 238
239 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; 239 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
240 240
241 memcpy(radio_parms->stat_radio_params, wl->nvs->stat_radio_params, 241 /* 2.4GHz parameters */
242 WL1271_NVS_STAT_RADIO_PARAMS_SIZE); 242 memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2,
243 memcpy(radio_parms->dyn_radio_params, 243 sizeof(struct wl1271_ini_band_params_2));
244 wl->nvs->dyn_radio_params[rparam->fem], 244 memcpy(&radio_parms->dyn_params_2,
245 WL1271_NVS_DYN_RADIO_PARAMS_SIZE); 245 &wl->nvs->dyn_radio_params_2[rparam->fem].params,
246 246 sizeof(struct wl1271_ini_fem_params_2));
247 /* FIXME: current NVS is missing 5GHz parameters */ 247
248 /* 5GHz parameters */
249 memcpy(&radio_parms->static_params_5,
250 &wl->nvs->stat_radio_params_5,
251 sizeof(struct wl1271_ini_band_params_5));
252 memcpy(&radio_parms->dyn_params_5,
253 &wl->nvs->dyn_radio_params_5[rparam->fem].params,
254 sizeof(struct wl1271_ini_fem_params_5));
248 255
249 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", 256 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
250 radio_parms, sizeof(*radio_parms)); 257 radio_parms, sizeof(*radio_parms));
@@ -329,12 +336,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
329 join->channel = wl->channel; 336 join->channel = wl->channel;
330 join->ssid_len = wl->ssid_len; 337 join->ssid_len = wl->ssid_len;
331 memcpy(join->ssid, wl->ssid, wl->ssid_len); 338 memcpy(join->ssid, wl->ssid, wl->ssid_len);
332 join->ctrl = WL1271_JOIN_CMD_CTRL_TX_FLUSH;
333
334 /* increment the session counter */
335 wl->session_counter++;
336 if (wl->session_counter >= SESSION_COUNTER_MAX)
337 wl->session_counter = 0;
338 339
339 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; 340 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
340 341
@@ -517,7 +518,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
517 ps_params->send_null_data = send; 518 ps_params->send_null_data = send;
518 ps_params->retries = 5; 519 ps_params->retries = 5;
519 ps_params->hang_over_period = 1; 520 ps_params->hang_over_period = 1;
520 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */ 521 ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set);
521 522
522 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 523 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
523 sizeof(*ps_params), 0); 524 sizeof(*ps_params), 0);
@@ -567,7 +568,7 @@ out:
567} 568}
568 569
569int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, 570int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
570 const u8 *ie, size_t ie_len, u8 active_scan, 571 struct cfg80211_scan_request *req, u8 active_scan,
571 u8 high_prio, u8 band, u8 probe_requests) 572 u8 high_prio, u8 band, u8 probe_requests)
572{ 573{
573 574
@@ -648,7 +649,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
648 } 649 }
649 650
650 ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len, 651 ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len,
651 ie, ie_len, ieee_band); 652 req->ie, req->ie_len, ieee_band);
652 if (ret < 0) { 653 if (ret < 0) {
653 wl1271_error("PROBE request template failed"); 654 wl1271_error("PROBE request template failed");
654 goto out; 655 goto out;
@@ -684,7 +685,9 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
684 memcpy(wl->scan.ssid, ssid, ssid_len); 685 memcpy(wl->scan.ssid, ssid, ssid_len);
685 } else 686 } else
686 wl->scan.ssid_len = 0; 687 wl->scan.ssid_len = 0;
687 } 688 wl->scan.req = req;
689 } else
690 wl->scan.req = NULL;
688 } 691 }
689 692
690 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0); 693 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0);
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index f2820b42a943..68001dffe716 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -42,7 +42,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 43 size_t len);
44int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, 44int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
45 const u8 *ie, size_t ie_len, u8 active_scan, 45 struct cfg80211_scan_request *req, u8 active_scan,
46 u8 high_prio, u8 band, u8 probe_requests); 46 u8 high_prio, u8 band, u8 probe_requests);
47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
48 void *buf, size_t buf_len, int index, u32 rates); 48 void *buf, size_t buf_len, int index, u32 rates);
@@ -439,24 +439,30 @@ struct wl1271_general_parms_cmd {
439 439
440 struct wl1271_cmd_test_header test; 440 struct wl1271_cmd_test_header test;
441 441
442 u8 params[WL1271_NVS_GENERAL_PARAMS_SIZE]; 442 struct wl1271_ini_general_params general_params;
443 s8 reserved[23];
444} __attribute__ ((packed));
445 443
446#define WL1271_STAT_RADIO_PARAMS_5_SIZE 29 444 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
447#define WL1271_DYN_RADIO_PARAMS_5_SIZE 104 445 u8 sr_sen_n_p;
446 u8 sr_sen_n_p_gain;
447 u8 sr_sen_nrn;
448 u8 sr_sen_prn;
449 u8 padding[3];
450} __attribute__ ((packed));
448 451
449struct wl1271_radio_parms_cmd { 452struct wl1271_radio_parms_cmd {
450 struct wl1271_cmd_header header; 453 struct wl1271_cmd_header header;
451 454
452 struct wl1271_cmd_test_header test; 455 struct wl1271_cmd_test_header test;
453 456
454 u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE]; 457 /* Static radio parameters */
455 u8 stat_radio_params_5[WL1271_STAT_RADIO_PARAMS_5_SIZE]; 458 struct wl1271_ini_band_params_2 static_params_2;
459 struct wl1271_ini_band_params_5 static_params_5;
456 460
457 u8 dyn_radio_params[WL1271_NVS_DYN_RADIO_PARAMS_SIZE]; 461 /* Dynamic radio parameters */
458 u8 reserved; 462 struct wl1271_ini_fem_params_2 dyn_params_2;
459 u8 dyn_radio_params_5[WL1271_DYN_RADIO_PARAMS_5_SIZE]; 463 u8 padding2;
464 struct wl1271_ini_fem_params_5 dyn_params_5;
465 u8 padding3[2];
460} __attribute__ ((packed)); 466} __attribute__ ((packed));
461 467
462struct wl1271_cmd_cal_channel_tune { 468struct wl1271_cmd_cal_channel_tune {
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index cf37aa6eb137..ca52cdec7a8f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -43,11 +43,11 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
43 clear_bit(WL1271_FLAG_SCANNING, &wl->flags); 43 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
44 /* FIXME: ie missing! */ 44 /* FIXME: ie missing! */
45 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, 45 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
46 NULL, 0, 46 wl->scan.req,
47 wl->scan.active, 47 wl->scan.active,
48 wl->scan.high_prio, 48 wl->scan.high_prio,
49 WL1271_SCAN_BAND_5_GHZ, 49 WL1271_SCAN_BAND_5_GHZ,
50 wl->scan.probe_requests); 50 wl->scan.probe_requests);
51 } else { 51 } else {
52 mutex_unlock(&wl->mutex); 52 mutex_unlock(&wl->mutex);
53 ieee80211_scan_completed(wl->hw, false); 53 ieee80211_scan_completed(wl->hw, false);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ini.h b/drivers/net/wireless/wl12xx/wl1271_ini.h
new file mode 100644
index 000000000000..0fb156a5af12
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_ini.h
@@ -0,0 +1,123 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __WL1271_INI_H__
25#define __WL1271_INI_H__
26
27#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16
28
29struct wl1271_ini_general_params {
30 u8 ref_clock;
31 u8 settling_time;
32 u8 clk_valid_on_wakeup;
33 u8 dc2dc_mode;
34 u8 dual_mode_select;
35 u8 tx_bip_fem_auto_detect;
36 u8 tx_bip_fem_manufacturer;
37 u8 general_settings;
38 u8 sr_state;
39 u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
40 u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
41 u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
42} __attribute__ ((packed));
43
44#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15
45
46struct wl1271_ini_band_params_2 {
47 u8 rx_trace_insertion_loss;
48 u8 tx_trace_loss;
49 u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
50} __attribute__ ((packed));
51
52#define WL1271_INI_RATE_GROUP_COUNT 6
53#define WL1271_INI_CHANNEL_COUNT_2 14
54
55struct wl1271_ini_fem_params_2 {
56 __le16 tx_bip_ref_pd_voltage;
57 u8 tx_bip_ref_power;
58 u8 tx_bip_ref_offset;
59 u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT];
60 u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT];
61 u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT];
62 u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
63 u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
64 u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT];
65 u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT];
66 u8 rx_fem_insertion_loss;
67 u8 degraded_low_to_normal_thr;
68 u8 normal_to_degraded_high_thr;
69} __attribute__ ((packed));
70
71#define WL1271_INI_CHANNEL_COUNT_5 35
72#define WL1271_INI_SUB_BAND_COUNT_5 7
73
74struct wl1271_ini_band_params_5 {
75 u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
76 u8 tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5];
77 u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
78} __attribute__ ((packed));
79
80struct wl1271_ini_fem_params_5 {
81 __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
82 u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
83 u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
84 u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT];
85 u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT];
86 u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT];
87 u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
88 u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT];
89 u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT];
90 u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
91 u8 degraded_low_to_normal_thr;
92 u8 normal_to_degraded_high_thr;
93} __attribute__ ((packed));
94
95
96/* NVS data structure */
97#define WL1271_INI_NVS_SECTION_SIZE 468
98#define WL1271_INI_FEM_MODULE_COUNT 2
99
100#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800
101
102struct wl1271_nvs_file {
103 /* NVS section */
104 u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
105
106 /* INI section */
107 struct wl1271_ini_general_params general_params;
108 u8 padding1;
109 struct wl1271_ini_band_params_2 stat_radio_params_2;
110 u8 padding2;
111 struct {
112 struct wl1271_ini_fem_params_2 params;
113 u8 padding;
114 } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
115 struct wl1271_ini_band_params_5 stat_radio_params_5;
116 u8 padding3;
117 struct {
118 struct wl1271_ini_fem_params_5 params;
119 u8 padding;
120 } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
121} __attribute__ ((packed));
122
123#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index b7d9137851ac..7a14da506d78 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -566,14 +566,21 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
566 return ret; 566 return ret;
567 } 567 }
568 568
569 if (fw->size != sizeof(struct wl1271_nvs_file)) { 569 /*
570 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
571 * configurations) can be removed when those NVS files stop floating
572 * around.
573 */
574 if (fw->size != sizeof(struct wl1271_nvs_file) &&
575 (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
576 wl1271_11a_enabled())) {
570 wl1271_error("nvs size is not as expected: %zu != %zu", 577 wl1271_error("nvs size is not as expected: %zu != %zu",
571 fw->size, sizeof(struct wl1271_nvs_file)); 578 fw->size, sizeof(struct wl1271_nvs_file));
572 ret = -EILSEQ; 579 ret = -EILSEQ;
573 goto out; 580 goto out;
574 } 581 }
575 582
576 wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); 583 wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
577 584
578 if (!wl->nvs) { 585 if (!wl->nvs) {
579 wl1271_error("could not allocate memory for the nvs file"); 586 wl1271_error("could not allocate memory for the nvs file");
@@ -581,7 +588,7 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
581 goto out; 588 goto out;
582 } 589 }
583 590
584 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); 591 memcpy(wl->nvs, fw->data, fw->size);
585 592
586out: 593out:
587 release_firmware(fw); 594 release_firmware(fw);
@@ -1044,7 +1051,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1044 mutex_lock(&wl->mutex); 1051 mutex_lock(&wl->mutex);
1045 1052
1046 /* let's notify MAC80211 about the remaining pending TX frames */ 1053 /* let's notify MAC80211 about the remaining pending TX frames */
1047 wl1271_tx_flush(wl); 1054 wl1271_tx_reset(wl);
1048 wl1271_power_off(wl); 1055 wl1271_power_off(wl);
1049 1056
1050 memset(wl->bssid, 0, ETH_ALEN); 1057 memset(wl->bssid, 0, ETH_ALEN);
@@ -1241,6 +1248,42 @@ static u32 wl1271_min_rate_get(struct wl1271 *wl)
1241 return rate; 1248 return rate;
1242} 1249}
1243 1250
1251static int wl1271_handle_idle(struct wl1271 *wl, bool idle)
1252{
1253 int ret;
1254
1255 if (idle) {
1256 if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) {
1257 ret = wl1271_unjoin(wl);
1258 if (ret < 0)
1259 goto out;
1260 }
1261 wl->rate_set = wl1271_min_rate_get(wl);
1262 wl->sta_rate_set = 0;
1263 ret = wl1271_acx_rate_policies(wl);
1264 if (ret < 0)
1265 goto out;
1266 ret = wl1271_acx_keep_alive_config(
1267 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1268 ACX_KEEP_ALIVE_TPL_INVALID);
1269 if (ret < 0)
1270 goto out;
1271 set_bit(WL1271_FLAG_IDLE, &wl->flags);
1272 } else {
1273 /* increment the session counter */
1274 wl->session_counter++;
1275 if (wl->session_counter >= SESSION_COUNTER_MAX)
1276 wl->session_counter = 0;
1277 ret = wl1271_dummy_join(wl);
1278 if (ret < 0)
1279 goto out;
1280 clear_bit(WL1271_FLAG_IDLE, &wl->flags);
1281 }
1282
1283out:
1284 return ret;
1285}
1286
1244static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) 1287static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1245{ 1288{
1246 struct wl1271 *wl = hw->priv; 1289 struct wl1271 *wl = hw->priv;
@@ -1255,6 +1298,15 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1255 conf->power_level, 1298 conf->power_level,
1256 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use"); 1299 conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use");
1257 1300
1301 /*
1302 * mac80211 will go to idle nearly immediately after transmitting some
1303 * frames, such as the deauth. To make sure those frames reach the air,
1304 * wait here until the TX queue is fully flushed.
1305 */
1306 if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
1307 (conf->flags & IEEE80211_CONF_IDLE))
1308 wl1271_tx_flush(wl);
1309
1258 mutex_lock(&wl->mutex); 1310 mutex_lock(&wl->mutex);
1259 1311
1260 if (unlikely(wl->state == WL1271_STATE_OFF)) 1312 if (unlikely(wl->state == WL1271_STATE_OFF))
@@ -1295,22 +1347,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1295 } 1347 }
1296 1348
1297 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1349 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1298 if (conf->flags & IEEE80211_CONF_IDLE && 1350 ret = wl1271_handle_idle(wl, conf->flags & IEEE80211_CONF_IDLE);
1299 test_bit(WL1271_FLAG_JOINED, &wl->flags)) 1351 if (ret < 0)
1300 wl1271_unjoin(wl); 1352 wl1271_warning("idle mode change failed %d", ret);
1301 else if (!(conf->flags & IEEE80211_CONF_IDLE))
1302 wl1271_dummy_join(wl);
1303
1304 if (conf->flags & IEEE80211_CONF_IDLE) {
1305 wl->rate_set = wl1271_min_rate_get(wl);
1306 wl->sta_rate_set = 0;
1307 wl1271_acx_rate_policies(wl);
1308 wl1271_acx_keep_alive_config(
1309 wl, CMD_TEMPL_KLV_IDX_NULL_DATA,
1310 ACX_KEEP_ALIVE_TPL_INVALID);
1311 set_bit(WL1271_FLAG_IDLE, &wl->flags);
1312 } else
1313 clear_bit(WL1271_FLAG_IDLE, &wl->flags);
1314 } 1353 }
1315 1354
1316 if (conf->flags & IEEE80211_CONF_PS && 1355 if (conf->flags & IEEE80211_CONF_PS &&
@@ -1595,13 +1634,11 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1595 goto out; 1634 goto out;
1596 1635
1597 if (wl1271_11a_enabled()) 1636 if (wl1271_11a_enabled())
1598 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1637 ret = wl1271_cmd_scan(hw->priv, ssid, len, req,
1599 req->ie, req->ie_len, 1, 0, 1638 1, 0, WL1271_SCAN_BAND_DUAL, 3);
1600 WL1271_SCAN_BAND_DUAL, 3);
1601 else 1639 else
1602 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1640 ret = wl1271_cmd_scan(hw->priv, ssid, len, req,
1603 req->ie, req->ie_len, 1, 0, 1641 1, 0, WL1271_SCAN_BAND_2_4_GHZ, 3);
1604 WL1271_SCAN_BAND_2_4_GHZ, 3);
1605 1642
1606 wl1271_ps_elp_sleep(wl); 1643 wl1271_ps_elp_sleep(wl);
1607 1644
@@ -1991,7 +2028,7 @@ static struct ieee80211_channel wl1271_channels[] = {
1991}; 2028};
1992 2029
1993/* mapping to indexes for wl1271_rates */ 2030/* mapping to indexes for wl1271_rates */
1994const static u8 wl1271_rate_to_idx_2ghz[] = { 2031static const u8 wl1271_rate_to_idx_2ghz[] = {
1995 /* MCS rates are used only with 11n */ 2032 /* MCS rates are used only with 11n */
1996 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ 2033 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
1997 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ 2034 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
@@ -2103,7 +2140,7 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
2103}; 2140};
2104 2141
2105/* mapping to indexes for wl1271_rates_5ghz */ 2142/* mapping to indexes for wl1271_rates_5ghz */
2106const static u8 wl1271_rate_to_idx_5ghz[] = { 2143static const u8 wl1271_rate_to_idx_5ghz[] = {
2107 /* MCS rates are used only with 11n */ 2144 /* MCS rates are used only with 11n */
2108 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ 2145 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
2109 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ 2146 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
@@ -2139,7 +2176,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
2139 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 2176 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
2140}; 2177};
2141 2178
2142const static u8 *wl1271_band_rate_to_idx[] = { 2179static const u8 *wl1271_band_rate_to_idx[] = {
2143 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz, 2180 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
2144 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz 2181 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
2145}; 2182};
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index d3d6f302f705..7059b5cccf0f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -28,7 +28,7 @@
28#include <linux/mmc/sdio_func.h> 28#include <linux/mmc/sdio_func.h>
29#include <linux/mmc/sdio_ids.h> 29#include <linux/mmc/sdio_ids.h>
30#include <linux/mmc/card.h> 30#include <linux/mmc/card.h>
31#include <plat/gpio.h> 31#include <linux/gpio.h>
32 32
33#include "wl1271.h" 33#include "wl1271.h"
34#include "wl12xx_80211.h" 34#include "wl12xx_80211.h"
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 554deb4d024e..6e0952f79e9a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -199,7 +199,14 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
199 buf = nla_data(tb[WL1271_TM_ATTR_DATA]); 199 buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
200 len = nla_len(tb[WL1271_TM_ATTR_DATA]); 200 len = nla_len(tb[WL1271_TM_ATTR_DATA]);
201 201
202 if (len != sizeof(struct wl1271_nvs_file)) { 202 /*
203 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
204 * configurations) can be removed when those NVS files stop floating
205 * around.
206 */
207 if (len != sizeof(struct wl1271_nvs_file) &&
208 (len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
209 wl1271_11a_enabled())) {
203 wl1271_error("nvs size is not as expected: %zu != %zu", 210 wl1271_error("nvs size is not as expected: %zu != %zu",
204 len, sizeof(struct wl1271_nvs_file)); 211 len, sizeof(struct wl1271_nvs_file));
205 return -EMSGSIZE; 212 return -EMSGSIZE;
@@ -209,7 +216,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
209 216
210 kfree(wl->nvs); 217 kfree(wl->nvs);
211 218
212 wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); 219 wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
213 if (!wl->nvs) { 220 if (!wl->nvs) {
214 wl1271_error("could not allocate memory for the nvs file"); 221 wl1271_error("could not allocate memory for the nvs file");
215 ret = -ENOMEM; 222 ret = -ENOMEM;
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 62db79508ddf..c592cc2e9fe8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -36,6 +36,7 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
36 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 36 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
37 if (wl->tx_frames[i] == NULL) { 37 if (wl->tx_frames[i] == NULL) {
38 wl->tx_frames[i] = skb; 38 wl->tx_frames[i] = skb;
39 wl->tx_frames_cnt++;
39 return i; 40 return i;
40 } 41 }
41 42
@@ -73,8 +74,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
73 wl1271_debug(DEBUG_TX, 74 wl1271_debug(DEBUG_TX,
74 "tx_allocate: size: %d, blocks: %d, id: %d", 75 "tx_allocate: size: %d, blocks: %d, id: %d",
75 total_len, total_blocks, id); 76 total_len, total_blocks, id);
76 } else 77 } else {
77 wl->tx_frames[id] = NULL; 78 wl->tx_frames[id] = NULL;
79 wl->tx_frames_cnt--;
80 }
78 81
79 return ret; 82 return ret;
80} 83}
@@ -358,6 +361,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
358 /* return the packet to the stack */ 361 /* return the packet to the stack */
359 ieee80211_tx_status(wl->hw, skb); 362 ieee80211_tx_status(wl->hw, skb);
360 wl->tx_frames[result->id] = NULL; 363 wl->tx_frames[result->id] = NULL;
364 wl->tx_frames_cnt--;
361} 365}
362 366
363/* Called upon reception of a TX complete interrupt */ 367/* Called upon reception of a TX complete interrupt */
@@ -412,7 +416,7 @@ void wl1271_tx_complete(struct wl1271 *wl)
412} 416}
413 417
414/* caller must hold wl->mutex */ 418/* caller must hold wl->mutex */
415void wl1271_tx_flush(struct wl1271 *wl) 419void wl1271_tx_reset(struct wl1271 *wl)
416{ 420{
417 int i; 421 int i;
418 struct sk_buff *skb; 422 struct sk_buff *skb;
@@ -421,7 +425,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
421/* control->flags = 0; FIXME */ 425/* control->flags = 0; FIXME */
422 426
423 while ((skb = skb_dequeue(&wl->tx_queue))) { 427 while ((skb = skb_dequeue(&wl->tx_queue))) {
424 wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb); 428 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
425 ieee80211_tx_status(wl->hw, skb); 429 ieee80211_tx_status(wl->hw, skb);
426 } 430 }
427 431
@@ -429,6 +433,32 @@ void wl1271_tx_flush(struct wl1271 *wl)
429 if (wl->tx_frames[i] != NULL) { 433 if (wl->tx_frames[i] != NULL) {
430 skb = wl->tx_frames[i]; 434 skb = wl->tx_frames[i];
431 wl->tx_frames[i] = NULL; 435 wl->tx_frames[i] = NULL;
436 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
432 ieee80211_tx_status(wl->hw, skb); 437 ieee80211_tx_status(wl->hw, skb);
433 } 438 }
439 wl->tx_frames_cnt = 0;
440}
441
442#define WL1271_TX_FLUSH_TIMEOUT 500000
443
444/* caller must *NOT* hold wl->mutex */
445void wl1271_tx_flush(struct wl1271 *wl)
446{
447 unsigned long timeout;
448 timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT);
449
450 while (!time_after(jiffies, timeout)) {
451 mutex_lock(&wl->mutex);
452 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d",
453 wl->tx_frames_cnt);
454 if ((wl->tx_frames_cnt == 0) &&
455 skb_queue_empty(&wl->tx_queue)) {
456 mutex_unlock(&wl->mutex);
457 return;
458 }
459 mutex_unlock(&wl->mutex);
460 msleep(1);
461 }
462
463 wl1271_warning("Unable to flush all TX buffers, timed out.");
434} 464}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 3b8b7ac253fd..0ae00637933e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -158,6 +158,7 @@ static inline int wl1271_tx_ac_to_tid(int ac)
158 158
159void wl1271_tx_work(struct work_struct *work); 159void wl1271_tx_work(struct work_struct *work);
160void wl1271_tx_complete(struct wl1271 *wl); 160void wl1271_tx_complete(struct wl1271 *wl);
161void wl1271_tx_reset(struct wl1271 *wl);
161void wl1271_tx_flush(struct wl1271 *wl); 162void wl1271_tx_flush(struct wl1271 *wl);
162u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); 163u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate);
163u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); 164u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index b0b666019a93..43307bd42a69 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -42,7 +42,8 @@ static struct zd_reg_alpha2_map reg_alpha2_map[] = {
42 { ZD_REGDOMAIN_IC, "CA" }, 42 { ZD_REGDOMAIN_IC, "CA" },
43 { ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */ 43 { ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */
44 { ZD_REGDOMAIN_JAPAN, "JP" }, 44 { ZD_REGDOMAIN_JAPAN, "JP" },
45 { ZD_REGDOMAIN_JAPAN_ADD, "JP" }, 45 { ZD_REGDOMAIN_JAPAN_2, "JP" },
46 { ZD_REGDOMAIN_JAPAN_3, "JP" },
46 { ZD_REGDOMAIN_SPAIN, "ES" }, 47 { ZD_REGDOMAIN_SPAIN, "ES" },
47 { ZD_REGDOMAIN_FRANCE, "FR" }, 48 { ZD_REGDOMAIN_FRANCE, "FR" },
48}; 49};
@@ -855,7 +856,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
855 if (skb == NULL) 856 if (skb == NULL)
856 return -ENOMEM; 857 return -ENOMEM;
857 if (need_padding) { 858 if (need_padding) {
858 /* Make sure the the payload data is 4 byte aligned. */ 859 /* Make sure the payload data is 4 byte aligned. */
859 skb_reserve(skb, 2); 860 skb_reserve(skb, 2);
860 } 861 }
861 862
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 630c298a730e..d21739a530ec 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -212,8 +212,9 @@ struct zd_mac {
212#define ZD_REGDOMAIN_ETSI 0x30 212#define ZD_REGDOMAIN_ETSI 0x30
213#define ZD_REGDOMAIN_SPAIN 0x31 213#define ZD_REGDOMAIN_SPAIN 0x31
214#define ZD_REGDOMAIN_FRANCE 0x32 214#define ZD_REGDOMAIN_FRANCE 0x32
215#define ZD_REGDOMAIN_JAPAN_ADD 0x40 215#define ZD_REGDOMAIN_JAPAN_2 0x40
216#define ZD_REGDOMAIN_JAPAN 0x41 216#define ZD_REGDOMAIN_JAPAN 0x41
217#define ZD_REGDOMAIN_JAPAN_3 0x49
217 218
218enum { 219enum {
219 MIN_CHANNEL24 = 1, 220 MIN_CHANNEL24 = 1,
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index c257940b71b6..818e1480ca93 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -844,7 +844,7 @@ out:
844 * @usb: a &struct zd_usb pointer 844 * @usb: a &struct zd_usb pointer
845 * @urb: URB to be freed 845 * @urb: URB to be freed
846 * 846 *
847 * Frees the the transmission URB, which means to put it on the free URB 847 * Frees the transmission URB, which means to put it on the free URB
848 * list. 848 * list.
849 */ 849 */
850static void free_tx_urb(struct zd_usb *usb, struct urb *urb) 850static void free_tx_urb(struct zd_usb *usb, struct urb *urb)
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 59ae76bace14..7c031fdc8205 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -209,6 +209,24 @@ static void chipco_powercontrol_init(struct ssb_chipcommon *cc)
209 } 209 }
210} 210}
211 211
212/* http://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */
213static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)
214{
215 struct ssb_bus *bus = cc->dev->bus;
216
217 switch (bus->chip_id) {
218 case 0x4312:
219 case 0x4322:
220 case 0x4328:
221 return 7000;
222 case 0x4325:
223 /* TODO: */
224 default:
225 return 15000;
226 }
227}
228
229/* http://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */
212static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) 230static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
213{ 231{
214 struct ssb_bus *bus = cc->dev->bus; 232 struct ssb_bus *bus = cc->dev->bus;
@@ -218,6 +236,12 @@ static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
218 236
219 if (bus->bustype != SSB_BUSTYPE_PCI) 237 if (bus->bustype != SSB_BUSTYPE_PCI)
220 return; 238 return;
239
240 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
241 cc->fast_pwrup_delay = pmu_fast_powerup_delay(cc);
242 return;
243 }
244
221 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) 245 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
222 return; 246 return;
223 247
@@ -235,6 +259,7 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
235 return; /* We don't have a ChipCommon */ 259 return; /* We don't have a ChipCommon */
236 if (cc->dev->id.revision >= 11) 260 if (cc->dev->id.revision >= 11)
237 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 261 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
262 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
238 ssb_pmu_init(cc); 263 ssb_pmu_init(cc);
239 chipco_powercontrol_init(cc); 264 chipco_powercontrol_init(cc);
240 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); 265 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 3d551245a4e2..5732bb2c3578 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -502,9 +502,9 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc)
502 chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk); 502 chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk);
503} 503}
504 504
505/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */
505void ssb_pmu_init(struct ssb_chipcommon *cc) 506void ssb_pmu_init(struct ssb_chipcommon *cc)
506{ 507{
507 struct ssb_bus *bus = cc->dev->bus;
508 u32 pmucap; 508 u32 pmucap;
509 509
510 if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU)) 510 if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
@@ -516,15 +516,12 @@ void ssb_pmu_init(struct ssb_chipcommon *cc)
516 ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", 516 ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
517 cc->pmu.rev, pmucap); 517 cc->pmu.rev, pmucap);
518 518
519 if (cc->pmu.rev >= 1) { 519 if (cc->pmu.rev == 1)
520 if ((bus->chip_id == 0x4325) && (bus->chip_rev < 2)) { 520 chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
521 chipco_mask32(cc, SSB_CHIPCO_PMU_CTL, 521 ~SSB_CHIPCO_PMU_CTL_NOILPONW);
522 ~SSB_CHIPCO_PMU_CTL_NOILPONW); 522 else
523 } else { 523 chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
524 chipco_set32(cc, SSB_CHIPCO_PMU_CTL, 524 SSB_CHIPCO_PMU_CTL_NOILPONW);
525 SSB_CHIPCO_PMU_CTL_NOILPONW);
526 }
527 }
528 ssb_pmu_pll_init(cc); 525 ssb_pmu_pll_init(cc);
529 ssb_pmu_resources_init(cc); 526 ssb_pmu_resources_init(cc);
530} 527}
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 51275aac5b34..7cee7f4eb60b 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -486,6 +486,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
486#ifdef CONFIG_SSB_PCIHOST 486#ifdef CONFIG_SSB_PCIHOST
487 sdev->irq = bus->host_pci->irq; 487 sdev->irq = bus->host_pci->irq;
488 dev->parent = &bus->host_pci->dev; 488 dev->parent = &bus->host_pci->dev;
489 sdev->dma_dev = dev->parent;
489#endif 490#endif
490 break; 491 break;
491 case SSB_BUSTYPE_PCMCIA: 492 case SSB_BUSTYPE_PCMCIA:
@@ -501,6 +502,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
501 break; 502 break;
502 case SSB_BUSTYPE_SSB: 503 case SSB_BUSTYPE_SSB:
503 dev->dma_mask = &dev->coherent_dma_mask; 504 dev->dma_mask = &dev->coherent_dma_mask;
505 sdev->dma_dev = dev;
504 break; 506 break;
505 } 507 }
506 508
@@ -1226,80 +1228,6 @@ u32 ssb_dma_translation(struct ssb_device *dev)
1226} 1228}
1227EXPORT_SYMBOL(ssb_dma_translation); 1229EXPORT_SYMBOL(ssb_dma_translation);
1228 1230
1229int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
1230{
1231#ifdef CONFIG_SSB_PCIHOST
1232 int err;
1233#endif
1234
1235 switch (dev->bus->bustype) {
1236 case SSB_BUSTYPE_PCI:
1237#ifdef CONFIG_SSB_PCIHOST
1238 err = pci_set_dma_mask(dev->bus->host_pci, mask);
1239 if (err)
1240 return err;
1241 err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
1242 return err;
1243#endif
1244 case SSB_BUSTYPE_SSB:
1245 return dma_set_mask(dev->dev, mask);
1246 default:
1247 __ssb_dma_not_implemented(dev);
1248 }
1249 return -ENOSYS;
1250}
1251EXPORT_SYMBOL(ssb_dma_set_mask);
1252
1253void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
1254 dma_addr_t *dma_handle, gfp_t gfp_flags)
1255{
1256 switch (dev->bus->bustype) {
1257 case SSB_BUSTYPE_PCI:
1258#ifdef CONFIG_SSB_PCIHOST
1259 if (gfp_flags & GFP_DMA) {
1260 /* Workaround: The PCI API does not support passing
1261 * a GFP flag. */
1262 return dma_alloc_coherent(&dev->bus->host_pci->dev,
1263 size, dma_handle, gfp_flags);
1264 }
1265 return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
1266#endif
1267 case SSB_BUSTYPE_SSB:
1268 return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
1269 default:
1270 __ssb_dma_not_implemented(dev);
1271 }
1272 return NULL;
1273}
1274EXPORT_SYMBOL(ssb_dma_alloc_consistent);
1275
1276void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
1277 void *vaddr, dma_addr_t dma_handle,
1278 gfp_t gfp_flags)
1279{
1280 switch (dev->bus->bustype) {
1281 case SSB_BUSTYPE_PCI:
1282#ifdef CONFIG_SSB_PCIHOST
1283 if (gfp_flags & GFP_DMA) {
1284 /* Workaround: The PCI API does not support passing
1285 * a GFP flag. */
1286 dma_free_coherent(&dev->bus->host_pci->dev,
1287 size, vaddr, dma_handle);
1288 return;
1289 }
1290 pci_free_consistent(dev->bus->host_pci, size,
1291 vaddr, dma_handle);
1292 return;
1293#endif
1294 case SSB_BUSTYPE_SSB:
1295 dma_free_coherent(dev->dev, size, vaddr, dma_handle);
1296 return;
1297 default:
1298 __ssb_dma_not_implemented(dev);
1299 }
1300}
1301EXPORT_SYMBOL(ssb_dma_free_consistent);
1302
1303int ssb_bus_may_powerdown(struct ssb_bus *bus) 1231int ssb_bus_may_powerdown(struct ssb_bus *bus)
1304{ 1232{
1305 struct ssb_chipcommon *cc; 1233 struct ssb_chipcommon *cc;
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 6dcda86be6eb..6e88d2b603b4 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -626,11 +626,22 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
626 return -ENODEV; 626 return -ENODEV;
627 } 627 }
628 if (bus->chipco.dev) { /* can be unavailible! */ 628 if (bus->chipco.dev) { /* can be unavailible! */
629 bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? 629 /*
630 SSB_SPROM_BASE1 : SSB_SPROM_BASE31; 630 * get SPROM offset: SSB_SPROM_BASE1 except for
631 * chipcommon rev >= 31 or chip ID is 0x4312 and
632 * chipcommon status & 3 == 2
633 */
634 if (bus->chipco.dev->id.revision >= 31)
635 bus->sprom_offset = SSB_SPROM_BASE31;
636 else if (bus->chip_id == 0x4312 &&
637 (bus->chipco.status & 0x03) == 2)
638 bus->sprom_offset = SSB_SPROM_BASE31;
639 else
640 bus->sprom_offset = SSB_SPROM_BASE1;
631 } else { 641 } else {
632 bus->sprom_offset = SSB_SPROM_BASE1; 642 bus->sprom_offset = SSB_SPROM_BASE1;
633 } 643 }
644 ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
634 645
635 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 646 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
636 if (!buf) 647 if (!buf)