aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c32
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c24
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c30
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h18
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c123
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c69
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c48
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c62
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c70
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c88
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c86
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c167
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c40
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c31
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c42
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c102
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h5
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h13
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c56
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c19
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c17
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h24
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c80
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
-rw-r--r--drivers/net/wireless/ath/debug.h2
-rw-r--r--drivers/net/wireless/ath/key.c9
-rw-r--r--drivers/net/wireless/b43/b43.h13
-rw-r--r--drivers/net/wireless/b43/dma.c5
-rw-r--r--drivers/net/wireless/b43/phy_n.c14
-rw-r--r--drivers/net/wireless/b43/radio_2055.c8
-rw-r--r--drivers/net/wireless/b43/radio_2056.c51
-rw-r--r--drivers/net/wireless/b43/radio_2056.h1081
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig3
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c352
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c230
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c619
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c493
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c841
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.c662
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.h79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c95
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c49
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c5
-rw-r--r--drivers/net/wireless/mwl8k.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h61
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c43
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c66
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c37
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c52
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h33
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c25
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c28
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c140
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c22
-rw-r--r--drivers/net/wireless/wl1251/main.c15
-rw-r--r--drivers/net/wireless/wl1251/sdio.c101
-rw-r--r--drivers/net/wireless/wl1251/spi.c9
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h1
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h13
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c83
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h89
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c10
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c215
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c220
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c28
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.c5
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c132
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h3
-rw-r--r--drivers/net/wireless/zd1201.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/ssb/pcihost_wrapper.c7
-rw-r--r--include/linux/bitops.h11
-rw-r--r--include/linux/nl80211.h6
-rw-r--r--include/linux/rfkill.h31
-rw-r--r--include/linux/wl12xx.h8
-rw-r--r--include/net/cfg80211.h15
-rw-r--r--net/mac80211/aes_ccm.c3
-rw-r--r--net/mac80211/aes_cmac.c3
-rw-r--r--net/mac80211/debugfs.c60
-rw-r--r--net/mac80211/debugfs.h2
-rw-r--r--net/mac80211/debugfs_key.c19
-rw-r--r--net/mac80211/debugfs_sta.c26
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c16
-rw-r--r--net/rfkill/core.c14
-rw-r--r--net/wireless/reg.c134
148 files changed, 5604 insertions, 2949 deletions
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 89ed1be2d62e..8be261506056 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -642,31 +642,13 @@ static void __init omap3pandora_init_irq(void)
642 omap_gpio_init(); 642 omap_gpio_init();
643} 643}
644 644
645static void pandora_wl1251_set_power(bool enable) 645static void __init pandora_wl1251_init(void)
646{
647 /*
648 * Keep power always on until wl1251_sdio driver learns to re-init
649 * the chip after powering it down and back up.
650 */
651}
652
653static struct wl12xx_platform_data pandora_wl1251_pdata = {
654 .set_power = pandora_wl1251_set_power,
655 .use_eeprom = true,
656};
657
658static struct platform_device pandora_wl1251_data = {
659 .name = "wl1251_data",
660 .id = -1,
661 .dev = {
662 .platform_data = &pandora_wl1251_pdata,
663 },
664};
665
666static void pandora_wl1251_init(void)
667{ 646{
647 struct wl12xx_platform_data pandora_wl1251_pdata;
668 int ret; 648 int ret;
669 649
650 memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
651
670 ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq"); 652 ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq");
671 if (ret < 0) 653 if (ret < 0)
672 goto fail; 654 goto fail;
@@ -679,6 +661,11 @@ static void pandora_wl1251_init(void)
679 if (pandora_wl1251_pdata.irq < 0) 661 if (pandora_wl1251_pdata.irq < 0)
680 goto fail_irq; 662 goto fail_irq;
681 663
664 pandora_wl1251_pdata.use_eeprom = true;
665 ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
666 if (ret < 0)
667 goto fail_irq;
668
682 return; 669 return;
683 670
684fail_irq: 671fail_irq:
@@ -691,7 +678,6 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
691 &pandora_leds_gpio, 678 &pandora_leds_gpio,
692 &pandora_keys_gpio, 679 &pandora_keys_gpio,
693 &pandora_dss_device, 680 &pandora_dss_device,
694 &pandora_wl1251_data,
695 &pandora_vwlan_device, 681 &pandora_vwlan_device,
696}; 682};
697 683
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 8251946842e6..b9f93fbd9728 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -566,8 +566,8 @@ static void ath_do_set_opmode(struct ath5k_softc *sc)
566 sc->opmode, ath_opmode_to_string(sc->opmode)); 566 sc->opmode, ath_opmode_to_string(sc->opmode));
567} 567}
568 568
569void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, 569static void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
570 struct ieee80211_vif *vif) 570 struct ieee80211_vif *vif)
571{ 571{
572 struct ath_common *common = ath5k_hw_common(sc->ah); 572 struct ath_common *common = ath5k_hw_common(sc->ah);
573 struct ath_vif_iter_data iter_data; 573 struct ath_vif_iter_data iter_data;
@@ -3206,14 +3206,32 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
3206{ 3206{
3207 struct ath5k_softc *sc = hw->priv; 3207 struct ath5k_softc *sc = hw->priv;
3208 struct ieee80211_conf *conf = &hw->conf; 3208 struct ieee80211_conf *conf = &hw->conf;
3209 struct ath_common *common = ath5k_hw_common(sc->ah);
3210 struct ath_cycle_counters *cc = &common->cc_survey;
3211 unsigned int div = common->clockrate * 1000;
3209 3212
3210 if (idx != 0) 3213 if (idx != 0)
3211 return -ENOENT; 3214 return -ENOENT;
3212 3215
3213 survey->channel = conf->channel; 3216 survey->channel = conf->channel;
3214 survey->filled = SURVEY_INFO_NOISE_DBM; 3217 survey->filled = SURVEY_INFO_NOISE_DBM;
3215 survey->noise = sc->ah->ah_noise_floor; 3218 survey->noise = sc->ah->ah_noise_floor;
3216 3219
3220 spin_lock_bh(&common->cc_lock);
3221 ath_hw_cycle_counters_update(common);
3222 if (cc->cycles > 0) {
3223 survey->filled |= SURVEY_INFO_CHANNEL_TIME |
3224 SURVEY_INFO_CHANNEL_TIME_BUSY |
3225 SURVEY_INFO_CHANNEL_TIME_RX |
3226 SURVEY_INFO_CHANNEL_TIME_TX;
3227 survey->channel_time += cc->cycles / div;
3228 survey->channel_time_busy += cc->rx_busy / div;
3229 survey->channel_time_rx += cc->rx_frame / div;
3230 survey->channel_time_tx += cc->tx_frame / div;
3231 }
3232 memset(cc, 0, sizeof(*cc));
3233 spin_unlock_bh(&common->cc_lock);
3234
3217 return 0; 3235 return 0;
3218} 3236}
3219 3237
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index acda56ee521b..54dcf77e9646 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -554,63 +554,63 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
554 554
555 len += snprintf(buf+len, sizeof(buf)-len, 555 len += snprintf(buf+len, sizeof(buf)-len,
556 "RX\n---------------------\n"); 556 "RX\n---------------------\n");
557 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n", 557 len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%u\t(%u%%)\n",
558 st->rxerr_crc, 558 st->rxerr_crc,
559 st->rx_all_count > 0 ? 559 st->rx_all_count > 0 ?
560 st->rxerr_crc*100/st->rx_all_count : 0); 560 st->rxerr_crc*100/st->rx_all_count : 0);
561 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n", 561 len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%u\t(%u%%)\n",
562 st->rxerr_phy, 562 st->rxerr_phy,
563 st->rx_all_count > 0 ? 563 st->rx_all_count > 0 ?
564 st->rxerr_phy*100/st->rx_all_count : 0); 564 st->rxerr_phy*100/st->rx_all_count : 0);
565 for (i = 0; i < 32; i++) { 565 for (i = 0; i < 32; i++) {
566 if (st->rxerr_phy_code[i]) 566 if (st->rxerr_phy_code[i])
567 len += snprintf(buf+len, sizeof(buf)-len, 567 len += snprintf(buf+len, sizeof(buf)-len,
568 " phy_err[%d]\t%d\n", 568 " phy_err[%u]\t%u\n",
569 i, st->rxerr_phy_code[i]); 569 i, st->rxerr_phy_code[i]);
570 } 570 }
571 571
572 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", 572 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
573 st->rxerr_fifo, 573 st->rxerr_fifo,
574 st->rx_all_count > 0 ? 574 st->rx_all_count > 0 ?
575 st->rxerr_fifo*100/st->rx_all_count : 0); 575 st->rxerr_fifo*100/st->rx_all_count : 0);
576 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n", 576 len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%u\t(%u%%)\n",
577 st->rxerr_decrypt, 577 st->rxerr_decrypt,
578 st->rx_all_count > 0 ? 578 st->rx_all_count > 0 ?
579 st->rxerr_decrypt*100/st->rx_all_count : 0); 579 st->rxerr_decrypt*100/st->rx_all_count : 0);
580 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n", 580 len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%u\t(%u%%)\n",
581 st->rxerr_mic, 581 st->rxerr_mic,
582 st->rx_all_count > 0 ? 582 st->rx_all_count > 0 ?
583 st->rxerr_mic*100/st->rx_all_count : 0); 583 st->rxerr_mic*100/st->rx_all_count : 0);
584 len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n", 584 len += snprintf(buf+len, sizeof(buf)-len, "process\t%u\t(%u%%)\n",
585 st->rxerr_proc, 585 st->rxerr_proc,
586 st->rx_all_count > 0 ? 586 st->rx_all_count > 0 ?
587 st->rxerr_proc*100/st->rx_all_count : 0); 587 st->rxerr_proc*100/st->rx_all_count : 0);
588 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n", 588 len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%u\t(%u%%)\n",
589 st->rxerr_jumbo, 589 st->rxerr_jumbo,
590 st->rx_all_count > 0 ? 590 st->rx_all_count > 0 ?
591 st->rxerr_jumbo*100/st->rx_all_count : 0); 591 st->rxerr_jumbo*100/st->rx_all_count : 0);
592 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", 592 len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%u]\n",
593 st->rx_all_count); 593 st->rx_all_count);
594 len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n", 594 len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%u\n",
595 st->rx_bytes_count); 595 st->rx_bytes_count);
596 596
597 len += snprintf(buf+len, sizeof(buf)-len, 597 len += snprintf(buf+len, sizeof(buf)-len,
598 "\nTX\n---------------------\n"); 598 "\nTX\n---------------------\n");
599 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n", 599 len += snprintf(buf+len, sizeof(buf)-len, "retry\t%u\t(%u%%)\n",
600 st->txerr_retry, 600 st->txerr_retry,
601 st->tx_all_count > 0 ? 601 st->tx_all_count > 0 ?
602 st->txerr_retry*100/st->tx_all_count : 0); 602 st->txerr_retry*100/st->tx_all_count : 0);
603 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", 603 len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%u\t(%u%%)\n",
604 st->txerr_fifo, 604 st->txerr_fifo,
605 st->tx_all_count > 0 ? 605 st->tx_all_count > 0 ?
606 st->txerr_fifo*100/st->tx_all_count : 0); 606 st->txerr_fifo*100/st->tx_all_count : 0);
607 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n", 607 len += snprintf(buf+len, sizeof(buf)-len, "filter\t%u\t(%u%%)\n",
608 st->txerr_filt, 608 st->txerr_filt,
609 st->tx_all_count > 0 ? 609 st->tx_all_count > 0 ?
610 st->txerr_filt*100/st->tx_all_count : 0); 610 st->txerr_filt*100/st->tx_all_count : 0);
611 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", 611 len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%u]\n",
612 st->tx_all_count); 612 st->tx_all_count);
613 len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n", 613 len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%u\n",
614 st->tx_bytes_count); 614 st->tx_bytes_count);
615 615
616 if (len > sizeof(buf)) 616 if (len > sizeof(buf))
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
index b2adb2a281c2..2509d0bf037d 100644
--- a/drivers/net/wireless/ath/ath5k/desc.h
+++ b/drivers/net/wireless/ath/ath5k/desc.h
@@ -26,7 +26,7 @@
26struct ath5k_hw_rx_ctl { 26struct ath5k_hw_rx_ctl {
27 u32 rx_control_0; /* RX control word 0 */ 27 u32 rx_control_0; /* RX control word 0 */
28 u32 rx_control_1; /* RX control word 1 */ 28 u32 rx_control_1; /* RX control word 1 */
29} __packed; 29} __packed __aligned(4);
30 30
31/* RX control word 1 fields/flags */ 31/* RX control word 1 fields/flags */
32#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */ 32#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */
@@ -39,7 +39,7 @@ struct ath5k_hw_rx_ctl {
39struct ath5k_hw_rx_status { 39struct ath5k_hw_rx_status {
40 u32 rx_status_0; /* RX status word 0 */ 40 u32 rx_status_0; /* RX status word 0 */
41 u32 rx_status_1; /* RX status word 1 */ 41 u32 rx_status_1; /* RX status word 1 */
42} __packed; 42} __packed __aligned(4);
43 43
44/* 5210/5211 */ 44/* 5210/5211 */
45/* RX status word 0 fields/flags */ 45/* RX status word 0 fields/flags */
@@ -129,7 +129,7 @@ enum ath5k_phy_error_code {
129struct ath5k_hw_2w_tx_ctl { 129struct ath5k_hw_2w_tx_ctl {
130 u32 tx_control_0; /* TX control word 0 */ 130 u32 tx_control_0; /* TX control word 0 */
131 u32 tx_control_1; /* TX control word 1 */ 131 u32 tx_control_1; /* TX control word 1 */
132} __packed; 132} __packed __aligned(4);
133 133
134/* TX control word 0 fields/flags */ 134/* TX control word 0 fields/flags */
135#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ 135#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -185,7 +185,7 @@ struct ath5k_hw_4w_tx_ctl {
185 u32 tx_control_1; /* TX control word 1 */ 185 u32 tx_control_1; /* TX control word 1 */
186 u32 tx_control_2; /* TX control word 2 */ 186 u32 tx_control_2; /* TX control word 2 */
187 u32 tx_control_3; /* TX control word 3 */ 187 u32 tx_control_3; /* TX control word 3 */
188} __packed; 188} __packed __aligned(4);
189 189
190/* TX control word 0 fields/flags */ 190/* TX control word 0 fields/flags */
191#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ 191#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */
@@ -244,7 +244,7 @@ struct ath5k_hw_4w_tx_ctl {
244struct ath5k_hw_tx_status { 244struct ath5k_hw_tx_status {
245 u32 tx_status_0; /* TX status word 0 */ 245 u32 tx_status_0; /* TX status word 0 */
246 u32 tx_status_1; /* TX status word 1 */ 246 u32 tx_status_1; /* TX status word 1 */
247} __packed; 247} __packed __aligned(4);
248 248
249/* TX status word 0 fields/flags */ 249/* TX status word 0 fields/flags */
250#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */ 250#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */
@@ -282,7 +282,7 @@ struct ath5k_hw_tx_status {
282struct ath5k_hw_5210_tx_desc { 282struct ath5k_hw_5210_tx_desc {
283 struct ath5k_hw_2w_tx_ctl tx_ctl; 283 struct ath5k_hw_2w_tx_ctl tx_ctl;
284 struct ath5k_hw_tx_status tx_stat; 284 struct ath5k_hw_tx_status tx_stat;
285} __packed; 285} __packed __aligned(4);
286 286
287/* 287/*
288 * 5212 hardware TX descriptor 288 * 5212 hardware TX descriptor
@@ -290,7 +290,7 @@ struct ath5k_hw_5210_tx_desc {
290struct ath5k_hw_5212_tx_desc { 290struct ath5k_hw_5212_tx_desc {
291 struct ath5k_hw_4w_tx_ctl tx_ctl; 291 struct ath5k_hw_4w_tx_ctl tx_ctl;
292 struct ath5k_hw_tx_status tx_stat; 292 struct ath5k_hw_tx_status tx_stat;
293} __packed; 293} __packed __aligned(4);
294 294
295/* 295/*
296 * Common hardware RX descriptor 296 * Common hardware RX descriptor
@@ -298,7 +298,7 @@ struct ath5k_hw_5212_tx_desc {
298struct ath5k_hw_all_rx_desc { 298struct ath5k_hw_all_rx_desc {
299 struct ath5k_hw_rx_ctl rx_ctl; 299 struct ath5k_hw_rx_ctl rx_ctl;
300 struct ath5k_hw_rx_status rx_stat; 300 struct ath5k_hw_rx_status rx_stat;
301} __packed; 301} __packed __aligned(4);
302 302
303/* 303/*
304 * Atheros hardware DMA descriptor 304 * Atheros hardware DMA descriptor
@@ -313,7 +313,7 @@ struct ath5k_desc {
313 struct ath5k_hw_5212_tx_desc ds_tx5212; 313 struct ath5k_hw_5212_tx_desc ds_tx5212;
314 struct ath5k_hw_all_rx_desc ds_rx; 314 struct ath5k_hw_all_rx_desc ds_rx;
315 } ud; 315 } ud;
316} __packed; 316} __packed __aligned(4);
317 317
318#define AR5K_RXDESC_INTREQ 0x0020 318#define AR5K_RXDESC_INTREQ 0x0020
319 319
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 219367884e64..6b43f535ff53 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1102,18 +1102,12 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1102 PHY calibration 1102 PHY calibration
1103\*****************/ 1103\*****************/
1104 1104
1105static int sign_extend(int val, const int nbits)
1106{
1107 int order = BIT(nbits-1);
1108 return (val ^ order) - order;
1109}
1110
1111static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah) 1105static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1112{ 1106{
1113 s32 val; 1107 s32 val;
1114 1108
1115 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF); 1109 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1116 return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9); 1110 return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
1117} 1111}
1118 1112
1119void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) 1113void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index ea9f4497f58c..c83a22cfbe1e 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -873,7 +873,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
873 channel->max_antenna_gain * 2, 873 channel->max_antenna_gain * 2,
874 channel->max_power * 2, 874 channel->max_power * 2,
875 min((u32) MAX_RATE_POWER, 875 min((u32) MAX_RATE_POWER,
876 (u32) regulatory->power_limit)); 876 (u32) regulatory->power_limit), false);
877 877
878 /* Write analog registers */ 878 /* Write analog registers */
879 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 879 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
@@ -1490,25 +1490,25 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
1490 int16_t nf; 1490 int16_t nf;
1491 1491
1492 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); 1492 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1493 nfarray[0] = sign_extend(nf, 9); 1493 nfarray[0] = sign_extend32(nf, 8);
1494 1494
1495 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); 1495 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
1496 nfarray[1] = sign_extend(nf, 9); 1496 nfarray[1] = sign_extend32(nf, 8);
1497 1497
1498 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); 1498 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
1499 nfarray[2] = sign_extend(nf, 9); 1499 nfarray[2] = sign_extend32(nf, 8);
1500 1500
1501 if (!IS_CHAN_HT40(ah->curchan)) 1501 if (!IS_CHAN_HT40(ah->curchan))
1502 return; 1502 return;
1503 1503
1504 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 1504 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
1505 nfarray[3] = sign_extend(nf, 9); 1505 nfarray[3] = sign_extend32(nf, 8);
1506 1506
1507 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); 1507 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
1508 nfarray[4] = sign_extend(nf, 9); 1508 nfarray[4] = sign_extend32(nf, 8);
1509 1509
1510 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); 1510 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
1511 nfarray[5] = sign_extend(nf, 9); 1511 nfarray[5] = sign_extend32(nf, 8);
1512} 1512}
1513 1513
1514/* 1514/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 50dda394f8be..f0268e5eab34 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -90,13 +90,10 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
90 90
91 *masked = isr & ATH9K_INT_COMMON; 91 *masked = isr & ATH9K_INT_COMMON;
92 92
93 if (ah->config.rx_intr_mitigation) { 93 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM |
94 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) 94 AR_ISR_RXOK | AR_ISR_RXERR))
95 *masked |= ATH9K_INT_RX;
96 }
97
98 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
99 *masked |= ATH9K_INT_RX; 95 *masked |= ATH9K_INT_RX;
96
100 if (isr & 97 if (isr &
101 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | 98 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
102 AR_ISR_TXEOL)) { 99 AR_ISR_TXEOL)) {
@@ -118,14 +115,6 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
118 "receive FIFO overrun interrupt\n"); 115 "receive FIFO overrun interrupt\n");
119 } 116 }
120 117
121 if (!AR_SREV_9100(ah)) {
122 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
123 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
124 if (isr5 & AR_ISR_S5_TIM_TIMER)
125 *masked |= ATH9K_INT_TIM_TIMER;
126 }
127 }
128
129 *masked |= mask2; 118 *masked |= mask2;
130 } 119 }
131 120
@@ -136,17 +125,18 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
136 u32 s5_s; 125 u32 s5_s;
137 126
138 s5_s = REG_READ(ah, AR_ISR_S5_S); 127 s5_s = REG_READ(ah, AR_ISR_S5_S);
139 if (isr & AR_ISR_GENTMR) { 128 ah->intr_gen_timer_trigger =
140 ah->intr_gen_timer_trigger =
141 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); 129 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
142 130
143 ah->intr_gen_timer_thresh = 131 ah->intr_gen_timer_thresh =
144 MS(s5_s, AR_ISR_S5_GENTIMER_THRESH); 132 MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
145 133
146 if (ah->intr_gen_timer_trigger) 134 if (ah->intr_gen_timer_trigger)
147 *masked |= ATH9K_INT_GENTIMER; 135 *masked |= ATH9K_INT_GENTIMER;
148 136
149 } 137 if ((s5_s & AR_ISR_S5_TIM_TIMER) &&
138 !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
139 *masked |= ATH9K_INT_TIM_TIMER;
150 } 140 }
151 141
152 if (sync_cause) { 142 if (sync_cause) {
@@ -218,77 +208,70 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
218 struct ath_tx_status *ts) 208 struct ath_tx_status *ts)
219{ 209{
220 struct ar5416_desc *ads = AR5416DESC(ds); 210 struct ar5416_desc *ads = AR5416DESC(ds);
211 u32 status;
221 212
222 if ((ads->ds_txstatus9 & AR_TxDone) == 0) 213 status = ACCESS_ONCE(ads->ds_txstatus9);
214 if ((status & AR_TxDone) == 0)
223 return -EINPROGRESS; 215 return -EINPROGRESS;
224 216
225 ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
226 ts->ts_tstamp = ads->AR_SendTimestamp; 217 ts->ts_tstamp = ads->AR_SendTimestamp;
227 ts->ts_status = 0; 218 ts->ts_status = 0;
228 ts->ts_flags = 0; 219 ts->ts_flags = 0;
229 220
230 if (ads->ds_txstatus1 & AR_FrmXmitOK) 221 if (status & AR_TxOpExceeded)
222 ts->ts_status |= ATH9K_TXERR_XTXOP;
223 ts->tid = MS(status, AR_TxTid);
224 ts->ts_rateindex = MS(status, AR_FinalTxIdx);
225 ts->ts_seqnum = MS(status, AR_SeqNum);
226
227 status = ACCESS_ONCE(ads->ds_txstatus0);
228 ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
229 ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
230 ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
231 if (status & AR_TxBaStatus) {
232 ts->ts_flags |= ATH9K_TX_BA;
233 ts->ba_low = ads->AR_BaBitmapLow;
234 ts->ba_high = ads->AR_BaBitmapHigh;
235 }
236
237 status = ACCESS_ONCE(ads->ds_txstatus1);
238 if (status & AR_FrmXmitOK)
231 ts->ts_status |= ATH9K_TX_ACKED; 239 ts->ts_status |= ATH9K_TX_ACKED;
232 if (ads->ds_txstatus1 & AR_ExcessiveRetries) 240 else {
233 ts->ts_status |= ATH9K_TXERR_XRETRY; 241 if (status & AR_ExcessiveRetries)
234 if (ads->ds_txstatus1 & AR_Filtered) 242 ts->ts_status |= ATH9K_TXERR_XRETRY;
235 ts->ts_status |= ATH9K_TXERR_FILT; 243 if (status & AR_Filtered)
236 if (ads->ds_txstatus1 & AR_FIFOUnderrun) { 244 ts->ts_status |= ATH9K_TXERR_FILT;
237 ts->ts_status |= ATH9K_TXERR_FIFO; 245 if (status & AR_FIFOUnderrun) {
238 ath9k_hw_updatetxtriglevel(ah, true); 246 ts->ts_status |= ATH9K_TXERR_FIFO;
247 ath9k_hw_updatetxtriglevel(ah, true);
248 }
239 } 249 }
240 if (ads->ds_txstatus9 & AR_TxOpExceeded) 250 if (status & AR_TxTimerExpired)
241 ts->ts_status |= ATH9K_TXERR_XTXOP;
242 if (ads->ds_txstatus1 & AR_TxTimerExpired)
243 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; 251 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
244 252 if (status & AR_DescCfgErr)
245 if (ads->ds_txstatus1 & AR_DescCfgErr)
246 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; 253 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
247 if (ads->ds_txstatus1 & AR_TxDataUnderrun) { 254 if (status & AR_TxDataUnderrun) {
248 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; 255 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
249 ath9k_hw_updatetxtriglevel(ah, true); 256 ath9k_hw_updatetxtriglevel(ah, true);
250 } 257 }
251 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { 258 if (status & AR_TxDelimUnderrun) {
252 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; 259 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
253 ath9k_hw_updatetxtriglevel(ah, true); 260 ath9k_hw_updatetxtriglevel(ah, true);
254 } 261 }
255 if (ads->ds_txstatus0 & AR_TxBaStatus) { 262 ts->ts_shortretry = MS(status, AR_RTSFailCnt);
256 ts->ts_flags |= ATH9K_TX_BA; 263 ts->ts_longretry = MS(status, AR_DataFailCnt);
257 ts->ba_low = ads->AR_BaBitmapLow; 264 ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
258 ts->ba_high = ads->AR_BaBitmapHigh;
259 }
260 265
261 ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); 266 status = ACCESS_ONCE(ads->ds_txstatus5);
262 switch (ts->ts_rateindex) { 267 ts->ts_rssi = MS(status, AR_TxRSSICombined);
263 case 0: 268 ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
264 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); 269 ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
265 break; 270 ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
266 case 1:
267 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
268 break;
269 case 2:
270 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
271 break;
272 case 3:
273 ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
274 break;
275 }
276 271
277 ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
278 ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
279 ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
280 ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
281 ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
282 ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
283 ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
284 ts->evm0 = ads->AR_TxEVM0; 272 ts->evm0 = ads->AR_TxEVM0;
285 ts->evm1 = ads->AR_TxEVM1; 273 ts->evm1 = ads->AR_TxEVM1;
286 ts->evm2 = ads->AR_TxEVM2; 274 ts->evm2 = ads->AR_TxEVM2;
287 ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
288 ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
289 ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
290 ts->tid = MS(ads->ds_txstatus9, AR_TxTid);
291 ts->ts_antenna = 0;
292 275
293 return 0; 276 return 0;
294} 277}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index c00cdc67b55b..3fb97fdc1240 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -473,21 +473,21 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
473 int16_t nf; 473 int16_t nf;
474 474
475 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); 475 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
476 nfarray[0] = sign_extend(nf, 9); 476 nfarray[0] = sign_extend32(nf, 8);
477 477
478 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); 478 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
479 if (IS_CHAN_HT40(ah->curchan)) 479 if (IS_CHAN_HT40(ah->curchan))
480 nfarray[3] = sign_extend(nf, 9); 480 nfarray[3] = sign_extend32(nf, 8);
481 481
482 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) 482 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
483 return; 483 return;
484 484
485 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); 485 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
486 nfarray[1] = sign_extend(nf, 9); 486 nfarray[1] = sign_extend32(nf, 8);
487 487
488 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); 488 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
489 if (IS_CHAN_HT40(ah->curchan)) 489 if (IS_CHAN_HT40(ah->curchan))
490 nfarray[4] = sign_extend(nf, 9); 490 nfarray[4] = sign_extend32(nf, 8);
491} 491}
492 492
493static void ar9002_hw_set_nf_limits(struct ath_hw *ah) 493static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c4182359bee4..a88fe0d6142f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -2131,8 +2131,9 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2131 struct ath9k_channel *chan, u16 cfgCtl, 2131 struct ath9k_channel *chan, u16 cfgCtl,
2132 u8 twiceAntennaReduction, 2132 u8 twiceAntennaReduction,
2133 u8 twiceMaxRegulatoryPower, 2133 u8 twiceMaxRegulatoryPower,
2134 u8 powerLimit) 2134 u8 powerLimit, bool test)
2135{ 2135{
2136 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
2136 struct ath_common *common = ath9k_hw_common(ah); 2137 struct ath_common *common = ath9k_hw_common(ah);
2137 u8 targetPowerValT2[ar9300RateSize]; 2138 u8 targetPowerValT2[ar9300RateSize];
2138 unsigned int i = 0; 2139 unsigned int i = 0;
@@ -2144,7 +2145,16 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2144 twiceMaxRegulatoryPower, 2145 twiceMaxRegulatoryPower,
2145 powerLimit); 2146 powerLimit);
2146 2147
2147 while (i < ar9300RateSize) { 2148 regulatory->max_power_level = 0;
2149 for (i = 0; i < ar9300RateSize; i++) {
2150 if (targetPowerValT2[i] > regulatory->max_power_level)
2151 regulatory->max_power_level = targetPowerValT2[i];
2152 }
2153
2154 if (test)
2155 return;
2156
2157 for (i = 0; i < ar9300RateSize; i++) {
2148 ath_print(common, ATH_DBG_EEPROM, 2158 ath_print(common, ATH_DBG_EEPROM,
2149 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 2159 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2150 i++; 2160 i++;
@@ -2159,9 +2169,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2159 i++; 2169 i++;
2160 } 2170 }
2161 2171
2162 /* Write target power array to registers */
2163 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
2164
2165 /* 2172 /*
2166 * This is the TX power we send back to driver core, 2173 * This is the TX power we send back to driver core,
2167 * and it can use to pass to userspace to display our 2174 * and it can use to pass to userspace to display our
@@ -2180,7 +2187,10 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2180 i = ALL_TARGET_HT20_0_8_16; /* ht20 */ 2187 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
2181 2188
2182 ah->txpower_limit = targetPowerValT2[i]; 2189 ah->txpower_limit = targetPowerValT2[i];
2190 regulatory->max_power_level = targetPowerValT2[i];
2183 2191
2192 /* Write target power array to registers */
2193 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
2184 ar9003_hw_calibration_apply(ah, chan->channel); 2194 ar9003_hw_calibration_apply(ah, chan->channel);
2185} 2195}
2186 2196
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 3b424ca1ba84..10c812e353a6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -237,10 +237,12 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
237 struct ath_tx_status *ts) 237 struct ath_tx_status *ts)
238{ 238{
239 struct ar9003_txs *ads; 239 struct ar9003_txs *ads;
240 u32 status;
240 241
241 ads = &ah->ts_ring[ah->ts_tail]; 242 ads = &ah->ts_ring[ah->ts_tail];
242 243
243 if ((ads->status8 & AR_TxDone) == 0) 244 status = ACCESS_ONCE(ads->status8);
245 if ((status & AR_TxDone) == 0)
244 return -EINPROGRESS; 246 return -EINPROGRESS;
245 247
246 ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; 248 ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
@@ -253,57 +255,58 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
253 return -EIO; 255 return -EIO;
254 } 256 }
255 257
258 if (status & AR_TxOpExceeded)
259 ts->ts_status |= ATH9K_TXERR_XTXOP;
260 ts->ts_rateindex = MS(status, AR_FinalTxIdx);
261 ts->ts_seqnum = MS(status, AR_SeqNum);
262 ts->tid = MS(status, AR_TxTid);
263
256 ts->qid = MS(ads->ds_info, AR_TxQcuNum); 264 ts->qid = MS(ads->ds_info, AR_TxQcuNum);
257 ts->desc_id = MS(ads->status1, AR_TxDescId); 265 ts->desc_id = MS(ads->status1, AR_TxDescId);
258 ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
259 ts->ts_tstamp = ads->status4; 266 ts->ts_tstamp = ads->status4;
260 ts->ts_status = 0; 267 ts->ts_status = 0;
261 ts->ts_flags = 0; 268 ts->ts_flags = 0;
262 269
263 if (ads->status3 & AR_ExcessiveRetries) 270 status = ACCESS_ONCE(ads->status2);
271 ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
272 ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
273 ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
274 if (status & AR_TxBaStatus) {
275 ts->ts_flags |= ATH9K_TX_BA;
276 ts->ba_low = ads->status5;
277 ts->ba_high = ads->status6;
278 }
279
280 status = ACCESS_ONCE(ads->status3);
281 if (status & AR_ExcessiveRetries)
264 ts->ts_status |= ATH9K_TXERR_XRETRY; 282 ts->ts_status |= ATH9K_TXERR_XRETRY;
265 if (ads->status3 & AR_Filtered) 283 if (status & AR_Filtered)
266 ts->ts_status |= ATH9K_TXERR_FILT; 284 ts->ts_status |= ATH9K_TXERR_FILT;
267 if (ads->status3 & AR_FIFOUnderrun) { 285 if (status & AR_FIFOUnderrun) {
268 ts->ts_status |= ATH9K_TXERR_FIFO; 286 ts->ts_status |= ATH9K_TXERR_FIFO;
269 ath9k_hw_updatetxtriglevel(ah, true); 287 ath9k_hw_updatetxtriglevel(ah, true);
270 } 288 }
271 if (ads->status8 & AR_TxOpExceeded) 289 if (status & AR_TxTimerExpired)
272 ts->ts_status |= ATH9K_TXERR_XTXOP;
273 if (ads->status3 & AR_TxTimerExpired)
274 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; 290 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
275 291 if (status & AR_DescCfgErr)
276 if (ads->status3 & AR_DescCfgErr)
277 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; 292 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
278 if (ads->status3 & AR_TxDataUnderrun) { 293 if (status & AR_TxDataUnderrun) {
279 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; 294 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
280 ath9k_hw_updatetxtriglevel(ah, true); 295 ath9k_hw_updatetxtriglevel(ah, true);
281 } 296 }
282 if (ads->status3 & AR_TxDelimUnderrun) { 297 if (status & AR_TxDelimUnderrun) {
283 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; 298 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
284 ath9k_hw_updatetxtriglevel(ah, true); 299 ath9k_hw_updatetxtriglevel(ah, true);
285 } 300 }
286 if (ads->status2 & AR_TxBaStatus) { 301 ts->ts_shortretry = MS(status, AR_RTSFailCnt);
287 ts->ts_flags |= ATH9K_TX_BA; 302 ts->ts_longretry = MS(status, AR_DataFailCnt);
288 ts->ba_low = ads->status5; 303 ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
289 ts->ba_high = ads->status6; 304
290 } 305 status = ACCESS_ONCE(ads->status7);
291 306 ts->ts_rssi = MS(status, AR_TxRSSICombined);
292 ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx); 307 ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
293 308 ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
294 ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined); 309 ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
295 ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
296 ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
297 ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
298 ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
299 ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
300 ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
301 ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
302 ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
303 ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
304 ts->ts_antenna = 0;
305
306 ts->tid = MS(ads->status8, AR_TxTid);
307 310
308 memset(ads, 0, sizeof(*ads)); 311 memset(ads, 0, sizeof(*ads));
309 312
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 9f2cea70a840..45cc7e80436c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -65,7 +65,7 @@ struct ar9003_rxs {
65 u32 status9; 65 u32 status9;
66 u32 status10; 66 u32 status10;
67 u32 status11; 67 u32 status11;
68} __packed; 68} __packed __aligned(4);
69 69
70/* Transmit Control Descriptor */ 70/* Transmit Control Descriptor */
71struct ar9003_txc { 71struct ar9003_txc {
@@ -93,7 +93,7 @@ struct ar9003_txc {
93 u32 ctl21; /* DMA control 21 */ 93 u32 ctl21; /* DMA control 21 */
94 u32 ctl22; /* DMA control 22 */ 94 u32 ctl22; /* DMA control 22 */
95 u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */ 95 u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
96} __packed; 96} __packed __aligned(4);
97 97
98struct ar9003_txs { 98struct ar9003_txs {
99 u32 ds_info; 99 u32 ds_info;
@@ -105,7 +105,7 @@ struct ar9003_txs {
105 u32 status6; 105 u32 status6;
106 u32 status7; 106 u32 status7;
107 u32 status8; 107 u32 status8;
108} __packed; 108} __packed __aligned(4);
109 109
110void ar9003_hw_attach_mac_ops(struct ath_hw *hw); 110void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
111void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size); 111void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 669b777729b3..44c5454b2ad8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -614,7 +614,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
614 channel->max_antenna_gain * 2, 614 channel->max_antenna_gain * 2,
615 channel->max_power * 2, 615 channel->max_power * 2,
616 min((u32) MAX_RATE_POWER, 616 min((u32) MAX_RATE_POWER,
617 (u32) regulatory->power_limit)); 617 (u32) regulatory->power_limit), false);
618 618
619 return 0; 619 return 0;
620} 620}
@@ -1023,25 +1023,25 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah,
1023 int16_t nf; 1023 int16_t nf;
1024 1024
1025 nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); 1025 nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
1026 nfarray[0] = sign_extend(nf, 9); 1026 nfarray[0] = sign_extend32(nf, 8);
1027 1027
1028 nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); 1028 nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
1029 nfarray[1] = sign_extend(nf, 9); 1029 nfarray[1] = sign_extend32(nf, 8);
1030 1030
1031 nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); 1031 nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
1032 nfarray[2] = sign_extend(nf, 9); 1032 nfarray[2] = sign_extend32(nf, 8);
1033 1033
1034 if (!IS_CHAN_HT40(ah->curchan)) 1034 if (!IS_CHAN_HT40(ah->curchan))
1035 return; 1035 return;
1036 1036
1037 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 1037 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
1038 nfarray[3] = sign_extend(nf, 9); 1038 nfarray[3] = sign_extend32(nf, 8);
1039 1039
1040 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); 1040 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
1041 nfarray[4] = sign_extend(nf, 9); 1041 nfarray[4] = sign_extend32(nf, 8);
1042 1042
1043 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); 1043 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
1044 nfarray[5] = sign_extend(nf, 9); 1044 nfarray[5] = sign_extend32(nf, 8);
1045} 1045}
1046 1046
1047static void ar9003_hw_set_nf_limits(struct ath_hw *ah) 1047static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 170d44a35ccb..b3180935875d 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -195,7 +195,6 @@ enum ATH_AGGR_STATUS {
195 195
196#define ATH_TXFIFO_DEPTH 8 196#define ATH_TXFIFO_DEPTH 8
197struct ath_txq { 197struct ath_txq {
198 int axq_class;
199 u32 axq_qnum; 198 u32 axq_qnum;
200 u32 *axq_link; 199 u32 *axq_link;
201 struct list_head axq_q; 200 struct list_head axq_q;
@@ -208,11 +207,12 @@ struct ath_txq {
208 struct list_head txq_fifo_pending; 207 struct list_head txq_fifo_pending;
209 u8 txq_headidx; 208 u8 txq_headidx;
210 u8 txq_tailidx; 209 u8 txq_tailidx;
210 int pending_frames;
211}; 211};
212 212
213struct ath_atx_ac { 213struct ath_atx_ac {
214 struct ath_txq *txq;
214 int sched; 215 int sched;
215 int qnum;
216 struct list_head list; 216 struct list_head list;
217 struct list_head tid_q; 217 struct list_head tid_q;
218}; 218};
@@ -270,7 +270,6 @@ struct ath_node {
270 struct ath_atx_ac ac[WME_NUM_AC]; 270 struct ath_atx_ac ac[WME_NUM_AC];
271 u16 maxampdu; 271 u16 maxampdu;
272 u8 mpdudensity; 272 u8 mpdudensity;
273 int last_rssi;
274}; 273};
275 274
276#define AGGR_CLEANUP BIT(1) 275#define AGGR_CLEANUP BIT(1)
@@ -291,12 +290,11 @@ struct ath_tx_control {
291struct ath_tx { 290struct ath_tx {
292 u16 seq_no; 291 u16 seq_no;
293 u32 txqsetup; 292 u32 txqsetup;
294 int hwq_map[WME_NUM_AC];
295 spinlock_t txbuflock; 293 spinlock_t txbuflock;
296 struct list_head txbuf; 294 struct list_head txbuf;
297 struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; 295 struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
298 struct ath_descdma txdma; 296 struct ath_descdma txdma;
299 int pending_frames[WME_NUM_AC]; 297 struct ath_txq *txq_map[WME_NUM_AC];
300}; 298};
301 299
302struct ath_rx_edma { 300struct ath_rx_edma {
@@ -310,7 +308,6 @@ struct ath_rx {
310 u8 rxotherant; 308 u8 rxotherant;
311 u32 *rxlink; 309 u32 *rxlink;
312 unsigned int rxfilter; 310 unsigned int rxfilter;
313 spinlock_t pcu_lock;
314 spinlock_t rxbuflock; 311 spinlock_t rxbuflock;
315 struct list_head rxbuf; 312 struct list_head rxbuf;
316 struct ath_descdma rxdma; 313 struct ath_descdma rxdma;
@@ -327,7 +324,6 @@ void ath_rx_cleanup(struct ath_softc *sc);
327int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); 324int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
328struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); 325struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
329void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); 326void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
330int ath_tx_setup(struct ath_softc *sc, int haltype);
331void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); 327void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
332void ath_draintxq(struct ath_softc *sc, 328void ath_draintxq(struct ath_softc *sc,
333 struct ath_txq *txq, bool retry_tx); 329 struct ath_txq *txq, bool retry_tx);
@@ -600,9 +596,9 @@ struct ath_softc {
600 struct ath_hw *sc_ah; 596 struct ath_hw *sc_ah;
601 void __iomem *mem; 597 void __iomem *mem;
602 int irq; 598 int irq;
603 spinlock_t sc_resetlock;
604 spinlock_t sc_serial_rw; 599 spinlock_t sc_serial_rw;
605 spinlock_t sc_pm_lock; 600 spinlock_t sc_pm_lock;
601 spinlock_t sc_pcu_lock;
606 struct mutex mutex; 602 struct mutex mutex;
607 struct work_struct paprd_work; 603 struct work_struct paprd_work;
608 struct work_struct hw_check_work; 604 struct work_struct hw_check_work;
@@ -662,11 +658,11 @@ struct ath_wiphy {
662 bool idle; 658 bool idle;
663 int chan_idx; 659 int chan_idx;
664 int chan_is_ht; 660 int chan_is_ht;
661 int last_rssi;
665}; 662};
666 663
667void ath9k_tasklet(unsigned long data); 664void ath9k_tasklet(unsigned long data);
668int ath_reset(struct ath_softc *sc, bool retry_tx); 665int ath_reset(struct ath_softc *sc, bool retry_tx);
669int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
670int ath_cabq_update(struct ath_softc *); 666int ath_cabq_update(struct ath_softc *);
671 667
672static inline void ath_read_cachesize(struct ath_common *common, int *csz) 668static inline void ath_read_cachesize(struct ath_common *common, int *csz)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 19891e7d49ae..2377376c8d4d 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -28,7 +28,7 @@ int ath_beaconq_config(struct ath_softc *sc)
28 struct ath_hw *ah = sc->sc_ah; 28 struct ath_hw *ah = sc->sc_ah;
29 struct ath_common *common = ath9k_hw_common(ah); 29 struct ath_common *common = ath9k_hw_common(ah);
30 struct ath9k_tx_queue_info qi, qi_be; 30 struct ath9k_tx_queue_info qi, qi_be;
31 int qnum; 31 struct ath_txq *txq;
32 32
33 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); 33 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
34 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 34 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
@@ -38,8 +38,8 @@ 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 = sc->tx.hwq_map[WME_AC_BE]; 41 txq = sc->tx.txq_map[WME_AC_BE];
42 ath9k_hw_get_txq_props(ah, qnum, &qi_be); 42 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
43 qi.tqi_aifs = qi_be.tqi_aifs; 43 qi.tqi_aifs = qi_be.tqi_aifs;
44 qi.tqi_cwmin = 4*qi_be.tqi_cwmin; 44 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
45 qi.tqi_cwmax = qi_be.tqi_cwmax; 45 qi.tqi_cwmax = qi_be.tqi_cwmax;
@@ -503,7 +503,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
503 503
504 /* Set the computed AP beacon timers */ 504 /* Set the computed AP beacon timers */
505 505
506 ath9k_hw_set_interrupts(ah, 0); 506 ath9k_hw_disable_interrupts(ah);
507 ath9k_beacon_init(sc, nexttbtt, intval); 507 ath9k_beacon_init(sc, nexttbtt, intval);
508 sc->beacon.bmisscnt = 0; 508 sc->beacon.bmisscnt = 0;
509 ath9k_hw_set_interrupts(ah, ah->imask); 509 ath9k_hw_set_interrupts(ah, ah->imask);
@@ -638,7 +638,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
638 638
639 /* Set the computed STA beacon timers */ 639 /* Set the computed STA beacon timers */
640 640
641 ath9k_hw_set_interrupts(ah, 0); 641 ath9k_hw_disable_interrupts(ah);
642 ath9k_hw_set_sta_beacon_timers(ah, &bs); 642 ath9k_hw_set_sta_beacon_timers(ah, &bs);
643 ah->imask |= ATH9K_INT_BMISS; 643 ah->imask |= ATH9K_INT_BMISS;
644 ath9k_hw_set_interrupts(ah, ah->imask); 644 ath9k_hw_set_interrupts(ah, ah->imask);
@@ -686,7 +686,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
686 686
687 /* Set the computed ADHOC beacon timers */ 687 /* Set the computed ADHOC beacon timers */
688 688
689 ath9k_hw_set_interrupts(ah, 0); 689 ath9k_hw_disable_interrupts(ah);
690 ath9k_beacon_init(sc, nexttbtt, intval); 690 ath9k_beacon_init(sc, nexttbtt, intval);
691 sc->beacon.bmisscnt = 0; 691 sc->beacon.bmisscnt = 0;
692 ath9k_hw_set_interrupts(ah, ah->imask); 692 ath9k_hw_set_interrupts(ah, ah->imask);
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index f43a2d98421c..48b07c319a7f 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -107,12 +107,10 @@ static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
107/* 107/*
108 * Update internal channel flags. 108 * Update internal channel flags.
109 */ 109 */
110void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, 110void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
111 struct ath9k_channel *ichan) 111 struct ieee80211_channel *chan,
112 enum nl80211_channel_type channel_type)
112{ 113{
113 struct ieee80211_channel *chan = hw->conf.channel;
114 struct ieee80211_conf *conf = &hw->conf;
115
116 ichan->channel = chan->center_freq; 114 ichan->channel = chan->center_freq;
117 ichan->chan = chan; 115 ichan->chan = chan;
118 116
@@ -124,9 +122,8 @@ void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
124 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; 122 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
125 } 123 }
126 124
127 if (conf_is_ht(conf)) 125 if (channel_type != NL80211_CHAN_NO_HT)
128 ichan->chanmode = ath9k_get_extchanmode(chan, 126 ichan->chanmode = ath9k_get_extchanmode(chan, channel_type);
129 conf->channel_type);
130} 127}
131EXPORT_SYMBOL(ath9k_cmn_update_ichannel); 128EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
132 129
@@ -142,7 +139,7 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
142 139
143 chan_idx = curchan->hw_value; 140 chan_idx = curchan->hw_value;
144 channel = &ah->channels[chan_idx]; 141 channel = &ah->channels[chan_idx];
145 ath9k_cmn_update_ichannel(hw, channel); 142 ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type);
146 143
147 return channel; 144 return channel;
148} 145}
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index fea3b3315391..4c04ee85ff0e 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -31,10 +31,11 @@
31#define WME_MAX_BA WME_BA_BMP_SIZE 31#define WME_MAX_BA WME_BA_BMP_SIZE
32#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) 32#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
33 33
34#define WME_AC_BE 0 34/* These must match mac80211 skb queue mapping numbers */
35#define WME_AC_BK 1 35#define WME_AC_VO 0
36#define WME_AC_VI 2 36#define WME_AC_VI 1
37#define WME_AC_VO 3 37#define WME_AC_BE 2
38#define WME_AC_BK 3
38#define WME_NUM_AC 4 39#define WME_NUM_AC 4
39 40
40#define ATH_RSSI_DUMMY_MARKER 0x127 41#define ATH_RSSI_DUMMY_MARKER 0x127
@@ -62,8 +63,9 @@ enum ath_stomp_type {
62 63
63int ath9k_cmn_padpos(__le16 frame_control); 64int ath9k_cmn_padpos(__le16 frame_control);
64int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); 65int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
65void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, 66void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
66 struct ath9k_channel *ichan); 67 struct ieee80211_channel *chan,
68 enum nl80211_channel_type channel_type);
67struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, 69struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
68 struct ath_hw *ah); 70 struct ath_hw *ah);
69int ath9k_cmn_count_streams(unsigned int chainmask, int max); 71int 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 43e71a944cb1..0c3c74c157fb 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -461,16 +461,16 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
461 461
462 /* Put variable-length stuff down here, and check for overflows. */ 462 /* Put variable-length stuff down here, and check for overflows. */
463 for (i = 0; i < sc->num_sec_wiphy; i++) { 463 for (i = 0; i < sc->num_sec_wiphy; i++) {
464 struct ath_wiphy *aphy = sc->sec_wiphy[i]; 464 struct ath_wiphy *aphy_tmp = sc->sec_wiphy[i];
465 if (aphy == NULL) 465 if (aphy_tmp == NULL)
466 continue; 466 continue;
467 chan = aphy->hw->conf.channel; 467 chan = aphy_tmp->hw->conf.channel;
468 len += snprintf(buf + len, sizeof(buf) - len, 468 len += snprintf(buf + len, sizeof(buf) - len,
469 "secondary: %s (%s chan=%d ht=%d)\n", 469 "secondary: %s (%s chan=%d ht=%d)\n",
470 wiphy_name(aphy->hw->wiphy), 470 wiphy_name(aphy_tmp->hw->wiphy),
471 ath_wiphy_state_str(aphy->state), 471 ath_wiphy_state_str(aphy_tmp->state),
472 ieee80211_frequency_to_channel(chan->center_freq), 472 ieee80211_frequency_to_channel(chan->center_freq),
473 aphy->chan_is_ht); 473 aphy_tmp->chan_is_ht);
474 } 474 }
475 if (len > sizeof(buf)) 475 if (len > sizeof(buf))
476 len = sizeof(buf); 476 len = sizeof(buf);
@@ -585,10 +585,10 @@ static const struct file_operations fops_wiphy = {
585 do { \ 585 do { \
586 len += snprintf(buf + len, size - len, \ 586 len += snprintf(buf + len, size - len, \
587 "%s%13u%11u%10u%10u\n", str, \ 587 "%s%13u%11u%10u%10u\n", str, \
588 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \ 588 sc->debug.stats.txstats[WME_AC_BE].elem, \
589 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \ 589 sc->debug.stats.txstats[WME_AC_BK].elem, \
590 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \ 590 sc->debug.stats.txstats[WME_AC_VI].elem, \
591 sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \ 591 sc->debug.stats.txstats[WME_AC_VO].elem); \
592} while(0) 592} while(0)
593 593
594static ssize_t read_file_xmit(struct file *file, char __user *user_buf, 594static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
@@ -630,33 +630,35 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
630 return retval; 630 return retval;
631} 631}
632 632
633void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 633void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
634 struct ath_buf *bf, struct ath_tx_status *ts) 634 struct ath_tx_status *ts)
635{ 635{
636 TX_STAT_INC(txq->axq_qnum, tx_pkts_all); 636 int qnum = skb_get_queue_mapping(bf->bf_mpdu);
637 sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len; 637
638 TX_STAT_INC(qnum, tx_pkts_all);
639 sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
638 640
639 if (bf_isampdu(bf)) { 641 if (bf_isampdu(bf)) {
640 if (bf_isxretried(bf)) 642 if (bf_isxretried(bf))
641 TX_STAT_INC(txq->axq_qnum, a_xretries); 643 TX_STAT_INC(qnum, a_xretries);
642 else 644 else
643 TX_STAT_INC(txq->axq_qnum, a_completed); 645 TX_STAT_INC(qnum, a_completed);
644 } else { 646 } else {
645 TX_STAT_INC(txq->axq_qnum, completed); 647 TX_STAT_INC(qnum, completed);
646 } 648 }
647 649
648 if (ts->ts_status & ATH9K_TXERR_FIFO) 650 if (ts->ts_status & ATH9K_TXERR_FIFO)
649 TX_STAT_INC(txq->axq_qnum, fifo_underrun); 651 TX_STAT_INC(qnum, fifo_underrun);
650 if (ts->ts_status & ATH9K_TXERR_XTXOP) 652 if (ts->ts_status & ATH9K_TXERR_XTXOP)
651 TX_STAT_INC(txq->axq_qnum, xtxop); 653 TX_STAT_INC(qnum, xtxop);
652 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED) 654 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
653 TX_STAT_INC(txq->axq_qnum, timer_exp); 655 TX_STAT_INC(qnum, timer_exp);
654 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR) 656 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
655 TX_STAT_INC(txq->axq_qnum, desc_cfg_err); 657 TX_STAT_INC(qnum, desc_cfg_err);
656 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN) 658 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
657 TX_STAT_INC(txq->axq_qnum, data_underrun); 659 TX_STAT_INC(qnum, data_underrun);
658 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) 660 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
659 TX_STAT_INC(txq->axq_qnum, delim_underrun); 661 TX_STAT_INC(qnum, delim_underrun);
660} 662}
661 663
662static const struct file_operations fops_xmit = { 664static const struct file_operations fops_xmit = {
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index bb0823242ba0..646ff7e04c88 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -169,8 +169,8 @@ void ath9k_exit_debug(struct ath_hw *ah);
169int ath9k_debug_create_root(void); 169int ath9k_debug_create_root(void);
170void ath9k_debug_remove_root(void); 170void ath9k_debug_remove_root(void);
171void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 171void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
172void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 172void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
173 struct ath_buf *bf, struct ath_tx_status *ts); 173 struct ath_tx_status *ts);
174void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); 174void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
175 175
176#else 176#else
@@ -199,7 +199,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
199} 199}
200 200
201static inline void ath_debug_stat_tx(struct ath_softc *sc, 201static inline void ath_debug_stat_tx(struct ath_softc *sc,
202 struct ath_txq *txq,
203 struct ath_buf *bf, 202 struct ath_buf *bf,
204 struct ath_tx_status *ts) 203 struct ath_tx_status *ts)
205{ 204{
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index dacb45e1b906..3c99830dab0c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -680,7 +680,8 @@ struct eeprom_ops {
680 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); 680 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
681 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, 681 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
682 u16 cfgCtl, u8 twiceAntennaReduction, 682 u16 cfgCtl, u8 twiceAntennaReduction,
683 u8 twiceMaxRegulatoryPower, u8 powerLimit); 683 u8 twiceMaxRegulatoryPower, u8 powerLimit,
684 bool test);
684 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); 685 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
685}; 686};
686 687
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 4fa4d8e28c64..c40c534c6662 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -726,7 +726,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
726 u16 cfgCtl, 726 u16 cfgCtl,
727 u8 twiceAntennaReduction, 727 u8 twiceAntennaReduction,
728 u8 twiceMaxRegulatoryPower, 728 u8 twiceMaxRegulatoryPower,
729 u8 powerLimit) 729 u8 powerLimit, bool test)
730{ 730{
731 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 731 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
732 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 732 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -751,15 +751,20 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
751 751
752 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset); 752 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
753 753
754 regulatory->max_power_level = 0;
754 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 755 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
755 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 756 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
756 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 757 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
757 ratesArray[i] = AR5416_MAX_RATE_POWER; 758 ratesArray[i] = AR5416_MAX_RATE_POWER;
759
760 if (ratesArray[i] > regulatory->max_power_level)
761 regulatory->max_power_level = ratesArray[i];
758 } 762 }
759 763
764 if (test)
765 return;
760 766
761 /* Update regulatory */ 767 /* Update regulatory */
762
763 i = rate6mb; 768 i = rate6mb;
764 if (IS_CHAN_HT40(chan)) 769 if (IS_CHAN_HT40(chan))
765 i = rateHt40_0; 770 i = rateHt40_0;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 966b9496a9dd..ebf7a89f547c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -853,7 +853,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
853 struct ath9k_channel *chan, u16 cfgCtl, 853 struct ath9k_channel *chan, u16 cfgCtl,
854 u8 twiceAntennaReduction, 854 u8 twiceAntennaReduction,
855 u8 twiceMaxRegulatoryPower, 855 u8 twiceMaxRegulatoryPower,
856 u8 powerLimit) 856 u8 powerLimit, bool test)
857{ 857{
858 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 858 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
859 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 859 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
@@ -877,12 +877,26 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
877 877
878 ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset); 878 ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
879 879
880 regulatory->max_power_level = 0;
880 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 881 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
881 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 882 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
882 if (ratesArray[i] > AR9287_MAX_RATE_POWER) 883 if (ratesArray[i] > AR9287_MAX_RATE_POWER)
883 ratesArray[i] = AR9287_MAX_RATE_POWER; 884 ratesArray[i] = AR9287_MAX_RATE_POWER;
885
886 if (ratesArray[i] > regulatory->max_power_level)
887 regulatory->max_power_level = ratesArray[i];
884 } 888 }
885 889
890 if (test)
891 return;
892
893 if (IS_CHAN_2GHZ(chan))
894 i = rate1l;
895 else
896 i = rate6mb;
897
898 regulatory->max_power_level = ratesArray[i];
899
886 if (AR_SREV_9280_20_OR_LATER(ah)) { 900 if (AR_SREV_9280_20_OR_LATER(ah)) {
887 for (i = 0; i < Ar5416RateSize; i++) 901 for (i = 0; i < Ar5416RateSize; i++)
888 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; 902 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
@@ -971,17 +985,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
971 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 985 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
972 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 986 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
973 } 987 }
974
975 if (IS_CHAN_2GHZ(chan))
976 i = rate1l;
977 else
978 i = rate6mb;
979
980 if (AR_SREV_9280_20_OR_LATER(ah))
981 regulatory->max_power_level =
982 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
983 else
984 regulatory->max_power_level = ratesArray[i];
985} 988}
986 989
987static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, 990static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 76b4d65472dd..a819ddc9fdbc 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -1258,7 +1258,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1258 u16 cfgCtl, 1258 u16 cfgCtl,
1259 u8 twiceAntennaReduction, 1259 u8 twiceAntennaReduction,
1260 u8 twiceMaxRegulatoryPower, 1260 u8 twiceMaxRegulatoryPower,
1261 u8 powerLimit) 1261 u8 powerLimit, bool test)
1262{ 1262{
1263#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 1263#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1264 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 1264 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -1285,12 +1285,44 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1285 1285
1286 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset); 1286 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
1287 1287
1288 regulatory->max_power_level = 0;
1288 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1289 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1289 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1290 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1290 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1291 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
1291 ratesArray[i] = AR5416_MAX_RATE_POWER; 1292 ratesArray[i] = AR5416_MAX_RATE_POWER;
1293 if (ratesArray[i] > regulatory->max_power_level)
1294 regulatory->max_power_level = ratesArray[i];
1292 } 1295 }
1293 1296
1297 if (!test) {
1298 i = rate6mb;
1299
1300 if (IS_CHAN_HT40(chan))
1301 i = rateHt40_0;
1302 else if (IS_CHAN_HT20(chan))
1303 i = rateHt20_0;
1304
1305 regulatory->max_power_level = ratesArray[i];
1306 }
1307
1308 switch(ar5416_get_ntxchains(ah->txchainmask)) {
1309 case 1:
1310 break;
1311 case 2:
1312 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1313 break;
1314 case 3:
1315 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1316 break;
1317 default:
1318 ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM,
1319 "Invalid chainmask configuration\n");
1320 break;
1321 }
1322
1323 if (test)
1324 return;
1325
1294 if (AR_SREV_9280_20_OR_LATER(ah)) { 1326 if (AR_SREV_9280_20_OR_LATER(ah)) {
1295 for (i = 0; i < Ar5416RateSize; i++) { 1327 for (i = 0; i < Ar5416RateSize; i++) {
1296 int8_t pwr_table_offset; 1328 int8_t pwr_table_offset;
@@ -1387,34 +1419,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1387 REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1419 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
1388 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1420 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1389 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 1421 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1390
1391 i = rate6mb;
1392
1393 if (IS_CHAN_HT40(chan))
1394 i = rateHt40_0;
1395 else if (IS_CHAN_HT20(chan))
1396 i = rateHt20_0;
1397
1398 if (AR_SREV_9280_20_OR_LATER(ah))
1399 regulatory->max_power_level =
1400 ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2;
1401 else
1402 regulatory->max_power_level = ratesArray[i];
1403
1404 switch(ar5416_get_ntxchains(ah->txchainmask)) {
1405 case 1:
1406 break;
1407 case 2:
1408 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1409 break;
1410 case 3:
1411 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1412 break;
1413 default:
1414 ath_print(ath9k_hw_common(ah), ATH_DBG_EEPROM,
1415 "Invalid chainmask configuration\n");
1416 break;
1417 }
1418} 1422}
1419 1423
1420static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, 1424static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 4a9a68bba324..6a1a482f9dc3 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -259,7 +259,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
259 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); 259 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
260 260
261 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { 261 if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
262 ath9k_hw_set_interrupts(ah, 0); 262 ath9k_hw_disable_interrupts(ah);
263 ah->imask |= ATH9K_INT_GENTIMER; 263 ah->imask |= ATH9K_INT_GENTIMER;
264 ath9k_hw_set_interrupts(ah, ah->imask); 264 ath9k_hw_set_interrupts(ah, ah->imask);
265 } 265 }
@@ -273,7 +273,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
273 273
274 /* if no timer is enabled, turn off interrupt mask */ 274 /* if no timer is enabled, turn off interrupt mask */
275 if (timer_table->timer_mask.val == 0) { 275 if (timer_table->timer_mask.val == 0) {
276 ath9k_hw_set_interrupts(ah, 0); 276 ath9k_hw_disable_interrupts(ah);
277 ah->imask &= ~ATH9K_INT_GENTIMER; 277 ah->imask &= ~ATH9K_INT_GENTIMER;
278 ath9k_hw_set_interrupts(ah, ah->imask); 278 ath9k_hw_set_interrupts(ah, ah->imask);
279 } 279 }
@@ -310,10 +310,8 @@ static void ath_btcoex_period_timer(unsigned long data)
310 310
311 timer_period = is_btscan ? btcoex->btscan_no_stomp : 311 timer_period = is_btscan ? btcoex->btscan_no_stomp :
312 btcoex->btcoex_no_stomp; 312 btcoex->btcoex_no_stomp;
313 ath9k_gen_timer_start(ah, 313 ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
314 btcoex->no_stomp_timer, 314 timer_period * 10);
315 (ath9k_hw_gettsf32(ah) +
316 timer_period), timer_period * 10);
317 btcoex->hw_timer_enabled = true; 315 btcoex->hw_timer_enabled = true;
318 } 316 }
319 317
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9a3be8da755d..e9761c2c8700 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -29,7 +29,7 @@ static void ath_update_txpow(struct ath9k_htc_priv *priv)
29 struct ath_hw *ah = priv->ah; 29 struct ath_hw *ah = priv->ah;
30 30
31 if (priv->curtxpow != priv->txpowlimit) { 31 if (priv->curtxpow != priv->txpowlimit) {
32 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit); 32 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false);
33 /* read back in case value is clamped */ 33 /* read back in case value is clamped */
34 priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit; 34 priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
35 } 35 }
@@ -184,47 +184,6 @@ err:
184 return ret; 184 return ret;
185} 185}
186 186
187static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
188{
189 struct ath_common *common = ath9k_hw_common(priv->ah);
190 struct ath9k_htc_target_vif hvif;
191 int ret = 0;
192 u8 cmd_rsp;
193
194 if (priv->nvifs > 0)
195 return -ENOBUFS;
196
197 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
198 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
199
200 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
201 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
202 hvif.index = priv->nvifs;
203
204 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
205 if (ret)
206 return ret;
207
208 priv->nvifs++;
209 return 0;
210}
211
212static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
213{
214 struct ath_common *common = ath9k_hw_common(priv->ah);
215 struct ath9k_htc_target_vif hvif;
216 int ret = 0;
217 u8 cmd_rsp;
218
219 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
220 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
221 hvif.index = 0; /* Should do for now */
222 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
223 priv->nvifs--;
224
225 return ret;
226}
227
228static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, 187static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
229 struct ieee80211_vif *vif, 188 struct ieee80211_vif *vif,
230 struct ieee80211_sta *sta) 189 struct ieee80211_sta *sta)
@@ -1240,16 +1199,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1240 WMI_CMD(WMI_STOP_RECV_CMDID); 1199 WMI_CMD(WMI_STOP_RECV_CMDID);
1241 skb_queue_purge(&priv->tx_queue); 1200 skb_queue_purge(&priv->tx_queue);
1242 1201
1243 /* Remove monitor interface here */
1244 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1245 if (ath9k_htc_remove_monitor_interface(priv))
1246 ath_print(common, ATH_DBG_FATAL,
1247 "Unable to remove monitor interface\n");
1248 else
1249 ath_print(common, ATH_DBG_CONFIG,
1250 "Monitor interface removed\n");
1251 }
1252
1253 if (ah->btcoex_hw.enabled) { 1202 if (ah->btcoex_hw.enabled) {
1254 ath9k_hw_btcoex_disable(ah); 1203 ath9k_hw_btcoex_disable(ah);
1255 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 1204 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -1400,7 +1349,9 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1400 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", 1349 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1401 curchan->center_freq); 1350 curchan->center_freq);
1402 1351
1403 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]); 1352 ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1353 hw->conf.channel,
1354 hw->conf.channel_type);
1404 1355
1405 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { 1356 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1406 ath_print(common, ATH_DBG_FATAL, 1357 ath_print(common, ATH_DBG_FATAL,
@@ -1421,16 +1372,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1421 } 1372 }
1422 } 1373 }
1423 1374
1424 if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 1375 if (changed & IEEE80211_CONF_CHANGE_MONITOR)
1425 if (conf->flags & IEEE80211_CONF_MONITOR) { 1376 if (conf->flags & IEEE80211_CONF_MONITOR) {
1426 if (ath9k_htc_add_monitor_interface(priv)) 1377 ath_print(common, ATH_DBG_CONFIG,
1427 ath_print(common, ATH_DBG_FATAL, 1378 "HW opmode set to Monitor mode\n");
1428 "Failed to set monitor mode\n"); 1379 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
1429 else
1430 ath_print(common, ATH_DBG_CONFIG,
1431 "HW opmode set to Monitor mode\n");
1432 } 1380 }
1433 } 1381
1434 1382
1435 if (changed & IEEE80211_CONF_CHANGE_IDLE) { 1383 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1436 mutex_lock(&priv->htc_pm_lock); 1384 mutex_lock(&priv->htc_pm_lock);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 3d19b5bc937f..5324ffd96ec7 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -20,8 +20,15 @@
20/* TX */ 20/* TX */
21/******/ 21/******/
22 22
23static const int subtype_txq_to_hwq[] = {
24 [WME_AC_BE] = ATH_TXQ_AC_BE,
25 [WME_AC_BK] = ATH_TXQ_AC_BK,
26 [WME_AC_VI] = ATH_TXQ_AC_VI,
27 [WME_AC_VO] = ATH_TXQ_AC_VO,
28};
29
23#define ATH9K_HTC_INIT_TXQ(subtype) do { \ 30#define ATH9K_HTC_INIT_TXQ(subtype) do { \
24 qi.tqi_subtype = subtype; \ 31 qi.tqi_subtype = subtype_txq_to_hwq[subtype]; \
25 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \ 32 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \
26 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \ 33 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \
27 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \ 34 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 6ebc68bca91f..5fb1bf33faa0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1170,7 +1170,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1170 channel->max_antenna_gain * 2, 1170 channel->max_antenna_gain * 2,
1171 channel->max_power * 2, 1171 channel->max_power * 2,
1172 min((u32) MAX_RATE_POWER, 1172 min((u32) MAX_RATE_POWER,
1173 (u32) regulatory->power_limit)); 1173 (u32) regulatory->power_limit), false);
1174 1174
1175 ath9k_hw_rfbus_done(ah); 1175 ath9k_hw_rfbus_done(ah);
1176 1176
@@ -2176,7 +2176,7 @@ bool ath9k_hw_disable(struct ath_hw *ah)
2176} 2176}
2177EXPORT_SYMBOL(ath9k_hw_disable); 2177EXPORT_SYMBOL(ath9k_hw_disable);
2178 2178
2179void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) 2179void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
2180{ 2180{
2181 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 2181 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
2182 struct ath9k_channel *chan = ah->curchan; 2182 struct ath9k_channel *chan = ah->curchan;
@@ -2189,7 +2189,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
2189 channel->max_antenna_gain * 2, 2189 channel->max_antenna_gain * 2,
2190 channel->max_power * 2, 2190 channel->max_power * 2,
2191 min((u32) MAX_RATE_POWER, 2191 min((u32) MAX_RATE_POWER,
2192 (u32) regulatory->power_limit)); 2192 (u32) regulatory->power_limit), test);
2193} 2193}
2194EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); 2194EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
2195 2195
@@ -2323,11 +2323,10 @@ static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
2323 return timer_table->gen_timer_index[b]; 2323 return timer_table->gen_timer_index[b];
2324} 2324}
2325 2325
2326u32 ath9k_hw_gettsf32(struct ath_hw *ah) 2326static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
2327{ 2327{
2328 return REG_READ(ah, AR_TSF_L32); 2328 return REG_READ(ah, AR_TSF_L32);
2329} 2329}
2330EXPORT_SYMBOL(ath9k_hw_gettsf32);
2331 2330
2332struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 2331struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
2333 void (*trigger)(void *), 2332 void (*trigger)(void *),
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d47d1b4b6002..e29c7122f466 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -157,6 +157,13 @@
157#define PAPRD_GAIN_TABLE_ENTRIES 32 157#define PAPRD_GAIN_TABLE_ENTRIES 32
158#define PAPRD_TABLE_SZ 24 158#define PAPRD_TABLE_SZ 24
159 159
160enum ath_hw_txq_subtype {
161 ATH_TXQ_AC_BE = 0,
162 ATH_TXQ_AC_BK = 1,
163 ATH_TXQ_AC_VI = 2,
164 ATH_TXQ_AC_VO = 3,
165};
166
160enum ath_ini_subsys { 167enum ath_ini_subsys {
161 ATH_INI_PRE = 0, 168 ATH_INI_PRE = 0,
162 ATH_INI_CORE, 169 ATH_INI_CORE,
@@ -819,12 +826,6 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
819 return &ah->ops; 826 return &ah->ops;
820} 827}
821 828
822static inline int sign_extend(int val, const int nbits)
823{
824 int order = BIT(nbits-1);
825 return (val ^ order) - order;
826}
827
828/* Initialization, Detach, Reset */ 829/* Initialization, Detach, Reset */
829const char *ath9k_hw_probe(u16 vendorid, u16 devid); 830const char *ath9k_hw_probe(u16 vendorid, u16 devid);
830void ath9k_hw_deinit(struct ath_hw *ah); 831void ath9k_hw_deinit(struct ath_hw *ah);
@@ -861,7 +862,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
861void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); 862void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
862bool ath9k_hw_phy_disable(struct ath_hw *ah); 863bool ath9k_hw_phy_disable(struct ath_hw *ah);
863bool ath9k_hw_disable(struct ath_hw *ah); 864bool ath9k_hw_disable(struct ath_hw *ah);
864void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); 865void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test);
865void ath9k_hw_setopmode(struct ath_hw *ah); 866void ath9k_hw_setopmode(struct ath_hw *ah);
866void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); 867void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
867void ath9k_hw_setbssidmask(struct ath_hw *ah); 868void ath9k_hw_setbssidmask(struct ath_hw *ah);
@@ -893,7 +894,6 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer);
893 894
894void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer); 895void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
895void ath_gen_timer_isr(struct ath_hw *hw); 896void ath_gen_timer_isr(struct ath_hw *hw);
896u32 ath9k_hw_gettsf32(struct ath_hw *ah);
897 897
898void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); 898void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
899 899
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 6a0d99eff404..d28e580bb486 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -398,7 +398,8 @@ static void ath9k_init_crypto(struct ath_softc *sc)
398 398
399static int ath9k_init_btcoex(struct ath_softc *sc) 399static int ath9k_init_btcoex(struct ath_softc *sc)
400{ 400{
401 int r, qnum; 401 struct ath_txq *txq;
402 int r;
402 403
403 switch (sc->sc_ah->btcoex_hw.scheme) { 404 switch (sc->sc_ah->btcoex_hw.scheme) {
404 case ATH_BTCOEX_CFG_NONE: 405 case ATH_BTCOEX_CFG_NONE:
@@ -411,8 +412,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
411 r = ath_init_btcoex_timer(sc); 412 r = ath_init_btcoex_timer(sc);
412 if (r) 413 if (r)
413 return -1; 414 return -1;
414 qnum = sc->tx.hwq_map[WME_AC_BE]; 415 txq = sc->tx.txq_map[WME_AC_BE];
415 ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); 416 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
416 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 417 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
417 break; 418 break;
418 default: 419 default:
@@ -425,59 +426,18 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
425 426
426static int ath9k_init_queues(struct ath_softc *sc) 427static int ath9k_init_queues(struct ath_softc *sc)
427{ 428{
428 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
429 int i = 0; 429 int i = 0;
430 430
431 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
432 sc->tx.hwq_map[i] = -1;
433
434 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); 431 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
435 if (sc->beacon.beaconq == -1) {
436 ath_print(common, ATH_DBG_FATAL,
437 "Unable to setup a beacon xmit queue\n");
438 goto err;
439 }
440
441 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); 432 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
442 if (sc->beacon.cabq == NULL) {
443 ath_print(common, ATH_DBG_FATAL,
444 "Unable to setup CAB xmit queue\n");
445 goto err;
446 }
447 433
448 sc->config.cabqReadytime = ATH_CABQ_READY_TIME; 434 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
449 ath_cabq_update(sc); 435 ath_cabq_update(sc);
450 436
451 if (!ath_tx_setup(sc, WME_AC_BK)) { 437 for (i = 0; i < WME_NUM_AC; i++)
452 ath_print(common, ATH_DBG_FATAL, 438 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
453 "Unable to setup xmit queue for BK traffic\n");
454 goto err;
455 }
456
457 if (!ath_tx_setup(sc, WME_AC_BE)) {
458 ath_print(common, ATH_DBG_FATAL,
459 "Unable to setup xmit queue for BE traffic\n");
460 goto err;
461 }
462 if (!ath_tx_setup(sc, WME_AC_VI)) {
463 ath_print(common, ATH_DBG_FATAL,
464 "Unable to setup xmit queue for VI traffic\n");
465 goto err;
466 }
467 if (!ath_tx_setup(sc, WME_AC_VO)) {
468 ath_print(common, ATH_DBG_FATAL,
469 "Unable to setup xmit queue for VO traffic\n");
470 goto err;
471 }
472 439
473 return 0; 440 return 0;
474
475err:
476 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
477 if (ATH_TXQ_SETUP(sc, i))
478 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
479
480 return -EIO;
481} 441}
482 442
483static int ath9k_init_channels_rates(struct ath_softc *sc) 443static int ath9k_init_channels_rates(struct ath_softc *sc)
@@ -583,7 +543,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
583 spin_lock_init(&common->cc_lock); 543 spin_lock_init(&common->cc_lock);
584 544
585 spin_lock_init(&sc->wiphy_lock); 545 spin_lock_init(&sc->wiphy_lock);
586 spin_lock_init(&sc->sc_resetlock);
587 spin_lock_init(&sc->sc_serial_rw); 546 spin_lock_init(&sc->sc_serial_rw);
588 spin_lock_init(&sc->sc_pm_lock); 547 spin_lock_init(&sc->sc_pm_lock);
589 mutex_init(&sc->mutex); 548 mutex_init(&sc->mutex);
@@ -645,6 +604,37 @@ err_hw:
645 return ret; 604 return ret;
646} 605}
647 606
607static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
608{
609 struct ieee80211_supported_band *sband;
610 struct ieee80211_channel *chan;
611 struct ath_hw *ah = sc->sc_ah;
612 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
613 int i;
614
615 sband = &sc->sbands[band];
616 for (i = 0; i < sband->n_channels; i++) {
617 chan = &sband->channels[i];
618 ah->curchan = &ah->channels[chan->hw_value];
619 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
620 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
621 chan->max_power = reg->max_power_level / 2;
622 }
623}
624
625static void ath9k_init_txpower_limits(struct ath_softc *sc)
626{
627 struct ath_hw *ah = sc->sc_ah;
628 struct ath9k_channel *curchan = ah->curchan;
629
630 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
631 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
632 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
633 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
634
635 ah->curchan = curchan;
636}
637
648void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) 638void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
649{ 639{
650 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 640 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -706,6 +696,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
706 const struct ath_bus_ops *bus_ops) 696 const struct ath_bus_ops *bus_ops)
707{ 697{
708 struct ieee80211_hw *hw = sc->hw; 698 struct ieee80211_hw *hw = sc->hw;
699 struct ath_wiphy *aphy = hw->priv;
709 struct ath_common *common; 700 struct ath_common *common;
710 struct ath_hw *ah; 701 struct ath_hw *ah;
711 int error = 0; 702 int error = 0;
@@ -738,6 +729,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
738 if (error != 0) 729 if (error != 0)
739 goto error_rx; 730 goto error_rx;
740 731
732 ath9k_init_txpower_limits(sc);
733
741 /* Register with mac80211 */ 734 /* Register with mac80211 */
742 error = ieee80211_register_hw(hw); 735 error = ieee80211_register_hw(hw);
743 if (error) 736 if (error)
@@ -755,6 +748,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
755 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); 748 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
756 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); 749 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
757 sc->wiphy_scheduler_int = msecs_to_jiffies(500); 750 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
751 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
758 752
759 ath_init_leds(sc); 753 ath_init_leds(sc);
760 ath_start_rfkill_poll(sc); 754 ath_start_rfkill_poll(sc);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 8c13479b17cd..65b1ee2a9792 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -117,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending);
117bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) 117bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
118{ 118{
119 u32 txcfg, curLevel, newLevel; 119 u32 txcfg, curLevel, newLevel;
120 enum ath9k_int omask;
121 120
122 if (ah->tx_trig_level >= ah->config.max_txtrig_level) 121 if (ah->tx_trig_level >= ah->config.max_txtrig_level)
123 return false; 122 return false;
124 123
125 omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL); 124 ath9k_hw_disable_interrupts(ah);
126 125
127 txcfg = REG_READ(ah, AR_TXCFG); 126 txcfg = REG_READ(ah, AR_TXCFG);
128 curLevel = MS(txcfg, AR_FTRIG); 127 curLevel = MS(txcfg, AR_FTRIG);
@@ -136,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
136 REG_WRITE(ah, AR_TXCFG, 135 REG_WRITE(ah, AR_TXCFG,
137 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG)); 136 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
138 137
139 ath9k_hw_set_interrupts(ah, omask); 138 ath9k_hw_enable_interrupts(ah);
140 139
141 ah->tx_trig_level = newLevel; 140 ah->tx_trig_level = newLevel;
142 141
@@ -849,28 +848,59 @@ bool ath9k_hw_intrpend(struct ath_hw *ah)
849} 848}
850EXPORT_SYMBOL(ath9k_hw_intrpend); 849EXPORT_SYMBOL(ath9k_hw_intrpend);
851 850
852enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, 851void ath9k_hw_disable_interrupts(struct ath_hw *ah)
853 enum ath9k_int ints) 852{
853 struct ath_common *common = ath9k_hw_common(ah);
854
855 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
856 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
857 (void) REG_READ(ah, AR_IER);
858 if (!AR_SREV_9100(ah)) {
859 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
860 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
861
862 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
863 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
864 }
865}
866EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
867
868void ath9k_hw_enable_interrupts(struct ath_hw *ah)
869{
870 struct ath_common *common = ath9k_hw_common(ah);
871
872 if (!(ah->imask & ATH9K_INT_GLOBAL))
873 return;
874
875 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
876 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
877 if (!AR_SREV_9100(ah)) {
878 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
879 AR_INTR_MAC_IRQ);
880 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
881
882
883 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
884 AR_INTR_SYNC_DEFAULT);
885 REG_WRITE(ah, AR_INTR_SYNC_MASK,
886 AR_INTR_SYNC_DEFAULT);
887 }
888 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
889 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
890}
891EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
892
893void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
854{ 894{
855 enum ath9k_int omask = ah->imask; 895 enum ath9k_int omask = ah->imask;
856 u32 mask, mask2; 896 u32 mask, mask2;
857 struct ath9k_hw_capabilities *pCap = &ah->caps; 897 struct ath9k_hw_capabilities *pCap = &ah->caps;
858 struct ath_common *common = ath9k_hw_common(ah); 898 struct ath_common *common = ath9k_hw_common(ah);
859 899
860 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 900 if (!(ints & ATH9K_INT_GLOBAL))
861 901 ath9k_hw_enable_interrupts(ah);
862 if (omask & ATH9K_INT_GLOBAL) {
863 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
864 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
865 (void) REG_READ(ah, AR_IER);
866 if (!AR_SREV_9100(ah)) {
867 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
868 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
869 902
870 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 903 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
871 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
872 }
873 }
874 904
875 /* TODO: global int Ref count */ 905 /* TODO: global int Ref count */
876 mask = ints & ATH9K_INT_COMMON; 906 mask = ints & ATH9K_INT_COMMON;
@@ -946,24 +976,8 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
946 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 976 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
947 } 977 }
948 978
949 if (ints & ATH9K_INT_GLOBAL) { 979 ath9k_hw_enable_interrupts(ah);
950 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
951 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
952 if (!AR_SREV_9100(ah)) {
953 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
954 AR_INTR_MAC_IRQ);
955 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
956
957
958 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
959 AR_INTR_SYNC_DEFAULT);
960 REG_WRITE(ah, AR_INTR_SYNC_MASK,
961 AR_INTR_SYNC_DEFAULT);
962 }
963 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
964 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
965 }
966 980
967 return omask; 981 return;
968} 982}
969EXPORT_SYMBOL(ath9k_hw_set_interrupts); 983EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 7c1a34d64f6d..22907e21cc46 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -104,13 +104,11 @@ struct ath_tx_status {
104 u32 ts_tstamp; 104 u32 ts_tstamp;
105 u16 ts_seqnum; 105 u16 ts_seqnum;
106 u8 ts_status; 106 u8 ts_status;
107 u8 ts_ratecode;
108 u8 ts_rateindex; 107 u8 ts_rateindex;
109 int8_t ts_rssi; 108 int8_t ts_rssi;
110 u8 ts_shortretry; 109 u8 ts_shortretry;
111 u8 ts_longretry; 110 u8 ts_longretry;
112 u8 ts_virtcol; 111 u8 ts_virtcol;
113 u8 ts_antenna;
114 u8 ts_flags; 112 u8 ts_flags;
115 int8_t ts_rssi_ctl0; 113 int8_t ts_rssi_ctl0;
116 int8_t ts_rssi_ctl1; 114 int8_t ts_rssi_ctl1;
@@ -121,7 +119,6 @@ struct ath_tx_status {
121 u8 qid; 119 u8 qid;
122 u16 desc_id; 120 u16 desc_id;
123 u8 tid; 121 u8 tid;
124 u8 pad[2];
125 u32 ba_low; 122 u32 ba_low;
126 u32 ba_high; 123 u32 ba_high;
127 u32 evm0; 124 u32 evm0;
@@ -240,7 +237,7 @@ struct ath_desc {
240 u32 ds_ctl1; 237 u32 ds_ctl1;
241 u32 ds_hw[20]; 238 u32 ds_hw[20];
242 void *ds_vdata; 239 void *ds_vdata;
243} __packed; 240} __packed __aligned(4);
244 241
245#define ATH9K_TXDESC_CLRDMASK 0x0001 242#define ATH9K_TXDESC_CLRDMASK 0x0001
246#define ATH9K_TXDESC_NOACK 0x0002 243#define ATH9K_TXDESC_NOACK 0x0002
@@ -310,7 +307,7 @@ struct ar5416_desc {
310 u32 status8; 307 u32 status8;
311 } rx; 308 } rx;
312 } u; 309 } u;
313} __packed; 310} __packed __aligned(4);
314 311
315#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds)) 312#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
316#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds)) 313#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
@@ -669,6 +666,7 @@ enum ath9k_key_type {
669 666
670struct ath_hw; 667struct ath_hw;
671struct ath9k_channel; 668struct ath9k_channel;
669enum ath9k_int;
672 670
673u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); 671u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
674void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); 672void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
@@ -700,8 +698,9 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah);
700 698
701/* Interrupt Handling */ 699/* Interrupt Handling */
702bool ath9k_hw_intrpend(struct ath_hw *ah); 700bool ath9k_hw_intrpend(struct ath_hw *ah);
703enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, 701void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
704 enum ath9k_int ints); 702void ath9k_hw_enable_interrupts(struct ath_hw *ah);
703void ath9k_hw_disable_interrupts(struct ath_hw *ah);
705 704
706void ar9002_hw_attach_mac_ops(struct ath_hw *ah); 705void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
707 706
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 25d3ef4c338e..f8c811af312d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -24,7 +24,7 @@ static void ath_update_txpow(struct ath_softc *sc)
24 struct ath_hw *ah = sc->sc_ah; 24 struct ath_hw *ah = sc->sc_ah;
25 25
26 if (sc->curtxpow != sc->config.txpowlimit) { 26 if (sc->curtxpow != sc->config.txpowlimit) {
27 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); 27 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
28 /* read back in case value is clamped */ 28 /* read back in case value is clamped */
29 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; 29 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
30 } 30 }
@@ -235,6 +235,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
235 235
236 ath9k_ps_wakeup(sc); 236 ath9k_ps_wakeup(sc);
237 237
238 spin_lock_bh(&sc->sc_pcu_lock);
239
238 /* 240 /*
239 * This is only performed if the channel settings have 241 * This is only performed if the channel settings have
240 * actually changed. 242 * actually changed.
@@ -244,11 +246,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
244 * hardware at the new frequency, and then re-enable 246 * hardware at the new frequency, and then re-enable
245 * the relevant bits of the h/w. 247 * the relevant bits of the h/w.
246 */ 248 */
247 ath9k_hw_set_interrupts(ah, 0); 249 ath9k_hw_disable_interrupts(ah);
248 ath_drain_all_txq(sc, false); 250 ath_drain_all_txq(sc, false);
249 251
250 spin_lock_bh(&sc->rx.pcu_lock);
251
252 stopped = ath_stoprecv(sc); 252 stopped = ath_stoprecv(sc);
253 253
254 /* XXX: do not flush receive queue here. We don't want 254 /* XXX: do not flush receive queue here. We don't want
@@ -267,30 +267,22 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
267 channel->center_freq, conf_is_ht40(conf), 267 channel->center_freq, conf_is_ht40(conf),
268 fastcc); 268 fastcc);
269 269
270 spin_lock_bh(&sc->sc_resetlock);
271
272 r = ath9k_hw_reset(ah, hchan, caldata, fastcc); 270 r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
273 if (r) { 271 if (r) {
274 ath_print(common, ATH_DBG_FATAL, 272 ath_print(common, ATH_DBG_FATAL,
275 "Unable to reset channel (%u MHz), " 273 "Unable to reset channel (%u MHz), "
276 "reset status %d\n", 274 "reset status %d\n",
277 channel->center_freq, r); 275 channel->center_freq, r);
278 spin_unlock_bh(&sc->sc_resetlock);
279 spin_unlock_bh(&sc->rx.pcu_lock);
280 goto ps_restore; 276 goto ps_restore;
281 } 277 }
282 spin_unlock_bh(&sc->sc_resetlock);
283 278
284 if (ath_startrecv(sc) != 0) { 279 if (ath_startrecv(sc) != 0) {
285 ath_print(common, ATH_DBG_FATAL, 280 ath_print(common, ATH_DBG_FATAL,
286 "Unable to restart recv logic\n"); 281 "Unable to restart recv logic\n");
287 r = -EIO; 282 r = -EIO;
288 spin_unlock_bh(&sc->rx.pcu_lock);
289 goto ps_restore; 283 goto ps_restore;
290 } 284 }
291 285
292 spin_unlock_bh(&sc->rx.pcu_lock);
293
294 ath_update_txpow(sc); 286 ath_update_txpow(sc);
295 ath9k_hw_set_interrupts(ah, ah->imask); 287 ath9k_hw_set_interrupts(ah, ah->imask);
296 288
@@ -301,6 +293,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
301 } 293 }
302 294
303 ps_restore: 295 ps_restore:
296 spin_unlock_bh(&sc->sc_pcu_lock);
297
304 ath9k_ps_restore(sc); 298 ath9k_ps_restore(sc);
305 return r; 299 return r;
306} 300}
@@ -341,7 +335,7 @@ void ath_paprd_calibrate(struct work_struct *work)
341 struct ath_tx_control txctl; 335 struct ath_tx_control txctl;
342 struct ath9k_hw_cal_data *caldata = ah->caldata; 336 struct ath9k_hw_cal_data *caldata = ah->caldata;
343 struct ath_common *common = ath9k_hw_common(ah); 337 struct ath_common *common = ath9k_hw_common(ah);
344 int qnum, ftype; 338 int ftype;
345 int chain_ok = 0; 339 int chain_ok = 0;
346 int chain; 340 int chain;
347 int len = 1800; 341 int len = 1800;
@@ -368,8 +362,7 @@ void ath_paprd_calibrate(struct work_struct *work)
368 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); 362 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
369 363
370 memset(&txctl, 0, sizeof(txctl)); 364 memset(&txctl, 0, sizeof(txctl));
371 qnum = sc->tx.hwq_map[WME_AC_BE]; 365 txctl.txq = sc->tx.txq_map[WME_AC_BE];
372 txctl.txq = &sc->tx.txq[qnum];
373 366
374 ath9k_ps_wakeup(sc); 367 ath9k_ps_wakeup(sc);
375 ar9003_paprd_init_table(ah); 368 ar9003_paprd_init_table(ah);
@@ -567,7 +560,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
567 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + 560 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
568 sta->ht_cap.ampdu_factor); 561 sta->ht_cap.ampdu_factor);
569 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); 562 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
570 an->last_rssi = ATH_RSSI_DUMMY_MARKER;
571 } 563 }
572} 564}
573 565
@@ -615,6 +607,8 @@ void ath9k_tasklet(unsigned long data)
615 return; 607 return;
616 } 608 }
617 609
610 spin_lock_bh(&sc->sc_pcu_lock);
611
618 if (!ath9k_hw_check_alive(ah)) 612 if (!ath9k_hw_check_alive(ah))
619 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 613 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
620 614
@@ -625,15 +619,12 @@ void ath9k_tasklet(unsigned long data)
625 rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); 619 rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
626 620
627 if (status & rxmask) { 621 if (status & rxmask) {
628 spin_lock_bh(&sc->rx.pcu_lock);
629
630 /* Check for high priority Rx first */ 622 /* Check for high priority Rx first */
631 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && 623 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
632 (status & ATH9K_INT_RXHP)) 624 (status & ATH9K_INT_RXHP))
633 ath_rx_tasklet(sc, 0, true); 625 ath_rx_tasklet(sc, 0, true);
634 626
635 ath_rx_tasklet(sc, 0, false); 627 ath_rx_tasklet(sc, 0, false);
636 spin_unlock_bh(&sc->rx.pcu_lock);
637 } 628 }
638 629
639 if (status & ATH9K_INT_TX) { 630 if (status & ATH9K_INT_TX) {
@@ -658,7 +649,9 @@ void ath9k_tasklet(unsigned long data)
658 ath_gen_timer_isr(sc->sc_ah); 649 ath_gen_timer_isr(sc->sc_ah);
659 650
660 /* re-enable hardware interrupt */ 651 /* re-enable hardware interrupt */
661 ath9k_hw_set_interrupts(ah, ah->imask); 652 ath9k_hw_enable_interrupts(ah);
653
654 spin_unlock_bh(&sc->sc_pcu_lock);
662 ath9k_ps_restore(sc); 655 ath9k_ps_restore(sc);
663} 656}
664 657
@@ -757,7 +750,7 @@ irqreturn_t ath_isr(int irq, void *dev)
757 * interrupt; otherwise it will continue to 750 * interrupt; otherwise it will continue to
758 * fire. 751 * fire.
759 */ 752 */
760 ath9k_hw_set_interrupts(ah, 0); 753 ath9k_hw_disable_interrupts(ah);
761 /* 754 /*
762 * Let the hal handle the event. We assume 755 * Let the hal handle the event. We assume
763 * it will clear whatever condition caused 756 * it will clear whatever condition caused
@@ -766,7 +759,7 @@ irqreturn_t ath_isr(int irq, void *dev)
766 spin_lock(&common->cc_lock); 759 spin_lock(&common->cc_lock);
767 ath9k_hw_proc_mib_event(ah); 760 ath9k_hw_proc_mib_event(ah);
768 spin_unlock(&common->cc_lock); 761 spin_unlock(&common->cc_lock);
769 ath9k_hw_set_interrupts(ah, ah->imask); 762 ath9k_hw_enable_interrupts(ah);
770 } 763 }
771 764
772 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) 765 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
@@ -783,8 +776,8 @@ chip_reset:
783 ath_debug_stat_interrupt(sc, status); 776 ath_debug_stat_interrupt(sc, status);
784 777
785 if (sched) { 778 if (sched) {
786 /* turn off every interrupt except SWBA */ 779 /* turn off every interrupt */
787 ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA)); 780 ath9k_hw_disable_interrupts(ah);
788 tasklet_schedule(&sc->intr_tq); 781 tasklet_schedule(&sc->intr_tq);
789 } 782 }
790 783
@@ -836,9 +829,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
836} 829}
837 830
838static void ath9k_bss_assoc_info(struct ath_softc *sc, 831static void ath9k_bss_assoc_info(struct ath_softc *sc,
832 struct ieee80211_hw *hw,
839 struct ieee80211_vif *vif, 833 struct ieee80211_vif *vif,
840 struct ieee80211_bss_conf *bss_conf) 834 struct ieee80211_bss_conf *bss_conf)
841{ 835{
836 struct ath_wiphy *aphy = hw->priv;
842 struct ath_hw *ah = sc->sc_ah; 837 struct ath_hw *ah = sc->sc_ah;
843 struct ath_common *common = ath9k_hw_common(ah); 838 struct ath_common *common = ath9k_hw_common(ah);
844 839
@@ -862,6 +857,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
862 ath_beacon_config(sc, vif); 857 ath_beacon_config(sc, vif);
863 858
864 /* Reset rssi stats */ 859 /* Reset rssi stats */
860 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
865 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; 861 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
866 862
867 sc->sc_flags |= SC_OP_ANI_RUN; 863 sc->sc_flags |= SC_OP_ANI_RUN;
@@ -883,13 +879,13 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
883 int r; 879 int r;
884 880
885 ath9k_ps_wakeup(sc); 881 ath9k_ps_wakeup(sc);
882 spin_lock_bh(&sc->sc_pcu_lock);
883
886 ath9k_hw_configpcipowersave(ah, 0, 0); 884 ath9k_hw_configpcipowersave(ah, 0, 0);
887 885
888 if (!ah->curchan) 886 if (!ah->curchan)
889 ah->curchan = ath_get_curchannel(sc, sc->hw); 887 ah->curchan = ath_get_curchannel(sc, sc->hw);
890 888
891 spin_lock_bh(&sc->rx.pcu_lock);
892 spin_lock_bh(&sc->sc_resetlock);
893 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 889 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
894 if (r) { 890 if (r) {
895 ath_print(common, ATH_DBG_FATAL, 891 ath_print(common, ATH_DBG_FATAL,
@@ -897,17 +893,14 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
897 "reset status %d\n", 893 "reset status %d\n",
898 channel->center_freq, r); 894 channel->center_freq, r);
899 } 895 }
900 spin_unlock_bh(&sc->sc_resetlock);
901 896
902 ath_update_txpow(sc); 897 ath_update_txpow(sc);
903 if (ath_startrecv(sc) != 0) { 898 if (ath_startrecv(sc) != 0) {
904 ath_print(common, ATH_DBG_FATAL, 899 ath_print(common, ATH_DBG_FATAL,
905 "Unable to restart recv logic\n"); 900 "Unable to restart recv logic\n");
906 spin_unlock_bh(&sc->rx.pcu_lock); 901 spin_unlock_bh(&sc->sc_pcu_lock);
907 return; 902 return;
908 } 903 }
909 spin_unlock_bh(&sc->rx.pcu_lock);
910
911 if (sc->sc_flags & SC_OP_BEACONS) 904 if (sc->sc_flags & SC_OP_BEACONS)
912 ath_beacon_config(sc, NULL); /* restart beacons */ 905 ath_beacon_config(sc, NULL); /* restart beacons */
913 906
@@ -920,6 +913,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
920 ath9k_hw_set_gpio(ah, ah->led_pin, 0); 913 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
921 914
922 ieee80211_wake_queues(hw); 915 ieee80211_wake_queues(hw);
916 spin_unlock_bh(&sc->sc_pcu_lock);
917
923 ath9k_ps_restore(sc); 918 ath9k_ps_restore(sc);
924} 919}
925 920
@@ -930,6 +925,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
930 int r; 925 int r;
931 926
932 ath9k_ps_wakeup(sc); 927 ath9k_ps_wakeup(sc);
928 spin_lock_bh(&sc->sc_pcu_lock);
929
933 ieee80211_stop_queues(hw); 930 ieee80211_stop_queues(hw);
934 931
935 /* 932 /*
@@ -942,19 +939,16 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
942 } 939 }
943 940
944 /* Disable interrupts */ 941 /* Disable interrupts */
945 ath9k_hw_set_interrupts(ah, 0); 942 ath9k_hw_disable_interrupts(ah);
946 943
947 ath_drain_all_txq(sc, false); /* clear pending tx frames */ 944 ath_drain_all_txq(sc, false); /* clear pending tx frames */
948 945
949 spin_lock_bh(&sc->rx.pcu_lock);
950
951 ath_stoprecv(sc); /* turn off frame recv */ 946 ath_stoprecv(sc); /* turn off frame recv */
952 ath_flushrecv(sc); /* flush recv queue */ 947 ath_flushrecv(sc); /* flush recv queue */
953 948
954 if (!ah->curchan) 949 if (!ah->curchan)
955 ah->curchan = ath_get_curchannel(sc, hw); 950 ah->curchan = ath_get_curchannel(sc, hw);
956 951
957 spin_lock_bh(&sc->sc_resetlock);
958 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 952 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
959 if (r) { 953 if (r) {
960 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 954 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
@@ -962,14 +956,14 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
962 "reset status %d\n", 956 "reset status %d\n",
963 channel->center_freq, r); 957 channel->center_freq, r);
964 } 958 }
965 spin_unlock_bh(&sc->sc_resetlock);
966 959
967 ath9k_hw_phy_disable(ah); 960 ath9k_hw_phy_disable(ah);
968 961
969 spin_unlock_bh(&sc->rx.pcu_lock);
970
971 ath9k_hw_configpcipowersave(ah, 1, 1); 962 ath9k_hw_configpcipowersave(ah, 1, 1);
963
964 spin_unlock_bh(&sc->sc_pcu_lock);
972 ath9k_ps_restore(sc); 965 ath9k_ps_restore(sc);
966
973 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); 967 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
974} 968}
975 969
@@ -983,29 +977,25 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
983 /* Stop ANI */ 977 /* Stop ANI */
984 del_timer_sync(&common->ani.timer); 978 del_timer_sync(&common->ani.timer);
985 979
980 spin_lock_bh(&sc->sc_pcu_lock);
981
986 ieee80211_stop_queues(hw); 982 ieee80211_stop_queues(hw);
987 983
988 ath9k_hw_set_interrupts(ah, 0); 984 ath9k_hw_disable_interrupts(ah);
989 ath_drain_all_txq(sc, retry_tx); 985 ath_drain_all_txq(sc, retry_tx);
990 986
991 spin_lock_bh(&sc->rx.pcu_lock);
992
993 ath_stoprecv(sc); 987 ath_stoprecv(sc);
994 ath_flushrecv(sc); 988 ath_flushrecv(sc);
995 989
996 spin_lock_bh(&sc->sc_resetlock);
997 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); 990 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
998 if (r) 991 if (r)
999 ath_print(common, ATH_DBG_FATAL, 992 ath_print(common, ATH_DBG_FATAL,
1000 "Unable to reset hardware; reset status %d\n", r); 993 "Unable to reset hardware; reset status %d\n", r);
1001 spin_unlock_bh(&sc->sc_resetlock);
1002 994
1003 if (ath_startrecv(sc) != 0) 995 if (ath_startrecv(sc) != 0)
1004 ath_print(common, ATH_DBG_FATAL, 996 ath_print(common, ATH_DBG_FATAL,
1005 "Unable to start recv logic\n"); 997 "Unable to start recv logic\n");
1006 998
1007 spin_unlock_bh(&sc->rx.pcu_lock);
1008
1009 /* 999 /*
1010 * We may be doing a reset in response to a request 1000 * We may be doing a reset in response to a request
1011 * that changes the channel so update any state that 1001 * that changes the channel so update any state that
@@ -1030,6 +1020,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1030 } 1020 }
1031 1021
1032 ieee80211_wake_queues(hw); 1022 ieee80211_wake_queues(hw);
1023 spin_unlock_bh(&sc->sc_pcu_lock);
1033 1024
1034 /* Start ANI */ 1025 /* Start ANI */
1035 ath_start_ani(common); 1026 ath_start_ani(common);
@@ -1037,56 +1028,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1037 return r; 1028 return r;
1038} 1029}
1039 1030
1040static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1041{
1042 int qnum;
1043
1044 switch (queue) {
1045 case 0:
1046 qnum = sc->tx.hwq_map[WME_AC_VO];
1047 break;
1048 case 1:
1049 qnum = sc->tx.hwq_map[WME_AC_VI];
1050 break;
1051 case 2:
1052 qnum = sc->tx.hwq_map[WME_AC_BE];
1053 break;
1054 case 3:
1055 qnum = sc->tx.hwq_map[WME_AC_BK];
1056 break;
1057 default:
1058 qnum = sc->tx.hwq_map[WME_AC_BE];
1059 break;
1060 }
1061
1062 return qnum;
1063}
1064
1065int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
1066{
1067 int qnum;
1068
1069 switch (queue) {
1070 case WME_AC_VO:
1071 qnum = 0;
1072 break;
1073 case WME_AC_VI:
1074 qnum = 1;
1075 break;
1076 case WME_AC_BE:
1077 qnum = 2;
1078 break;
1079 case WME_AC_BK:
1080 qnum = 3;
1081 break;
1082 default:
1083 qnum = -1;
1084 break;
1085 }
1086
1087 return qnum;
1088}
1089
1090/* XXX: Remove me once we don't depend on ath9k_channel for all 1031/* XXX: Remove me once we don't depend on ath9k_channel for all
1091 * this redundant data */ 1032 * this redundant data */
1092void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, 1033void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
@@ -1168,19 +1109,16 @@ static int ath9k_start(struct ieee80211_hw *hw)
1168 * be followed by initialization of the appropriate bits 1109 * be followed by initialization of the appropriate bits
1169 * and then setup of the interrupt mask. 1110 * and then setup of the interrupt mask.
1170 */ 1111 */
1171 spin_lock_bh(&sc->rx.pcu_lock); 1112 spin_lock_bh(&sc->sc_pcu_lock);
1172 spin_lock_bh(&sc->sc_resetlock);
1173 r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); 1113 r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1174 if (r) { 1114 if (r) {
1175 ath_print(common, ATH_DBG_FATAL, 1115 ath_print(common, ATH_DBG_FATAL,
1176 "Unable to reset hardware; reset status %d " 1116 "Unable to reset hardware; reset status %d "
1177 "(freq %u MHz)\n", r, 1117 "(freq %u MHz)\n", r,
1178 curchan->center_freq); 1118 curchan->center_freq);
1179 spin_unlock_bh(&sc->sc_resetlock); 1119 spin_unlock_bh(&sc->sc_pcu_lock);
1180 spin_unlock_bh(&sc->rx.pcu_lock);
1181 goto mutex_unlock; 1120 goto mutex_unlock;
1182 } 1121 }
1183 spin_unlock_bh(&sc->sc_resetlock);
1184 1122
1185 /* 1123 /*
1186 * This is needed only to setup initial state 1124 * This is needed only to setup initial state
@@ -1199,10 +1137,10 @@ static int ath9k_start(struct ieee80211_hw *hw)
1199 ath_print(common, ATH_DBG_FATAL, 1137 ath_print(common, ATH_DBG_FATAL,
1200 "Unable to start recv logic\n"); 1138 "Unable to start recv logic\n");
1201 r = -EIO; 1139 r = -EIO;
1202 spin_unlock_bh(&sc->rx.pcu_lock); 1140 spin_unlock_bh(&sc->sc_pcu_lock);
1203 goto mutex_unlock; 1141 goto mutex_unlock;
1204 } 1142 }
1205 spin_unlock_bh(&sc->rx.pcu_lock); 1143 spin_unlock_bh(&sc->sc_pcu_lock);
1206 1144
1207 /* Setup our intr mask. */ 1145 /* Setup our intr mask. */
1208 ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | 1146 ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
@@ -1262,7 +1200,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1262 struct ath_tx_control txctl; 1200 struct ath_tx_control txctl;
1263 int padpos, padsize; 1201 int padpos, padsize;
1264 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1202 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1265 int qnum;
1266 1203
1267 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { 1204 if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
1268 ath_print(common, ATH_DBG_XMIT, 1205 ath_print(common, ATH_DBG_XMIT,
@@ -1335,8 +1272,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
1335 memmove(skb->data, skb->data + padsize, padpos); 1272 memmove(skb->data, skb->data + padsize, padpos);
1336 } 1273 }
1337 1274
1338 qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); 1275 txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
1339 txctl.txq = &sc->tx.txq[qnum];
1340 1276
1341 ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); 1277 ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
1342 1278
@@ -1400,22 +1336,25 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1400 ath9k_btcoex_timer_pause(sc); 1336 ath9k_btcoex_timer_pause(sc);
1401 } 1337 }
1402 1338
1339 spin_lock_bh(&sc->sc_pcu_lock);
1340
1403 /* make sure h/w will not generate any interrupt 1341 /* make sure h/w will not generate any interrupt
1404 * before setting the invalid flag. */ 1342 * before setting the invalid flag. */
1405 ath9k_hw_set_interrupts(ah, 0); 1343 ath9k_hw_disable_interrupts(ah);
1406 1344
1407 spin_lock_bh(&sc->rx.pcu_lock);
1408 if (!(sc->sc_flags & SC_OP_INVALID)) { 1345 if (!(sc->sc_flags & SC_OP_INVALID)) {
1409 ath_drain_all_txq(sc, false); 1346 ath_drain_all_txq(sc, false);
1410 ath_stoprecv(sc); 1347 ath_stoprecv(sc);
1411 ath9k_hw_phy_disable(ah); 1348 ath9k_hw_phy_disable(ah);
1412 } else 1349 } else
1413 sc->rx.rxlink = NULL; 1350 sc->rx.rxlink = NULL;
1414 spin_unlock_bh(&sc->rx.pcu_lock);
1415 1351
1416 /* disable HAL and put h/w to sleep */ 1352 /* disable HAL and put h/w to sleep */
1417 ath9k_hw_disable(ah); 1353 ath9k_hw_disable(ah);
1418 ath9k_hw_configpcipowersave(ah, 1, 1); 1354 ath9k_hw_configpcipowersave(ah, 1, 1);
1355
1356 spin_unlock_bh(&sc->sc_pcu_lock);
1357
1419 ath9k_ps_restore(sc); 1358 ath9k_ps_restore(sc);
1420 1359
1421 /* Finally, put the chip in FULL SLEEP mode */ 1360 /* Finally, put the chip in FULL SLEEP mode */
@@ -1822,12 +1761,15 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1822 struct ath_wiphy *aphy = hw->priv; 1761 struct ath_wiphy *aphy = hw->priv;
1823 struct ath_softc *sc = aphy->sc; 1762 struct ath_softc *sc = aphy->sc;
1824 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1763 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1764 struct ath_txq *txq;
1825 struct ath9k_tx_queue_info qi; 1765 struct ath9k_tx_queue_info qi;
1826 int ret = 0, qnum; 1766 int ret = 0;
1827 1767
1828 if (queue >= WME_NUM_AC) 1768 if (queue >= WME_NUM_AC)
1829 return 0; 1769 return 0;
1830 1770
1771 txq = sc->tx.txq_map[queue];
1772
1831 mutex_lock(&sc->mutex); 1773 mutex_lock(&sc->mutex);
1832 1774
1833 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); 1775 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
@@ -1836,20 +1778,19 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
1836 qi.tqi_cwmin = params->cw_min; 1778 qi.tqi_cwmin = params->cw_min;
1837 qi.tqi_cwmax = params->cw_max; 1779 qi.tqi_cwmax = params->cw_max;
1838 qi.tqi_burstTime = params->txop; 1780 qi.tqi_burstTime = params->txop;
1839 qnum = ath_get_hal_qnum(queue, sc);
1840 1781
1841 ath_print(common, ATH_DBG_CONFIG, 1782 ath_print(common, ATH_DBG_CONFIG,
1842 "Configure tx [queue/halq] [%d/%d], " 1783 "Configure tx [queue/halq] [%d/%d], "
1843 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", 1784 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1844 queue, qnum, params->aifs, params->cw_min, 1785 queue, txq->axq_qnum, params->aifs, params->cw_min,
1845 params->cw_max, params->txop); 1786 params->cw_max, params->txop);
1846 1787
1847 ret = ath_txq_update(sc, qnum, &qi); 1788 ret = ath_txq_update(sc, txq->axq_qnum, &qi);
1848 if (ret) 1789 if (ret)
1849 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); 1790 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1850 1791
1851 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) 1792 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1852 if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret) 1793 if (queue == WME_AC_BE && !ret)
1853 ath_beaconq_config(sc); 1794 ath_beaconq_config(sc);
1854 1795
1855 mutex_unlock(&sc->mutex); 1796 mutex_unlock(&sc->mutex);
@@ -2011,7 +1952,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2011 if (changed & BSS_CHANGED_ASSOC) { 1952 if (changed & BSS_CHANGED_ASSOC) {
2012 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", 1953 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
2013 bss_conf->assoc); 1954 bss_conf->assoc);
2014 ath9k_bss_assoc_info(sc, vif, bss_conf); 1955 ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
2015 } 1956 }
2016 1957
2017 mutex_unlock(&sc->mutex); 1958 mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b5b651413e77..6605bc2c2036 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -247,34 +247,25 @@ static void ath_pci_remove(struct pci_dev *pdev)
247 247
248#ifdef CONFIG_PM 248#ifdef CONFIG_PM
249 249
250static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) 250static int ath_pci_suspend(struct device *device)
251{ 251{
252 struct pci_dev *pdev = to_pci_dev(device);
252 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 253 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
253 struct ath_wiphy *aphy = hw->priv; 254 struct ath_wiphy *aphy = hw->priv;
254 struct ath_softc *sc = aphy->sc; 255 struct ath_softc *sc = aphy->sc;
255 256
256 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); 257 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
257 258
258 pci_save_state(pdev);
259 pci_disable_device(pdev);
260 pci_set_power_state(pdev, PCI_D3hot);
261
262 return 0; 259 return 0;
263} 260}
264 261
265static int ath_pci_resume(struct pci_dev *pdev) 262static int ath_pci_resume(struct device *device)
266{ 263{
264 struct pci_dev *pdev = to_pci_dev(device);
267 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 265 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
268 struct ath_wiphy *aphy = hw->priv; 266 struct ath_wiphy *aphy = hw->priv;
269 struct ath_softc *sc = aphy->sc; 267 struct ath_softc *sc = aphy->sc;
270 u32 val; 268 u32 val;
271 int err;
272
273 pci_restore_state(pdev);
274
275 err = pci_enable_device(pdev);
276 if (err)
277 return err;
278 269
279 /* 270 /*
280 * Suspend/Resume resets the PCI configuration space, so we have to 271 * Suspend/Resume resets the PCI configuration space, so we have to
@@ -293,7 +284,23 @@ static int ath_pci_resume(struct pci_dev *pdev)
293 return 0; 284 return 0;
294} 285}
295 286
296#endif /* CONFIG_PM */ 287static const struct dev_pm_ops ath9k_pm_ops = {
288 .suspend = ath_pci_suspend,
289 .resume = ath_pci_resume,
290 .freeze = ath_pci_suspend,
291 .thaw = ath_pci_resume,
292 .poweroff = ath_pci_suspend,
293 .restore = ath_pci_resume,
294};
295
296#define ATH9K_PM_OPS (&ath9k_pm_ops)
297
298#else /* !CONFIG_PM */
299
300#define ATH9K_PM_OPS NULL
301
302#endif /* !CONFIG_PM */
303
297 304
298MODULE_DEVICE_TABLE(pci, ath_pci_id_table); 305MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
299 306
@@ -302,10 +309,7 @@ static struct pci_driver ath_pci_driver = {
302 .id_table = ath_pci_id_table, 309 .id_table = ath_pci_id_table,
303 .probe = ath_pci_probe, 310 .probe = ath_pci_probe,
304 .remove = ath_pci_remove, 311 .remove = ath_pci_remove,
305#ifdef CONFIG_PM 312 .driver.pm = ATH9K_PM_OPS,
306 .suspend = ath_pci_suspend,
307 .resume = ath_pci_resume,
308#endif /* CONFIG_PM */
309}; 313};
310 314
311int ath_pci_init(void) 315int ath_pci_init(void)
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 89978d71617f..85c8e9310cae 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -381,25 +381,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
381static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, 381static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
382 struct ieee80211_tx_rate *rate); 382 struct ieee80211_tx_rate *rate);
383 383
384static inline int8_t median(int8_t a, int8_t b, int8_t c)
385{
386 if (a >= b) {
387 if (b >= c)
388 return b;
389 else if (a > c)
390 return c;
391 else
392 return a;
393 } else {
394 if (a >= c)
395 return a;
396 else if (b >= c)
397 return c;
398 else
399 return b;
400 }
401}
402
403static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table, 384static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
404 struct ath_rate_priv *ath_rc_priv) 385 struct ath_rate_priv *ath_rc_priv)
405{ 386{
@@ -1444,12 +1425,12 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1444 ath_rc_priv->neg_ht_rates.rs_nrates = j; 1425 ath_rc_priv->neg_ht_rates.rs_nrates = j;
1445 } 1426 }
1446 1427
1447 is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; 1428 is_cw40 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
1448 1429
1449 if (is_cw40) 1430 if (is_cw40)
1450 is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; 1431 is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
1451 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) 1432 else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
1452 is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; 1433 is_sgi = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
1453 1434
1454 /* Choose rate table first */ 1435 /* Choose rate table first */
1455 1436
@@ -1468,10 +1449,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1468 struct ath_rate_priv *ath_rc_priv = priv_sta; 1449 struct ath_rate_priv *ath_rc_priv = priv_sta;
1469 const struct ath_rate_table *rate_table = NULL; 1450 const struct ath_rate_table *rate_table = NULL;
1470 bool oper_cw40 = false, oper_sgi; 1451 bool oper_cw40 = false, oper_sgi;
1471 bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? 1452 bool local_cw40 = !!(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
1472 true : false; 1453 bool local_sgi = !!(ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG);
1473 bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
1474 true : false;
1475 1454
1476 /* FIXME: Handle AP mode later when we support CWM */ 1455 /* FIXME: Handle AP mode later when we support CWM */
1477 1456
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c76ea53c20ce..c5c80764a94a 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -317,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
317 struct ath_buf *bf; 317 struct ath_buf *bf;
318 int error = 0; 318 int error = 0;
319 319
320 spin_lock_init(&sc->rx.pcu_lock); 320 spin_lock_init(&sc->sc_pcu_lock);
321 sc->sc_flags &= ~SC_OP_RXFLUSH; 321 sc->sc_flags &= ~SC_OP_RXFLUSH;
322 spin_lock_init(&sc->rx.rxbuflock); 322 spin_lock_init(&sc->rx.rxbuflock);
323 323
@@ -528,6 +528,8 @@ bool ath_stoprecv(struct ath_softc *sc)
528 sc->rx.rxlink = NULL; 528 sc->rx.rxlink = NULL;
529 spin_unlock_bh(&sc->rx.rxbuflock); 529 spin_unlock_bh(&sc->rx.rxbuflock);
530 530
531 ATH_DBG_WARN(!stopped, "Could not stop RX, we could be "
532 "confusing the DMA engine when we start RX up\n");
531 return stopped; 533 return stopped;
532} 534}
533 535
@@ -962,36 +964,23 @@ static void ath9k_process_rssi(struct ath_common *common,
962 struct ieee80211_hdr *hdr, 964 struct ieee80211_hdr *hdr,
963 struct ath_rx_status *rx_stats) 965 struct ath_rx_status *rx_stats)
964{ 966{
967 struct ath_wiphy *aphy = hw->priv;
965 struct ath_hw *ah = common->ah; 968 struct ath_hw *ah = common->ah;
966 struct ieee80211_sta *sta; 969 int last_rssi;
967 struct ath_node *an;
968 int last_rssi = ATH_RSSI_DUMMY_MARKER;
969 __le16 fc; 970 __le16 fc;
970 971
972 if (ah->opmode != NL80211_IFTYPE_STATION)
973 return;
974
971 fc = hdr->frame_control; 975 fc = hdr->frame_control;
976 if (!ieee80211_is_beacon(fc) ||
977 compare_ether_addr(hdr->addr3, common->curbssid))
978 return;
972 979
973 rcu_read_lock(); 980 if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr)
974 /* 981 ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi);
975 * XXX: use ieee80211_find_sta! This requires quite a bit of work
976 * under the current ath9k virtual wiphy implementation as we have
977 * no way of tying a vif to wiphy. Typically vifs are attached to
978 * at least one sdata of a wiphy on mac80211 but with ath9k virtual
979 * wiphy you'd have to iterate over every wiphy and each sdata.
980 */
981 if (is_multicast_ether_addr(hdr->addr1))
982 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL);
983 else
984 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1);
985
986 if (sta) {
987 an = (struct ath_node *) sta->drv_priv;
988 if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
989 !rx_stats->rs_moreaggr)
990 ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi);
991 last_rssi = an->last_rssi;
992 }
993 rcu_read_unlock();
994 982
983 last_rssi = aphy->last_rssi;
995 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) 984 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
996 rx_stats->rs_rssi = ATH_EP_RND(last_rssi, 985 rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
997 ATH_RSSI_EP_MULTIPLIER); 986 ATH_RSSI_EP_MULTIPLIER);
@@ -999,8 +988,7 @@ static void ath9k_process_rssi(struct ath_common *common,
999 rx_stats->rs_rssi = 0; 988 rx_stats->rs_rssi = 0;
1000 989
1001 /* Update Beacon RSSI, this is used by ANI. */ 990 /* Update Beacon RSSI, this is used by ANI. */
1002 if (ieee80211_is_beacon(fc)) 991 ah->stats.avgbrssi = rx_stats->rs_rssi;
1003 ah->stats.avgbrssi = rx_stats->rs_rssi;
1004} 992}
1005 993
1006/* 994/*
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index ec7cf5ee56bc..4008f51d34c8 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -107,6 +107,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
107 aphy->sc = sc; 107 aphy->sc = sc;
108 aphy->hw = hw; 108 aphy->hw = hw;
109 sc->sec_wiphy[i] = aphy; 109 sc->sec_wiphy[i] = aphy;
110 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
110 spin_unlock_bh(&sc->wiphy_lock); 111 spin_unlock_bh(&sc->wiphy_lock);
111 112
112 memcpy(addr, common->macaddr, ETH_ALEN); 113 memcpy(addr, common->macaddr, ETH_ALEN);
@@ -186,7 +187,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
186 info->control.rates[1].idx = -1; 187 info->control.rates[1].idx = -1;
187 188
188 memset(&txctl, 0, sizeof(struct ath_tx_control)); 189 memset(&txctl, 0, sizeof(struct ath_tx_control));
189 txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]]; 190 txctl.txq = sc->tx.txq_map[WME_AC_VO];
190 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; 191 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
191 192
192 if (ath_tx_start(aphy->hw, skb, &txctl) != 0) 193 if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f2ade2402ce2..6380bbd82d49 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -124,7 +124,7 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
124 124
125static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) 125static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
126{ 126{
127 struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; 127 struct ath_txq *txq = tid->ac->txq;
128 128
129 WARN_ON(!tid->paused); 129 WARN_ON(!tid->paused);
130 130
@@ -142,7 +142,7 @@ unlock:
142 142
143static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) 143static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
144{ 144{
145 struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; 145 struct ath_txq *txq = tid->ac->txq;
146 struct ath_buf *bf; 146 struct ath_buf *bf;
147 struct list_head bf_head; 147 struct list_head bf_head;
148 struct ath_tx_status ts; 148 struct ath_tx_status ts;
@@ -817,7 +817,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
817{ 817{
818 struct ath_node *an = (struct ath_node *)sta->drv_priv; 818 struct ath_node *an = (struct ath_node *)sta->drv_priv;
819 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); 819 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
820 struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; 820 struct ath_txq *txq = txtid->ac->txq;
821 821
822 if (txtid->state & AGGR_CLEANUP) 822 if (txtid->state & AGGR_CLEANUP)
823 return; 823 return;
@@ -888,10 +888,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
888 struct ath_hw *ah = sc->sc_ah; 888 struct ath_hw *ah = sc->sc_ah;
889 struct ath_common *common = ath9k_hw_common(ah); 889 struct ath_common *common = ath9k_hw_common(ah);
890 struct ath9k_tx_queue_info qi; 890 struct ath9k_tx_queue_info qi;
891 static const int subtype_txq_to_hwq[] = {
892 [WME_AC_BE] = ATH_TXQ_AC_BE,
893 [WME_AC_BK] = ATH_TXQ_AC_BK,
894 [WME_AC_VI] = ATH_TXQ_AC_VI,
895 [WME_AC_VO] = ATH_TXQ_AC_VO,
896 };
891 int qnum, i; 897 int qnum, i;
892 898
893 memset(&qi, 0, sizeof(qi)); 899 memset(&qi, 0, sizeof(qi));
894 qi.tqi_subtype = subtype; 900 qi.tqi_subtype = subtype_txq_to_hwq[subtype];
895 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; 901 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
896 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; 902 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
897 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; 903 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
@@ -940,7 +946,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
940 if (!ATH_TXQ_SETUP(sc, qnum)) { 946 if (!ATH_TXQ_SETUP(sc, qnum)) {
941 struct ath_txq *txq = &sc->tx.txq[qnum]; 947 struct ath_txq *txq = &sc->tx.txq[qnum];
942 948
943 txq->axq_class = subtype;
944 txq->axq_qnum = qnum; 949 txq->axq_qnum = qnum;
945 txq->axq_link = NULL; 950 txq->axq_link = NULL;
946 INIT_LIST_HEAD(&txq->axq_q); 951 INIT_LIST_HEAD(&txq->axq_q);
@@ -1148,13 +1153,11 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1148 ath_print(common, ATH_DBG_FATAL, 1153 ath_print(common, ATH_DBG_FATAL,
1149 "Failed to stop TX DMA. Resetting hardware!\n"); 1154 "Failed to stop TX DMA. Resetting hardware!\n");
1150 1155
1151 spin_lock_bh(&sc->sc_resetlock);
1152 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); 1156 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
1153 if (r) 1157 if (r)
1154 ath_print(common, ATH_DBG_FATAL, 1158 ath_print(common, ATH_DBG_FATAL,
1155 "Unable to reset hardware; reset status %d\n", 1159 "Unable to reset hardware; reset status %d\n",
1156 r); 1160 r);
1157 spin_unlock_bh(&sc->sc_resetlock);
1158 } 1161 }
1159 1162
1160 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 1163 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
@@ -1212,24 +1215,6 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1212 } 1215 }
1213} 1216}
1214 1217
1215int ath_tx_setup(struct ath_softc *sc, int haltype)
1216{
1217 struct ath_txq *txq;
1218
1219 if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
1220 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1221 "HAL AC %u out of range, max %zu!\n",
1222 haltype, ARRAY_SIZE(sc->tx.hwq_map));
1223 return 0;
1224 }
1225 txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
1226 if (txq != NULL) {
1227 sc->tx.hwq_map[haltype] = txq->axq_qnum;
1228 return 1;
1229 } else
1230 return 0;
1231}
1232
1233/***********/ 1218/***********/
1234/* TX, DMA */ 1219/* TX, DMA */
1235/***********/ 1220/***********/
@@ -1710,6 +1695,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1710 goto tx_done; 1695 goto tx_done;
1711 } 1696 }
1712 1697
1698 WARN_ON(tid->ac->txq != txctl->txq);
1713 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 1699 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
1714 /* 1700 /*
1715 * Try aggregation if it's a unicast data frame 1701 * Try aggregation if it's a unicast data frame
@@ -1749,6 +1735,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1749 return -1; 1735 return -1;
1750 } 1736 }
1751 1737
1738 q = skb_get_queue_mapping(skb);
1752 r = ath_tx_setup_buffer(hw, bf, skb, txctl); 1739 r = ath_tx_setup_buffer(hw, bf, skb, txctl);
1753 if (unlikely(r)) { 1740 if (unlikely(r)) {
1754 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); 1741 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
@@ -1758,8 +1745,9 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1758 * we will at least have to run TX completionon one buffer 1745 * we will at least have to run TX completionon one buffer
1759 * on the queue */ 1746 * on the queue */
1760 spin_lock_bh(&txq->axq_lock); 1747 spin_lock_bh(&txq->axq_lock);
1761 if (!txq->stopped && txq->axq_depth > 1) { 1748 if (txq == sc->tx.txq_map[q] && !txq->stopped &&
1762 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); 1749 txq->axq_depth > 1) {
1750 ath_mac80211_stop_queue(sc, q);
1763 txq->stopped = 1; 1751 txq->stopped = 1;
1764 } 1752 }
1765 spin_unlock_bh(&txq->axq_lock); 1753 spin_unlock_bh(&txq->axq_lock);
@@ -1769,13 +1757,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1769 return r; 1757 return r;
1770 } 1758 }
1771 1759
1772 q = skb_get_queue_mapping(skb);
1773 if (q >= 4)
1774 q = 0;
1775
1776 spin_lock_bh(&txq->axq_lock); 1760 spin_lock_bh(&txq->axq_lock);
1777 if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) { 1761 if (txq == sc->tx.txq_map[q] &&
1778 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); 1762 ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
1763 ath_mac80211_stop_queue(sc, q);
1779 txq->stopped = 1; 1764 txq->stopped = 1;
1780 } 1765 }
1781 spin_unlock_bh(&txq->axq_lock); 1766 spin_unlock_bh(&txq->axq_lock);
@@ -1843,7 +1828,8 @@ exit:
1843/*****************/ 1828/*****************/
1844 1829
1845static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 1830static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1846 struct ath_wiphy *aphy, int tx_flags) 1831 struct ath_wiphy *aphy, int tx_flags,
1832 struct ath_txq *txq)
1847{ 1833{
1848 struct ieee80211_hw *hw = sc->hw; 1834 struct ieee80211_hw *hw = sc->hw;
1849 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1835 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -1890,11 +1876,12 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1890 ath9k_tx_status(hw, skb); 1876 ath9k_tx_status(hw, skb);
1891 else { 1877 else {
1892 q = skb_get_queue_mapping(skb); 1878 q = skb_get_queue_mapping(skb);
1893 if (q >= 4) 1879 if (txq == sc->tx.txq_map[q]) {
1894 q = 0; 1880 spin_lock_bh(&txq->axq_lock);
1895 1881 if (WARN_ON(--txq->pending_frames < 0))
1896 if (--sc->tx.pending_frames[q] < 0) 1882 txq->pending_frames = 0;
1897 sc->tx.pending_frames[q] = 0; 1883 spin_unlock_bh(&txq->axq_lock);
1884 }
1898 1885
1899 ieee80211_tx_status(hw, skb); 1886 ieee80211_tx_status(hw, skb);
1900 } 1887 }
@@ -1929,8 +1916,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1929 else 1916 else
1930 complete(&sc->paprd_complete); 1917 complete(&sc->paprd_complete);
1931 } else { 1918 } else {
1932 ath_debug_stat_tx(sc, txq, bf, ts); 1919 ath_debug_stat_tx(sc, bf, ts);
1933 ath_tx_complete(sc, skb, bf->aphy, tx_flags); 1920 ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq);
1934 } 1921 }
1935 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't 1922 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
1936 * accidentally reference it later. 1923 * accidentally reference it later.
@@ -2020,16 +2007,13 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
2020 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; 2007 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
2021} 2008}
2022 2009
2023static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) 2010static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum)
2024{ 2011{
2025 int qnum; 2012 struct ath_txq *txq;
2026
2027 qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
2028 if (qnum == -1)
2029 return;
2030 2013
2014 txq = sc->tx.txq_map[qnum];
2031 spin_lock_bh(&txq->axq_lock); 2015 spin_lock_bh(&txq->axq_lock);
2032 if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { 2016 if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
2033 if (ath_mac80211_start_queue(sc, qnum)) 2017 if (ath_mac80211_start_queue(sc, qnum))
2034 txq->stopped = 0; 2018 txq->stopped = 0;
2035 } 2019 }
@@ -2046,6 +2030,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2046 struct ath_tx_status ts; 2030 struct ath_tx_status ts;
2047 int txok; 2031 int txok;
2048 int status; 2032 int status;
2033 int qnum;
2049 2034
2050 ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", 2035 ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
2051 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), 2036 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
@@ -2121,12 +2106,15 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2121 ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); 2106 ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
2122 } 2107 }
2123 2108
2109 qnum = skb_get_queue_mapping(bf->bf_mpdu);
2110
2124 if (bf_isampdu(bf)) 2111 if (bf_isampdu(bf))
2125 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); 2112 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok);
2126 else 2113 else
2127 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); 2114 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
2128 2115
2129 ath_wake_mac80211_queue(sc, txq); 2116 if (txq == sc->tx.txq_map[qnum])
2117 ath_wake_mac80211_queue(sc, qnum);
2130 2118
2131 spin_lock_bh(&txq->axq_lock); 2119 spin_lock_bh(&txq->axq_lock);
2132 if (sc->sc_flags & SC_OP_TXAGGR) 2120 if (sc->sc_flags & SC_OP_TXAGGR)
@@ -2196,6 +2184,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2196 struct list_head bf_head; 2184 struct list_head bf_head;
2197 int status; 2185 int status;
2198 int txok; 2186 int txok;
2187 int qnum;
2199 2188
2200 for (;;) { 2189 for (;;) {
2201 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); 2190 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs);
@@ -2239,13 +2228,16 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2239 ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); 2228 ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
2240 } 2229 }
2241 2230
2231 qnum = skb_get_queue_mapping(bf->bf_mpdu);
2232
2242 if (bf_isampdu(bf)) 2233 if (bf_isampdu(bf))
2243 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); 2234 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok);
2244 else 2235 else
2245 ath_tx_complete_buf(sc, bf, txq, &bf_head, 2236 ath_tx_complete_buf(sc, bf, txq, &bf_head,
2246 &txs, txok, 0); 2237 &txs, txok, 0);
2247 2238
2248 ath_wake_mac80211_queue(sc, txq); 2239 if (txq == sc->tx.txq_map[qnum])
2240 ath_wake_mac80211_queue(sc, qnum);
2249 2241
2250 spin_lock_bh(&txq->axq_lock); 2242 spin_lock_bh(&txq->axq_lock);
2251 if (!list_empty(&txq->txq_fifo_pending)) { 2243 if (!list_empty(&txq->txq_fifo_pending)) {
@@ -2377,7 +2369,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2377 for (acno = 0, ac = &an->ac[acno]; 2369 for (acno = 0, ac = &an->ac[acno];
2378 acno < WME_NUM_AC; acno++, ac++) { 2370 acno < WME_NUM_AC; acno++, ac++) {
2379 ac->sched = false; 2371 ac->sched = false;
2380 ac->qnum = sc->tx.hwq_map[acno]; 2372 ac->txq = sc->tx.txq_map[acno];
2381 INIT_LIST_HEAD(&ac->tid_q); 2373 INIT_LIST_HEAD(&ac->tid_q);
2382 } 2374 }
2383} 2375}
@@ -2387,17 +2379,13 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
2387 struct ath_atx_ac *ac; 2379 struct ath_atx_ac *ac;
2388 struct ath_atx_tid *tid; 2380 struct ath_atx_tid *tid;
2389 struct ath_txq *txq; 2381 struct ath_txq *txq;
2390 int i, tidno; 2382 int tidno;
2391 2383
2392 for (tidno = 0, tid = &an->tid[tidno]; 2384 for (tidno = 0, tid = &an->tid[tidno];
2393 tidno < WME_NUM_TID; tidno++, tid++) { 2385 tidno < WME_NUM_TID; tidno++, tid++) {
2394 i = tid->ac->qnum;
2395
2396 if (!ATH_TXQ_SETUP(sc, i))
2397 continue;
2398 2386
2399 txq = &sc->tx.txq[i];
2400 ac = tid->ac; 2387 ac = tid->ac;
2388 txq = ac->txq;
2401 2389
2402 spin_lock_bh(&txq->axq_lock); 2390 spin_lock_bh(&txq->axq_lock);
2403 2391
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 6cf0c9ef47aa..d07ff7f2fd92 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -48,7 +48,7 @@
48#include <linux/usb.h> 48#include <linux/usb.h>
49#ifdef CONFIG_CARL9170_LEDS 49#ifdef CONFIG_CARL9170_LEDS
50#include <linux/leds.h> 50#include <linux/leds.h>
51#endif /* CONFIG_CARL170_LEDS */ 51#endif /* CONFIG_CARL9170_LEDS */
52#ifdef CONFIG_CARL9170_WPC 52#ifdef CONFIG_CARL9170_WPC
53#include <linux/input.h> 53#include <linux/input.h>
54#endif /* CONFIG_CARL9170_WPC */ 54#endif /* CONFIG_CARL9170_WPC */
@@ -215,7 +215,7 @@ enum carl9170_restart_reasons {
215 CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS, 215 CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
216 CARL9170_RR_WATCHDOG, 216 CARL9170_RR_WATCHDOG,
217 CARL9170_RR_STUCK_TX, 217 CARL9170_RR_STUCK_TX,
218 CARL9170_RR_SLOW_SYSTEM, 218 CARL9170_RR_UNRESPONSIVE_DEVICE,
219 CARL9170_RR_COMMAND_TIMEOUT, 219 CARL9170_RR_COMMAND_TIMEOUT,
220 CARL9170_RR_TOO_MANY_PHY_ERRORS, 220 CARL9170_RR_TOO_MANY_PHY_ERRORS,
221 CARL9170_RR_LOST_RSP, 221 CARL9170_RR_LOST_RSP,
@@ -287,6 +287,7 @@ struct ar9170 {
287 287
288 /* reset / stuck frames/queue detection */ 288 /* reset / stuck frames/queue detection */
289 struct work_struct restart_work; 289 struct work_struct restart_work;
290 struct work_struct ping_work;
290 unsigned int restart_counter; 291 unsigned int restart_counter;
291 unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; 292 unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
292 unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; 293 unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d552166db505..3680dfc70f46 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -97,13 +97,13 @@ struct carl9170_set_key_cmd {
97 __le16 type; 97 __le16 type;
98 u8 macAddr[6]; 98 u8 macAddr[6];
99 u32 key[4]; 99 u32 key[4];
100} __packed; 100} __packed __aligned(4);
101#define CARL9170_SET_KEY_CMD_SIZE 28 101#define CARL9170_SET_KEY_CMD_SIZE 28
102 102
103struct carl9170_disable_key_cmd { 103struct carl9170_disable_key_cmd {
104 __le16 user; 104 __le16 user;
105 __le16 padding; 105 __le16 padding;
106} __packed; 106} __packed __aligned(4);
107#define CARL9170_DISABLE_KEY_CMD_SIZE 4 107#define CARL9170_DISABLE_KEY_CMD_SIZE 4
108 108
109struct carl9170_u32_list { 109struct carl9170_u32_list {
@@ -206,7 +206,7 @@ struct carl9170_cmd {
206 struct carl9170_rx_filter_cmd rx_filter; 206 struct carl9170_rx_filter_cmd rx_filter;
207 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 207 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
208 } __packed; 208 } __packed;
209} __packed; 209} __packed __aligned(4);
210 210
211#define CARL9170_TX_STATUS_QUEUE 3 211#define CARL9170_TX_STATUS_QUEUE 3
212#define CARL9170_TX_STATUS_QUEUE_S 0 212#define CARL9170_TX_STATUS_QUEUE_S 0
@@ -216,6 +216,7 @@ struct carl9170_cmd {
216#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) 216#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S)
217#define CARL9170_TX_STATUS_SUCCESS 0x80 217#define CARL9170_TX_STATUS_SUCCESS 0x80
218 218
219#ifdef __CARL9170FW__
219/* 220/*
220 * NOTE: 221 * NOTE:
221 * Both structs [carl9170_tx_status and _carl9170_tx_status] 222 * Both structs [carl9170_tx_status and _carl9170_tx_status]
@@ -232,6 +233,8 @@ struct carl9170_tx_status {
232 u8 tries:3; 233 u8 tries:3;
233 u8 success:1; 234 u8 success:1;
234} __packed; 235} __packed;
236#endif /* __CARL9170FW__ */
237
235struct _carl9170_tx_status { 238struct _carl9170_tx_status {
236 /* 239 /*
237 * This version should be immune to all alignment bugs. 240 * This version should be immune to all alignment bugs.
@@ -272,13 +275,15 @@ struct carl9170_rsp {
272 struct carl9170_rf_init_result rf_init_res; 275 struct carl9170_rf_init_result rf_init_res;
273 struct carl9170_u32_list rreg_res; 276 struct carl9170_u32_list rreg_res;
274 struct carl9170_u32_list echo; 277 struct carl9170_u32_list echo;
278#ifdef __CARL9170FW__
275 struct carl9170_tx_status tx_status[0]; 279 struct carl9170_tx_status tx_status[0];
280#endif /* __CARL9170FW__ */
276 struct _carl9170_tx_status _tx_status[0]; 281 struct _carl9170_tx_status _tx_status[0];
277 struct carl9170_gpio gpio; 282 struct carl9170_gpio gpio;
278 struct carl9170_tsf_rsp tsf; 283 struct carl9170_tsf_rsp tsf;
279 struct carl9170_psm psm; 284 struct carl9170_psm psm;
280 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; 285 u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
281 } __packed; 286 } __packed;
282} __packed; 287} __packed __aligned(4);
283 288
284#endif /* __CARL9170_SHARED_FWCMD_H */ 289#endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 2f471b3f05af..e85df6edfed3 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -712,7 +712,8 @@ struct ar9170_stream {
712 __le16 tag; 712 __le16 tag;
713 713
714 u8 payload[0]; 714 u8 payload[0];
715}; 715} __packed __aligned(4);
716#define AR9170_STREAM_LEN 4
716 717
717#define AR9170_MAX_ACKTABLE_ENTRIES 8 718#define AR9170_MAX_ACKTABLE_ENTRIES 8
718#define AR9170_MAX_VIRTUAL_MAC 7 719#define AR9170_MAX_VIRTUAL_MAC 7
@@ -736,4 +737,8 @@ struct ar9170_stream {
736 737
737#define MOD_VAL(reg, value, newvalue) \ 738#define MOD_VAL(reg, value, newvalue) \
738 (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) 739 (((value) & ~reg) | (((newvalue) << reg##_S) & reg))
740
741#define GET_VAL(reg, value) \
742 (((value) & reg) >> reg##_S)
743
739#endif /* __CARL9170_SHARED_HW_H */ 744#endif /* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 2305bc27151c..385cf508479b 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -205,8 +205,8 @@ int carl9170_init_mac(struct ar9170 *ar)
205 carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); 205 carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
206 206
207 /* Aggregation MAX number and timeout */ 207 /* Aggregation MAX number and timeout */
208 carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa); 208 carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
209 carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00); 209 carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
210 210
211 carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, 211 carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
212 AR9170_MAC_FTF_DEFAULTS); 212 AR9170_MAC_FTF_DEFAULTS);
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
457 457
458int carl9170_update_beacon(struct ar9170 *ar, const bool submit) 458int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
459{ 459{
460 struct sk_buff *skb; 460 struct sk_buff *skb = NULL;
461 struct carl9170_vif_info *cvif; 461 struct carl9170_vif_info *cvif;
462 struct ieee80211_tx_info *txinfo;
462 __le32 *data, *old = NULL; 463 __le32 *data, *old = NULL;
463 u32 word, off, addr, len; 464 u32 word, off, addr, len;
464 int i = 0, err = 0; 465 int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
487 488
488 if (!skb) { 489 if (!skb) {
489 err = -ENOMEM; 490 err = -ENOMEM;
490 goto out_unlock; 491 goto err_free;
492 }
493
494 txinfo = IEEE80211_SKB_CB(skb);
495 if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
496 err = -EINVAL;
497 goto err_free;
491 } 498 }
492 499
493 spin_lock_bh(&ar->beacon_lock); 500 spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
504 wiphy_err(ar->hw->wiphy, "beacon does not " 511 wiphy_err(ar->hw->wiphy, "beacon does not "
505 "fit into device memory!\n"); 512 "fit into device memory!\n");
506 } 513 }
507
508 spin_unlock_bh(&ar->beacon_lock);
509 dev_kfree_skb_any(skb);
510 err = -EINVAL; 514 err = -EINVAL;
511 goto out_unlock; 515 goto err_unlock;
512 } 516 }
513 517
514 if (len > AR9170_MAC_BCN_LENGTH_MAX) { 518 if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
518 AR9170_MAC_BCN_LENGTH_MAX, len); 522 AR9170_MAC_BCN_LENGTH_MAX, len);
519 } 523 }
520 524
521 spin_unlock_bh(&ar->beacon_lock);
522 dev_kfree_skb_any(skb);
523 err = -EMSGSIZE; 525 err = -EMSGSIZE;
524 goto out_unlock; 526 goto err_unlock;
525 } 527 }
526 528
527 carl9170_async_regwrite_begin(ar); 529 i = txinfo->control.rates[0].idx;
530 if (txinfo->band != IEEE80211_BAND_2GHZ)
531 i += 4;
528 532
529 /* XXX: use skb->cb info */ 533 word = __carl9170_ratetable[i].hw_value & 0xf;
530 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { 534 if (i < 4)
531 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, 535 word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
532 ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); 536 else
533 } else { 537 word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
534 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, 538
535 ((skb->len + FCS_LEN) << 16) + 0x001b); 539 carl9170_async_regwrite_begin(ar);
536 } 540 carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
537 541
538 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { 542 for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
539 /* 543 /*
@@ -557,7 +561,7 @@ found:
557 cvif->beacon = skb; 561 cvif->beacon = skb;
558 spin_unlock_bh(&ar->beacon_lock); 562 spin_unlock_bh(&ar->beacon_lock);
559 if (err) 563 if (err)
560 goto out_unlock; 564 goto err_free;
561 565
562 if (submit) { 566 if (submit) {
563 err = carl9170_bcn_ctrl(ar, cvif->id, 567 err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
565 addr, skb->len + FCS_LEN); 569 addr, skb->len + FCS_LEN);
566 570
567 if (err) 571 if (err)
568 goto out_unlock; 572 goto err_free;
569 } 573 }
570out_unlock: 574out_unlock:
571 rcu_read_unlock(); 575 rcu_read_unlock();
576 return 0;
577
578err_unlock:
579 spin_unlock_bh(&ar->beacon_lock);
580
581err_free:
582 rcu_read_unlock();
583 dev_kfree_skb_any(skb);
572 return err; 584 return err;
573} 585}
574 586
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 980ae70ea424..4ae6a5849076 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar)
428 cancel_delayed_work_sync(&ar->led_work); 428 cancel_delayed_work_sync(&ar->led_work);
429#endif /* CONFIG_CARL9170_LEDS */ 429#endif /* CONFIG_CARL9170_LEDS */
430 cancel_work_sync(&ar->ps_work); 430 cancel_work_sync(&ar->ps_work);
431 cancel_work_sync(&ar->ping_work);
431 cancel_work_sync(&ar->ampdu_work); 432 cancel_work_sync(&ar->ampdu_work);
432} 433}
433 434
@@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
533 */ 534 */
534} 535}
535 536
537static void carl9170_ping_work(struct work_struct *work)
538{
539 struct ar9170 *ar = container_of(work, struct ar9170, ping_work);
540 int err;
541
542 if (!IS_STARTED(ar))
543 return;
544
545 mutex_lock(&ar->mutex);
546 err = carl9170_echo_test(ar, 0xdeadbeef);
547 if (err)
548 carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE);
549 mutex_unlock(&ar->mutex);
550}
551
536static int carl9170_init_interface(struct ar9170 *ar, 552static int carl9170_init_interface(struct ar9170 *ar,
537 struct ieee80211_vif *vif) 553 struct ieee80211_vif *vif)
538{ 554{
@@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size)
1614 skb_queue_head_init(&ar->tx_pending[i]); 1630 skb_queue_head_init(&ar->tx_pending[i]);
1615 } 1631 }
1616 INIT_WORK(&ar->ps_work, carl9170_ps_work); 1632 INIT_WORK(&ar->ps_work, carl9170_ps_work);
1633 INIT_WORK(&ar->ping_work, carl9170_ping_work);
1617 INIT_WORK(&ar->restart_work, carl9170_restart_work); 1634 INIT_WORK(&ar->restart_work, carl9170_restart_work);
1618 INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); 1635 INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
1619 INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); 1636 INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
@@ -1828,7 +1845,7 @@ int carl9170_register(struct ar9170 *ar)
1828 err = carl9170_led_register(ar); 1845 err = carl9170_led_register(ar);
1829 if (err) 1846 if (err)
1830 goto err_unreg; 1847 goto err_unreg;
1831#endif /* CONFIG_CAR9L170_LEDS */ 1848#endif /* CONFIG_CARL9170_LEDS */
1832 1849
1833#ifdef CONFIG_CARL9170_WPC 1850#ifdef CONFIG_CARL9170_WPC
1834 err = carl9170_register_wps_button(ar); 1851 err = carl9170_register_wps_button(ar);
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 89deca37a988..82bc81c4c930 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1554,15 +1554,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
1554 return carl9170_regwrite_result(); 1554 return carl9170_regwrite_result();
1555} 1555}
1556 1556
1557/* TODO: replace this with sign_extend32(noise, 8) */
1558static int carl9170_calc_noise_dbm(u32 raw_noise)
1559{
1560 if (raw_noise & 0x100)
1561 return ~0x1ff | raw_noise;
1562 else
1563 return raw_noise;
1564}
1565
1566int carl9170_get_noisefloor(struct ar9170 *ar) 1557int carl9170_get_noisefloor(struct ar9170 *ar)
1567{ 1558{
1568 static const u32 phy_regs[] = { 1559 static const u32 phy_regs[] = {
@@ -1578,11 +1569,11 @@ int carl9170_get_noisefloor(struct ar9170 *ar)
1578 return err; 1569 return err;
1579 1570
1580 for (i = 0; i < 2; i++) { 1571 for (i = 0; i < 2; i++) {
1581 ar->noise[i] = carl9170_calc_noise_dbm( 1572 ar->noise[i] = sign_extend32(GET_VAL(
1582 (phy_res[i] >> 19) & 0x1ff); 1573 AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8);
1583 1574
1584 ar->noise[i + 2] = carl9170_calc_noise_dbm( 1575 ar->noise[i + 2] = sign_extend32(GET_VAL(
1585 (phy_res[i + 2] >> 23) & 0x1ff); 1576 AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
1586 } 1577 }
1587 1578
1588 return 0; 1579 return 0;
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 02c34eb4ebde..024fb42bc787 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -139,8 +139,8 @@
139#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 139#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
140 140
141#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) 141#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064)
142#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000 142#define AR9170_PHY_CCA_MIN_PWR 0x0ff80000
143#define AR9170_PHY_CCA_MINCCA_PWR_S 19 143#define AR9170_PHY_CCA_MIN_PWR_S 19
144#define AR9170_PHY_CCA_THRESH62 0x0007f000 144#define AR9170_PHY_CCA_THRESH62 0x0007f000
145#define AR9170_PHY_CCA_THRESH62_S 12 145#define AR9170_PHY_CCA_THRESH62_S 12
146 146
@@ -338,8 +338,8 @@
338#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 338#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9
339#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 339#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000
340#define AR9170_PHY_EXT_CCA_THRESH62_S 16 340#define AR9170_PHY_EXT_CCA_THRESH62_S 16
341#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000 341#define AR9170_PHY_EXT_CCA_MIN_PWR 0xff800000
342#define AR9170_PHY_EXT_MINCCA_PWR_S 23 342#define AR9170_PHY_EXT_CCA_MIN_PWR_S 23
343 343
344#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) 344#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0)
345#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f 345#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f
@@ -546,19 +546,19 @@
546#define AR9170_PHY_FORCE_XPA_CFG_S 0 546#define AR9170_PHY_FORCE_XPA_CFG_S 0
547 547
548#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) 548#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064)
549#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000 549#define AR9170_PHY_CH1_CCA_MIN_PWR 0x0ff80000
550#define AR9170_PHY_CH1_MINCCA_PWR_S 19 550#define AR9170_PHY_CH1_CCA_MIN_PWR_S 19
551 551
552#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) 552#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064)
553#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000 553#define AR9170_PHY_CH2_CCA_MIN_PWR 0x0ff80000
554#define AR9170_PHY_CH2_MINCCA_PWR_S 19 554#define AR9170_PHY_CH2_CCA_MIN_PWR_S 19
555 555
556#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) 556#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc)
557#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000 557#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR 0xff800000
558#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23 558#define AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S 23
559 559
560#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) 560#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc)
561#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 561#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR 0xff800000
562#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 562#define AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S 23
563 563
564#endif /* __CARL9170_SHARED_PHY_H */ 564#endif /* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index b575c865142d..688eede48516 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -242,9 +242,11 @@ static void carl9170_tx_release(struct kref *ref)
242 ar->tx_ampdu_schedule = true; 242 ar->tx_ampdu_schedule = true;
243 243
244 if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) { 244 if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) {
245 txinfo->status.ampdu_len = txinfo->pad[0]; 245 struct _carl9170_tx_superframe *super;
246 txinfo->status.ampdu_ack_len = txinfo->pad[1]; 246
247 txinfo->pad[0] = txinfo->pad[1] = 0; 247 super = (void *)skb->data;
248 txinfo->status.ampdu_len = super->s.rix;
249 txinfo->status.ampdu_ack_len = super->s.cnt;
248 } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { 250 } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
249 /* 251 /*
250 * drop redundant tx_status reports: 252 * drop redundant tx_status reports:
@@ -337,7 +339,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
337 u8 tid; 339 u8 tid;
338 340
339 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || 341 if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
340 txinfo->flags & IEEE80211_TX_CTL_INJECTED) 342 txinfo->flags & IEEE80211_TX_CTL_INJECTED ||
343 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
341 return; 344 return;
342 345
343 tx_info = IEEE80211_SKB_CB(skb); 346 tx_info = IEEE80211_SKB_CB(skb);
@@ -389,8 +392,8 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
389 sta_info->stats[tid].ampdu_ack_len++; 392 sta_info->stats[tid].ampdu_ack_len++;
390 393
391 if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { 394 if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) {
392 txinfo->pad[0] = sta_info->stats[tid].ampdu_len; 395 super->s.rix = sta_info->stats[tid].ampdu_len;
393 txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len; 396 super->s.cnt = sta_info->stats[tid].ampdu_ack_len;
394 txinfo->flags |= IEEE80211_TX_STAT_AMPDU; 397 txinfo->flags |= IEEE80211_TX_STAT_AMPDU;
395 sta_info->stats[tid].clear = true; 398 sta_info->stats[tid].clear = true;
396 } 399 }
@@ -524,6 +527,59 @@ next:
524 } 527 }
525} 528}
526 529
530static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
531{
532 struct carl9170_sta_tid *iter;
533 struct sk_buff *skb;
534 struct ieee80211_tx_info *txinfo;
535 struct carl9170_tx_info *arinfo;
536 struct _carl9170_tx_superframe *super;
537 struct ieee80211_sta *sta;
538 struct ieee80211_vif *vif;
539 struct ieee80211_hdr *hdr;
540 unsigned int vif_id;
541
542 rcu_read_lock();
543 list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
544 if (iter->state < CARL9170_TID_STATE_IDLE)
545 continue;
546
547 spin_lock_bh(&iter->lock);
548 skb = skb_peek(&iter->queue);
549 if (!skb)
550 goto unlock;
551
552 txinfo = IEEE80211_SKB_CB(skb);
553 arinfo = (void *)txinfo->rate_driver_data;
554 if (time_is_after_jiffies(arinfo->timeout +
555 msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
556 goto unlock;
557
558 super = (void *) skb->data;
559 hdr = (void *) super->frame_data;
560
561 vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
562 CARL9170_TX_SUPER_MISC_VIF_ID_S;
563
564 if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
565 goto unlock;
566
567 vif = rcu_dereference(ar->vif_priv[vif_id].vif);
568 if (WARN_ON(!vif))
569 goto unlock;
570
571 sta = ieee80211_find_sta(vif, hdr->addr1);
572 if (WARN_ON(!sta))
573 goto unlock;
574
575 ieee80211_stop_tx_ba_session(sta, iter->tid);
576unlock:
577 spin_unlock_bh(&iter->lock);
578
579 }
580 rcu_read_unlock();
581}
582
527void carl9170_tx_janitor(struct work_struct *work) 583void carl9170_tx_janitor(struct work_struct *work)
528{ 584{
529 struct ar9170 *ar = container_of(work, struct ar9170, 585 struct ar9170 *ar = container_of(work, struct ar9170,
@@ -534,6 +590,7 @@ void carl9170_tx_janitor(struct work_struct *work)
534 ar->tx_janitor_last_run = jiffies; 590 ar->tx_janitor_last_run = jiffies;
535 591
536 carl9170_check_queue_stop_timeout(ar); 592 carl9170_check_queue_stop_timeout(ar);
593 carl9170_tx_ampdu_timeout(ar);
537 594
538 if (!atomic_read(&ar->tx_total_queued)) 595 if (!atomic_read(&ar->tx_total_queued))
539 return; 596 return;
@@ -842,10 +899,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
842 if (unlikely(!sta || !cvif)) 899 if (unlikely(!sta || !cvif))
843 goto err_out; 900 goto err_out;
844 901
845 factor = min_t(unsigned int, 1u, 902 factor = min_t(unsigned int, 1u, sta->ht_cap.ampdu_factor);
846 info->control.sta->ht_cap.ampdu_factor); 903 density = sta->ht_cap.ampdu_density;
847
848 density = info->control.sta->ht_cap.ampdu_density;
849 904
850 if (density) { 905 if (density) {
851 /* 906 /*
@@ -1206,6 +1261,7 @@ static void carl9170_tx(struct ar9170 *ar)
1206static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, 1261static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
1207 struct ieee80211_sta *sta, struct sk_buff *skb) 1262 struct ieee80211_sta *sta, struct sk_buff *skb)
1208{ 1263{
1264 struct _carl9170_tx_superframe *super = (void *) super;
1209 struct carl9170_sta_info *sta_info; 1265 struct carl9170_sta_info *sta_info;
1210 struct carl9170_sta_tid *agg; 1266 struct carl9170_sta_tid *agg;
1211 struct sk_buff *iter; 1267 struct sk_buff *iter;
@@ -1274,6 +1330,7 @@ err_unlock:
1274 1330
1275err_unlock_rcu: 1331err_unlock_rcu:
1276 rcu_read_unlock(); 1332 rcu_read_unlock();
1333 super->f.mac_control &= ~cpu_to_le16(AR9170_TX_MAC_AGGR);
1277 carl9170_tx_status(ar, skb, false); 1334 carl9170_tx_status(ar, skb, false);
1278 ar->tx_dropped++; 1335 ar->tx_dropped++;
1279 return false; 1336 return false;
@@ -1302,9 +1359,6 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1302 */ 1359 */
1303 1360
1304 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1361 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1305 if (WARN_ON_ONCE(!sta))
1306 goto err_free;
1307
1308 run = carl9170_tx_ampdu_queue(ar, sta, skb); 1362 run = carl9170_tx_ampdu_queue(ar, sta, skb);
1309 if (run) 1363 if (run)
1310 carl9170_tx_ampdu(ar); 1364 carl9170_tx_ampdu(ar);
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 3317039cd28f..82c5f1c50650 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -433,7 +433,7 @@ static void carl9170_usb_rx_complete(struct urb *urb)
433 * device. 433 * device.
434 */ 434 */
435 435
436 carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM); 436 ieee80211_queue_work(ar->hw, &ar->ping_work);
437 } 437 }
438 } else { 438 } else {
439 /* 439 /*
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index ff53f078a0b5..ee0f84f2a2f6 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
1#ifndef __CARL9170_SHARED_VERSION_H 1#ifndef __CARL9170_SHARED_VERSION_H
2#define __CARL9170_SHARED_VERSION_H 2#define __CARL9170_SHARED_VERSION_H
3#define CARL9170FW_VERSION_YEAR 10 3#define CARL9170FW_VERSION_YEAR 10
4#define CARL9170FW_VERSION_MONTH 9 4#define CARL9170FW_VERSION_MONTH 10
5#define CARL9170FW_VERSION_DAY 28 5#define CARL9170FW_VERSION_DAY 29
6#define CARL9170FW_VERSION_GIT "1.8.8.3" 6#define CARL9170FW_VERSION_GIT "1.9.0"
7#endif /* __CARL9170_SHARED_VERSION_H */ 7#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 64e4af2c2887..f207007ee391 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -70,11 +70,13 @@ enum ATH_DEBUG {
70#ifdef CONFIG_ATH_DEBUG 70#ifdef CONFIG_ATH_DEBUG
71void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) 71void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
72 __attribute__ ((format (printf, 3, 4))); 72 __attribute__ ((format (printf, 3, 4)));
73#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
73#else 74#else
74static inline void __attribute__ ((format (printf, 3, 4))) 75static inline void __attribute__ ((format (printf, 3, 4)))
75ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) 76ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
76{ 77{
77} 78}
79#define ATH_DBG_WARN(foo, arg)
78#endif /* CONFIG_ATH_DEBUG */ 80#endif /* CONFIG_ATH_DEBUG */
79 81
80/** Returns string describing opmode, or NULL if unknown mode. */ 82/** Returns string describing opmode, or NULL if unknown mode. */
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index bd21a4d82085..62e3dac8f92a 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -67,7 +67,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
67} 67}
68EXPORT_SYMBOL(ath_hw_keyreset); 68EXPORT_SYMBOL(ath_hw_keyreset);
69 69
70bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) 70static bool ath_hw_keysetmac(struct ath_common *common,
71 u16 entry, const u8 *mac)
71{ 72{
72 u32 macHi, macLo; 73 u32 macHi, macLo;
73 u32 unicast_flag = AR_KEYTABLE_VALID; 74 u32 unicast_flag = AR_KEYTABLE_VALID;
@@ -107,9 +108,9 @@ bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
107 return true; 108 return true;
108} 109}
109 110
110bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, 111static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
111 const struct ath_keyval *k, 112 const struct ath_keyval *k,
112 const u8 *mac) 113 const u8 *mac)
113{ 114{
114 void *ah = common->ah; 115 void *ah = common->ah;
115 u32 key0, key1, key2, key3, key4; 116 u32 key0, key1, key2, key3, key4;
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 72821c456b02..9aad2ca3c112 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -153,6 +153,19 @@
153#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna 153#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna
154 * with bluetooth */ 154 * with bluetooth */
155 155
156/* SPROM boardflags2_lo values */
157#define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */
158#define B43_BFL2_APLL_WAR 0x0002 /* alternative A-band PLL settings implemented */
159#define B43_BFL2_TXPWRCTRL_EN 0x0004 /* permits enabling TX Power Control */
160#define B43_BFL2_2X4_DIV 0x0008 /* 2x4 diversity switch */
161#define B43_BFL2_5G_PWRGAIN 0x0010 /* supports 5G band power gain */
162#define B43_BFL2_PCIEWAR_OVR 0x0020 /* overrides ASPM and Clkreq settings */
163#define B43_BFL2_CAESERS_BRD 0x0040 /* is Caesers board (unused) */
164#define B43_BFL2_BTC3WIRE 0x0080 /* used 3-wire bluetooth coexist */
165#define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */
166#define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */
167#define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */
168
156/* GPIO register offset, in both ChipCommon and PCI core. */ 169/* GPIO register offset, in both ChipCommon and PCI core. */
157#define B43_GPIO_CONTROL 0x6c 170#define B43_GPIO_CONTROL 0x6c
158 171
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 10d0aaf754c5..3d5566e7af0a 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -415,11 +415,6 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
415 415
416static void free_ringmemory(struct b43_dmaring *ring) 416static void free_ringmemory(struct b43_dmaring *ring)
417{ 417{
418 gfp_t flags = GFP_KERNEL;
419
420 if (ring->type == B43_DMA_64BIT)
421 flags |= GFP_DMA;
422
423 dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, 418 dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
424 ring->descbase, ring->dmabase); 419 ring->descbase, ring->dmabase);
425} 420}
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e0f2d122e124..6facb8ab05d1 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -191,7 +191,8 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
191 binfo->type != 0x46D || 191 binfo->type != 0x46D ||
192 binfo->rev < 0x41); 192 binfo->rev < 0x41);
193 else 193 else
194 workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0); 194 workaround =
195 !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
195 196
196 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); 197 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
197 if (workaround) { 198 if (workaround) {
@@ -240,10 +241,13 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
240static void b43_radio_init2055(struct b43_wldev *dev) 241static void b43_radio_init2055(struct b43_wldev *dev)
241{ 242{
242 b43_radio_init2055_pre(dev); 243 b43_radio_init2055_pre(dev);
243 if (b43_status(dev) < B43_STAT_INITIALIZED) 244 if (b43_status(dev) < B43_STAT_INITIALIZED) {
244 b2055_upload_inittab(dev, 0, 1); 245 /* Follow wl, not specs. Do not force uploading all regs */
245 else 246 b2055_upload_inittab(dev, 0, 0);
246 b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0); 247 } else {
248 bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ;
249 b2055_upload_inittab(dev, ghz5, 0);
250 }
247 b43_radio_init2055_post(dev); 251 b43_radio_init2055_post(dev);
248} 252}
249 253
diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c
index 1b5316586cbf..0d6771515bce 100644
--- a/drivers/net/wireless/b43/radio_2055.c
+++ b/drivers/net/wireless/b43/radio_2055.c
@@ -244,7 +244,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = {
244 [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 244 [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
245 [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 245 [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
246 [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 246 [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
247 [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 247 [0xCE] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
248 [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 248 [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
249 [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 249 [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
250 [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, 250 [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
@@ -256,7 +256,7 @@ static const struct b2055_inittab_entry b2055_inittab [] = {
256 [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 256 [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
257 [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 257 [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
258 [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 258 [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
259 [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 259 [0xDA] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
260 [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 260 [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
261 [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, 261 [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
262 [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, 262 [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
@@ -1299,7 +1299,7 @@ void b2055_upload_inittab(struct b43_wldev *dev,
1299 bool ghz5, bool ignore_uploadflag) 1299 bool ghz5, bool ignore_uploadflag)
1300{ 1300{
1301 const struct b2055_inittab_entry *e; 1301 const struct b2055_inittab_entry *e;
1302 unsigned int i; 1302 unsigned int i, writes = 0;
1303 u16 value; 1303 u16 value;
1304 1304
1305 for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) { 1305 for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
@@ -1312,6 +1312,8 @@ void b2055_upload_inittab(struct b43_wldev *dev,
1312 else 1312 else
1313 value = e->ghz2; 1313 value = e->ghz2;
1314 b43_radio_write16(dev, i, value); 1314 b43_radio_write16(dev, i, value);
1315 if (++writes % 4 == 0)
1316 b43_read32(dev, B43_MMIO_MACCTL); /* flush */
1315 } 1317 }
1316 } 1318 }
1317} 1319}
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
index d8563192ce56..f710c01f2cc4 100644
--- a/drivers/net/wireless/b43/radio_2056.c
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -24,9 +24,60 @@
24#include "radio_2056.h" 24#include "radio_2056.h"
25#include "phy_common.h" 25#include "phy_common.h"
26 26
27#define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
28 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
29 r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \
30 r30, r31, r32, r33, r34, r35, r36) \
31 .radio_syn_pll_vcocal1 = r00, \
32 .radio_syn_pll_vcocal2 = r01, \
33 .radio_syn_pll_refdiv = r02, \
34 .radio_syn_pll_mmd2 = r03, \
35 .radio_syn_pll_mmd1 = r04, \
36 .radio_syn_pll_loopfilter1 = r05, \
37 .radio_syn_pll_loopfilter2 = r06, \
38 .radio_syn_pll_loopfilter3 = r07, \
39 .radio_syn_pll_loopfilter4 = r08, \
40 .radio_syn_pll_loopfilter5 = r09, \
41 .radio_syn_reserved_addr27 = r10, \
42 .radio_syn_reserved_addr28 = r11, \
43 .radio_syn_reserved_addr29 = r12, \
44 .radio_syn_logen_vcobuf1 = r13, \
45 .radio_syn_logen_mixer2 = r14, \
46 .radio_syn_logen_buf3 = r15, \
47 .radio_syn_logen_buf4 = r16, \
48 .radio_rx0_lnaa_tune = r17, \
49 .radio_rx0_lnag_tune = r18, \
50 .radio_tx0_intpaa_boost_tune = r19, \
51 .radio_tx0_intpag_boost_tune = r20, \
52 .radio_tx0_pada_boost_tune = r21, \
53 .radio_tx0_padg_boost_tune = r22, \
54 .radio_tx0_pgaa_boost_tune = r23, \
55 .radio_tx0_pgag_boost_tune = r24, \
56 .radio_tx0_mixa_boost_tune = r25, \
57 .radio_tx0_mixg_boost_tune = r26, \
58 .radio_rx1_lnaa_tune = r27, \
59 .radio_rx1_lnag_tune = r28, \
60 .radio_tx1_intpaa_boost_tune = r29, \
61 .radio_tx1_intpag_boost_tune = r30, \
62 .radio_tx1_pada_boost_tune = r31, \
63 .radio_tx1_padg_boost_tune = r32, \
64 .radio_tx1_pgaa_boost_tune = r33, \
65 .radio_tx1_pgag_boost_tune = r34, \
66 .radio_tx1_mixa_boost_tune = r35, \
67 .radio_tx1_mixg_boost_tune = r36
68
69#define PHYREGS(r0, r1, r2, r3, r4, r5) \
70 .phy_regs.phy_bw1a = r0, \
71 .phy_regs.phy_bw2 = r1, \
72 .phy_regs.phy_bw3 = r2, \
73 .phy_regs.phy_bw4 = r3, \
74 .phy_regs.phy_bw5 = r4, \
75 .phy_regs.phy_bw6 = r5
76
27static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { 77static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
28}; 78};
29 79
80/* TODO: add support for rev4+ devices by searching in rev4+ tables */
30const struct b43_nphy_channeltab_entry_rev3 * 81const struct b43_nphy_channeltab_entry_rev3 *
31b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) 82b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
32{ 83{
diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h
index fda6dafecb8c..302600c0afa4 100644
--- a/drivers/net/wireless/b43/radio_2056.h
+++ b/drivers/net/wireless/b43/radio_2056.h
@@ -4,6 +4,9 @@
4 4
5 Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com> 5 Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
6 6
7 Some parts of the code in this file are derived from the brcm80211
8 driver Copyright (c) 2010 Broadcom Corporation
9
7 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 12 the Free Software Foundation; either version 2 of the License, or
@@ -28,13 +31,1085 @@
28 31
29#include "tables_nphy.h" 32#include "tables_nphy.h"
30 33
34#define B2056_SYN (0x0 << 12)
35#define B2056_TX0 (0x2 << 12)
36#define B2056_TX1 (0x3 << 12)
37#define B2056_RX0 (0x6 << 12)
38#define B2056_RX1 (0x7 << 12)
39#define B2056_ALLTX (0xE << 12)
40#define B2056_ALLRX (0xF << 12)
41
42#define B2056_SYN_RESERVED_ADDR0 0x00
43#define B2056_SYN_IDCODE 0x01
44#define B2056_SYN_RESERVED_ADDR2 0x02
45#define B2056_SYN_RESERVED_ADDR3 0x03
46#define B2056_SYN_RESERVED_ADDR4 0x04
47#define B2056_SYN_RESERVED_ADDR5 0x05
48#define B2056_SYN_RESERVED_ADDR6 0x06
49#define B2056_SYN_RESERVED_ADDR7 0x07
50#define B2056_SYN_COM_CTRL 0x08
51#define B2056_SYN_COM_PU 0x09
52#define B2056_SYN_COM_OVR 0x0A
53#define B2056_SYN_COM_RESET 0x0B
54#define B2056_SYN_COM_RCAL 0x0C
55#define B2056_SYN_COM_RC_RXLPF 0x0D
56#define B2056_SYN_COM_RC_TXLPF 0x0E
57#define B2056_SYN_COM_RC_RXHPF 0x0F
58#define B2056_SYN_RESERVED_ADDR16 0x10
59#define B2056_SYN_RESERVED_ADDR17 0x11
60#define B2056_SYN_RESERVED_ADDR18 0x12
61#define B2056_SYN_RESERVED_ADDR19 0x13
62#define B2056_SYN_RESERVED_ADDR20 0x14
63#define B2056_SYN_RESERVED_ADDR21 0x15
64#define B2056_SYN_RESERVED_ADDR22 0x16
65#define B2056_SYN_RESERVED_ADDR23 0x17
66#define B2056_SYN_RESERVED_ADDR24 0x18
67#define B2056_SYN_RESERVED_ADDR25 0x19
68#define B2056_SYN_RESERVED_ADDR26 0x1A
69#define B2056_SYN_RESERVED_ADDR27 0x1B
70#define B2056_SYN_RESERVED_ADDR28 0x1C
71#define B2056_SYN_RESERVED_ADDR29 0x1D
72#define B2056_SYN_RESERVED_ADDR30 0x1E
73#define B2056_SYN_RESERVED_ADDR31 0x1F
74#define B2056_SYN_GPIO_MASTER1 0x20
75#define B2056_SYN_GPIO_MASTER2 0x21
76#define B2056_SYN_TOPBIAS_MASTER 0x22
77#define B2056_SYN_TOPBIAS_RCAL 0x23
78#define B2056_SYN_AFEREG 0x24
79#define B2056_SYN_TEMPPROCSENSE 0x25
80#define B2056_SYN_TEMPPROCSENSEIDAC 0x26
81#define B2056_SYN_TEMPPROCSENSERCAL 0x27
82#define B2056_SYN_LPO 0x28
83#define B2056_SYN_VDDCAL_MASTER 0x29
84#define B2056_SYN_VDDCAL_IDAC 0x2A
85#define B2056_SYN_VDDCAL_STATUS 0x2B
86#define B2056_SYN_RCAL_MASTER 0x2C
87#define B2056_SYN_RCAL_CODE_OUT 0x2D
88#define B2056_SYN_RCCAL_CTRL0 0x2E
89#define B2056_SYN_RCCAL_CTRL1 0x2F
90#define B2056_SYN_RCCAL_CTRL2 0x30
91#define B2056_SYN_RCCAL_CTRL3 0x31
92#define B2056_SYN_RCCAL_CTRL4 0x32
93#define B2056_SYN_RCCAL_CTRL5 0x33
94#define B2056_SYN_RCCAL_CTRL6 0x34
95#define B2056_SYN_RCCAL_CTRL7 0x35
96#define B2056_SYN_RCCAL_CTRL8 0x36
97#define B2056_SYN_RCCAL_CTRL9 0x37
98#define B2056_SYN_RCCAL_CTRL10 0x38
99#define B2056_SYN_RCCAL_CTRL11 0x39
100#define B2056_SYN_ZCAL_SPARE1 0x3A
101#define B2056_SYN_ZCAL_SPARE2 0x3B
102#define B2056_SYN_PLL_MAST1 0x3C
103#define B2056_SYN_PLL_MAST2 0x3D
104#define B2056_SYN_PLL_MAST3 0x3E
105#define B2056_SYN_PLL_BIAS_RESET 0x3F
106#define B2056_SYN_PLL_XTAL0 0x40
107#define B2056_SYN_PLL_XTAL1 0x41
108#define B2056_SYN_PLL_XTAL3 0x42
109#define B2056_SYN_PLL_XTAL4 0x43
110#define B2056_SYN_PLL_XTAL5 0x44
111#define B2056_SYN_PLL_XTAL6 0x45
112#define B2056_SYN_PLL_REFDIV 0x46
113#define B2056_SYN_PLL_PFD 0x47
114#define B2056_SYN_PLL_CP1 0x48
115#define B2056_SYN_PLL_CP2 0x49
116#define B2056_SYN_PLL_CP3 0x4A
117#define B2056_SYN_PLL_LOOPFILTER1 0x4B
118#define B2056_SYN_PLL_LOOPFILTER2 0x4C
119#define B2056_SYN_PLL_LOOPFILTER3 0x4D
120#define B2056_SYN_PLL_LOOPFILTER4 0x4E
121#define B2056_SYN_PLL_LOOPFILTER5 0x4F
122#define B2056_SYN_PLL_MMD1 0x50
123#define B2056_SYN_PLL_MMD2 0x51
124#define B2056_SYN_PLL_VCO1 0x52
125#define B2056_SYN_PLL_VCO2 0x53
126#define B2056_SYN_PLL_MONITOR1 0x54
127#define B2056_SYN_PLL_MONITOR2 0x55
128#define B2056_SYN_PLL_VCOCAL1 0x56
129#define B2056_SYN_PLL_VCOCAL2 0x57
130#define B2056_SYN_PLL_VCOCAL4 0x58
131#define B2056_SYN_PLL_VCOCAL5 0x59
132#define B2056_SYN_PLL_VCOCAL6 0x5A
133#define B2056_SYN_PLL_VCOCAL7 0x5B
134#define B2056_SYN_PLL_VCOCAL8 0x5C
135#define B2056_SYN_PLL_VCOCAL9 0x5D
136#define B2056_SYN_PLL_VCOCAL10 0x5E
137#define B2056_SYN_PLL_VCOCAL11 0x5F
138#define B2056_SYN_PLL_VCOCAL12 0x60
139#define B2056_SYN_PLL_VCOCAL13 0x61
140#define B2056_SYN_PLL_VREG 0x62
141#define B2056_SYN_PLL_STATUS1 0x63
142#define B2056_SYN_PLL_STATUS2 0x64
143#define B2056_SYN_PLL_STATUS3 0x65
144#define B2056_SYN_LOGEN_PU0 0x66
145#define B2056_SYN_LOGEN_PU1 0x67
146#define B2056_SYN_LOGEN_PU2 0x68
147#define B2056_SYN_LOGEN_PU3 0x69
148#define B2056_SYN_LOGEN_PU5 0x6A
149#define B2056_SYN_LOGEN_PU6 0x6B
150#define B2056_SYN_LOGEN_PU7 0x6C
151#define B2056_SYN_LOGEN_PU8 0x6D
152#define B2056_SYN_LOGEN_BIAS_RESET 0x6E
153#define B2056_SYN_LOGEN_RCCR1 0x6F
154#define B2056_SYN_LOGEN_VCOBUF1 0x70
155#define B2056_SYN_LOGEN_MIXER1 0x71
156#define B2056_SYN_LOGEN_MIXER2 0x72
157#define B2056_SYN_LOGEN_BUF1 0x73
158#define B2056_SYN_LOGENBUF2 0x74
159#define B2056_SYN_LOGEN_BUF3 0x75
160#define B2056_SYN_LOGEN_BUF4 0x76
161#define B2056_SYN_LOGEN_DIV1 0x77
162#define B2056_SYN_LOGEN_DIV2 0x78
163#define B2056_SYN_LOGEN_DIV3 0x79
164#define B2056_SYN_LOGEN_ACL1 0x7A
165#define B2056_SYN_LOGEN_ACL2 0x7B
166#define B2056_SYN_LOGEN_ACL3 0x7C
167#define B2056_SYN_LOGEN_ACL4 0x7D
168#define B2056_SYN_LOGEN_ACL5 0x7E
169#define B2056_SYN_LOGEN_ACL6 0x7F
170#define B2056_SYN_LOGEN_ACLOUT 0x80
171#define B2056_SYN_LOGEN_ACLCAL1 0x81
172#define B2056_SYN_LOGEN_ACLCAL2 0x82
173#define B2056_SYN_LOGEN_ACLCAL3 0x83
174#define B2056_SYN_CALEN 0x84
175#define B2056_SYN_LOGEN_PEAKDET1 0x85
176#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86
177#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
178#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
179#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
180#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A
181#define B2056_SYN_LOGEN_VCOBUF2 0x8B
182#define B2056_SYN_LOGEN_MIXER3 0x8C
183#define B2056_SYN_LOGEN_BUF5 0x8D
184#define B2056_SYN_LOGEN_BUF6 0x8E
185#define B2056_SYN_LOGEN_CBUFRX1 0x8F
186#define B2056_SYN_LOGEN_CBUFRX2 0x90
187#define B2056_SYN_LOGEN_CBUFRX3 0x91
188#define B2056_SYN_LOGEN_CBUFRX4 0x92
189#define B2056_SYN_LOGEN_CBUFTX1 0x93
190#define B2056_SYN_LOGEN_CBUFTX2 0x94
191#define B2056_SYN_LOGEN_CBUFTX3 0x95
192#define B2056_SYN_LOGEN_CBUFTX4 0x96
193#define B2056_SYN_LOGEN_CMOSRX1 0x97
194#define B2056_SYN_LOGEN_CMOSRX2 0x98
195#define B2056_SYN_LOGEN_CMOSRX3 0x99
196#define B2056_SYN_LOGEN_CMOSRX4 0x9A
197#define B2056_SYN_LOGEN_CMOSTX1 0x9B
198#define B2056_SYN_LOGEN_CMOSTX2 0x9C
199#define B2056_SYN_LOGEN_CMOSTX3 0x9D
200#define B2056_SYN_LOGEN_CMOSTX4 0x9E
201#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F
202#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0
203#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1
204#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2
205#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3
206#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4
207#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5
208#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6
209#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7
210#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8
211#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9
212#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA
213#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB
214#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC
215#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD
216#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE
217#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF
218#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0
219#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1
220#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2
221#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3
222#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4
223#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5
224#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6
225
226#define B2056_TX_RESERVED_ADDR0 0x00
227#define B2056_TX_IDCODE 0x01
228#define B2056_TX_RESERVED_ADDR2 0x02
229#define B2056_TX_RESERVED_ADDR3 0x03
230#define B2056_TX_RESERVED_ADDR4 0x04
231#define B2056_TX_RESERVED_ADDR5 0x05
232#define B2056_TX_RESERVED_ADDR6 0x06
233#define B2056_TX_RESERVED_ADDR7 0x07
234#define B2056_TX_COM_CTRL 0x08
235#define B2056_TX_COM_PU 0x09
236#define B2056_TX_COM_OVR 0x0A
237#define B2056_TX_COM_RESET 0x0B
238#define B2056_TX_COM_RCAL 0x0C
239#define B2056_TX_COM_RC_RXLPF 0x0D
240#define B2056_TX_COM_RC_TXLPF 0x0E
241#define B2056_TX_COM_RC_RXHPF 0x0F
242#define B2056_TX_RESERVED_ADDR16 0x10
243#define B2056_TX_RESERVED_ADDR17 0x11
244#define B2056_TX_RESERVED_ADDR18 0x12
245#define B2056_TX_RESERVED_ADDR19 0x13
246#define B2056_TX_RESERVED_ADDR20 0x14
247#define B2056_TX_RESERVED_ADDR21 0x15
248#define B2056_TX_RESERVED_ADDR22 0x16
249#define B2056_TX_RESERVED_ADDR23 0x17
250#define B2056_TX_RESERVED_ADDR24 0x18
251#define B2056_TX_RESERVED_ADDR25 0x19
252#define B2056_TX_RESERVED_ADDR26 0x1A
253#define B2056_TX_RESERVED_ADDR27 0x1B
254#define B2056_TX_RESERVED_ADDR28 0x1C
255#define B2056_TX_RESERVED_ADDR29 0x1D
256#define B2056_TX_RESERVED_ADDR30 0x1E
257#define B2056_TX_RESERVED_ADDR31 0x1F
258#define B2056_TX_IQCAL_GAIN_BW 0x20
259#define B2056_TX_LOFT_FINE_I 0x21
260#define B2056_TX_LOFT_FINE_Q 0x22
261#define B2056_TX_LOFT_COARSE_I 0x23
262#define B2056_TX_LOFT_COARSE_Q 0x24
263#define B2056_TX_TX_COM_MASTER1 0x25
264#define B2056_TX_TX_COM_MASTER2 0x26
265#define B2056_TX_RXIQCAL_TXMUX 0x27
266#define B2056_TX_TX_SSI_MASTER 0x28
267#define B2056_TX_IQCAL_VCM_HG 0x29
268#define B2056_TX_IQCAL_IDAC 0x2A
269#define B2056_TX_TSSI_VCM 0x2B
270#define B2056_TX_TX_AMP_DET 0x2C
271#define B2056_TX_TX_SSI_MUX 0x2D
272#define B2056_TX_TSSIA 0x2E
273#define B2056_TX_TSSIG 0x2F
274#define B2056_TX_TSSI_MISC1 0x30
275#define B2056_TX_TSSI_MISC2 0x31
276#define B2056_TX_TSSI_MISC3 0x32
277#define B2056_TX_PA_SPARE1 0x33
278#define B2056_TX_PA_SPARE2 0x34
279#define B2056_TX_INTPAA_MASTER 0x35
280#define B2056_TX_INTPAA_GAIN 0x36
281#define B2056_TX_INTPAA_BOOST_TUNE 0x37
282#define B2056_TX_INTPAA_IAUX_STAT 0x38
283#define B2056_TX_INTPAA_IAUX_DYN 0x39
284#define B2056_TX_INTPAA_IMAIN_STAT 0x3A
285#define B2056_TX_INTPAA_IMAIN_DYN 0x3B
286#define B2056_TX_INTPAA_CASCBIAS 0x3C
287#define B2056_TX_INTPAA_PASLOPE 0x3D
288#define B2056_TX_INTPAA_PA_MISC 0x3E
289#define B2056_TX_INTPAG_MASTER 0x3F
290#define B2056_TX_INTPAG_GAIN 0x40
291#define B2056_TX_INTPAG_BOOST_TUNE 0x41
292#define B2056_TX_INTPAG_IAUX_STAT 0x42
293#define B2056_TX_INTPAG_IAUX_DYN 0x43
294#define B2056_TX_INTPAG_IMAIN_STAT 0x44
295#define B2056_TX_INTPAG_IMAIN_DYN 0x45
296#define B2056_TX_INTPAG_CASCBIAS 0x46
297#define B2056_TX_INTPAG_PASLOPE 0x47
298#define B2056_TX_INTPAG_PA_MISC 0x48
299#define B2056_TX_PADA_MASTER 0x49
300#define B2056_TX_PADA_IDAC 0x4A
301#define B2056_TX_PADA_CASCBIAS 0x4B
302#define B2056_TX_PADA_GAIN 0x4C
303#define B2056_TX_PADA_BOOST_TUNE 0x4D
304#define B2056_TX_PADA_SLOPE 0x4E
305#define B2056_TX_PADG_MASTER 0x4F
306#define B2056_TX_PADG_IDAC 0x50
307#define B2056_TX_PADG_CASCBIAS 0x51
308#define B2056_TX_PADG_GAIN 0x52
309#define B2056_TX_PADG_BOOST_TUNE 0x53
310#define B2056_TX_PADG_SLOPE 0x54
311#define B2056_TX_PGAA_MASTER 0x55
312#define B2056_TX_PGAA_IDAC 0x56
313#define B2056_TX_PGAA_GAIN 0x57
314#define B2056_TX_PGAA_BOOST_TUNE 0x58
315#define B2056_TX_PGAA_SLOPE 0x59
316#define B2056_TX_PGAA_MISC 0x5A
317#define B2056_TX_PGAG_MASTER 0x5B
318#define B2056_TX_PGAG_IDAC 0x5C
319#define B2056_TX_PGAG_GAIN 0x5D
320#define B2056_TX_PGAG_BOOST_TUNE 0x5E
321#define B2056_TX_PGAG_SLOPE 0x5F
322#define B2056_TX_PGAG_MISC 0x60
323#define B2056_TX_MIXA_MASTER 0x61
324#define B2056_TX_MIXA_BOOST_TUNE 0x62
325#define B2056_TX_MIXG 0x63
326#define B2056_TX_MIXG_BOOST_TUNE 0x64
327#define B2056_TX_BB_GM_MASTER 0x65
328#define B2056_TX_GMBB_GM 0x66
329#define B2056_TX_GMBB_IDAC 0x67
330#define B2056_TX_TXLPF_MASTER 0x68
331#define B2056_TX_TXLPF_RCCAL 0x69
332#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A
333#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B
334#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C
335#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D
336#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E
337#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F
338#define B2056_TX_TXLPF_RCCAL_OFF6 0x70
339#define B2056_TX_TXLPF_BW 0x71
340#define B2056_TX_TXLPF_GAIN 0x72
341#define B2056_TX_TXLPF_IDAC 0x73
342#define B2056_TX_TXLPF_IDAC_0 0x74
343#define B2056_TX_TXLPF_IDAC_1 0x75
344#define B2056_TX_TXLPF_IDAC_2 0x76
345#define B2056_TX_TXLPF_IDAC_3 0x77
346#define B2056_TX_TXLPF_IDAC_4 0x78
347#define B2056_TX_TXLPF_IDAC_5 0x79
348#define B2056_TX_TXLPF_IDAC_6 0x7A
349#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B
350#define B2056_TX_TXLPF_MISC 0x7C
351#define B2056_TX_TXSPARE1 0x7D
352#define B2056_TX_TXSPARE2 0x7E
353#define B2056_TX_TXSPARE3 0x7F
354#define B2056_TX_TXSPARE4 0x80
355#define B2056_TX_TXSPARE5 0x81
356#define B2056_TX_TXSPARE6 0x82
357#define B2056_TX_TXSPARE7 0x83
358#define B2056_TX_TXSPARE8 0x84
359#define B2056_TX_TXSPARE9 0x85
360#define B2056_TX_TXSPARE10 0x86
361#define B2056_TX_TXSPARE11 0x87
362#define B2056_TX_TXSPARE12 0x88
363#define B2056_TX_TXSPARE13 0x89
364#define B2056_TX_TXSPARE14 0x8A
365#define B2056_TX_TXSPARE15 0x8B
366#define B2056_TX_TXSPARE16 0x8C
367#define B2056_TX_STATUS_INTPA_GAIN 0x8D
368#define B2056_TX_STATUS_PAD_GAIN 0x8E
369#define B2056_TX_STATUS_PGA_GAIN 0x8F
370#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90
371#define B2056_TX_STATUS_TXLPF_BW 0x91
372#define B2056_TX_STATUS_TXLPF_RC 0x92
373#define B2056_TX_GMBB_IDAC0 0x93
374#define B2056_TX_GMBB_IDAC1 0x94
375#define B2056_TX_GMBB_IDAC2 0x95
376#define B2056_TX_GMBB_IDAC3 0x96
377#define B2056_TX_GMBB_IDAC4 0x97
378#define B2056_TX_GMBB_IDAC5 0x98
379#define B2056_TX_GMBB_IDAC6 0x99
380#define B2056_TX_GMBB_IDAC7 0x9A
381
382#define B2056_RX_RESERVED_ADDR0 0x00
383#define B2056_RX_IDCODE 0x01
384#define B2056_RX_RESERVED_ADDR2 0x02
385#define B2056_RX_RESERVED_ADDR3 0x03
386#define B2056_RX_RESERVED_ADDR4 0x04
387#define B2056_RX_RESERVED_ADDR5 0x05
388#define B2056_RX_RESERVED_ADDR6 0x06
389#define B2056_RX_RESERVED_ADDR7 0x07
390#define B2056_RX_COM_CTRL 0x08
391#define B2056_RX_COM_PU 0x09
392#define B2056_RX_COM_OVR 0x0A
393#define B2056_RX_COM_RESET 0x0B
394#define B2056_RX_COM_RCAL 0x0C
395#define B2056_RX_COM_RC_RXLPF 0x0D
396#define B2056_RX_COM_RC_TXLPF 0x0E
397#define B2056_RX_COM_RC_RXHPF 0x0F
398#define B2056_RX_RESERVED_ADDR16 0x10
399#define B2056_RX_RESERVED_ADDR17 0x11
400#define B2056_RX_RESERVED_ADDR18 0x12
401#define B2056_RX_RESERVED_ADDR19 0x13
402#define B2056_RX_RESERVED_ADDR20 0x14
403#define B2056_RX_RESERVED_ADDR21 0x15
404#define B2056_RX_RESERVED_ADDR22 0x16
405#define B2056_RX_RESERVED_ADDR23 0x17
406#define B2056_RX_RESERVED_ADDR24 0x18
407#define B2056_RX_RESERVED_ADDR25 0x19
408#define B2056_RX_RESERVED_ADDR26 0x1A
409#define B2056_RX_RESERVED_ADDR27 0x1B
410#define B2056_RX_RESERVED_ADDR28 0x1C
411#define B2056_RX_RESERVED_ADDR29 0x1D
412#define B2056_RX_RESERVED_ADDR30 0x1E
413#define B2056_RX_RESERVED_ADDR31 0x1F
414#define B2056_RX_RXIQCAL_RXMUX 0x20
415#define B2056_RX_RSSI_PU 0x21
416#define B2056_RX_RSSI_SEL 0x22
417#define B2056_RX_RSSI_GAIN 0x23
418#define B2056_RX_RSSI_NB_IDAC 0x24
419#define B2056_RX_RSSI_WB2I_IDAC_1 0x25
420#define B2056_RX_RSSI_WB2I_IDAC_2 0x26
421#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27
422#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28
423#define B2056_RX_RSSI_POLE 0x29
424#define B2056_RX_RSSI_WB1_IDAC 0x2A
425#define B2056_RX_RSSI_MISC 0x2B
426#define B2056_RX_LNAA_MASTER 0x2C
427#define B2056_RX_LNAA_TUNE 0x2D
428#define B2056_RX_LNAA_GAIN 0x2E
429#define B2056_RX_LNA_A_SLOPE 0x2F
430#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30
431#define B2056_RX_LNAA2_IDAC 0x31
432#define B2056_RX_LNA1A_MISC 0x32
433#define B2056_RX_LNAG_MASTER 0x33
434#define B2056_RX_LNAG_TUNE 0x34
435#define B2056_RX_LNAG_GAIN 0x35
436#define B2056_RX_LNA_G_SLOPE 0x36
437#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37
438#define B2056_RX_LNAG2_IDAC 0x38
439#define B2056_RX_LNA1G_MISC 0x39
440#define B2056_RX_MIXA_MASTER 0x3A
441#define B2056_RX_MIXA_VCM 0x3B
442#define B2056_RX_MIXA_CTRLPTAT 0x3C
443#define B2056_RX_MIXA_LOB_BIAS 0x3D
444#define B2056_RX_MIXA_CORE_IDAC 0x3E
445#define B2056_RX_MIXA_CMFB_IDAC 0x3F
446#define B2056_RX_MIXA_BIAS_AUX 0x40
447#define B2056_RX_MIXA_BIAS_MAIN 0x41
448#define B2056_RX_MIXA_BIAS_MISC 0x42
449#define B2056_RX_MIXA_MAST_BIAS 0x43
450#define B2056_RX_MIXG_MASTER 0x44
451#define B2056_RX_MIXG_VCM 0x45
452#define B2056_RX_MIXG_CTRLPTAT 0x46
453#define B2056_RX_MIXG_LOB_BIAS 0x47
454#define B2056_RX_MIXG_CORE_IDAC 0x48
455#define B2056_RX_MIXG_CMFB_IDAC 0x49
456#define B2056_RX_MIXG_BIAS_AUX 0x4A
457#define B2056_RX_MIXG_BIAS_MAIN 0x4B
458#define B2056_RX_MIXG_BIAS_MISC 0x4C
459#define B2056_RX_MIXG_MAST_BIAS 0x4D
460#define B2056_RX_TIA_MASTER 0x4E
461#define B2056_RX_TIA_IOPAMP 0x4F
462#define B2056_RX_TIA_QOPAMP 0x50
463#define B2056_RX_TIA_IMISC 0x51
464#define B2056_RX_TIA_QMISC 0x52
465#define B2056_RX_TIA_GAIN 0x53
466#define B2056_RX_TIA_SPARE1 0x54
467#define B2056_RX_TIA_SPARE2 0x55
468#define B2056_RX_BB_LPF_MASTER 0x56
469#define B2056_RX_AACI_MASTER 0x57
470#define B2056_RX_RXLPF_IDAC 0x58
471#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
472#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A
473#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B
474#define B2056_RX_RXLPF_OUTVCM 0x5C
475#define B2056_RX_RXLPF_INVCM_BODY 0x5D
476#define B2056_RX_RXLPF_CC_OP 0x5E
477#define B2056_RX_RXLPF_GAIN 0x5F
478#define B2056_RX_RXLPF_Q_BW 0x60
479#define B2056_RX_RXLPF_HP_CORNER_BW 0x61
480#define B2056_RX_RXLPF_RCCAL_HPC 0x62
481#define B2056_RX_RXHPF_OFF0 0x63
482#define B2056_RX_RXHPF_OFF1 0x64
483#define B2056_RX_RXHPF_OFF2 0x65
484#define B2056_RX_RXHPF_OFF3 0x66
485#define B2056_RX_RXHPF_OFF4 0x67
486#define B2056_RX_RXHPF_OFF5 0x68
487#define B2056_RX_RXHPF_OFF6 0x69
488#define B2056_RX_RXHPF_OFF7 0x6A
489#define B2056_RX_RXLPF_RCCAL_LPC 0x6B
490#define B2056_RX_RXLPF_OFF_0 0x6C
491#define B2056_RX_RXLPF_OFF_1 0x6D
492#define B2056_RX_RXLPF_OFF_2 0x6E
493#define B2056_RX_RXLPF_OFF_3 0x6F
494#define B2056_RX_RXLPF_OFF_4 0x70
495#define B2056_RX_UNUSED 0x71
496#define B2056_RX_VGA_MASTER 0x72
497#define B2056_RX_VGA_BIAS 0x73
498#define B2056_RX_VGA_BIAS_DCCANCEL 0x74
499#define B2056_RX_VGA_GAIN 0x75
500#define B2056_RX_VGA_HP_CORNER_BW 0x76
501#define B2056_RX_VGABUF_BIAS 0x77
502#define B2056_RX_VGABUF_GAIN_BW 0x78
503#define B2056_RX_TXFBMIX_A 0x79
504#define B2056_RX_TXFBMIX_G 0x7A
505#define B2056_RX_RXSPARE1 0x7B
506#define B2056_RX_RXSPARE2 0x7C
507#define B2056_RX_RXSPARE3 0x7D
508#define B2056_RX_RXSPARE4 0x7E
509#define B2056_RX_RXSPARE5 0x7F
510#define B2056_RX_RXSPARE6 0x80
511#define B2056_RX_RXSPARE7 0x81
512#define B2056_RX_RXSPARE8 0x82
513#define B2056_RX_RXSPARE9 0x83
514#define B2056_RX_RXSPARE10 0x84
515#define B2056_RX_RXSPARE11 0x85
516#define B2056_RX_RXSPARE12 0x86
517#define B2056_RX_RXSPARE13 0x87
518#define B2056_RX_RXSPARE14 0x88
519#define B2056_RX_RXSPARE15 0x89
520#define B2056_RX_RXSPARE16 0x8A
521#define B2056_RX_STATUS_LNAA_GAIN 0x8B
522#define B2056_RX_STATUS_LNAG_GAIN 0x8C
523#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D
524#define B2056_RX_STATUS_RXLPF_GAIN 0x8E
525#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F
526#define B2056_RX_STATUS_RXLPF_Q 0x90
527#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91
528#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92
529#define B2056_RX_STATUS_RXLPF_RC 0x93
530#define B2056_RX_STATUS_HPC_RC 0x94
531
532#define B2056_LNA1_A_PU 0x01
533#define B2056_LNA2_A_PU 0x02
534#define B2056_LNA1_G_PU 0x01
535#define B2056_LNA2_G_PU 0x02
536#define B2056_MIXA_PU_I 0x01
537#define B2056_MIXA_PU_Q 0x02
538#define B2056_MIXA_PU_GM 0x10
539#define B2056_MIXG_PU_I 0x01
540#define B2056_MIXG_PU_Q 0x02
541#define B2056_MIXG_PU_GM 0x10
542#define B2056_TIA_PU 0x01
543#define B2056_BB_LPF_PU 0x20
544#define B2056_W1_PU 0x02
545#define B2056_W2_PU 0x04
546#define B2056_NB_PU 0x08
547#define B2056_RSSI_W1_SEL 0x02
548#define B2056_RSSI_W2_SEL 0x04
549#define B2056_RSSI_NB_SEL 0x08
550#define B2056_VCM_MASK 0x1C
551#define B2056_RSSI_VCM_SHIFT 0x02
552
553#define B2056_SYN (0x0 << 12)
554#define B2056_TX0 (0x2 << 12)
555#define B2056_TX1 (0x3 << 12)
556#define B2056_RX0 (0x6 << 12)
557#define B2056_RX1 (0x7 << 12)
558#define B2056_ALLTX (0xE << 12)
559#define B2056_ALLRX (0xF << 12)
560
561#define B2056_SYN_RESERVED_ADDR0 0x00
562#define B2056_SYN_IDCODE 0x01
563#define B2056_SYN_RESERVED_ADDR2 0x02
564#define B2056_SYN_RESERVED_ADDR3 0x03
565#define B2056_SYN_RESERVED_ADDR4 0x04
566#define B2056_SYN_RESERVED_ADDR5 0x05
567#define B2056_SYN_RESERVED_ADDR6 0x06
568#define B2056_SYN_RESERVED_ADDR7 0x07
569#define B2056_SYN_COM_CTRL 0x08
570#define B2056_SYN_COM_PU 0x09
571#define B2056_SYN_COM_OVR 0x0A
572#define B2056_SYN_COM_RESET 0x0B
573#define B2056_SYN_COM_RCAL 0x0C
574#define B2056_SYN_COM_RC_RXLPF 0x0D
575#define B2056_SYN_COM_RC_TXLPF 0x0E
576#define B2056_SYN_COM_RC_RXHPF 0x0F
577#define B2056_SYN_RESERVED_ADDR16 0x10
578#define B2056_SYN_RESERVED_ADDR17 0x11
579#define B2056_SYN_RESERVED_ADDR18 0x12
580#define B2056_SYN_RESERVED_ADDR19 0x13
581#define B2056_SYN_RESERVED_ADDR20 0x14
582#define B2056_SYN_RESERVED_ADDR21 0x15
583#define B2056_SYN_RESERVED_ADDR22 0x16
584#define B2056_SYN_RESERVED_ADDR23 0x17
585#define B2056_SYN_RESERVED_ADDR24 0x18
586#define B2056_SYN_RESERVED_ADDR25 0x19
587#define B2056_SYN_RESERVED_ADDR26 0x1A
588#define B2056_SYN_RESERVED_ADDR27 0x1B
589#define B2056_SYN_RESERVED_ADDR28 0x1C
590#define B2056_SYN_RESERVED_ADDR29 0x1D
591#define B2056_SYN_RESERVED_ADDR30 0x1E
592#define B2056_SYN_RESERVED_ADDR31 0x1F
593#define B2056_SYN_GPIO_MASTER1 0x20
594#define B2056_SYN_GPIO_MASTER2 0x21
595#define B2056_SYN_TOPBIAS_MASTER 0x22
596#define B2056_SYN_TOPBIAS_RCAL 0x23
597#define B2056_SYN_AFEREG 0x24
598#define B2056_SYN_TEMPPROCSENSE 0x25
599#define B2056_SYN_TEMPPROCSENSEIDAC 0x26
600#define B2056_SYN_TEMPPROCSENSERCAL 0x27
601#define B2056_SYN_LPO 0x28
602#define B2056_SYN_VDDCAL_MASTER 0x29
603#define B2056_SYN_VDDCAL_IDAC 0x2A
604#define B2056_SYN_VDDCAL_STATUS 0x2B
605#define B2056_SYN_RCAL_MASTER 0x2C
606#define B2056_SYN_RCAL_CODE_OUT 0x2D
607#define B2056_SYN_RCCAL_CTRL0 0x2E
608#define B2056_SYN_RCCAL_CTRL1 0x2F
609#define B2056_SYN_RCCAL_CTRL2 0x30
610#define B2056_SYN_RCCAL_CTRL3 0x31
611#define B2056_SYN_RCCAL_CTRL4 0x32
612#define B2056_SYN_RCCAL_CTRL5 0x33
613#define B2056_SYN_RCCAL_CTRL6 0x34
614#define B2056_SYN_RCCAL_CTRL7 0x35
615#define B2056_SYN_RCCAL_CTRL8 0x36
616#define B2056_SYN_RCCAL_CTRL9 0x37
617#define B2056_SYN_RCCAL_CTRL10 0x38
618#define B2056_SYN_RCCAL_CTRL11 0x39
619#define B2056_SYN_ZCAL_SPARE1 0x3A
620#define B2056_SYN_ZCAL_SPARE2 0x3B
621#define B2056_SYN_PLL_MAST1 0x3C
622#define B2056_SYN_PLL_MAST2 0x3D
623#define B2056_SYN_PLL_MAST3 0x3E
624#define B2056_SYN_PLL_BIAS_RESET 0x3F
625#define B2056_SYN_PLL_XTAL0 0x40
626#define B2056_SYN_PLL_XTAL1 0x41
627#define B2056_SYN_PLL_XTAL3 0x42
628#define B2056_SYN_PLL_XTAL4 0x43
629#define B2056_SYN_PLL_XTAL5 0x44
630#define B2056_SYN_PLL_XTAL6 0x45
631#define B2056_SYN_PLL_REFDIV 0x46
632#define B2056_SYN_PLL_PFD 0x47
633#define B2056_SYN_PLL_CP1 0x48
634#define B2056_SYN_PLL_CP2 0x49
635#define B2056_SYN_PLL_CP3 0x4A
636#define B2056_SYN_PLL_LOOPFILTER1 0x4B
637#define B2056_SYN_PLL_LOOPFILTER2 0x4C
638#define B2056_SYN_PLL_LOOPFILTER3 0x4D
639#define B2056_SYN_PLL_LOOPFILTER4 0x4E
640#define B2056_SYN_PLL_LOOPFILTER5 0x4F
641#define B2056_SYN_PLL_MMD1 0x50
642#define B2056_SYN_PLL_MMD2 0x51
643#define B2056_SYN_PLL_VCO1 0x52
644#define B2056_SYN_PLL_VCO2 0x53
645#define B2056_SYN_PLL_MONITOR1 0x54
646#define B2056_SYN_PLL_MONITOR2 0x55
647#define B2056_SYN_PLL_VCOCAL1 0x56
648#define B2056_SYN_PLL_VCOCAL2 0x57
649#define B2056_SYN_PLL_VCOCAL4 0x58
650#define B2056_SYN_PLL_VCOCAL5 0x59
651#define B2056_SYN_PLL_VCOCAL6 0x5A
652#define B2056_SYN_PLL_VCOCAL7 0x5B
653#define B2056_SYN_PLL_VCOCAL8 0x5C
654#define B2056_SYN_PLL_VCOCAL9 0x5D
655#define B2056_SYN_PLL_VCOCAL10 0x5E
656#define B2056_SYN_PLL_VCOCAL11 0x5F
657#define B2056_SYN_PLL_VCOCAL12 0x60
658#define B2056_SYN_PLL_VCOCAL13 0x61
659#define B2056_SYN_PLL_VREG 0x62
660#define B2056_SYN_PLL_STATUS1 0x63
661#define B2056_SYN_PLL_STATUS2 0x64
662#define B2056_SYN_PLL_STATUS3 0x65
663#define B2056_SYN_LOGEN_PU0 0x66
664#define B2056_SYN_LOGEN_PU1 0x67
665#define B2056_SYN_LOGEN_PU2 0x68
666#define B2056_SYN_LOGEN_PU3 0x69
667#define B2056_SYN_LOGEN_PU5 0x6A
668#define B2056_SYN_LOGEN_PU6 0x6B
669#define B2056_SYN_LOGEN_PU7 0x6C
670#define B2056_SYN_LOGEN_PU8 0x6D
671#define B2056_SYN_LOGEN_BIAS_RESET 0x6E
672#define B2056_SYN_LOGEN_RCCR1 0x6F
673#define B2056_SYN_LOGEN_VCOBUF1 0x70
674#define B2056_SYN_LOGEN_MIXER1 0x71
675#define B2056_SYN_LOGEN_MIXER2 0x72
676#define B2056_SYN_LOGEN_BUF1 0x73
677#define B2056_SYN_LOGENBUF2 0x74
678#define B2056_SYN_LOGEN_BUF3 0x75
679#define B2056_SYN_LOGEN_BUF4 0x76
680#define B2056_SYN_LOGEN_DIV1 0x77
681#define B2056_SYN_LOGEN_DIV2 0x78
682#define B2056_SYN_LOGEN_DIV3 0x79
683#define B2056_SYN_LOGEN_ACL1 0x7A
684#define B2056_SYN_LOGEN_ACL2 0x7B
685#define B2056_SYN_LOGEN_ACL3 0x7C
686#define B2056_SYN_LOGEN_ACL4 0x7D
687#define B2056_SYN_LOGEN_ACL5 0x7E
688#define B2056_SYN_LOGEN_ACL6 0x7F
689#define B2056_SYN_LOGEN_ACLOUT 0x80
690#define B2056_SYN_LOGEN_ACLCAL1 0x81
691#define B2056_SYN_LOGEN_ACLCAL2 0x82
692#define B2056_SYN_LOGEN_ACLCAL3 0x83
693#define B2056_SYN_CALEN 0x84
694#define B2056_SYN_LOGEN_PEAKDET1 0x85
695#define B2056_SYN_LOGEN_CORE_ACL_OVR 0x86
696#define B2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
697#define B2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
698#define B2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
699#define B2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8A
700#define B2056_SYN_LOGEN_VCOBUF2 0x8B
701#define B2056_SYN_LOGEN_MIXER3 0x8C
702#define B2056_SYN_LOGEN_BUF5 0x8D
703#define B2056_SYN_LOGEN_BUF6 0x8E
704#define B2056_SYN_LOGEN_CBUFRX1 0x8F
705#define B2056_SYN_LOGEN_CBUFRX2 0x90
706#define B2056_SYN_LOGEN_CBUFRX3 0x91
707#define B2056_SYN_LOGEN_CBUFRX4 0x92
708#define B2056_SYN_LOGEN_CBUFTX1 0x93
709#define B2056_SYN_LOGEN_CBUFTX2 0x94
710#define B2056_SYN_LOGEN_CBUFTX3 0x95
711#define B2056_SYN_LOGEN_CBUFTX4 0x96
712#define B2056_SYN_LOGEN_CMOSRX1 0x97
713#define B2056_SYN_LOGEN_CMOSRX2 0x98
714#define B2056_SYN_LOGEN_CMOSRX3 0x99
715#define B2056_SYN_LOGEN_CMOSRX4 0x9A
716#define B2056_SYN_LOGEN_CMOSTX1 0x9B
717#define B2056_SYN_LOGEN_CMOSTX2 0x9C
718#define B2056_SYN_LOGEN_CMOSTX3 0x9D
719#define B2056_SYN_LOGEN_CMOSTX4 0x9E
720#define B2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9F
721#define B2056_SYN_LOGEN_MIXER3_OVRVAL 0xA0
722#define B2056_SYN_LOGEN_BUF5_OVRVAL 0xA1
723#define B2056_SYN_LOGEN_BUF6_OVRVAL 0xA2
724#define B2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xA3
725#define B2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xA4
726#define B2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xA5
727#define B2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xA6
728#define B2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xA7
729#define B2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xA8
730#define B2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xA9
731#define B2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xAA
732#define B2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xAB
733#define B2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xAC
734#define B2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xAD
735#define B2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xAE
736#define B2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xAF
737#define B2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xB0
738#define B2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xB1
739#define B2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xB2
740#define B2056_SYN_LOGEN_ACL_WAITCNT 0xB3
741#define B2056_SYN_LOGEN_CORE_CALVALID 0xB4
742#define B2056_SYN_LOGEN_RX_CMOS_CALVALID 0xB5
743#define B2056_SYN_LOGEN_TX_CMOS_VALID 0xB6
744
745#define B2056_TX_RESERVED_ADDR0 0x00
746#define B2056_TX_IDCODE 0x01
747#define B2056_TX_RESERVED_ADDR2 0x02
748#define B2056_TX_RESERVED_ADDR3 0x03
749#define B2056_TX_RESERVED_ADDR4 0x04
750#define B2056_TX_RESERVED_ADDR5 0x05
751#define B2056_TX_RESERVED_ADDR6 0x06
752#define B2056_TX_RESERVED_ADDR7 0x07
753#define B2056_TX_COM_CTRL 0x08
754#define B2056_TX_COM_PU 0x09
755#define B2056_TX_COM_OVR 0x0A
756#define B2056_TX_COM_RESET 0x0B
757#define B2056_TX_COM_RCAL 0x0C
758#define B2056_TX_COM_RC_RXLPF 0x0D
759#define B2056_TX_COM_RC_TXLPF 0x0E
760#define B2056_TX_COM_RC_RXHPF 0x0F
761#define B2056_TX_RESERVED_ADDR16 0x10
762#define B2056_TX_RESERVED_ADDR17 0x11
763#define B2056_TX_RESERVED_ADDR18 0x12
764#define B2056_TX_RESERVED_ADDR19 0x13
765#define B2056_TX_RESERVED_ADDR20 0x14
766#define B2056_TX_RESERVED_ADDR21 0x15
767#define B2056_TX_RESERVED_ADDR22 0x16
768#define B2056_TX_RESERVED_ADDR23 0x17
769#define B2056_TX_RESERVED_ADDR24 0x18
770#define B2056_TX_RESERVED_ADDR25 0x19
771#define B2056_TX_RESERVED_ADDR26 0x1A
772#define B2056_TX_RESERVED_ADDR27 0x1B
773#define B2056_TX_RESERVED_ADDR28 0x1C
774#define B2056_TX_RESERVED_ADDR29 0x1D
775#define B2056_TX_RESERVED_ADDR30 0x1E
776#define B2056_TX_RESERVED_ADDR31 0x1F
777#define B2056_TX_IQCAL_GAIN_BW 0x20
778#define B2056_TX_LOFT_FINE_I 0x21
779#define B2056_TX_LOFT_FINE_Q 0x22
780#define B2056_TX_LOFT_COARSE_I 0x23
781#define B2056_TX_LOFT_COARSE_Q 0x24
782#define B2056_TX_TX_COM_MASTER1 0x25
783#define B2056_TX_TX_COM_MASTER2 0x26
784#define B2056_TX_RXIQCAL_TXMUX 0x27
785#define B2056_TX_TX_SSI_MASTER 0x28
786#define B2056_TX_IQCAL_VCM_HG 0x29
787#define B2056_TX_IQCAL_IDAC 0x2A
788#define B2056_TX_TSSI_VCM 0x2B
789#define B2056_TX_TX_AMP_DET 0x2C
790#define B2056_TX_TX_SSI_MUX 0x2D
791#define B2056_TX_TSSIA 0x2E
792#define B2056_TX_TSSIG 0x2F
793#define B2056_TX_TSSI_MISC1 0x30
794#define B2056_TX_TSSI_MISC2 0x31
795#define B2056_TX_TSSI_MISC3 0x32
796#define B2056_TX_PA_SPARE1 0x33
797#define B2056_TX_PA_SPARE2 0x34
798#define B2056_TX_INTPAA_MASTER 0x35
799#define B2056_TX_INTPAA_GAIN 0x36
800#define B2056_TX_INTPAA_BOOST_TUNE 0x37
801#define B2056_TX_INTPAA_IAUX_STAT 0x38
802#define B2056_TX_INTPAA_IAUX_DYN 0x39
803#define B2056_TX_INTPAA_IMAIN_STAT 0x3A
804#define B2056_TX_INTPAA_IMAIN_DYN 0x3B
805#define B2056_TX_INTPAA_CASCBIAS 0x3C
806#define B2056_TX_INTPAA_PASLOPE 0x3D
807#define B2056_TX_INTPAA_PA_MISC 0x3E
808#define B2056_TX_INTPAG_MASTER 0x3F
809#define B2056_TX_INTPAG_GAIN 0x40
810#define B2056_TX_INTPAG_BOOST_TUNE 0x41
811#define B2056_TX_INTPAG_IAUX_STAT 0x42
812#define B2056_TX_INTPAG_IAUX_DYN 0x43
813#define B2056_TX_INTPAG_IMAIN_STAT 0x44
814#define B2056_TX_INTPAG_IMAIN_DYN 0x45
815#define B2056_TX_INTPAG_CASCBIAS 0x46
816#define B2056_TX_INTPAG_PASLOPE 0x47
817#define B2056_TX_INTPAG_PA_MISC 0x48
818#define B2056_TX_PADA_MASTER 0x49
819#define B2056_TX_PADA_IDAC 0x4A
820#define B2056_TX_PADA_CASCBIAS 0x4B
821#define B2056_TX_PADA_GAIN 0x4C
822#define B2056_TX_PADA_BOOST_TUNE 0x4D
823#define B2056_TX_PADA_SLOPE 0x4E
824#define B2056_TX_PADG_MASTER 0x4F
825#define B2056_TX_PADG_IDAC 0x50
826#define B2056_TX_PADG_CASCBIAS 0x51
827#define B2056_TX_PADG_GAIN 0x52
828#define B2056_TX_PADG_BOOST_TUNE 0x53
829#define B2056_TX_PADG_SLOPE 0x54
830#define B2056_TX_PGAA_MASTER 0x55
831#define B2056_TX_PGAA_IDAC 0x56
832#define B2056_TX_PGAA_GAIN 0x57
833#define B2056_TX_PGAA_BOOST_TUNE 0x58
834#define B2056_TX_PGAA_SLOPE 0x59
835#define B2056_TX_PGAA_MISC 0x5A
836#define B2056_TX_PGAG_MASTER 0x5B
837#define B2056_TX_PGAG_IDAC 0x5C
838#define B2056_TX_PGAG_GAIN 0x5D
839#define B2056_TX_PGAG_BOOST_TUNE 0x5E
840#define B2056_TX_PGAG_SLOPE 0x5F
841#define B2056_TX_PGAG_MISC 0x60
842#define B2056_TX_MIXA_MASTER 0x61
843#define B2056_TX_MIXA_BOOST_TUNE 0x62
844#define B2056_TX_MIXG 0x63
845#define B2056_TX_MIXG_BOOST_TUNE 0x64
846#define B2056_TX_BB_GM_MASTER 0x65
847#define B2056_TX_GMBB_GM 0x66
848#define B2056_TX_GMBB_IDAC 0x67
849#define B2056_TX_TXLPF_MASTER 0x68
850#define B2056_TX_TXLPF_RCCAL 0x69
851#define B2056_TX_TXLPF_RCCAL_OFF0 0x6A
852#define B2056_TX_TXLPF_RCCAL_OFF1 0x6B
853#define B2056_TX_TXLPF_RCCAL_OFF2 0x6C
854#define B2056_TX_TXLPF_RCCAL_OFF3 0x6D
855#define B2056_TX_TXLPF_RCCAL_OFF4 0x6E
856#define B2056_TX_TXLPF_RCCAL_OFF5 0x6F
857#define B2056_TX_TXLPF_RCCAL_OFF6 0x70
858#define B2056_TX_TXLPF_BW 0x71
859#define B2056_TX_TXLPF_GAIN 0x72
860#define B2056_TX_TXLPF_IDAC 0x73
861#define B2056_TX_TXLPF_IDAC_0 0x74
862#define B2056_TX_TXLPF_IDAC_1 0x75
863#define B2056_TX_TXLPF_IDAC_2 0x76
864#define B2056_TX_TXLPF_IDAC_3 0x77
865#define B2056_TX_TXLPF_IDAC_4 0x78
866#define B2056_TX_TXLPF_IDAC_5 0x79
867#define B2056_TX_TXLPF_IDAC_6 0x7A
868#define B2056_TX_TXLPF_OPAMP_IDAC 0x7B
869#define B2056_TX_TXLPF_MISC 0x7C
870#define B2056_TX_TXSPARE1 0x7D
871#define B2056_TX_TXSPARE2 0x7E
872#define B2056_TX_TXSPARE3 0x7F
873#define B2056_TX_TXSPARE4 0x80
874#define B2056_TX_TXSPARE5 0x81
875#define B2056_TX_TXSPARE6 0x82
876#define B2056_TX_TXSPARE7 0x83
877#define B2056_TX_TXSPARE8 0x84
878#define B2056_TX_TXSPARE9 0x85
879#define B2056_TX_TXSPARE10 0x86
880#define B2056_TX_TXSPARE11 0x87
881#define B2056_TX_TXSPARE12 0x88
882#define B2056_TX_TXSPARE13 0x89
883#define B2056_TX_TXSPARE14 0x8A
884#define B2056_TX_TXSPARE15 0x8B
885#define B2056_TX_TXSPARE16 0x8C
886#define B2056_TX_STATUS_INTPA_GAIN 0x8D
887#define B2056_TX_STATUS_PAD_GAIN 0x8E
888#define B2056_TX_STATUS_PGA_GAIN 0x8F
889#define B2056_TX_STATUS_GM_TXLPF_GAIN 0x90
890#define B2056_TX_STATUS_TXLPF_BW 0x91
891#define B2056_TX_STATUS_TXLPF_RC 0x92
892#define B2056_TX_GMBB_IDAC0 0x93
893#define B2056_TX_GMBB_IDAC1 0x94
894#define B2056_TX_GMBB_IDAC2 0x95
895#define B2056_TX_GMBB_IDAC3 0x96
896#define B2056_TX_GMBB_IDAC4 0x97
897#define B2056_TX_GMBB_IDAC5 0x98
898#define B2056_TX_GMBB_IDAC6 0x99
899#define B2056_TX_GMBB_IDAC7 0x9A
900
901#define B2056_RX_RESERVED_ADDR0 0x00
902#define B2056_RX_IDCODE 0x01
903#define B2056_RX_RESERVED_ADDR2 0x02
904#define B2056_RX_RESERVED_ADDR3 0x03
905#define B2056_RX_RESERVED_ADDR4 0x04
906#define B2056_RX_RESERVED_ADDR5 0x05
907#define B2056_RX_RESERVED_ADDR6 0x06
908#define B2056_RX_RESERVED_ADDR7 0x07
909#define B2056_RX_COM_CTRL 0x08
910#define B2056_RX_COM_PU 0x09
911#define B2056_RX_COM_OVR 0x0A
912#define B2056_RX_COM_RESET 0x0B
913#define B2056_RX_COM_RCAL 0x0C
914#define B2056_RX_COM_RC_RXLPF 0x0D
915#define B2056_RX_COM_RC_TXLPF 0x0E
916#define B2056_RX_COM_RC_RXHPF 0x0F
917#define B2056_RX_RESERVED_ADDR16 0x10
918#define B2056_RX_RESERVED_ADDR17 0x11
919#define B2056_RX_RESERVED_ADDR18 0x12
920#define B2056_RX_RESERVED_ADDR19 0x13
921#define B2056_RX_RESERVED_ADDR20 0x14
922#define B2056_RX_RESERVED_ADDR21 0x15
923#define B2056_RX_RESERVED_ADDR22 0x16
924#define B2056_RX_RESERVED_ADDR23 0x17
925#define B2056_RX_RESERVED_ADDR24 0x18
926#define B2056_RX_RESERVED_ADDR25 0x19
927#define B2056_RX_RESERVED_ADDR26 0x1A
928#define B2056_RX_RESERVED_ADDR27 0x1B
929#define B2056_RX_RESERVED_ADDR28 0x1C
930#define B2056_RX_RESERVED_ADDR29 0x1D
931#define B2056_RX_RESERVED_ADDR30 0x1E
932#define B2056_RX_RESERVED_ADDR31 0x1F
933#define B2056_RX_RXIQCAL_RXMUX 0x20
934#define B2056_RX_RSSI_PU 0x21
935#define B2056_RX_RSSI_SEL 0x22
936#define B2056_RX_RSSI_GAIN 0x23
937#define B2056_RX_RSSI_NB_IDAC 0x24
938#define B2056_RX_RSSI_WB2I_IDAC_1 0x25
939#define B2056_RX_RSSI_WB2I_IDAC_2 0x26
940#define B2056_RX_RSSI_WB2Q_IDAC_1 0x27
941#define B2056_RX_RSSI_WB2Q_IDAC_2 0x28
942#define B2056_RX_RSSI_POLE 0x29
943#define B2056_RX_RSSI_WB1_IDAC 0x2A
944#define B2056_RX_RSSI_MISC 0x2B
945#define B2056_RX_LNAA_MASTER 0x2C
946#define B2056_RX_LNAA_TUNE 0x2D
947#define B2056_RX_LNAA_GAIN 0x2E
948#define B2056_RX_LNA_A_SLOPE 0x2F
949#define B2056_RX_BIASPOLE_LNAA1_IDAC 0x30
950#define B2056_RX_LNAA2_IDAC 0x31
951#define B2056_RX_LNA1A_MISC 0x32
952#define B2056_RX_LNAG_MASTER 0x33
953#define B2056_RX_LNAG_TUNE 0x34
954#define B2056_RX_LNAG_GAIN 0x35
955#define B2056_RX_LNA_G_SLOPE 0x36
956#define B2056_RX_BIASPOLE_LNAG1_IDAC 0x37
957#define B2056_RX_LNAG2_IDAC 0x38
958#define B2056_RX_LNA1G_MISC 0x39
959#define B2056_RX_MIXA_MASTER 0x3A
960#define B2056_RX_MIXA_VCM 0x3B
961#define B2056_RX_MIXA_CTRLPTAT 0x3C
962#define B2056_RX_MIXA_LOB_BIAS 0x3D
963#define B2056_RX_MIXA_CORE_IDAC 0x3E
964#define B2056_RX_MIXA_CMFB_IDAC 0x3F
965#define B2056_RX_MIXA_BIAS_AUX 0x40
966#define B2056_RX_MIXA_BIAS_MAIN 0x41
967#define B2056_RX_MIXA_BIAS_MISC 0x42
968#define B2056_RX_MIXA_MAST_BIAS 0x43
969#define B2056_RX_MIXG_MASTER 0x44
970#define B2056_RX_MIXG_VCM 0x45
971#define B2056_RX_MIXG_CTRLPTAT 0x46
972#define B2056_RX_MIXG_LOB_BIAS 0x47
973#define B2056_RX_MIXG_CORE_IDAC 0x48
974#define B2056_RX_MIXG_CMFB_IDAC 0x49
975#define B2056_RX_MIXG_BIAS_AUX 0x4A
976#define B2056_RX_MIXG_BIAS_MAIN 0x4B
977#define B2056_RX_MIXG_BIAS_MISC 0x4C
978#define B2056_RX_MIXG_MAST_BIAS 0x4D
979#define B2056_RX_TIA_MASTER 0x4E
980#define B2056_RX_TIA_IOPAMP 0x4F
981#define B2056_RX_TIA_QOPAMP 0x50
982#define B2056_RX_TIA_IMISC 0x51
983#define B2056_RX_TIA_QMISC 0x52
984#define B2056_RX_TIA_GAIN 0x53
985#define B2056_RX_TIA_SPARE1 0x54
986#define B2056_RX_TIA_SPARE2 0x55
987#define B2056_RX_BB_LPF_MASTER 0x56
988#define B2056_RX_AACI_MASTER 0x57
989#define B2056_RX_RXLPF_IDAC 0x58
990#define B2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
991#define B2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5A
992#define B2056_RX_RXLPF_BIAS_DCCANCEL 0x5B
993#define B2056_RX_RXLPF_OUTVCM 0x5C
994#define B2056_RX_RXLPF_INVCM_BODY 0x5D
995#define B2056_RX_RXLPF_CC_OP 0x5E
996#define B2056_RX_RXLPF_GAIN 0x5F
997#define B2056_RX_RXLPF_Q_BW 0x60
998#define B2056_RX_RXLPF_HP_CORNER_BW 0x61
999#define B2056_RX_RXLPF_RCCAL_HPC 0x62
1000#define B2056_RX_RXHPF_OFF0 0x63
1001#define B2056_RX_RXHPF_OFF1 0x64
1002#define B2056_RX_RXHPF_OFF2 0x65
1003#define B2056_RX_RXHPF_OFF3 0x66
1004#define B2056_RX_RXHPF_OFF4 0x67
1005#define B2056_RX_RXHPF_OFF5 0x68
1006#define B2056_RX_RXHPF_OFF6 0x69
1007#define B2056_RX_RXHPF_OFF7 0x6A
1008#define B2056_RX_RXLPF_RCCAL_LPC 0x6B
1009#define B2056_RX_RXLPF_OFF_0 0x6C
1010#define B2056_RX_RXLPF_OFF_1 0x6D
1011#define B2056_RX_RXLPF_OFF_2 0x6E
1012#define B2056_RX_RXLPF_OFF_3 0x6F
1013#define B2056_RX_RXLPF_OFF_4 0x70
1014#define B2056_RX_UNUSED 0x71
1015#define B2056_RX_VGA_MASTER 0x72
1016#define B2056_RX_VGA_BIAS 0x73
1017#define B2056_RX_VGA_BIAS_DCCANCEL 0x74
1018#define B2056_RX_VGA_GAIN 0x75
1019#define B2056_RX_VGA_HP_CORNER_BW 0x76
1020#define B2056_RX_VGABUF_BIAS 0x77
1021#define B2056_RX_VGABUF_GAIN_BW 0x78
1022#define B2056_RX_TXFBMIX_A 0x79
1023#define B2056_RX_TXFBMIX_G 0x7A
1024#define B2056_RX_RXSPARE1 0x7B
1025#define B2056_RX_RXSPARE2 0x7C
1026#define B2056_RX_RXSPARE3 0x7D
1027#define B2056_RX_RXSPARE4 0x7E
1028#define B2056_RX_RXSPARE5 0x7F
1029#define B2056_RX_RXSPARE6 0x80
1030#define B2056_RX_RXSPARE7 0x81
1031#define B2056_RX_RXSPARE8 0x82
1032#define B2056_RX_RXSPARE9 0x83
1033#define B2056_RX_RXSPARE10 0x84
1034#define B2056_RX_RXSPARE11 0x85
1035#define B2056_RX_RXSPARE12 0x86
1036#define B2056_RX_RXSPARE13 0x87
1037#define B2056_RX_RXSPARE14 0x88
1038#define B2056_RX_RXSPARE15 0x89
1039#define B2056_RX_RXSPARE16 0x8A
1040#define B2056_RX_STATUS_LNAA_GAIN 0x8B
1041#define B2056_RX_STATUS_LNAG_GAIN 0x8C
1042#define B2056_RX_STATUS_MIXTIA_GAIN 0x8D
1043#define B2056_RX_STATUS_RXLPF_GAIN 0x8E
1044#define B2056_RX_STATUS_VGA_BUF_GAIN 0x8F
1045#define B2056_RX_STATUS_RXLPF_Q 0x90
1046#define B2056_RX_STATUS_RXLPF_BUF_BW 0x91
1047#define B2056_RX_STATUS_RXLPF_VGA_HPC 0x92
1048#define B2056_RX_STATUS_RXLPF_RC 0x93
1049#define B2056_RX_STATUS_HPC_RC 0x94
1050
1051#define B2056_LNA1_A_PU 0x01
1052#define B2056_LNA2_A_PU 0x02
1053#define B2056_LNA1_G_PU 0x01
1054#define B2056_LNA2_G_PU 0x02
1055#define B2056_MIXA_PU_I 0x01
1056#define B2056_MIXA_PU_Q 0x02
1057#define B2056_MIXA_PU_GM 0x10
1058#define B2056_MIXG_PU_I 0x01
1059#define B2056_MIXG_PU_Q 0x02
1060#define B2056_MIXG_PU_GM 0x10
1061#define B2056_TIA_PU 0x01
1062#define B2056_BB_LPF_PU 0x20
1063#define B2056_W1_PU 0x02
1064#define B2056_W2_PU 0x04
1065#define B2056_NB_PU 0x08
1066#define B2056_RSSI_W1_SEL 0x02
1067#define B2056_RSSI_W2_SEL 0x04
1068#define B2056_RSSI_NB_SEL 0x08
1069#define B2056_VCM_MASK 0x1C
1070#define B2056_RSSI_VCM_SHIFT 0x02
1071
31struct b43_nphy_channeltab_entry_rev3 { 1072struct b43_nphy_channeltab_entry_rev3 {
32 /* The channel number */
33 u8 channel;
34 /* The channel frequency in MHz */ 1073 /* The channel frequency in MHz */
35 u16 freq; 1074 u16 freq;
36 /* Radio register values on channelswitch */ 1075 /* Radio register values on channelswitch */
37 /* TODO */ 1076 u8 radio_syn_pll_vcocal1;
1077 u8 radio_syn_pll_vcocal2;
1078 u8 radio_syn_pll_refdiv;
1079 u8 radio_syn_pll_mmd2;
1080 u8 radio_syn_pll_mmd1;
1081 u8 radio_syn_pll_loopfilter1;
1082 u8 radio_syn_pll_loopfilter2;
1083 u8 radio_syn_pll_loopfilter3;
1084 u8 radio_syn_pll_loopfilter4;
1085 u8 radio_syn_pll_loopfilter5;
1086 u8 radio_syn_reserved_addr27;
1087 u8 radio_syn_reserved_addr28;
1088 u8 radio_syn_reserved_addr29;
1089 u8 radio_syn_logen_vcobuf1;
1090 u8 radio_syn_logen_mixer2;
1091 u8 radio_syn_logen_buf3;
1092 u8 radio_syn_logen_buf4;
1093 u8 radio_rx0_lnaa_tune;
1094 u8 radio_rx0_lnag_tune;
1095 u8 radio_tx0_intpaa_boost_tune;
1096 u8 radio_tx0_intpag_boost_tune;
1097 u8 radio_tx0_pada_boost_tune;
1098 u8 radio_tx0_padg_boost_tune;
1099 u8 radio_tx0_pgaa_boost_tune;
1100 u8 radio_tx0_pgag_boost_tune;
1101 u8 radio_tx0_mixa_boost_tune;
1102 u8 radio_tx0_mixg_boost_tune;
1103 u8 radio_rx1_lnaa_tune;
1104 u8 radio_rx1_lnag_tune;
1105 u8 radio_tx1_intpaa_boost_tune;
1106 u8 radio_tx1_intpag_boost_tune;
1107 u8 radio_tx1_pada_boost_tune;
1108 u8 radio_tx1_padg_boost_tune;
1109 u8 radio_tx1_pgaa_boost_tune;
1110 u8 radio_tx1_pgag_boost_tune;
1111 u8 radio_tx1_mixa_boost_tune;
1112 u8 radio_tx1_mixg_boost_tune;
38 /* PHY register values on channelswitch */ 1113 /* PHY register values on channelswitch */
39 struct b43_phy_n_sfo_cfg phy_regs; 1114 struct b43_phy_n_sfo_cfg phy_regs;
40}; 1115};
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index d579df72b783..b90f223fb31c 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -29,7 +29,7 @@
29/* Returns TRUE, if the radio is enabled in hardware. */ 29/* Returns TRUE, if the radio is enabled in hardware. */
30bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) 30bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
31{ 31{
32 if (dev->phy.rev >= 3) { 32 if (dev->dev->id.revision >= 3) {
33 if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) 33 if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
34 & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) 34 & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
35 return 1; 35 return 1;
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b82364258dc5..ed424574160e 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -106,6 +106,9 @@ config IWL5000
106 Intel WiFi Link 1000BGN 106 Intel WiFi Link 1000BGN
107 Intel Wireless WiFi 5150AGN 107 Intel Wireless WiFi 5150AGN
108 Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN 108 Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
109 Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B)
110 Intel WIreless WiFi Link 6050BGN Gen 2 Adapter
111 Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
109 112
110config IWL3945 113config IWL3945
111 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" 114 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 63edbe2e557f..01aa2468bd69 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -2,6 +2,8 @@ obj-$(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 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_IWL3945) += iwl-legacy.o
6iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 7iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 8iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
7 9
@@ -9,13 +11,14 @@ CFLAGS_iwl-devtrace.o := -I$(src)
9 11
10# AGN 12# AGN
11obj-$(CONFIG_IWLAGN) += iwlagn.o 13obj-$(CONFIG_IWLAGN) += iwlagn.o
12iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o 14iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
13iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o 15iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o
14iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o 16iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
15iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o 17iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
16iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o 18iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
17 19
18iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 20iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
21iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o
19iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 22iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
20iwlagn-$(CONFIG_IWL5000) += iwl-6000.o 23iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
21iwlagn-$(CONFIG_IWL5000) += iwl-1000.o 24iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index db540910b110..068f1e1e3297 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -211,14 +211,16 @@ static struct iwl_lib_ops iwl1000_lib = {
211 .calib_version = iwlagn_eeprom_calib_version, 211 .calib_version = iwlagn_eeprom_calib_version,
212 .query_addr = iwlagn_eeprom_query_addr, 212 .query_addr = iwlagn_eeprom_query_addr,
213 }, 213 },
214 .post_associate = iwl_post_associate, 214 .isr_ops = {
215 .isr = iwl_isr_ict, 215 .isr = iwl_isr_ict,
216 .config_ap = iwl_config_ap, 216 .free = iwl_free_isr_ict,
217 .alloc = iwl_alloc_isr_ict,
218 .reset = iwl_reset_ict,
219 .disable = iwl_disable_ict,
220 },
217 .temp_ops = { 221 .temp_ops = {
218 .temperature = iwlagn_temperature, 222 .temperature = iwlagn_temperature,
219 }, 223 },
220 .manage_ibss_station = iwlagn_manage_ibss_station,
221 .update_bcast_stations = iwl_update_bcast_stations,
222 .debugfs_ops = { 224 .debugfs_ops = {
223 .rx_stats_read = iwl_ucode_rx_stats_read, 225 .rx_stats_read = iwl_ucode_rx_stats_read,
224 .tx_stats_read = iwl_ucode_tx_stats_read, 226 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -243,6 +245,7 @@ static const struct iwl_ops iwl1000_ops = {
243 .hcmd = &iwlagn_hcmd, 245 .hcmd = &iwlagn_hcmd,
244 .utils = &iwlagn_hcmd_utils, 246 .utils = &iwlagn_hcmd_utils,
245 .led = &iwlagn_led_ops, 247 .led = &iwlagn_led_ops,
248 .ieee80211_ops = &iwlagn_hw_ops,
246}; 249};
247 250
248static struct iwl_base_params iwl1000_base_params = { 251static struct iwl_base_params iwl1000_base_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 176e52577673..ebac04b7887c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -51,6 +51,7 @@
51#include "iwl-led.h" 51#include "iwl-led.h"
52#include "iwl-3945-led.h" 52#include "iwl-3945-led.h"
53#include "iwl-3945-debugfs.h" 53#include "iwl-3945-debugfs.h"
54#include "iwl-legacy.h"
54 55
55#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ 56#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
56 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 57 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -1451,6 +1452,10 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
1451 }; 1452 };
1452 u16 chan; 1453 u16 chan;
1453 1454
1455 if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
1456 "TX Power requested while scanning!\n"))
1457 return -EAGAIN;
1458
1454 chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); 1459 chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
1455 1460
1456 txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; 1461 txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
@@ -2722,10 +2727,9 @@ static struct iwl_lib_ops iwl3945_lib = {
2722 }, 2727 },
2723 .send_tx_power = iwl3945_send_tx_power, 2728 .send_tx_power = iwl3945_send_tx_power,
2724 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, 2729 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
2725 .post_associate = iwl3945_post_associate, 2730 .isr_ops = {
2726 .isr = iwl_isr_legacy, 2731 .isr = iwl_isr_legacy,
2727 .config_ap = iwl3945_config_ap, 2732 },
2728 .manage_ibss_station = iwl3945_manage_ibss_station,
2729 .recover_from_tx_stall = iwl_bg_monitor_recover, 2733 .recover_from_tx_stall = iwl_bg_monitor_recover,
2730 .check_plcp_health = iwl3945_good_plcp_health, 2734 .check_plcp_health = iwl3945_good_plcp_health,
2731 2735
@@ -2736,10 +2740,16 @@ static struct iwl_lib_ops iwl3945_lib = {
2736 }, 2740 },
2737}; 2741};
2738 2742
2743static const struct iwl_legacy_ops iwl3945_legacy_ops = {
2744 .post_associate = iwl3945_post_associate,
2745 .config_ap = iwl3945_config_ap,
2746 .manage_ibss_station = iwl3945_manage_ibss_station,
2747};
2748
2739static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2749static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2740 .get_hcmd_size = iwl3945_get_hcmd_size, 2750 .get_hcmd_size = iwl3945_get_hcmd_size,
2741 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2751 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
2742 .tx_cmd_protection = iwlcore_tx_cmd_protection, 2752 .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
2743 .request_scan = iwl3945_request_scan, 2753 .request_scan = iwl3945_request_scan,
2744 .post_scan = iwl3945_post_scan, 2754 .post_scan = iwl3945_post_scan,
2745}; 2755};
@@ -2749,6 +2759,8 @@ static const struct iwl_ops iwl3945_ops = {
2749 .hcmd = &iwl3945_hcmd, 2759 .hcmd = &iwl3945_hcmd,
2750 .utils = &iwl3945_hcmd_utils, 2760 .utils = &iwl3945_hcmd_utils,
2751 .led = &iwl3945_led_ops, 2761 .led = &iwl3945_led_ops,
2762 .legacy = &iwl3945_legacy_ops,
2763 .ieee80211_ops = &iwl3945_hw_ops,
2752}; 2764};
2753 2765
2754static struct iwl_base_params iwl3945_base_params = { 2766static struct iwl_base_params iwl3945_base_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 09391f0ee61f..3eef1eb74a78 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -264,10 +264,8 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
264 struct iwl_rx_mem_buffer *rxb); 264 struct iwl_rx_mem_buffer *rxb);
265extern void iwl3945_disable_events(struct iwl_priv *priv); 265extern void iwl3945_disable_events(struct iwl_priv *priv);
266extern int iwl4965_get_temperature(const struct iwl_priv *priv); 266extern int iwl4965_get_temperature(const struct iwl_priv *priv);
267extern void iwl3945_post_associate(struct iwl_priv *priv, 267extern void iwl3945_post_associate(struct iwl_priv *priv);
268 struct ieee80211_vif *vif); 268extern void iwl3945_config_ap(struct iwl_priv *priv);
269extern void iwl3945_config_ap(struct iwl_priv *priv,
270 struct ieee80211_vif *vif);
271 269
272extern int iwl3945_commit_rxon(struct iwl_priv *priv, 270extern int iwl3945_commit_rxon(struct iwl_priv *priv,
273 struct iwl_rxon_context *ctx); 271 struct iwl_rxon_context *ctx);
@@ -282,6 +280,8 @@ extern int iwl3945_commit_rxon(struct iwl_priv *priv,
282 */ 280 */
283extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); 281extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
284 282
283extern struct ieee80211_ops iwl3945_hw_ops;
284
285/* 285/*
286 * Forward declare iwl-3945.c functions for iwl-base.c 286 * Forward declare iwl-3945.c functions for iwl-base.c
287 */ 287 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b207e3e9299f..4748d067eb1d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -48,6 +48,7 @@
48#include "iwl-agn-led.h" 48#include "iwl-agn-led.h"
49#include "iwl-agn.h" 49#include "iwl-agn.h"
50#include "iwl-agn-debugfs.h" 50#include "iwl-agn-debugfs.h"
51#include "iwl-legacy.h"
51 52
52static int iwl4965_send_tx_power(struct iwl_priv *priv); 53static int iwl4965_send_tx_power(struct iwl_priv *priv);
53static int iwl4965_hw_get_temperature(struct iwl_priv *priv); 54static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -1377,13 +1378,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
1377 u8 ctrl_chan_high = 0; 1378 u8 ctrl_chan_high = 0;
1378 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 1379 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1379 1380
1380 if (test_bit(STATUS_SCANNING, &priv->status)) { 1381 if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
1381 /* If this gets hit a lot, switch it to a BUG() and catch 1382 "TX Power requested while scanning!\n"))
1382 * the stack trace to find out who is calling this during
1383 * a scan. */
1384 IWL_WARN(priv, "TX Power requested while scanning!\n");
1385 return -EAGAIN; 1383 return -EAGAIN;
1386 }
1387 1384
1388 band = priv->band == IEEE80211_BAND_2GHZ; 1385 band = priv->band == IEEE80211_BAND_2GHZ;
1389 1386
@@ -1447,6 +1444,142 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
1447 return ret; 1444 return ret;
1448} 1445}
1449 1446
1447static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1448{
1449 /* cast away the const for active_rxon in this function */
1450 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
1451 int ret;
1452 bool new_assoc =
1453 !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
1454
1455 if (!iwl_is_alive(priv))
1456 return -EBUSY;
1457
1458 if (!ctx->is_active)
1459 return 0;
1460
1461 /* always get timestamp with Rx frame */
1462 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
1463
1464 ret = iwl_check_rxon_cmd(priv, ctx);
1465 if (ret) {
1466 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
1467 return -EINVAL;
1468 }
1469
1470 /*
1471 * receive commit_rxon request
1472 * abort any previous channel switch if still in process
1473 */
1474 if (priv->switch_rxon.switch_in_progress &&
1475 (priv->switch_rxon.channel != ctx->staging.channel)) {
1476 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
1477 le16_to_cpu(priv->switch_rxon.channel));
1478 iwl_chswitch_done(priv, false);
1479 }
1480
1481 /* If we don't need to send a full RXON, we can use
1482 * iwl_rxon_assoc_cmd which is used to reconfigure filter
1483 * and other flags for the current radio configuration. */
1484 if (!iwl_full_rxon_required(priv, ctx)) {
1485 ret = iwl_send_rxon_assoc(priv, ctx);
1486 if (ret) {
1487 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
1488 return ret;
1489 }
1490
1491 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1492 iwl_print_rx_config_cmd(priv, ctx);
1493 return 0;
1494 }
1495
1496 /* If we are currently associated and the new config requires
1497 * an RXON_ASSOC and the new config wants the associated mask enabled,
1498 * we must clear the associated from the active configuration
1499 * before we apply the new config */
1500 if (iwl_is_associated_ctx(ctx) && new_assoc) {
1501 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
1502 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1503
1504 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1505 sizeof(struct iwl_rxon_cmd),
1506 active_rxon);
1507
1508 /* If the mask clearing failed then we set
1509 * active_rxon back to what it was previously */
1510 if (ret) {
1511 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1512 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
1513 return ret;
1514 }
1515 iwl_clear_ucode_stations(priv, ctx);
1516 iwl_restore_stations(priv, ctx);
1517 ret = iwl_restore_default_wep_keys(priv, ctx);
1518 if (ret) {
1519 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
1520 return ret;
1521 }
1522 }
1523
1524 IWL_DEBUG_INFO(priv, "Sending RXON\n"
1525 "* with%s RXON_FILTER_ASSOC_MSK\n"
1526 "* channel = %d\n"
1527 "* bssid = %pM\n",
1528 (new_assoc ? "" : "out"),
1529 le16_to_cpu(ctx->staging.channel),
1530 ctx->staging.bssid_addr);
1531
1532 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
1533
1534 /* Apply the new configuration
1535 * RXON unassoc clears the station table in uCode so restoration of
1536 * stations is needed after it (the RXON command) completes
1537 */
1538 if (!new_assoc) {
1539 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1540 sizeof(struct iwl_rxon_cmd), &ctx->staging);
1541 if (ret) {
1542 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
1543 return ret;
1544 }
1545 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
1546 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1547 iwl_clear_ucode_stations(priv, ctx);
1548 iwl_restore_stations(priv, ctx);
1549 ret = iwl_restore_default_wep_keys(priv, ctx);
1550 if (ret) {
1551 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
1552 return ret;
1553 }
1554 }
1555 if (new_assoc) {
1556 priv->start_calib = 0;
1557 /* Apply the new configuration
1558 * RXON assoc doesn't clear the station table in uCode,
1559 */
1560 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1561 sizeof(struct iwl_rxon_cmd), &ctx->staging);
1562 if (ret) {
1563 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
1564 return ret;
1565 }
1566 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1567 }
1568 iwl_print_rx_config_cmd(priv, ctx);
1569
1570 iwl_init_sensitivity(priv);
1571
1572 /* If we issue a new RXON command which required a tune then we must
1573 * send a new TXPOWER command or we won't be able to Tx any frames */
1574 ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
1575 if (ret) {
1576 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
1577 return ret;
1578 }
1579
1580 return 0;
1581}
1582
1450static int iwl4965_hw_channel_switch(struct iwl_priv *priv, 1583static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1451 struct ieee80211_channel_switch *ch_switch) 1584 struct ieee80211_channel_switch *ch_switch)
1452{ 1585{
@@ -1554,22 +1687,6 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
1554} 1687}
1555 1688
1556/** 1689/**
1557 * sign_extend - Sign extend a value using specified bit as sign-bit
1558 *
1559 * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1
1560 * and bit0..2 is 001b which when sign extended to 1111111111111001b is -7.
1561 *
1562 * @param oper value to sign extend
1563 * @param index 0 based bit index (0<=index<32) to sign bit
1564 */
1565static s32 sign_extend(u32 oper, int index)
1566{
1567 u8 shift = 31 - index;
1568
1569 return (s32)(oper << shift) >> shift;
1570}
1571
1572/**
1573 * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) 1690 * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
1574 * @statistics: Provides the temperature reading from the uCode 1691 * @statistics: Provides the temperature reading from the uCode
1575 * 1692 *
@@ -1606,9 +1723,9 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
1606 * "initialize" ALIVE response. 1723 * "initialize" ALIVE response.
1607 */ 1724 */
1608 if (!test_bit(STATUS_TEMPERATURE, &priv->status)) 1725 if (!test_bit(STATUS_TEMPERATURE, &priv->status))
1609 vt = sign_extend(R4, 23); 1726 vt = sign_extend32(R4, 23);
1610 else 1727 else
1611 vt = sign_extend(le32_to_cpu(priv->_agn.statistics. 1728 vt = sign_extend32(le32_to_cpu(priv->_agn.statistics.
1612 general.common.temperature), 23); 1729 general.common.temperature), 23);
1613 1730
1614 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); 1731 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
@@ -2216,7 +2333,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2216 2333
2217static struct iwl_hcmd_ops iwl4965_hcmd = { 2334static struct iwl_hcmd_ops iwl4965_hcmd = {
2218 .rxon_assoc = iwl4965_send_rxon_assoc, 2335 .rxon_assoc = iwl4965_send_rxon_assoc,
2219 .commit_rxon = iwlagn_commit_rxon, 2336 .commit_rxon = iwl4965_commit_rxon,
2220 .set_rxon_chain = iwlagn_set_rxon_chain, 2337 .set_rxon_chain = iwlagn_set_rxon_chain,
2221 .send_bt_config = iwl_send_bt_config, 2338 .send_bt_config = iwl_send_bt_config,
2222}; 2339};
@@ -2233,12 +2350,155 @@ static void iwl4965_post_scan(struct iwl_priv *priv)
2233 iwlcore_commit_rxon(priv, ctx); 2350 iwlcore_commit_rxon(priv, ctx);
2234} 2351}
2235 2352
2353static void iwl4965_post_associate(struct iwl_priv *priv)
2354{
2355 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2356 struct ieee80211_vif *vif = ctx->vif;
2357 struct ieee80211_conf *conf = NULL;
2358 int ret = 0;
2359
2360 if (!vif || !priv->is_open)
2361 return;
2362
2363 if (vif->type == NL80211_IFTYPE_AP) {
2364 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
2365 return;
2366 }
2367
2368 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2369 return;
2370
2371 iwl_scan_cancel_timeout(priv, 200);
2372
2373 conf = ieee80211_get_hw_conf(priv->hw);
2374
2375 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2376 iwlcore_commit_rxon(priv, ctx);
2377
2378 ret = iwl_send_rxon_timing(priv, ctx);
2379 if (ret)
2380 IWL_WARN(priv, "RXON timing - "
2381 "Attempting to continue.\n");
2382
2383 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2384
2385 iwl_set_rxon_ht(priv, &priv->current_ht_config);
2386
2387 if (priv->cfg->ops->hcmd->set_rxon_chain)
2388 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2389
2390 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
2391
2392 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2393 vif->bss_conf.aid, vif->bss_conf.beacon_int);
2394
2395 if (vif->bss_conf.use_short_preamble)
2396 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2397 else
2398 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2399
2400 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
2401 if (vif->bss_conf.use_short_slot)
2402 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
2403 else
2404 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2405 }
2406
2407 iwlcore_commit_rxon(priv, ctx);
2408
2409 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2410 vif->bss_conf.aid, ctx->active.bssid_addr);
2411
2412 switch (vif->type) {
2413 case NL80211_IFTYPE_STATION:
2414 break;
2415 case NL80211_IFTYPE_ADHOC:
2416 iwlagn_send_beacon_cmd(priv);
2417 break;
2418 default:
2419 IWL_ERR(priv, "%s Should not be called in %d mode\n",
2420 __func__, vif->type);
2421 break;
2422 }
2423
2424 /* the chain noise calibration will enabled PM upon completion
2425 * If chain noise has already been run, then we need to enable
2426 * power management here */
2427 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
2428 iwl_power_update_mode(priv, false);
2429
2430 /* Enable Rx differential gain and sensitivity calibrations */
2431 iwl_chain_noise_reset(priv);
2432 priv->start_calib = 1;
2433}
2434
2435static void iwl4965_config_ap(struct iwl_priv *priv)
2436{
2437 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2438 struct ieee80211_vif *vif = ctx->vif;
2439 int ret = 0;
2440
2441 lockdep_assert_held(&priv->mutex);
2442
2443 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2444 return;
2445
2446 /* The following should be done only at AP bring up */
2447 if (!iwl_is_associated_ctx(ctx)) {
2448
2449 /* RXON - unassoc (to set timing command) */
2450 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2451 iwlcore_commit_rxon(priv, ctx);
2452
2453 /* RXON Timing */
2454 ret = iwl_send_rxon_timing(priv, ctx);
2455 if (ret)
2456 IWL_WARN(priv, "RXON timing failed - "
2457 "Attempting to continue.\n");
2458
2459 /* AP has all antennas */
2460 priv->chain_noise_data.active_chains =
2461 priv->hw_params.valid_rx_ant;
2462 iwl_set_rxon_ht(priv, &priv->current_ht_config);
2463 if (priv->cfg->ops->hcmd->set_rxon_chain)
2464 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2465
2466 ctx->staging.assoc_id = 0;
2467
2468 if (vif->bss_conf.use_short_preamble)
2469 ctx->staging.flags |=
2470 RXON_FLG_SHORT_PREAMBLE_MSK;
2471 else
2472 ctx->staging.flags &=
2473 ~RXON_FLG_SHORT_PREAMBLE_MSK;
2474
2475 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
2476 if (vif->bss_conf.use_short_slot)
2477 ctx->staging.flags |=
2478 RXON_FLG_SHORT_SLOT_MSK;
2479 else
2480 ctx->staging.flags &=
2481 ~RXON_FLG_SHORT_SLOT_MSK;
2482 }
2483 /* need to send beacon cmd before committing assoc RXON! */
2484 iwlagn_send_beacon_cmd(priv);
2485 /* restore RXON assoc */
2486 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2487 iwlcore_commit_rxon(priv, ctx);
2488 }
2489 iwlagn_send_beacon_cmd(priv);
2490
2491 /* FIXME - we need to add code here to detect a totally new
2492 * configuration, reset the AP, unassoc, rxon timing, assoc,
2493 * clear sta table, add BCAST sta... */
2494}
2495
2236static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 2496static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2237 .get_hcmd_size = iwl4965_get_hcmd_size, 2497 .get_hcmd_size = iwl4965_get_hcmd_size,
2238 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2498 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
2239 .chain_noise_reset = iwl4965_chain_noise_reset, 2499 .chain_noise_reset = iwl4965_chain_noise_reset,
2240 .gain_computation = iwl4965_gain_computation, 2500 .gain_computation = iwl4965_gain_computation,
2241 .tx_cmd_protection = iwlcore_tx_cmd_protection, 2501 .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
2242 .calc_rssi = iwl4965_calc_rssi, 2502 .calc_rssi = iwl4965_calc_rssi,
2243 .request_scan = iwlagn_request_scan, 2503 .request_scan = iwlagn_request_scan,
2244 .post_scan = iwl4965_post_scan, 2504 .post_scan = iwl4965_post_scan,
@@ -2285,14 +2545,12 @@ static struct iwl_lib_ops iwl4965_lib = {
2285 }, 2545 },
2286 .send_tx_power = iwl4965_send_tx_power, 2546 .send_tx_power = iwl4965_send_tx_power,
2287 .update_chain_flags = iwl_update_chain_flags, 2547 .update_chain_flags = iwl_update_chain_flags,
2288 .post_associate = iwl_post_associate, 2548 .isr_ops = {
2289 .config_ap = iwl_config_ap, 2549 .isr = iwl_isr_legacy,
2290 .isr = iwl_isr_legacy, 2550 },
2291 .temp_ops = { 2551 .temp_ops = {
2292 .temperature = iwl4965_temperature_calib, 2552 .temperature = iwl4965_temperature_calib,
2293 }, 2553 },
2294 .manage_ibss_station = iwlagn_manage_ibss_station,
2295 .update_bcast_stations = iwl_update_bcast_stations,
2296 .debugfs_ops = { 2554 .debugfs_ops = {
2297 .rx_stats_read = iwl_ucode_rx_stats_read, 2555 .rx_stats_read = iwl_ucode_rx_stats_read,
2298 .tx_stats_read = iwl_ucode_tx_stats_read, 2556 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -2304,11 +2562,43 @@ static struct iwl_lib_ops iwl4965_lib = {
2304 .check_plcp_health = iwl_good_plcp_health, 2562 .check_plcp_health = iwl_good_plcp_health,
2305}; 2563};
2306 2564
2565static const struct iwl_legacy_ops iwl4965_legacy_ops = {
2566 .post_associate = iwl4965_post_associate,
2567 .config_ap = iwl4965_config_ap,
2568 .manage_ibss_station = iwlagn_manage_ibss_station,
2569 .update_bcast_stations = iwl_update_bcast_stations,
2570};
2571
2572struct ieee80211_ops iwl4965_hw_ops = {
2573 .tx = iwlagn_mac_tx,
2574 .start = iwlagn_mac_start,
2575 .stop = iwlagn_mac_stop,
2576 .add_interface = iwl_mac_add_interface,
2577 .remove_interface = iwl_mac_remove_interface,
2578 .change_interface = iwl_mac_change_interface,
2579 .config = iwl_legacy_mac_config,
2580 .configure_filter = iwlagn_configure_filter,
2581 .set_key = iwlagn_mac_set_key,
2582 .update_tkip_key = iwlagn_mac_update_tkip_key,
2583 .conf_tx = iwl_mac_conf_tx,
2584 .reset_tsf = iwl_legacy_mac_reset_tsf,
2585 .bss_info_changed = iwl_legacy_mac_bss_info_changed,
2586 .ampdu_action = iwlagn_mac_ampdu_action,
2587 .hw_scan = iwl_mac_hw_scan,
2588 .sta_add = iwlagn_mac_sta_add,
2589 .sta_remove = iwl_mac_sta_remove,
2590 .channel_switch = iwlagn_mac_channel_switch,
2591 .flush = iwlagn_mac_flush,
2592 .tx_last_beacon = iwl_mac_tx_last_beacon,
2593};
2594
2307static const struct iwl_ops iwl4965_ops = { 2595static const struct iwl_ops iwl4965_ops = {
2308 .lib = &iwl4965_lib, 2596 .lib = &iwl4965_lib,
2309 .hcmd = &iwl4965_hcmd, 2597 .hcmd = &iwl4965_hcmd,
2310 .utils = &iwl4965_hcmd_utils, 2598 .utils = &iwl4965_hcmd_utils,
2311 .led = &iwlagn_led_ops, 2599 .led = &iwlagn_led_ops,
2600 .legacy = &iwl4965_legacy_ops,
2601 .ieee80211_ops = &iwl4965_hw_ops,
2312}; 2602};
2313 2603
2314static struct iwl_base_params iwl4965_base_params = { 2604static struct iwl_base_params iwl4965_base_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index fd9fbc93ea1b..ad43f0fdf919 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -385,14 +385,16 @@ static struct iwl_lib_ops iwl5000_lib = {
385 .calib_version = iwlagn_eeprom_calib_version, 385 .calib_version = iwlagn_eeprom_calib_version,
386 .query_addr = iwlagn_eeprom_query_addr, 386 .query_addr = iwlagn_eeprom_query_addr,
387 }, 387 },
388 .post_associate = iwl_post_associate, 388 .isr_ops = {
389 .isr = iwl_isr_ict, 389 .isr = iwl_isr_ict,
390 .config_ap = iwl_config_ap, 390 .free = iwl_free_isr_ict,
391 .alloc = iwl_alloc_isr_ict,
392 .reset = iwl_reset_ict,
393 .disable = iwl_disable_ict,
394 },
391 .temp_ops = { 395 .temp_ops = {
392 .temperature = iwlagn_temperature, 396 .temperature = iwlagn_temperature,
393 }, 397 },
394 .manage_ibss_station = iwlagn_manage_ibss_station,
395 .update_bcast_stations = iwl_update_bcast_stations,
396 .debugfs_ops = { 398 .debugfs_ops = {
397 .rx_stats_read = iwl_ucode_rx_stats_read, 399 .rx_stats_read = iwl_ucode_rx_stats_read,
398 .tx_stats_read = iwl_ucode_tx_stats_read, 400 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -453,14 +455,16 @@ static struct iwl_lib_ops iwl5150_lib = {
453 .calib_version = iwlagn_eeprom_calib_version, 455 .calib_version = iwlagn_eeprom_calib_version,
454 .query_addr = iwlagn_eeprom_query_addr, 456 .query_addr = iwlagn_eeprom_query_addr,
455 }, 457 },
456 .post_associate = iwl_post_associate, 458 .isr_ops = {
457 .isr = iwl_isr_ict, 459 .isr = iwl_isr_ict,
458 .config_ap = iwl_config_ap, 460 .free = iwl_free_isr_ict,
461 .alloc = iwl_alloc_isr_ict,
462 .reset = iwl_reset_ict,
463 .disable = iwl_disable_ict,
464 },
459 .temp_ops = { 465 .temp_ops = {
460 .temperature = iwl5150_temperature, 466 .temperature = iwl5150_temperature,
461 }, 467 },
462 .manage_ibss_station = iwlagn_manage_ibss_station,
463 .update_bcast_stations = iwl_update_bcast_stations,
464 .debugfs_ops = { 468 .debugfs_ops = {
465 .rx_stats_read = iwl_ucode_rx_stats_read, 469 .rx_stats_read = iwl_ucode_rx_stats_read,
466 .tx_stats_read = iwl_ucode_tx_stats_read, 470 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -485,6 +489,7 @@ static const struct iwl_ops iwl5000_ops = {
485 .hcmd = &iwlagn_hcmd, 489 .hcmd = &iwlagn_hcmd,
486 .utils = &iwlagn_hcmd_utils, 490 .utils = &iwlagn_hcmd_utils,
487 .led = &iwlagn_led_ops, 491 .led = &iwlagn_led_ops,
492 .ieee80211_ops = &iwlagn_hw_ops,
488}; 493};
489 494
490static const struct iwl_ops iwl5150_ops = { 495static const struct iwl_ops iwl5150_ops = {
@@ -492,6 +497,7 @@ static const struct iwl_ops iwl5150_ops = {
492 .hcmd = &iwlagn_hcmd, 497 .hcmd = &iwlagn_hcmd,
493 .utils = &iwlagn_hcmd_utils, 498 .utils = &iwlagn_hcmd_utils,
494 .led = &iwlagn_led_ops, 499 .led = &iwlagn_led_ops,
500 .ieee80211_ops = &iwlagn_hw_ops,
495}; 501};
496 502
497static struct iwl_base_params iwl5000_base_params = { 503static struct iwl_base_params iwl5000_base_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 11e6532fc573..c7ff1bdf42cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -53,13 +53,11 @@
53#define IWL6000_UCODE_API_MAX 4 53#define IWL6000_UCODE_API_MAX 4
54#define IWL6050_UCODE_API_MAX 5 54#define IWL6050_UCODE_API_MAX 5
55#define IWL6000G2_UCODE_API_MAX 5 55#define IWL6000G2_UCODE_API_MAX 5
56#define IWL130_UCODE_API_MAX 5
57 56
58/* Lowest firmware API version supported */ 57/* Lowest firmware API version supported */
59#define IWL6000_UCODE_API_MIN 4 58#define IWL6000_UCODE_API_MIN 4
60#define IWL6050_UCODE_API_MIN 4 59#define IWL6050_UCODE_API_MIN 4
61#define IWL6000G2_UCODE_API_MIN 4 60#define IWL6000G2_UCODE_API_MIN 4
62#define IWL130_UCODE_API_MIN 5
63 61
64#define IWL6000_FW_PRE "iwlwifi-6000-" 62#define IWL6000_FW_PRE "iwlwifi-6000-"
65#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" 63#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
@@ -77,10 +75,6 @@
77#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" 75#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
78#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) 76#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
79 77
80#define IWL130_FW_PRE "iwlwifi-130-"
81#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode"
82#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api)
83
84static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 78static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
85{ 79{
86 /* want Celsius */ 80 /* want Celsius */
@@ -328,14 +322,16 @@ static struct iwl_lib_ops iwl6000_lib = {
328 .query_addr = iwlagn_eeprom_query_addr, 322 .query_addr = iwlagn_eeprom_query_addr,
329 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 323 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
330 }, 324 },
331 .post_associate = iwl_post_associate, 325 .isr_ops = {
332 .isr = iwl_isr_ict, 326 .isr = iwl_isr_ict,
333 .config_ap = iwl_config_ap, 327 .free = iwl_free_isr_ict,
328 .alloc = iwl_alloc_isr_ict,
329 .reset = iwl_reset_ict,
330 .disable = iwl_disable_ict,
331 },
334 .temp_ops = { 332 .temp_ops = {
335 .temperature = iwlagn_temperature, 333 .temperature = iwlagn_temperature,
336 }, 334 },
337 .manage_ibss_station = iwlagn_manage_ibss_station,
338 .update_bcast_stations = iwl_update_bcast_stations,
339 .debugfs_ops = { 335 .debugfs_ops = {
340 .rx_stats_read = iwl_ucode_rx_stats_read, 336 .rx_stats_read = iwl_ucode_rx_stats_read,
341 .tx_stats_read = iwl_ucode_tx_stats_read, 337 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -399,14 +395,16 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
399 .query_addr = iwlagn_eeprom_query_addr, 395 .query_addr = iwlagn_eeprom_query_addr,
400 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, 396 .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
401 }, 397 },
402 .post_associate = iwl_post_associate, 398 .isr_ops = {
403 .isr = iwl_isr_ict, 399 .isr = iwl_isr_ict,
404 .config_ap = iwl_config_ap, 400 .free = iwl_free_isr_ict,
401 .alloc = iwl_alloc_isr_ict,
402 .reset = iwl_reset_ict,
403 .disable = iwl_disable_ict,
404 },
405 .temp_ops = { 405 .temp_ops = {
406 .temperature = iwlagn_temperature, 406 .temperature = iwlagn_temperature,
407 }, 407 },
408 .manage_ibss_station = iwlagn_manage_ibss_station,
409 .update_bcast_stations = iwl_update_bcast_stations,
410 .debugfs_ops = { 408 .debugfs_ops = {
411 .rx_stats_read = iwl_ucode_rx_stats_read, 409 .rx_stats_read = iwl_ucode_rx_stats_read,
412 .tx_stats_read = iwl_ucode_tx_stats_read, 410 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -439,6 +437,7 @@ static const struct iwl_ops iwl6000_ops = {
439 .hcmd = &iwlagn_hcmd, 437 .hcmd = &iwlagn_hcmd,
440 .utils = &iwlagn_hcmd_utils, 438 .utils = &iwlagn_hcmd_utils,
441 .led = &iwlagn_led_ops, 439 .led = &iwlagn_led_ops,
440 .ieee80211_ops = &iwlagn_hw_ops,
442}; 441};
443 442
444static const struct iwl_ops iwl6050_ops = { 443static const struct iwl_ops iwl6050_ops = {
@@ -447,6 +446,7 @@ static const struct iwl_ops iwl6050_ops = {
447 .utils = &iwlagn_hcmd_utils, 446 .utils = &iwlagn_hcmd_utils,
448 .led = &iwlagn_led_ops, 447 .led = &iwlagn_led_ops,
449 .nic = &iwl6050_nic_ops, 448 .nic = &iwl6050_nic_ops,
449 .ieee80211_ops = &iwlagn_hw_ops,
450}; 450};
451 451
452static const struct iwl_ops iwl6050g2_ops = { 452static const struct iwl_ops iwl6050g2_ops = {
@@ -455,6 +455,7 @@ static const struct iwl_ops iwl6050g2_ops = {
455 .utils = &iwlagn_hcmd_utils, 455 .utils = &iwlagn_hcmd_utils,
456 .led = &iwlagn_led_ops, 456 .led = &iwlagn_led_ops,
457 .nic = &iwl6050g2_nic_ops, 457 .nic = &iwl6050g2_nic_ops,
458 .ieee80211_ops = &iwlagn_hw_ops,
458}; 459};
459 460
460static const struct iwl_ops iwl6000g2b_ops = { 461static const struct iwl_ops iwl6000g2b_ops = {
@@ -462,6 +463,7 @@ static const struct iwl_ops iwl6000g2b_ops = {
462 .hcmd = &iwlagn_bt_hcmd, 463 .hcmd = &iwlagn_bt_hcmd,
463 .utils = &iwlagn_hcmd_utils, 464 .utils = &iwlagn_hcmd_utils,
464 .led = &iwlagn_led_ops, 465 .led = &iwlagn_led_ops,
466 .ieee80211_ops = &iwlagn_hw_ops,
465}; 467};
466 468
467static struct iwl_base_params iwl6000_base_params = { 469static struct iwl_base_params iwl6000_base_params = {
@@ -485,6 +487,7 @@ static struct iwl_base_params iwl6000_base_params = {
485 .ucode_tracing = true, 487 .ucode_tracing = true,
486 .sensitivity_calib_by_driver = true, 488 .sensitivity_calib_by_driver = true,
487 .chain_noise_calib_by_driver = true, 489 .chain_noise_calib_by_driver = true,
490 .shadow_reg_enable = true,
488}; 491};
489 492
490static struct iwl_base_params iwl6050_base_params = { 493static struct iwl_base_params iwl6050_base_params = {
@@ -508,6 +511,7 @@ static struct iwl_base_params iwl6050_base_params = {
508 .ucode_tracing = true, 511 .ucode_tracing = true,
509 .sensitivity_calib_by_driver = true, 512 .sensitivity_calib_by_driver = true,
510 .chain_noise_calib_by_driver = true, 513 .chain_noise_calib_by_driver = true,
514 .shadow_reg_enable = true,
511}; 515};
512static struct iwl_base_params iwl6000_coex_base_params = { 516static struct iwl_base_params iwl6000_coex_base_params = {
513 .eeprom_size = OTP_LOW_IMAGE_SIZE, 517 .eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -530,6 +534,7 @@ static struct iwl_base_params iwl6000_coex_base_params = {
530 .ucode_tracing = true, 534 .ucode_tracing = true,
531 .sensitivity_calib_by_driver = true, 535 .sensitivity_calib_by_driver = true,
532 .chain_noise_calib_by_driver = true, 536 .chain_noise_calib_by_driver = true,
537 .shadow_reg_enable = true,
533}; 538};
534 539
535static struct iwl_ht_params iwl6000_ht_params = { 540static struct iwl_ht_params iwl6000_ht_params = {
@@ -842,8 +847,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
842struct iwl_cfg iwl130_bgn_cfg = { 847struct iwl_cfg iwl130_bgn_cfg = {
843 .name = "Intel(R) 130 Series 1x1 BGN", 848 .name = "Intel(R) 130 Series 1x1 BGN",
844 .fw_name_pre = IWL6000G2B_FW_PRE, 849 .fw_name_pre = IWL6000G2B_FW_PRE,
845 .ucode_api_max = IWL130_UCODE_API_MAX, 850 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
846 .ucode_api_min = IWL130_UCODE_API_MIN, 851 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
847 .sku = IWL_SKU_G|IWL_SKU_N, 852 .sku = IWL_SKU_G|IWL_SKU_N,
848 .valid_tx_ant = ANT_A, 853 .valid_tx_ant = ANT_A,
849 .valid_rx_ant = ANT_A, 854 .valid_rx_ant = ANT_A,
@@ -862,8 +867,8 @@ struct iwl_cfg iwl130_bgn_cfg = {
862struct iwl_cfg iwl130_bg_cfg = { 867struct iwl_cfg iwl130_bg_cfg = {
863 .name = "Intel(R) 130 Series 1x2 BG", 868 .name = "Intel(R) 130 Series 1x2 BG",
864 .fw_name_pre = IWL6000G2B_FW_PRE, 869 .fw_name_pre = IWL6000G2B_FW_PRE,
865 .ucode_api_max = IWL130_UCODE_API_MAX, 870 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
866 .ucode_api_min = IWL130_UCODE_API_MIN, 871 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
867 .sku = IWL_SKU_G, 872 .sku = IWL_SKU_G,
868 .valid_tx_ant = ANT_A, 873 .valid_tx_ant = ANT_A,
869 .valid_rx_ant = ANT_A, 874 .valid_rx_ant = ANT_A,
@@ -882,4 +887,3 @@ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
882MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 887MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
883MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 888MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
884MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 889MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
885MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index e2019e756936..d16bb5ede014 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -732,8 +732,122 @@ static inline u8 find_first_chain(u8 mask)
732 return CHAIN_C; 732 return CHAIN_C;
733} 733}
734 734
735/**
736 * Run disconnected antenna algorithm to find out which antennas are
737 * disconnected.
738 */
739static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
740 struct iwl_chain_noise_data *data)
741{
742 u32 active_chains = 0;
743 u32 max_average_sig;
744 u16 max_average_sig_antenna_i;
745 u8 num_tx_chains;
746 u8 first_chain;
747 u16 i = 0;
748
749 average_sig[0] = data->chain_signal_a /
750 priv->cfg->base_params->chain_noise_num_beacons;
751 average_sig[1] = data->chain_signal_b /
752 priv->cfg->base_params->chain_noise_num_beacons;
753 average_sig[2] = data->chain_signal_c /
754 priv->cfg->base_params->chain_noise_num_beacons;
755
756 if (average_sig[0] >= average_sig[1]) {
757 max_average_sig = average_sig[0];
758 max_average_sig_antenna_i = 0;
759 active_chains = (1 << max_average_sig_antenna_i);
760 } else {
761 max_average_sig = average_sig[1];
762 max_average_sig_antenna_i = 1;
763 active_chains = (1 << max_average_sig_antenna_i);
764 }
765
766 if (average_sig[2] >= max_average_sig) {
767 max_average_sig = average_sig[2];
768 max_average_sig_antenna_i = 2;
769 active_chains = (1 << max_average_sig_antenna_i);
770 }
771
772 IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
773 average_sig[0], average_sig[1], average_sig[2]);
774 IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
775 max_average_sig, max_average_sig_antenna_i);
776
777 /* Compare signal strengths for all 3 receivers. */
778 for (i = 0; i < NUM_RX_CHAINS; i++) {
779 if (i != max_average_sig_antenna_i) {
780 s32 rssi_delta = (max_average_sig - average_sig[i]);
781
782 /* If signal is very weak, compared with
783 * strongest, mark it as disconnected. */
784 if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
785 data->disconn_array[i] = 1;
786 else
787 active_chains |= (1 << i);
788 IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
789 "disconn_array[i] = %d\n",
790 i, rssi_delta, data->disconn_array[i]);
791 }
792 }
793
794 /*
795 * The above algorithm sometimes fails when the ucode
796 * reports 0 for all chains. It's not clear why that
797 * happens to start with, but it is then causing trouble
798 * because this can make us enable more chains than the
799 * hardware really has.
800 *
801 * To be safe, simply mask out any chains that we know
802 * are not on the device.
803 */
804 active_chains &= priv->hw_params.valid_rx_ant;
805
806 num_tx_chains = 0;
807 for (i = 0; i < NUM_RX_CHAINS; i++) {
808 /* loops on all the bits of
809 * priv->hw_setting.valid_tx_ant */
810 u8 ant_msk = (1 << i);
811 if (!(priv->hw_params.valid_tx_ant & ant_msk))
812 continue;
813
814 num_tx_chains++;
815 if (data->disconn_array[i] == 0)
816 /* there is a Tx antenna connected */
817 break;
818 if (num_tx_chains == priv->hw_params.tx_chains_num &&
819 data->disconn_array[i]) {
820 /*
821 * If all chains are disconnected
822 * connect the first valid tx chain
823 */
824 first_chain =
825 find_first_chain(priv->cfg->valid_tx_ant);
826 data->disconn_array[first_chain] = 0;
827 active_chains |= BIT(first_chain);
828 IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \
829 W/A - declare %d as connected\n",
830 first_chain);
831 break;
832 }
833 }
834
835 if (active_chains != priv->hw_params.valid_rx_ant &&
836 active_chains != priv->chain_noise_data.active_chains)
837 IWL_DEBUG_CALIB(priv,
838 "Detected that not all antennas are connected! "
839 "Connected: %#x, valid: %#x.\n",
840 active_chains, priv->hw_params.valid_rx_ant);
841
842 /* Save for use within RXON, TX, SCAN commands, etc. */
843 data->active_chains = active_chains;
844 IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
845 active_chains);
846}
847
848
735/* 849/*
736 * Accumulate 20 beacons of signal and noise statistics for each of 850 * Accumulate 16 beacons of signal and noise statistics for each of
737 * 3 receivers/antennas/rx-chains, then figure out: 851 * 3 receivers/antennas/rx-chains, then figure out:
738 * 1) Which antennas are connected. 852 * 1) Which antennas are connected.
739 * 2) Differential rx gain settings to balance the 3 receivers. 853 * 2) Differential rx gain settings to balance the 3 receivers.
@@ -750,8 +864,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
750 u32 chain_sig_c; 864 u32 chain_sig_c;
751 u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE}; 865 u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
752 u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE}; 866 u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
753 u32 max_average_sig;
754 u16 max_average_sig_antenna_i;
755 u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE; 867 u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE;
756 u16 min_average_noise_antenna_i = INITIALIZATION_VALUE; 868 u16 min_average_noise_antenna_i = INITIALIZATION_VALUE;
757 u16 i = 0; 869 u16 i = 0;
@@ -759,11 +871,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
759 u16 stat_chnum = INITIALIZATION_VALUE; 871 u16 stat_chnum = INITIALIZATION_VALUE;
760 u8 rxon_band24; 872 u8 rxon_band24;
761 u8 stat_band24; 873 u8 stat_band24;
762 u32 active_chains = 0;
763 u8 num_tx_chains;
764 unsigned long flags; 874 unsigned long flags;
765 struct statistics_rx_non_phy *rx_info; 875 struct statistics_rx_non_phy *rx_info;
766 u8 first_chain; 876
767 /* 877 /*
768 * MULTI-FIXME: 878 * MULTI-FIXME:
769 * When we support multiple interfaces on different channels, 879 * When we support multiple interfaces on different channels,
@@ -869,108 +979,16 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
869 return; 979 return;
870 980
871 /* Analyze signal for disconnected antenna */ 981 /* Analyze signal for disconnected antenna */
872 average_sig[0] = data->chain_signal_a /
873 priv->cfg->base_params->chain_noise_num_beacons;
874 average_sig[1] = data->chain_signal_b /
875 priv->cfg->base_params->chain_noise_num_beacons;
876 average_sig[2] = data->chain_signal_c /
877 priv->cfg->base_params->chain_noise_num_beacons;
878
879 if (average_sig[0] >= average_sig[1]) {
880 max_average_sig = average_sig[0];
881 max_average_sig_antenna_i = 0;
882 active_chains = (1 << max_average_sig_antenna_i);
883 } else {
884 max_average_sig = average_sig[1];
885 max_average_sig_antenna_i = 1;
886 active_chains = (1 << max_average_sig_antenna_i);
887 }
888
889 if (average_sig[2] >= max_average_sig) {
890 max_average_sig = average_sig[2];
891 max_average_sig_antenna_i = 2;
892 active_chains = (1 << max_average_sig_antenna_i);
893 }
894
895 IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
896 average_sig[0], average_sig[1], average_sig[2]);
897 IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
898 max_average_sig, max_average_sig_antenna_i);
899
900 /* Compare signal strengths for all 3 receivers. */
901 for (i = 0; i < NUM_RX_CHAINS; i++) {
902 if (i != max_average_sig_antenna_i) {
903 s32 rssi_delta = (max_average_sig - average_sig[i]);
904
905 /* If signal is very weak, compared with
906 * strongest, mark it as disconnected. */
907 if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
908 data->disconn_array[i] = 1;
909 else
910 active_chains |= (1 << i);
911 IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
912 "disconn_array[i] = %d\n",
913 i, rssi_delta, data->disconn_array[i]);
914 }
915 }
916
917 /*
918 * The above algorithm sometimes fails when the ucode
919 * reports 0 for all chains. It's not clear why that
920 * happens to start with, but it is then causing trouble
921 * because this can make us enable more chains than the
922 * hardware really has.
923 *
924 * To be safe, simply mask out any chains that we know
925 * are not on the device.
926 */
927 if (priv->cfg->bt_params && 982 if (priv->cfg->bt_params &&
928 priv->cfg->bt_params->advanced_bt_coexist && 983 priv->cfg->bt_params->advanced_bt_coexist) {
929 priv->bt_full_concurrent) { 984 /* Disable disconnected antenna algorithm for advanced
930 /* operated as 1x1 in full concurrency mode */ 985 bt coex, assuming valid antennas are connected */
931 active_chains &= first_antenna(priv->hw_params.valid_rx_ant); 986 data->active_chains = priv->hw_params.valid_rx_ant;
987 for (i = 0; i < NUM_RX_CHAINS; i++)
988 if (!(data->active_chains & (1<<i)))
989 data->disconn_array[i] = 1;
932 } else 990 } else
933 active_chains &= priv->hw_params.valid_rx_ant; 991 iwl_find_disconn_antenna(priv, average_sig, data);
934
935 num_tx_chains = 0;
936 for (i = 0; i < NUM_RX_CHAINS; i++) {
937 /* loops on all the bits of
938 * priv->hw_setting.valid_tx_ant */
939 u8 ant_msk = (1 << i);
940 if (!(priv->hw_params.valid_tx_ant & ant_msk))
941 continue;
942
943 num_tx_chains++;
944 if (data->disconn_array[i] == 0)
945 /* there is a Tx antenna connected */
946 break;
947 if (num_tx_chains == priv->hw_params.tx_chains_num &&
948 data->disconn_array[i]) {
949 /*
950 * If all chains are disconnected
951 * connect the first valid tx chain
952 */
953 first_chain =
954 find_first_chain(priv->cfg->valid_tx_ant);
955 data->disconn_array[first_chain] = 0;
956 active_chains |= BIT(first_chain);
957 IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - declare %d as connected\n",
958 first_chain);
959 break;
960 }
961 }
962
963 if (active_chains != priv->hw_params.valid_rx_ant &&
964 active_chains != priv->chain_noise_data.active_chains)
965 IWL_DEBUG_CALIB(priv,
966 "Detected that not all antennas are connected! "
967 "Connected: %#x, valid: %#x.\n",
968 active_chains, priv->hw_params.valid_rx_ant);
969
970 /* Save for use within RXON, TX, SCAN commands, etc. */
971 priv->chain_noise_data.active_chains = active_chains;
972 IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
973 active_chains);
974 992
975 /* Analyze noise for rx balance */ 993 /* Analyze noise for rx balance */
976 average_noise[0] = data->chain_noise_a / 994 average_noise[0] = data->chain_noise_a /
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index b555edd53354..ca3530c4295a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -496,6 +496,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
496 struct iwlagn_tx_power_dbm_cmd tx_power_cmd; 496 struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
497 u8 tx_ant_cfg_cmd; 497 u8 tx_ant_cfg_cmd;
498 498
499 if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
500 "TX Power requested while scanning!\n"))
501 return -EAGAIN;
502
499 /* half dBm need to multiply */ 503 /* half dBm need to multiply */
500 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); 504 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
501 505
@@ -522,9 +526,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
522 else 526 else
523 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; 527 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
524 528
525 return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd, 529 return iwl_send_cmd_pdu(priv, tx_ant_cfg_cmd, sizeof(tx_power_cmd),
526 sizeof(tx_power_cmd), &tx_power_cmd, 530 &tx_power_cmd);
527 NULL);
528} 531}
529 532
530void iwlagn_temperature(struct iwl_priv *priv) 533void iwlagn_temperature(struct iwl_priv *priv)
@@ -750,6 +753,12 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
750 } else 753 } else
751 iwlagn_txq_ctx_reset(priv); 754 iwlagn_txq_ctx_reset(priv);
752 755
756 if (priv->cfg->base_params->shadow_reg_enable) {
757 /* enable shadow regs in HW */
758 iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL,
759 0x800FFFFF);
760 }
761
753 set_bit(STATUS_INIT, &priv->status); 762 set_bit(STATUS_INIT, &priv->status);
754 763
755 return 0; 764 return 0;
@@ -1584,22 +1593,6 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1584 return ret; 1593 return ret;
1585} 1594}
1586 1595
1587void iwlagn_post_scan(struct iwl_priv *priv)
1588{
1589 struct iwl_rxon_context *ctx;
1590
1591 /*
1592 * Since setting the RXON may have been deferred while
1593 * performing the scan, fire one off if needed
1594 */
1595 for_each_context(priv, ctx)
1596 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
1597 iwlagn_commit_rxon(priv, ctx);
1598
1599 if (priv->cfg->ops->hcmd->set_pan_params)
1600 priv->cfg->ops->hcmd->set_pan_params(priv);
1601}
1602
1603int iwlagn_manage_ibss_station(struct iwl_priv *priv, 1596int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1604 struct ieee80211_vif *vif, bool add) 1597 struct ieee80211_vif *vif, bool add)
1605{ 1598{
@@ -1884,12 +1877,20 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
1884 struct iwl_rxon_context *ctx; 1877 struct iwl_rxon_context *ctx;
1885 int smps_request = -1; 1878 int smps_request = -1;
1886 1879
1880 /*
1881 * Note: bt_traffic_load can be overridden by scan complete and
1882 * coex profile notifications. Ignore that since only bad consequence
1883 * can be not matching debug print with actual state.
1884 */
1887 IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", 1885 IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
1888 priv->bt_traffic_load); 1886 priv->bt_traffic_load);
1889 1887
1890 switch (priv->bt_traffic_load) { 1888 switch (priv->bt_traffic_load) {
1891 case IWL_BT_COEX_TRAFFIC_LOAD_NONE: 1889 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1892 smps_request = IEEE80211_SMPS_AUTOMATIC; 1890 if (priv->bt_status)
1891 smps_request = IEEE80211_SMPS_DYNAMIC;
1892 else
1893 smps_request = IEEE80211_SMPS_AUTOMATIC;
1893 break; 1894 break;
1894 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 1895 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1895 smps_request = IEEE80211_SMPS_DYNAMIC; 1896 smps_request = IEEE80211_SMPS_DYNAMIC;
@@ -1906,6 +1907,16 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
1906 1907
1907 mutex_lock(&priv->mutex); 1908 mutex_lock(&priv->mutex);
1908 1909
1910 /*
1911 * We can not send command to firmware while scanning. When the scan
1912 * complete we will schedule this work again. We do check with mutex
1913 * locked to prevent new scan request to arrive. We do not check
1914 * STATUS_SCANNING to avoid race when queue_work two times from
1915 * different notifications, but quit and not perform any work at all.
1916 */
1917 if (test_bit(STATUS_SCAN_HW, &priv->status))
1918 goto out;
1919
1909 if (priv->cfg->ops->lib->update_chain_flags) 1920 if (priv->cfg->ops->lib->update_chain_flags)
1910 priv->cfg->ops->lib->update_chain_flags(priv); 1921 priv->cfg->ops->lib->update_chain_flags(priv);
1911 1922
@@ -1915,7 +1926,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
1915 ieee80211_request_smps(ctx->vif, smps_request); 1926 ieee80211_request_smps(ctx->vif, smps_request);
1916 } 1927 }
1917 } 1928 }
1918 1929out:
1919 mutex_unlock(&priv->mutex); 1930 mutex_unlock(&priv->mutex);
1920} 1931}
1921 1932
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
new file mode 100644
index 000000000000..2d927a94074d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -0,0 +1,619 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include "iwl-dev.h"
28#include "iwl-agn.h"
29#include "iwl-sta.h"
30#include "iwl-core.h"
31#include "iwl-agn-calib.h"
32
33static int iwlagn_disable_bss(struct iwl_priv *priv,
34 struct iwl_rxon_context *ctx,
35 struct iwl_rxon_cmd *send)
36{
37 __le32 old_filter = send->filter_flags;
38 int ret;
39
40 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
41 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
42
43 send->filter_flags = old_filter;
44
45 if (ret)
46 IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret);
47
48 return ret;
49}
50
51static int iwlagn_disable_pan(struct iwl_priv *priv,
52 struct iwl_rxon_context *ctx,
53 struct iwl_rxon_cmd *send)
54{
55 __le32 old_filter = send->filter_flags;
56 u8 old_dev_type = send->dev_type;
57 int ret;
58
59 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
60 send->dev_type = RXON_DEV_TYPE_P2P;
61 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
62
63 send->filter_flags = old_filter;
64 send->dev_type = old_dev_type;
65
66 if (ret)
67 IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
68
69 /* FIXME: WAIT FOR PAN DISABLE */
70 msleep(300);
71
72 return ret;
73}
74
75static int iwlagn_update_beacon(struct iwl_priv *priv,
76 struct ieee80211_vif *vif)
77{
78 lockdep_assert_held(&priv->mutex);
79
80 dev_kfree_skb(priv->beacon_skb);
81 priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
82 if (!priv->beacon_skb)
83 return -ENOMEM;
84 return iwlagn_send_beacon_cmd(priv);
85}
86
87/**
88 * iwlagn_commit_rxon - commit staging_rxon to hardware
89 *
90 * The RXON command in staging_rxon is committed to the hardware and
91 * the active_rxon structure is updated with the new data. This
92 * function correctly transitions out of the RXON_ASSOC_MSK state if
93 * a HW tune is required based on the RXON structure changes.
94 */
95int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
96{
97 /* cast away the const for active_rxon in this function */
98 struct iwl_rxon_cmd *active = (void *)&ctx->active;
99 bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
100 int ret;
101
102 lockdep_assert_held(&priv->mutex);
103
104 if (!iwl_is_alive(priv))
105 return -EBUSY;
106
107 /* This function hardcodes a bunch of dual-mode assumptions */
108 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
109
110 if (!ctx->is_active)
111 return 0;
112
113 /* always get timestamp with Rx frame */
114 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
115
116 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
117 !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
118 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
119 else
120 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
121
122 ret = iwl_check_rxon_cmd(priv, ctx);
123 if (ret) {
124 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
125 return -EINVAL;
126 }
127
128 /*
129 * receive commit_rxon request
130 * abort any previous channel switch if still in process
131 */
132 if (priv->switch_rxon.switch_in_progress &&
133 (priv->switch_rxon.channel != ctx->staging.channel)) {
134 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
135 le16_to_cpu(priv->switch_rxon.channel));
136 iwl_chswitch_done(priv, false);
137 }
138
139 /*
140 * If we don't need to send a full RXON, we can use
141 * iwl_rxon_assoc_cmd which is used to reconfigure filter
142 * and other flags for the current radio configuration.
143 */
144 if (!iwl_full_rxon_required(priv, ctx)) {
145 ret = iwl_send_rxon_assoc(priv, ctx);
146 if (ret) {
147 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
148 return ret;
149 }
150
151 memcpy(active, &ctx->staging, sizeof(*active));
152 iwl_print_rx_config_cmd(priv, ctx);
153 return 0;
154 }
155
156 if (priv->cfg->ops->hcmd->set_pan_params) {
157 ret = priv->cfg->ops->hcmd->set_pan_params(priv);
158 if (ret)
159 return ret;
160 }
161
162 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
163
164 IWL_DEBUG_INFO(priv,
165 "Going to commit RXON\n"
166 " * with%s RXON_FILTER_ASSOC_MSK\n"
167 " * channel = %d\n"
168 " * bssid = %pM\n",
169 (new_assoc ? "" : "out"),
170 le16_to_cpu(ctx->staging.channel),
171 ctx->staging.bssid_addr);
172
173 /*
174 * Always clear associated first, but with the correct config.
175 * This is required as for example station addition for the
176 * AP station must be done after the BSSID is set to correctly
177 * set up filters in the device.
178 */
179 if (ctx->ctxid == IWL_RXON_CTX_BSS)
180 ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
181 else
182 ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
183 if (ret)
184 return ret;
185
186 memcpy(active, &ctx->staging, sizeof(*active));
187
188 /*
189 * Un-assoc RXON clears the station table and WEP
190 * keys, so we have to restore those afterwards.
191 */
192 iwl_clear_ucode_stations(priv, ctx);
193 iwl_restore_stations(priv, ctx);
194 ret = iwl_restore_default_wep_keys(priv, ctx);
195 if (ret) {
196 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
197 return ret;
198 }
199
200 /* RXON timing must be before associated RXON */
201 ret = iwl_send_rxon_timing(priv, ctx);
202 if (ret) {
203 IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
204 return ret;
205 }
206
207 if (new_assoc) {
208 /*
209 * We'll run into this code path when beaconing is
210 * enabled, but then we also need to send the beacon
211 * to the device.
212 */
213 if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
214 ret = iwlagn_update_beacon(priv, ctx->vif);
215 if (ret) {
216 IWL_ERR(priv,
217 "Error sending required beacon (%d)!\n",
218 ret);
219 return ret;
220 }
221 }
222
223 priv->start_calib = 0;
224 /*
225 * Apply the new configuration.
226 *
227 * Associated RXON doesn't clear the station table in uCode,
228 * so we don't need to restore stations etc. after this.
229 */
230 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
231 sizeof(struct iwl_rxon_cmd), &ctx->staging);
232 if (ret) {
233 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
234 return ret;
235 }
236 memcpy(active, &ctx->staging, sizeof(*active));
237
238 /* IBSS beacon needs to be sent after setting assoc */
239 if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
240 if (iwlagn_update_beacon(priv, ctx->vif))
241 IWL_ERR(priv, "Error sending IBSS beacon\n");
242 }
243
244 iwl_print_rx_config_cmd(priv, ctx);
245
246 iwl_init_sensitivity(priv);
247
248 /*
249 * If we issue a new RXON command which required a tune then we must
250 * send a new TXPOWER command or we won't be able to Tx any frames.
251 *
252 * FIXME: which RXON requires a tune? Can we optimise this out in
253 * some cases?
254 */
255 ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
256 if (ret) {
257 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
258 return ret;
259 }
260
261 return 0;
262}
263
264static void iwlagn_update_qos(struct iwl_priv *priv,
265 struct iwl_rxon_context *ctx)
266{
267 int ret;
268
269 if (!ctx->is_active)
270 return;
271
272 ctx->qos_data.def_qos_parm.qos_flags = 0;
273
274 if (ctx->qos_data.qos_active)
275 ctx->qos_data.def_qos_parm.qos_flags |=
276 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
277
278 if (ctx->ht.enabled)
279 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
280
281 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
282 ctx->qos_data.qos_active,
283 ctx->qos_data.def_qos_parm.qos_flags);
284
285 ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
286 sizeof(struct iwl_qosparam_cmd),
287 &ctx->qos_data.def_qos_parm);
288 if (ret)
289 IWL_ERR(priv, "Failed to update QoS\n");
290}
291
292int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
293{
294 struct iwl_priv *priv = hw->priv;
295 struct iwl_rxon_context *ctx;
296 struct ieee80211_conf *conf = &hw->conf;
297 struct ieee80211_channel *channel = conf->channel;
298 const struct iwl_channel_info *ch_info;
299 int ret = 0;
300 bool ht_changed[NUM_IWL_RXON_CTX] = {};
301
302 IWL_DEBUG_MAC80211(priv, "changed %#x", changed);
303
304 mutex_lock(&priv->mutex);
305
306 if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
307 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
308 goto out;
309 }
310
311 if (!iwl_is_ready(priv)) {
312 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
313 goto out;
314 }
315
316 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
317 IEEE80211_CONF_CHANGE_CHANNEL)) {
318 /* mac80211 uses static for non-HT which is what we want */
319 priv->current_ht_config.smps = conf->smps_mode;
320
321 /*
322 * Recalculate chain counts.
323 *
324 * If monitor mode is enabled then mac80211 will
325 * set up the SM PS mode to OFF if an HT channel is
326 * configured.
327 */
328 if (priv->cfg->ops->hcmd->set_rxon_chain)
329 for_each_context(priv, ctx)
330 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
331 }
332
333 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
334 unsigned long flags;
335
336 ch_info = iwl_get_channel_info(priv, channel->band,
337 channel->hw_value);
338 if (!is_channel_valid(ch_info)) {
339 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
340 ret = -EINVAL;
341 goto out;
342 }
343
344 spin_lock_irqsave(&priv->lock, flags);
345
346 for_each_context(priv, ctx) {
347 /* Configure HT40 channels */
348 if (ctx->ht.enabled != conf_is_ht(conf)) {
349 ctx->ht.enabled = conf_is_ht(conf);
350 ht_changed[ctx->ctxid] = true;
351 }
352
353 if (ctx->ht.enabled) {
354 if (conf_is_ht40_minus(conf)) {
355 ctx->ht.extension_chan_offset =
356 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
357 ctx->ht.is_40mhz = true;
358 } else if (conf_is_ht40_plus(conf)) {
359 ctx->ht.extension_chan_offset =
360 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
361 ctx->ht.is_40mhz = true;
362 } else {
363 ctx->ht.extension_chan_offset =
364 IEEE80211_HT_PARAM_CHA_SEC_NONE;
365 ctx->ht.is_40mhz = false;
366 }
367 } else
368 ctx->ht.is_40mhz = false;
369
370 /*
371 * Default to no protection. Protection mode will
372 * later be set from BSS config in iwl_ht_conf
373 */
374 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
375
376 /* if we are switching from ht to 2.4 clear flags
377 * from any ht related info since 2.4 does not
378 * support ht */
379 if (le16_to_cpu(ctx->staging.channel) !=
380 channel->hw_value)
381 ctx->staging.flags = 0;
382
383 iwl_set_rxon_channel(priv, channel, ctx);
384 iwl_set_rxon_ht(priv, &priv->current_ht_config);
385
386 iwl_set_flags_for_band(priv, ctx, channel->band,
387 ctx->vif);
388 }
389
390 spin_unlock_irqrestore(&priv->lock, flags);
391
392 iwl_update_bcast_stations(priv);
393
394 /*
395 * The list of supported rates and rate mask can be different
396 * for each band; since the band may have changed, reset
397 * the rate mask to what mac80211 lists.
398 */
399 iwl_set_rate(priv);
400 }
401
402 if (changed & (IEEE80211_CONF_CHANGE_PS |
403 IEEE80211_CONF_CHANGE_IDLE)) {
404 ret = iwl_power_update_mode(priv, false);
405 if (ret)
406 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
407 }
408
409 if (changed & IEEE80211_CONF_CHANGE_POWER) {
410 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
411 priv->tx_power_user_lmt, conf->power_level);
412
413 iwl_set_tx_power(priv, conf->power_level, false);
414 }
415
416 for_each_context(priv, ctx) {
417 if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
418 continue;
419 iwlagn_commit_rxon(priv, ctx);
420 if (ht_changed[ctx->ctxid])
421 iwlagn_update_qos(priv, ctx);
422 }
423 out:
424 mutex_unlock(&priv->mutex);
425 return ret;
426}
427
428static void iwlagn_check_needed_chains(struct iwl_priv *priv,
429 struct iwl_rxon_context *ctx,
430 struct ieee80211_bss_conf *bss_conf)
431{
432 struct ieee80211_vif *vif = ctx->vif;
433 struct iwl_rxon_context *tmp;
434 struct ieee80211_sta *sta;
435 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
436 bool need_multiple;
437
438 lockdep_assert_held(&priv->mutex);
439
440 switch (vif->type) {
441 case NL80211_IFTYPE_STATION:
442 rcu_read_lock();
443 sta = ieee80211_find_sta(vif, bss_conf->bssid);
444 if (sta) {
445 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
446 int maxstreams;
447
448 maxstreams = (ht_cap->mcs.tx_params &
449 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
450 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
451 maxstreams += 1;
452
453 need_multiple = true;
454
455 if ((ht_cap->mcs.rx_mask[1] == 0) &&
456 (ht_cap->mcs.rx_mask[2] == 0))
457 need_multiple = false;
458 if (maxstreams <= 1)
459 need_multiple = false;
460 } else {
461 /*
462 * If at all, this can only happen through a race
463 * when the AP disconnects us while we're still
464 * setting up the connection, in that case mac80211
465 * will soon tell us about that.
466 */
467 need_multiple = false;
468 }
469 rcu_read_unlock();
470 break;
471 case NL80211_IFTYPE_ADHOC:
472 /* currently */
473 need_multiple = false;
474 break;
475 default:
476 /* only AP really */
477 need_multiple = true;
478 break;
479 }
480
481 ctx->ht_need_multiple_chains = need_multiple;
482
483 if (!need_multiple) {
484 /* check all contexts */
485 for_each_context(priv, tmp) {
486 if (!tmp->vif)
487 continue;
488 if (tmp->ht_need_multiple_chains) {
489 need_multiple = true;
490 break;
491 }
492 }
493 }
494
495 ht_conf->single_chain_sufficient = !need_multiple;
496}
497
498void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
499 struct ieee80211_vif *vif,
500 struct ieee80211_bss_conf *bss_conf,
501 u32 changes)
502{
503 struct iwl_priv *priv = hw->priv;
504 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
505 int ret;
506 bool force = false;
507
508 mutex_lock(&priv->mutex);
509
510 if (changes & BSS_CHANGED_BEACON_INT)
511 force = true;
512
513 if (changes & BSS_CHANGED_QOS) {
514 ctx->qos_data.qos_active = bss_conf->qos;
515 iwlagn_update_qos(priv, ctx);
516 }
517
518 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
519 if (vif->bss_conf.use_short_preamble)
520 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
521 else
522 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
523
524 if (changes & BSS_CHANGED_ASSOC) {
525 if (bss_conf->assoc) {
526 iwl_led_associate(priv);
527 priv->timestamp = bss_conf->timestamp;
528 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
529 } else {
530 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
531 iwl_led_disassociate(priv);
532 }
533 }
534
535 if (ctx->ht.enabled) {
536 ctx->ht.protection = bss_conf->ht_operation_mode &
537 IEEE80211_HT_OP_MODE_PROTECTION;
538 ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode &
539 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
540 iwlagn_check_needed_chains(priv, ctx, bss_conf);
541 iwl_set_rxon_ht(priv, &priv->current_ht_config);
542 }
543
544 if (priv->cfg->ops->hcmd->set_rxon_chain)
545 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
546
547 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
548 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
549 else
550 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
551
552 if (bss_conf->use_cts_prot)
553 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
554 else
555 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
556
557 memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
558
559 if (vif->type == NL80211_IFTYPE_AP ||
560 vif->type == NL80211_IFTYPE_ADHOC) {
561 if (vif->bss_conf.enable_beacon) {
562 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
563 priv->beacon_ctx = ctx;
564 } else {
565 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
566 priv->beacon_ctx = NULL;
567 }
568 }
569
570 if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
571 iwlagn_commit_rxon(priv, ctx);
572
573 if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) {
574 /*
575 * The chain noise calibration will enable PM upon
576 * completion. If calibration has already been run
577 * then we need to enable power management here.
578 */
579 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
580 iwl_power_update_mode(priv, false);
581
582 /* Enable RX differential gain and sensitivity calibrations */
583 iwl_chain_noise_reset(priv);
584 priv->start_calib = 1;
585 }
586
587 if (changes & BSS_CHANGED_IBSS) {
588 ret = iwlagn_manage_ibss_station(priv, vif,
589 bss_conf->ibss_joined);
590 if (ret)
591 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
592 bss_conf->ibss_joined ? "add" : "remove",
593 bss_conf->bssid);
594 }
595
596 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC &&
597 priv->beacon_ctx) {
598 if (iwlagn_update_beacon(priv, vif))
599 IWL_ERR(priv, "Error sending IBSS beacon\n");
600 }
601
602 mutex_unlock(&priv->mutex);
603}
604
605void iwlagn_post_scan(struct iwl_priv *priv)
606{
607 struct iwl_rxon_context *ctx;
608
609 /*
610 * Since setting the RXON may have been deferred while
611 * performing the scan, fire one off if needed
612 */
613 for_each_context(priv, ctx)
614 if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
615 iwlagn_commit_rxon(priv, ctx);
616
617 if (priv->cfg->ops->hcmd->set_pan_params)
618 priv->cfg->ops->hcmd->set_pan_params(priv);
619}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 35a30d2e0734..35f085ac336b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -684,7 +684,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
684 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); 684 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
685} 685}
686 686
687void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) 687static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
688{ 688{
689 unsigned long flags; 689 unsigned long flags;
690 690
@@ -714,3 +714,33 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
714 spin_unlock_irqrestore(&priv->sta_lock, flags); 714 spin_unlock_irqrestore(&priv->sta_lock, flags);
715 715
716} 716}
717
718void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
719 struct ieee80211_vif *vif,
720 enum sta_notify_cmd cmd,
721 struct ieee80211_sta *sta)
722{
723 struct iwl_priv *priv = hw->priv;
724 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
725 int sta_id;
726
727 switch (cmd) {
728 case STA_NOTIFY_SLEEP:
729 WARN_ON(!sta_priv->client);
730 sta_priv->asleep = true;
731 if (atomic_read(&sta_priv->pending_frames) > 0)
732 ieee80211_sta_block_awake(hw, sta, true);
733 break;
734 case STA_NOTIFY_AWAKE:
735 WARN_ON(!sta_priv->client);
736 if (!sta_priv->asleep)
737 break;
738 sta_priv->asleep = false;
739 sta_id = iwl_sta_id(sta);
740 if (sta_id != IWL_INVALID_STATION)
741 iwl_sta_modify_ps_wake(priv, sta_id);
742 break;
743 default:
744 break;
745 }
746}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c2636a7ab9ee..007fb20d78ab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -90,170 +90,6 @@ MODULE_ALIAS("iwl4965");
90static int iwlagn_ant_coupling; 90static int iwlagn_ant_coupling;
91static bool iwlagn_bt_ch_announce = 1; 91static bool iwlagn_bt_ch_announce = 1;
92 92
93/**
94 * iwlagn_commit_rxon - commit staging_rxon to hardware
95 *
96 * The RXON command in staging_rxon is committed to the hardware and
97 * the active_rxon structure is updated with the new data. This
98 * function correctly transitions out of the RXON_ASSOC_MSK state if
99 * a HW tune is required based on the RXON structure changes.
100 */
101int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
102{
103 /* cast away the const for active_rxon in this function */
104 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
105 int ret;
106 bool new_assoc =
107 !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
108 bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
109
110 if (!iwl_is_alive(priv))
111 return -EBUSY;
112
113 if (!ctx->is_active)
114 return 0;
115
116 /* always get timestamp with Rx frame */
117 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
118
119 ret = iwl_check_rxon_cmd(priv, ctx);
120 if (ret) {
121 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
122 return -EINVAL;
123 }
124
125 /*
126 * receive commit_rxon request
127 * abort any previous channel switch if still in process
128 */
129 if (priv->switch_rxon.switch_in_progress &&
130 (priv->switch_rxon.channel != ctx->staging.channel)) {
131 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
132 le16_to_cpu(priv->switch_rxon.channel));
133 iwl_chswitch_done(priv, false);
134 }
135
136 /* If we don't need to send a full RXON, we can use
137 * iwl_rxon_assoc_cmd which is used to reconfigure filter
138 * and other flags for the current radio configuration. */
139 if (!iwl_full_rxon_required(priv, ctx)) {
140 ret = iwl_send_rxon_assoc(priv, ctx);
141 if (ret) {
142 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
143 return ret;
144 }
145
146 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
147 iwl_print_rx_config_cmd(priv, ctx);
148 return 0;
149 }
150
151 /* If we are currently associated and the new config requires
152 * an RXON_ASSOC and the new config wants the associated mask enabled,
153 * we must clear the associated from the active configuration
154 * before we apply the new config */
155 if (iwl_is_associated_ctx(ctx) && new_assoc) {
156 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
157 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
158
159 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
160 sizeof(struct iwl_rxon_cmd),
161 active_rxon);
162
163 /* If the mask clearing failed then we set
164 * active_rxon back to what it was previously */
165 if (ret) {
166 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
167 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
168 return ret;
169 }
170 iwl_clear_ucode_stations(priv, ctx);
171 iwl_restore_stations(priv, ctx);
172 ret = iwl_restore_default_wep_keys(priv, ctx);
173 if (ret) {
174 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
175 return ret;
176 }
177 }
178
179 IWL_DEBUG_INFO(priv, "Sending RXON\n"
180 "* with%s RXON_FILTER_ASSOC_MSK\n"
181 "* channel = %d\n"
182 "* bssid = %pM\n",
183 (new_assoc ? "" : "out"),
184 le16_to_cpu(ctx->staging.channel),
185 ctx->staging.bssid_addr);
186
187 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
188
189 if (!old_assoc) {
190 /*
191 * First of all, before setting associated, we need to
192 * send RXON timing so the device knows about the DTIM
193 * period and other timing values
194 */
195 ret = iwl_send_rxon_timing(priv, ctx);
196 if (ret) {
197 IWL_ERR(priv, "Error setting RXON timing!\n");
198 return ret;
199 }
200 }
201
202 if (priv->cfg->ops->hcmd->set_pan_params) {
203 ret = priv->cfg->ops->hcmd->set_pan_params(priv);
204 if (ret)
205 return ret;
206 }
207
208 /* Apply the new configuration
209 * RXON unassoc clears the station table in uCode so restoration of
210 * stations is needed after it (the RXON command) completes
211 */
212 if (!new_assoc) {
213 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
214 sizeof(struct iwl_rxon_cmd), &ctx->staging);
215 if (ret) {
216 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
217 return ret;
218 }
219 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
220 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
221 iwl_clear_ucode_stations(priv, ctx);
222 iwl_restore_stations(priv, ctx);
223 ret = iwl_restore_default_wep_keys(priv, ctx);
224 if (ret) {
225 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
226 return ret;
227 }
228 }
229 if (new_assoc) {
230 priv->start_calib = 0;
231 /* Apply the new configuration
232 * RXON assoc doesn't clear the station table in uCode,
233 */
234 ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
235 sizeof(struct iwl_rxon_cmd), &ctx->staging);
236 if (ret) {
237 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
238 return ret;
239 }
240 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
241 }
242 iwl_print_rx_config_cmd(priv, ctx);
243
244 iwl_init_sensitivity(priv);
245
246 /* If we issue a new RXON command which required a tune then we must
247 * send a new TXPOWER command or we won't be able to Tx any frames */
248 ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
249 if (ret) {
250 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
251 return ret;
252 }
253
254 return 0;
255}
256
257void iwl_update_chain_flags(struct iwl_priv *priv) 93void iwl_update_chain_flags(struct iwl_priv *priv)
258{ 94{
259 struct iwl_rxon_context *ctx; 95 struct iwl_rxon_context *ctx;
@@ -411,7 +247,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
411 247
412 return sizeof(*tx_beacon_cmd) + frame_size; 248 return sizeof(*tx_beacon_cmd) + frame_size;
413} 249}
414static int iwl_send_beacon_cmd(struct iwl_priv *priv) 250
251int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
415{ 252{
416 struct iwl_frame *frame; 253 struct iwl_frame *frame;
417 unsigned int frame_size; 254 unsigned int frame_size;
@@ -661,7 +498,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
661 498
662 priv->beacon_skb = beacon; 499 priv->beacon_skb = beacon;
663 500
664 iwl_send_beacon_cmd(priv); 501 iwlagn_send_beacon_cmd(priv);
665 out: 502 out:
666 mutex_unlock(&priv->mutex); 503 mutex_unlock(&priv->mutex);
667} 504}
@@ -2978,7 +2815,8 @@ static void __iwl_down(struct iwl_priv *priv)
2978 STATUS_EXIT_PENDING; 2815 STATUS_EXIT_PENDING;
2979 2816
2980 /* device going down, Stop using ICT table */ 2817 /* device going down, Stop using ICT table */
2981 iwl_disable_ict(priv); 2818 if (priv->cfg->ops->lib->isr_ops.disable)
2819 priv->cfg->ops->lib->isr_ops.disable(priv);
2982 2820
2983 iwlagn_txq_ctx_stop(priv); 2821 iwlagn_txq_ctx_stop(priv);
2984 iwlagn_rxq_stop(priv); 2822 iwlagn_rxq_stop(priv);
@@ -3201,7 +3039,8 @@ static void iwl_bg_alive_start(struct work_struct *data)
3201 return; 3039 return;
3202 3040
3203 /* enable dram interrupt */ 3041 /* enable dram interrupt */
3204 iwl_reset_ict(priv); 3042 if (priv->cfg->ops->lib->isr_ops.reset)
3043 priv->cfg->ops->lib->isr_ops.reset(priv);
3205 3044
3206 mutex_lock(&priv->mutex); 3045 mutex_lock(&priv->mutex);
3207 iwl_alive_start(priv); 3046 iwl_alive_start(priv);
@@ -3309,92 +3148,6 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
3309 mutex_unlock(&priv->mutex); 3148 mutex_unlock(&priv->mutex);
3310} 3149}
3311 3150
3312#define IWL_DELAY_NEXT_SCAN (HZ*2)
3313
3314void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3315{
3316 struct iwl_rxon_context *ctx;
3317 struct ieee80211_conf *conf = NULL;
3318 int ret = 0;
3319
3320 if (!vif || !priv->is_open)
3321 return;
3322
3323 ctx = iwl_rxon_ctx_from_vif(vif);
3324
3325 if (vif->type == NL80211_IFTYPE_AP) {
3326 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3327 return;
3328 }
3329
3330 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3331 return;
3332
3333 iwl_scan_cancel_timeout(priv, 200);
3334
3335 conf = ieee80211_get_hw_conf(priv->hw);
3336
3337 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3338 iwlcore_commit_rxon(priv, ctx);
3339
3340 ret = iwl_send_rxon_timing(priv, ctx);
3341 if (ret)
3342 IWL_WARN(priv, "RXON timing - "
3343 "Attempting to continue.\n");
3344
3345 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3346
3347 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3348
3349 if (priv->cfg->ops->hcmd->set_rxon_chain)
3350 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3351
3352 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3353
3354 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3355 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3356
3357 if (vif->bss_conf.use_short_preamble)
3358 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3359 else
3360 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3361
3362 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3363 if (vif->bss_conf.use_short_slot)
3364 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3365 else
3366 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3367 }
3368
3369 iwlcore_commit_rxon(priv, ctx);
3370
3371 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3372 vif->bss_conf.aid, ctx->active.bssid_addr);
3373
3374 switch (vif->type) {
3375 case NL80211_IFTYPE_STATION:
3376 break;
3377 case NL80211_IFTYPE_ADHOC:
3378 iwl_send_beacon_cmd(priv);
3379 break;
3380 default:
3381 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3382 __func__, vif->type);
3383 break;
3384 }
3385
3386 /* the chain noise calibration will enabled PM upon completion
3387 * If chain noise has already been run, then we need to enable
3388 * power management here */
3389 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
3390 iwl_power_update_mode(priv, false);
3391
3392 /* Enable Rx differential gain and sensitivity calibrations */
3393 iwl_chain_noise_reset(priv);
3394 priv->start_calib = 1;
3395
3396}
3397
3398/***************************************************************************** 3151/*****************************************************************************
3399 * 3152 *
3400 * mac80211 entry point functions 3153 * mac80211 entry point functions
@@ -3474,7 +3227,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
3474} 3227}
3475 3228
3476 3229
3477static int iwl_mac_start(struct ieee80211_hw *hw) 3230int iwlagn_mac_start(struct ieee80211_hw *hw)
3478{ 3231{
3479 struct iwl_priv *priv = hw->priv; 3232 struct iwl_priv *priv = hw->priv;
3480 int ret; 3233 int ret;
@@ -3515,7 +3268,7 @@ out:
3515 return 0; 3268 return 0;
3516} 3269}
3517 3270
3518static void iwl_mac_stop(struct ieee80211_hw *hw) 3271void iwlagn_mac_stop(struct ieee80211_hw *hw)
3519{ 3272{
3520 struct iwl_priv *priv = hw->priv; 3273 struct iwl_priv *priv = hw->priv;
3521 3274
@@ -3537,7 +3290,7 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
3537 IWL_DEBUG_MAC80211(priv, "leave\n"); 3290 IWL_DEBUG_MAC80211(priv, "leave\n");
3538} 3291}
3539 3292
3540static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 3293int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3541{ 3294{
3542 struct iwl_priv *priv = hw->priv; 3295 struct iwl_priv *priv = hw->priv;
3543 3296
@@ -3553,73 +3306,12 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3553 return NETDEV_TX_OK; 3306 return NETDEV_TX_OK;
3554} 3307}
3555 3308
3556void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3309void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
3557{ 3310 struct ieee80211_vif *vif,
3558 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 3311 struct ieee80211_key_conf *keyconf,
3559 int ret = 0; 3312 struct ieee80211_sta *sta,
3560 3313 u32 iv32, u16 *phase1key)
3561 lockdep_assert_held(&priv->mutex);
3562
3563 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3564 return;
3565
3566 /* The following should be done only at AP bring up */
3567 if (!iwl_is_associated_ctx(ctx)) {
3568
3569 /* RXON - unassoc (to set timing command) */
3570 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3571 iwlcore_commit_rxon(priv, ctx);
3572
3573 /* RXON Timing */
3574 ret = iwl_send_rxon_timing(priv, ctx);
3575 if (ret)
3576 IWL_WARN(priv, "RXON timing failed - "
3577 "Attempting to continue.\n");
3578
3579 /* AP has all antennas */
3580 priv->chain_noise_data.active_chains =
3581 priv->hw_params.valid_rx_ant;
3582 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3583 if (priv->cfg->ops->hcmd->set_rxon_chain)
3584 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3585
3586 ctx->staging.assoc_id = 0;
3587
3588 if (vif->bss_conf.use_short_preamble)
3589 ctx->staging.flags |=
3590 RXON_FLG_SHORT_PREAMBLE_MSK;
3591 else
3592 ctx->staging.flags &=
3593 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3594
3595 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3596 if (vif->bss_conf.use_short_slot)
3597 ctx->staging.flags |=
3598 RXON_FLG_SHORT_SLOT_MSK;
3599 else
3600 ctx->staging.flags &=
3601 ~RXON_FLG_SHORT_SLOT_MSK;
3602 }
3603 /* need to send beacon cmd before committing assoc RXON! */
3604 iwl_send_beacon_cmd(priv);
3605 /* restore RXON assoc */
3606 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3607 iwlcore_commit_rxon(priv, ctx);
3608 }
3609 iwl_send_beacon_cmd(priv);
3610
3611 /* FIXME - we need to add code here to detect a totally new
3612 * configuration, reset the AP, unassoc, rxon timing, assoc,
3613 * clear sta table, add BCAST sta... */
3614}
3615
3616static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
3617 struct ieee80211_vif *vif,
3618 struct ieee80211_key_conf *keyconf,
3619 struct ieee80211_sta *sta,
3620 u32 iv32, u16 *phase1key)
3621{ 3314{
3622
3623 struct iwl_priv *priv = hw->priv; 3315 struct iwl_priv *priv = hw->priv;
3624 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 3316 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
3625 3317
@@ -3631,10 +3323,9 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
3631 IWL_DEBUG_MAC80211(priv, "leave\n"); 3323 IWL_DEBUG_MAC80211(priv, "leave\n");
3632} 3324}
3633 3325
3634static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 3326int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3635 struct ieee80211_vif *vif, 3327 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
3636 struct ieee80211_sta *sta, 3328 struct ieee80211_key_conf *key)
3637 struct ieee80211_key_conf *key)
3638{ 3329{
3639 struct iwl_priv *priv = hw->priv; 3330 struct iwl_priv *priv = hw->priv;
3640 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 3331 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3701,10 +3392,10 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3701 return ret; 3392 return ret;
3702} 3393}
3703 3394
3704static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, 3395int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
3705 struct ieee80211_vif *vif, 3396 struct ieee80211_vif *vif,
3706 enum ieee80211_ampdu_mlme_action action, 3397 enum ieee80211_ampdu_mlme_action action,
3707 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 3398 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3708{ 3399{
3709 struct iwl_priv *priv = hw->priv; 3400 struct iwl_priv *priv = hw->priv;
3710 int ret = -EINVAL; 3401 int ret = -EINVAL;
@@ -3785,39 +3476,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
3785 return ret; 3476 return ret;
3786} 3477}
3787 3478
3788static void iwl_mac_sta_notify(struct ieee80211_hw *hw, 3479int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3789 struct ieee80211_vif *vif, 3480 struct ieee80211_vif *vif,
3790 enum sta_notify_cmd cmd, 3481 struct ieee80211_sta *sta)
3791 struct ieee80211_sta *sta)
3792{
3793 struct iwl_priv *priv = hw->priv;
3794 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
3795 int sta_id;
3796
3797 switch (cmd) {
3798 case STA_NOTIFY_SLEEP:
3799 WARN_ON(!sta_priv->client);
3800 sta_priv->asleep = true;
3801 if (atomic_read(&sta_priv->pending_frames) > 0)
3802 ieee80211_sta_block_awake(hw, sta, true);
3803 break;
3804 case STA_NOTIFY_AWAKE:
3805 WARN_ON(!sta_priv->client);
3806 if (!sta_priv->asleep)
3807 break;
3808 sta_priv->asleep = false;
3809 sta_id = iwl_sta_id(sta);
3810 if (sta_id != IWL_INVALID_STATION)
3811 iwl_sta_modify_ps_wake(priv, sta_id);
3812 break;
3813 default:
3814 break;
3815 }
3816}
3817
3818static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3819 struct ieee80211_vif *vif,
3820 struct ieee80211_sta *sta)
3821{ 3482{
3822 struct iwl_priv *priv = hw->priv; 3483 struct iwl_priv *priv = hw->priv;
3823 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3484 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3858,8 +3519,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3858 return 0; 3519 return 0;
3859} 3520}
3860 3521
3861static void iwl_mac_channel_switch(struct ieee80211_hw *hw, 3522void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3862 struct ieee80211_channel_switch *ch_switch) 3523 struct ieee80211_channel_switch *ch_switch)
3863{ 3524{
3864 struct iwl_priv *priv = hw->priv; 3525 struct iwl_priv *priv = hw->priv;
3865 const struct iwl_channel_info *ch_info; 3526 const struct iwl_channel_info *ch_info;
@@ -3956,10 +3617,10 @@ out_exit:
3956 IWL_DEBUG_MAC80211(priv, "leave\n"); 3617 IWL_DEBUG_MAC80211(priv, "leave\n");
3957} 3618}
3958 3619
3959static void iwlagn_configure_filter(struct ieee80211_hw *hw, 3620void iwlagn_configure_filter(struct ieee80211_hw *hw,
3960 unsigned int changed_flags, 3621 unsigned int changed_flags,
3961 unsigned int *total_flags, 3622 unsigned int *total_flags,
3962 u64 multicast) 3623 u64 multicast)
3963{ 3624{
3964 struct iwl_priv *priv = hw->priv; 3625 struct iwl_priv *priv = hw->priv;
3965 __le32 filter_or = 0, filter_nand = 0; 3626 __le32 filter_or = 0, filter_nand = 0;
@@ -3986,7 +3647,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3986 for_each_context(priv, ctx) { 3647 for_each_context(priv, ctx) {
3987 ctx->staging.filter_flags &= ~filter_nand; 3648 ctx->staging.filter_flags &= ~filter_nand;
3988 ctx->staging.filter_flags |= filter_or; 3649 ctx->staging.filter_flags |= filter_or;
3989 iwlcore_commit_rxon(priv, ctx); 3650
3651 /*
3652 * Not committing directly because hardware can perform a scan,
3653 * but we'll eventually commit the filter flags change anyway.
3654 */
3990 } 3655 }
3991 3656
3992 mutex_unlock(&priv->mutex); 3657 mutex_unlock(&priv->mutex);
@@ -4001,7 +3666,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
4001 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 3666 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
4002} 3667}
4003 3668
4004static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) 3669void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
4005{ 3670{
4006 struct iwl_priv *priv = hw->priv; 3671 struct iwl_priv *priv = hw->priv;
4007 3672
@@ -4179,6 +3844,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
4179 * this value will get overwritten by channel max power avg 3844 * this value will get overwritten by channel max power avg
4180 * from eeprom */ 3845 * from eeprom */
4181 priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN; 3846 priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
3847 priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
4182 3848
4183 ret = iwl_init_channel_map(priv); 3849 ret = iwl_init_channel_map(priv);
4184 if (ret) { 3850 if (ret) {
@@ -4209,28 +3875,30 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
4209 kfree(priv->scan_cmd); 3875 kfree(priv->scan_cmd);
4210} 3876}
4211 3877
4212static struct ieee80211_ops iwl_hw_ops = { 3878#ifdef CONFIG_IWL5000
4213 .tx = iwl_mac_tx, 3879struct ieee80211_ops iwlagn_hw_ops = {
4214 .start = iwl_mac_start, 3880 .tx = iwlagn_mac_tx,
4215 .stop = iwl_mac_stop, 3881 .start = iwlagn_mac_start,
3882 .stop = iwlagn_mac_stop,
4216 .add_interface = iwl_mac_add_interface, 3883 .add_interface = iwl_mac_add_interface,
4217 .remove_interface = iwl_mac_remove_interface, 3884 .remove_interface = iwl_mac_remove_interface,
4218 .config = iwl_mac_config, 3885 .change_interface = iwl_mac_change_interface,
3886 .config = iwlagn_mac_config,
4219 .configure_filter = iwlagn_configure_filter, 3887 .configure_filter = iwlagn_configure_filter,
4220 .set_key = iwl_mac_set_key, 3888 .set_key = iwlagn_mac_set_key,
4221 .update_tkip_key = iwl_mac_update_tkip_key, 3889 .update_tkip_key = iwlagn_mac_update_tkip_key,
4222 .conf_tx = iwl_mac_conf_tx, 3890 .conf_tx = iwl_mac_conf_tx,
4223 .reset_tsf = iwl_mac_reset_tsf, 3891 .bss_info_changed = iwlagn_bss_info_changed,
4224 .bss_info_changed = iwl_bss_info_changed, 3892 .ampdu_action = iwlagn_mac_ampdu_action,
4225 .ampdu_action = iwl_mac_ampdu_action,
4226 .hw_scan = iwl_mac_hw_scan, 3893 .hw_scan = iwl_mac_hw_scan,
4227 .sta_notify = iwl_mac_sta_notify, 3894 .sta_notify = iwlagn_mac_sta_notify,
4228 .sta_add = iwlagn_mac_sta_add, 3895 .sta_add = iwlagn_mac_sta_add,
4229 .sta_remove = iwl_mac_sta_remove, 3896 .sta_remove = iwl_mac_sta_remove,
4230 .channel_switch = iwl_mac_channel_switch, 3897 .channel_switch = iwlagn_mac_channel_switch,
4231 .flush = iwl_mac_flush, 3898 .flush = iwlagn_mac_flush,
4232 .tx_last_beacon = iwl_mac_tx_last_beacon, 3899 .tx_last_beacon = iwl_mac_tx_last_beacon,
4233}; 3900};
3901#endif
4234 3902
4235static void iwl_hw_detect(struct iwl_priv *priv) 3903static void iwl_hw_detect(struct iwl_priv *priv)
4236{ 3904{
@@ -4298,10 +3966,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4298 if (cfg->mod_params->disable_hw_scan) { 3966 if (cfg->mod_params->disable_hw_scan) {
4299 dev_printk(KERN_DEBUG, &(pdev->dev), 3967 dev_printk(KERN_DEBUG, &(pdev->dev),
4300 "sw scan support is deprecated\n"); 3968 "sw scan support is deprecated\n");
4301 iwl_hw_ops.hw_scan = NULL; 3969#ifdef CONFIG_IWL5000
3970 iwlagn_hw_ops.hw_scan = NULL;
3971#endif
3972#ifdef CONFIG_IWL4965
3973 iwl4965_hw_ops.hw_scan = NULL;
3974#endif
4302 } 3975 }
4303 3976
4304 hw = iwl_alloc_all(cfg, &iwl_hw_ops); 3977 hw = iwl_alloc_all(cfg);
4305 if (!hw) { 3978 if (!hw) {
4306 err = -ENOMEM; 3979 err = -ENOMEM;
4307 goto out; 3980 goto out;
@@ -4333,6 +4006,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4333 BIT(NL80211_IFTYPE_ADHOC); 4006 BIT(NL80211_IFTYPE_ADHOC);
4334 priv->contexts[IWL_RXON_CTX_BSS].interface_modes = 4007 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
4335 BIT(NL80211_IFTYPE_STATION); 4008 BIT(NL80211_IFTYPE_STATION);
4009 priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
4336 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; 4010 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
4337 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; 4011 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
4338 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; 4012 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
@@ -4500,8 +4174,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4500 4174
4501 pci_enable_msi(priv->pci_dev); 4175 pci_enable_msi(priv->pci_dev);
4502 4176
4503 iwl_alloc_isr_ict(priv); 4177 if (priv->cfg->ops->lib->isr_ops.alloc)
4504 err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr, 4178 priv->cfg->ops->lib->isr_ops.alloc(priv);
4179
4180 err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
4505 IRQF_SHARED, DRV_NAME, priv); 4181 IRQF_SHARED, DRV_NAME, priv);
4506 if (err) { 4182 if (err) {
4507 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); 4183 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4548,7 +4224,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4548 destroy_workqueue(priv->workqueue); 4224 destroy_workqueue(priv->workqueue);
4549 priv->workqueue = NULL; 4225 priv->workqueue = NULL;
4550 free_irq(priv->pci_dev->irq, priv); 4226 free_irq(priv->pci_dev->irq, priv);
4551 iwl_free_isr_ict(priv); 4227 if (priv->cfg->ops->lib->isr_ops.free)
4228 priv->cfg->ops->lib->isr_ops.free(priv);
4552 out_disable_msi: 4229 out_disable_msi:
4553 pci_disable_msi(priv->pci_dev); 4230 pci_disable_msi(priv->pci_dev);
4554 iwl_uninit_drv(priv); 4231 iwl_uninit_drv(priv);
@@ -4643,7 +4320,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
4643 4320
4644 iwl_uninit_drv(priv); 4321 iwl_uninit_drv(priv);
4645 4322
4646 iwl_free_isr_ict(priv); 4323 if (priv->cfg->ops->lib->isr_ops.free)
4324 priv->cfg->ops->lib->isr_ops.free(priv);
4647 4325
4648 dev_kfree_skb(priv->beacon_skb); 4326 dev_kfree_skb(priv->beacon_skb);
4649 4327
@@ -4735,13 +4413,6 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
4735 {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)}, 4413 {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
4736 4414
4737/* 6x00 Series Gen2a */ 4415/* 6x00 Series Gen2a */
4738 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
4739 {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
4740 {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
4741 {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)},
4742 {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)},
4743 {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)},
4744 {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)},
4745 {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)}, 4416 {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)},
4746 {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)}, 4417 {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)},
4747 {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)}, 4418 {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)},
@@ -4751,24 +4422,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
4751 {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)}, 4422 {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)},
4752 4423
4753/* 6x00 Series Gen2b */ 4424/* 6x00 Series Gen2b */
4754 {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)},
4755 {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)},
4756 {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)},
4757 {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)},
4758 {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)},
4759 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
4760 {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)},
4761 {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)},
4762 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
4763 {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)},
4764 {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)},
4765 {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)},
4766 {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)}, 4425 {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)},
4767 {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)}, 4426 {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)},
4768 {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)},
4769 {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)}, 4427 {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)},
4770 {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)}, 4428 {IWL_PCI_DEVICE(0x008A, 0x5327, iwl6000g2b_bg_cfg)},
4771 {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)}, 4429 {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)},
4430 {IWL_PCI_DEVICE(0x008B, 0x5317, iwl6000g2b_bg_cfg)},
4772 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)}, 4431 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
4773 {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)}, 4432 {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)},
4774 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)}, 4433 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
@@ -4812,10 +4471,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
4812 4471
4813/* 100 Series WiFi */ 4472/* 100 Series WiFi */
4814 {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, 4473 {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
4474 {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
4815 {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, 4475 {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
4476 {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)},
4816 {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, 4477 {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
4817 {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, 4478 {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)},
4818 {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)},
4819 4479
4820/* 130 Series WiFi */ 4480/* 130 Series WiFi */
4821 {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, 4481 {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
@@ -4836,10 +4496,7 @@ static struct pci_driver iwl_driver = {
4836 .id_table = iwl_hw_card_ids, 4496 .id_table = iwl_hw_card_ids,
4837 .probe = iwl_pci_probe, 4497 .probe = iwl_pci_probe,
4838 .remove = __devexit_p(iwl_pci_remove), 4498 .remove = __devexit_p(iwl_pci_remove),
4839#ifdef CONFIG_PM 4499 .driver.pm = IWL_PM_OPS,
4840 .suspend = iwl_pci_suspend,
4841 .resume = iwl_pci_resume,
4842#endif
4843}; 4500};
4844 4501
4845static int __init iwl_init(void) 4502static int __init iwl_init(void)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index f525d55f2c0f..28837a185a28 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -102,6 +102,9 @@ extern struct iwl_hcmd_ops iwlagn_hcmd;
102extern struct iwl_hcmd_ops iwlagn_bt_hcmd; 102extern struct iwl_hcmd_ops iwlagn_bt_hcmd;
103extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; 103extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
104 104
105extern struct ieee80211_ops iwlagn_hw_ops;
106extern struct ieee80211_ops iwl4965_hw_ops;
107
105int iwl_reset_ict(struct iwl_priv *priv); 108int iwl_reset_ict(struct iwl_priv *priv);
106void iwl_disable_ict(struct iwl_priv *priv); 109void iwl_disable_ict(struct iwl_priv *priv);
107int iwl_alloc_isr_ict(struct iwl_priv *priv); 110int iwl_alloc_isr_ict(struct iwl_priv *priv);
@@ -132,6 +135,11 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
132/* RXON */ 135/* RXON */
133int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 136int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
134void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); 137void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
138int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed);
139void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
140 struct ieee80211_vif *vif,
141 struct ieee80211_bss_conf *bss_conf,
142 u32 changes);
135 143
136/* uCode */ 144/* uCode */
137int iwlagn_load_ucode(struct iwl_priv *priv); 145int iwlagn_load_ucode(struct iwl_priv *priv);
@@ -249,6 +257,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
249int iwlagn_send_rxon_assoc(struct iwl_priv *priv, 257int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
250 struct iwl_rxon_context *ctx); 258 struct iwl_rxon_context *ctx);
251int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); 259int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
260int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
252 261
253/* bt coex */ 262/* bt coex */
254void iwlagn_send_advance_bt_config(struct iwl_priv *priv); 263void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
@@ -292,9 +301,12 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
292 int tid, u16 ssn); 301 int tid, u16 ssn);
293int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, 302int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
294 int tid); 303 int tid);
295void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
296void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); 304void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
297int iwl_update_bcast_stations(struct iwl_priv *priv); 305int iwl_update_bcast_stations(struct iwl_priv *priv);
306void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
307 struct ieee80211_vif *vif,
308 enum sta_notify_cmd cmd,
309 struct ieee80211_sta *sta);
298 310
299/* rate */ 311/* rate */
300static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) 312static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -318,4 +330,31 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
318int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); 330int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
319void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); 331void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
320 332
333/* mac80211 handlers (for 4965) */
334int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
335int iwlagn_mac_start(struct ieee80211_hw *hw);
336void iwlagn_mac_stop(struct ieee80211_hw *hw);
337void iwlagn_configure_filter(struct ieee80211_hw *hw,
338 unsigned int changed_flags,
339 unsigned int *total_flags,
340 u64 multicast);
341int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
342 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
343 struct ieee80211_key_conf *key);
344void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
345 struct ieee80211_vif *vif,
346 struct ieee80211_key_conf *keyconf,
347 struct ieee80211_sta *sta,
348 u32 iv32, u16 *phase1key);
349int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
350 struct ieee80211_vif *vif,
351 enum ieee80211_ampdu_mlme_action action,
352 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
353int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
354 struct ieee80211_vif *vif,
355 struct ieee80211_sta *sta);
356void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
357 struct ieee80211_channel_switch *ch_switch);
358void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
359
321#endif /* __iwl_agn_h__ */ 360#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 25fb3912342c..c884ed385fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -77,15 +77,15 @@ EXPORT_SYMBOL(iwl_bcast_addr);
77 77
78 78
79/* This function both allocates and initializes hw and priv. */ 79/* This function both allocates and initializes hw and priv. */
80struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 80struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
81 struct ieee80211_ops *hw_ops)
82{ 81{
83 struct iwl_priv *priv; 82 struct iwl_priv *priv;
84
85 /* mac80211 allocates memory for this device instance, including 83 /* mac80211 allocates memory for this device instance, including
86 * space for this driver's private structure */ 84 * space for this driver's private structure */
87 struct ieee80211_hw *hw = 85 struct ieee80211_hw *hw;
88 ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); 86
87 hw = ieee80211_alloc_hw(sizeof(struct iwl_priv),
88 cfg->ops->ieee80211_ops);
89 if (hw == NULL) { 89 if (hw == NULL) {
90 pr_err("%s: Can not allocate network device\n", 90 pr_err("%s: Can not allocate network device\n",
91 cfg->name); 91 cfg->name);
@@ -100,35 +100,6 @@ out:
100} 100}
101EXPORT_SYMBOL(iwl_alloc_all); 101EXPORT_SYMBOL(iwl_alloc_all);
102 102
103/*
104 * QoS support
105*/
106static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
107{
108 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
109 return;
110
111 if (!ctx->is_active)
112 return;
113
114 ctx->qos_data.def_qos_parm.qos_flags = 0;
115
116 if (ctx->qos_data.qos_active)
117 ctx->qos_data.def_qos_parm.qos_flags |=
118 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
119
120 if (ctx->ht.enabled)
121 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
122
123 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
124 ctx->qos_data.qos_active,
125 ctx->qos_data.def_qos_parm.qos_flags);
126
127 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
128 sizeof(struct iwl_qosparam_cmd),
129 &ctx->qos_data.def_qos_parm, NULL);
130}
131
132#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 103#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
133#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 104#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
134static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, 105static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -317,40 +288,6 @@ void iwlcore_free_geos(struct iwl_priv *priv)
317} 288}
318EXPORT_SYMBOL(iwlcore_free_geos); 289EXPORT_SYMBOL(iwlcore_free_geos);
319 290
320/*
321 * iwlcore_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
322 * function.
323 */
324void iwlcore_tx_cmd_protection(struct iwl_priv *priv,
325 struct ieee80211_tx_info *info,
326 __le16 fc, __le32 *tx_flags)
327{
328 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
329 *tx_flags |= TX_CMD_FLG_RTS_MSK;
330 *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
331 *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
332
333 if (!ieee80211_is_mgmt(fc))
334 return;
335
336 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
337 case cpu_to_le16(IEEE80211_STYPE_AUTH):
338 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
339 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
340 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
341 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
342 *tx_flags |= TX_CMD_FLG_CTS_MSK;
343 break;
344 }
345 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
346 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
347 *tx_flags |= TX_CMD_FLG_CTS_MSK;
348 *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
349 }
350}
351EXPORT_SYMBOL(iwlcore_tx_cmd_protection);
352
353
354static bool iwl_is_channel_extension(struct iwl_priv *priv, 291static bool iwl_is_channel_extension(struct iwl_priv *priv,
355 enum ieee80211_band band, 292 enum ieee80211_band band,
356 u16 channel, u8 extension_chan_offset) 293 u16 channel, u8 extension_chan_offset)
@@ -1206,8 +1143,16 @@ EXPORT_SYMBOL(iwl_apm_init);
1206 1143
1207int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) 1144int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1208{ 1145{
1209 int ret = 0; 1146 int ret;
1210 s8 prev_tx_power = priv->tx_power_user_lmt; 1147 s8 prev_tx_power;
1148
1149 lockdep_assert_held(&priv->mutex);
1150
1151 if (priv->tx_power_user_lmt == tx_power && !force)
1152 return 0;
1153
1154 if (!priv->cfg->ops->lib->send_tx_power)
1155 return -EOPNOTSUPP;
1211 1156
1212 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { 1157 if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
1213 IWL_WARN(priv, 1158 IWL_WARN(priv,
@@ -1224,93 +1169,29 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
1224 return -EINVAL; 1169 return -EINVAL;
1225 } 1170 }
1226 1171
1227 if (priv->tx_power_user_lmt != tx_power) 1172 if (!iwl_is_ready_rf(priv))
1228 force = true; 1173 return -EIO;
1229 1174
1230 /* if nic is not up don't send command */ 1175 /* scan complete use tx_power_next, need to be updated */
1231 if (iwl_is_ready_rf(priv)) { 1176 priv->tx_power_next = tx_power;
1232 priv->tx_power_user_lmt = tx_power; 1177 if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
1233 if (force && priv->cfg->ops->lib->send_tx_power) 1178 IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n");
1234 ret = priv->cfg->ops->lib->send_tx_power(priv); 1179 return 0;
1235 else if (!priv->cfg->ops->lib->send_tx_power)
1236 ret = -EOPNOTSUPP;
1237 /*
1238 * if fail to set tx_power, restore the orig. tx power
1239 */
1240 if (ret)
1241 priv->tx_power_user_lmt = prev_tx_power;
1242 } 1180 }
1243 1181
1244 /* 1182 prev_tx_power = priv->tx_power_user_lmt;
1245 * Even this is an async host command, the command 1183 priv->tx_power_user_lmt = tx_power;
1246 * will always report success from uCode
1247 * So once driver can placing the command into the queue
1248 * successfully, driver can use priv->tx_power_user_lmt
1249 * to reflect the current tx power
1250 */
1251 return ret;
1252}
1253EXPORT_SYMBOL(iwl_set_tx_power);
1254
1255irqreturn_t iwl_isr_legacy(int irq, void *data)
1256{
1257 struct iwl_priv *priv = data;
1258 u32 inta, inta_mask;
1259 u32 inta_fh;
1260 unsigned long flags;
1261 if (!priv)
1262 return IRQ_NONE;
1263 1184
1264 spin_lock_irqsave(&priv->lock, flags); 1185 ret = priv->cfg->ops->lib->send_tx_power(priv);
1265 1186
1266 /* Disable (but don't clear!) interrupts here to avoid 1187 /* if fail to set tx_power, restore the orig. tx power */
1267 * back-to-back ISRs and sporadic interrupts from our NIC. 1188 if (ret) {
1268 * If we have something to service, the tasklet will re-enable ints. 1189 priv->tx_power_user_lmt = prev_tx_power;
1269 * If we *don't* have something, we'll re-enable before leaving here. */ 1190 priv->tx_power_next = prev_tx_power;
1270 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
1271 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
1272
1273 /* Discover which interrupts are active/pending */
1274 inta = iwl_read32(priv, CSR_INT);
1275 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1276
1277 /* Ignore interrupt if there's nothing in NIC to service.
1278 * This may be due to IRQ shared with another device,
1279 * or due to sporadic interrupts thrown from our NIC. */
1280 if (!inta && !inta_fh) {
1281 IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 0\n");
1282 goto none;
1283 } 1191 }
1284 1192 return ret;
1285 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
1286 /* Hardware disappeared. It might have already raised
1287 * an interrupt */
1288 IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
1289 goto unplugged;
1290 }
1291
1292 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
1293 inta, inta_mask, inta_fh);
1294
1295 inta &= ~CSR_INT_BIT_SCD;
1296
1297 /* iwl_irq_tasklet() will service interrupts and re-enable them */
1298 if (likely(inta || inta_fh))
1299 tasklet_schedule(&priv->irq_tasklet);
1300
1301 unplugged:
1302 spin_unlock_irqrestore(&priv->lock, flags);
1303 return IRQ_HANDLED;
1304
1305 none:
1306 /* re-enable interrupts here since we don't have anything to service. */
1307 /* only Re-enable if diabled by irq */
1308 if (test_bit(STATUS_INT_ENABLED, &priv->status))
1309 iwl_enable_interrupts(priv);
1310 spin_unlock_irqrestore(&priv->lock, flags);
1311 return IRQ_NONE;
1312} 1193}
1313EXPORT_SYMBOL(iwl_isr_legacy); 1194EXPORT_SYMBOL(iwl_set_tx_power);
1314 1195
1315void iwl_send_bt_config(struct iwl_priv *priv) 1196void iwl_send_bt_config(struct iwl_priv *priv)
1316{ 1197{
@@ -1452,318 +1333,51 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
1452} 1333}
1453EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); 1334EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
1454 1335
1455static void iwl_ht_conf(struct iwl_priv *priv, 1336static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1456 struct ieee80211_vif *vif)
1457{ 1337{
1458 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 1338 iwl_connection_init_rx_config(priv, ctx);
1459 struct ieee80211_sta *sta;
1460 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1461 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1462
1463 IWL_DEBUG_MAC80211(priv, "enter:\n");
1464
1465 if (!ctx->ht.enabled)
1466 return;
1467
1468 ctx->ht.protection =
1469 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
1470 ctx->ht.non_gf_sta_present =
1471 !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1472
1473 ht_conf->single_chain_sufficient = false;
1474
1475 switch (vif->type) {
1476 case NL80211_IFTYPE_STATION:
1477 rcu_read_lock();
1478 sta = ieee80211_find_sta(vif, bss_conf->bssid);
1479 if (sta) {
1480 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1481 int maxstreams;
1482
1483 maxstreams = (ht_cap->mcs.tx_params &
1484 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
1485 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1486 maxstreams += 1;
1487
1488 if ((ht_cap->mcs.rx_mask[1] == 0) &&
1489 (ht_cap->mcs.rx_mask[2] == 0))
1490 ht_conf->single_chain_sufficient = true;
1491 if (maxstreams <= 1)
1492 ht_conf->single_chain_sufficient = true;
1493 } else {
1494 /*
1495 * If at all, this can only happen through a race
1496 * when the AP disconnects us while we're still
1497 * setting up the connection, in that case mac80211
1498 * will soon tell us about that.
1499 */
1500 ht_conf->single_chain_sufficient = true;
1501 }
1502 rcu_read_unlock();
1503 break;
1504 case NL80211_IFTYPE_ADHOC:
1505 ht_conf->single_chain_sufficient = true;
1506 break;
1507 default:
1508 break;
1509 }
1510
1511 IWL_DEBUG_MAC80211(priv, "leave\n");
1512}
1513 1339
1514static inline void iwl_set_no_assoc(struct iwl_priv *priv, 1340 if (priv->cfg->ops->hcmd->set_rxon_chain)
1515 struct ieee80211_vif *vif) 1341 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1516{
1517 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1518 1342
1519 iwl_led_disassociate(priv); 1343 return iwlcore_commit_rxon(priv, ctx);
1520 /*
1521 * inform the ucode that there is no longer an
1522 * association and that no more packets should be
1523 * sent
1524 */
1525 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1526 ctx->staging.assoc_id = 0;
1527 iwlcore_commit_rxon(priv, ctx);
1528} 1344}
1529 1345
1530static void iwlcore_beacon_update(struct ieee80211_hw *hw, 1346static int iwl_setup_interface(struct iwl_priv *priv,
1531 struct ieee80211_vif *vif) 1347 struct iwl_rxon_context *ctx)
1532{ 1348{
1533 struct iwl_priv *priv = hw->priv; 1349 struct ieee80211_vif *vif = ctx->vif;
1534 unsigned long flags; 1350 int err;
1535 __le64 timestamp;
1536 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
1537
1538 if (!skb)
1539 return;
1540
1541 IWL_DEBUG_ASSOC(priv, "enter\n");
1542 1351
1543 lockdep_assert_held(&priv->mutex); 1352 lockdep_assert_held(&priv->mutex);
1544 1353
1545 if (!priv->beacon_ctx) {
1546 IWL_ERR(priv, "update beacon but no beacon context!\n");
1547 dev_kfree_skb(skb);
1548 return;
1549 }
1550
1551 spin_lock_irqsave(&priv->lock, flags);
1552
1553 if (priv->beacon_skb)
1554 dev_kfree_skb(priv->beacon_skb);
1555
1556 priv->beacon_skb = skb;
1557
1558 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
1559 priv->timestamp = le64_to_cpu(timestamp);
1560
1561 IWL_DEBUG_ASSOC(priv, "leave\n");
1562
1563 spin_unlock_irqrestore(&priv->lock, flags);
1564
1565 if (!iwl_is_ready_rf(priv)) {
1566 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
1567 return;
1568 }
1569
1570 priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
1571}
1572
1573void iwl_bss_info_changed(struct ieee80211_hw *hw,
1574 struct ieee80211_vif *vif,
1575 struct ieee80211_bss_conf *bss_conf,
1576 u32 changes)
1577{
1578 struct iwl_priv *priv = hw->priv;
1579 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1580 int ret;
1581
1582 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
1583
1584 if (!iwl_is_alive(priv))
1585 return;
1586
1587 mutex_lock(&priv->mutex);
1588
1589 if (changes & BSS_CHANGED_QOS) {
1590 unsigned long flags;
1591
1592 spin_lock_irqsave(&priv->lock, flags);
1593 ctx->qos_data.qos_active = bss_conf->qos;
1594 iwl_update_qos(priv, ctx);
1595 spin_unlock_irqrestore(&priv->lock, flags);
1596 }
1597
1598 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1599 /*
1600 * the add_interface code must make sure we only ever
1601 * have a single interface that could be beaconing at
1602 * any time.
1603 */
1604 if (vif->bss_conf.enable_beacon)
1605 priv->beacon_ctx = ctx;
1606 else
1607 priv->beacon_ctx = NULL;
1608 }
1609
1610 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
1611 dev_kfree_skb(priv->beacon_skb);
1612 priv->beacon_skb = ieee80211_beacon_get(hw, vif);
1613 }
1614
1615 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
1616 iwl_send_rxon_timing(priv, ctx);
1617
1618 if (changes & BSS_CHANGED_BSSID) {
1619 IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
1620
1621 /*
1622 * If there is currently a HW scan going on in the
1623 * background then we need to cancel it else the RXON
1624 * below/in post_associate will fail.
1625 */
1626 if (iwl_scan_cancel_timeout(priv, 100)) {
1627 IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
1628 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
1629 mutex_unlock(&priv->mutex);
1630 return;
1631 }
1632
1633 /* mac80211 only sets assoc when in STATION mode */
1634 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
1635 memcpy(ctx->staging.bssid_addr,
1636 bss_conf->bssid, ETH_ALEN);
1637
1638 /* currently needed in a few places */
1639 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1640 } else {
1641 ctx->staging.filter_flags &=
1642 ~RXON_FILTER_ASSOC_MSK;
1643 }
1644
1645 }
1646
1647 /* 1354 /*
1648 * This needs to be after setting the BSSID in case 1355 * This variable will be correct only when there's just
1649 * mac80211 decides to do both changes at once because 1356 * a single context, but all code using it is for hardware
1650 * it will invoke post_associate. 1357 * that supports only one context.
1651 */ 1358 */
1652 if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) 1359 priv->iw_mode = vif->type;
1653 iwlcore_beacon_update(hw, vif);
1654
1655 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
1656 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
1657 bss_conf->use_short_preamble);
1658 if (bss_conf->use_short_preamble)
1659 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1660 else
1661 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1662 }
1663
1664 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
1665 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
1666 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
1667 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
1668 else
1669 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
1670 if (bss_conf->use_cts_prot)
1671 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
1672 else
1673 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
1674 }
1675
1676 if (changes & BSS_CHANGED_BASIC_RATES) {
1677 /* XXX use this information
1678 *
1679 * To do that, remove code from iwl_set_rate() and put something
1680 * like this here:
1681 *
1682 if (A-band)
1683 ctx->staging.ofdm_basic_rates =
1684 bss_conf->basic_rates;
1685 else
1686 ctx->staging.ofdm_basic_rates =
1687 bss_conf->basic_rates >> 4;
1688 ctx->staging.cck_basic_rates =
1689 bss_conf->basic_rates & 0xF;
1690 */
1691 }
1692
1693 if (changes & BSS_CHANGED_HT) {
1694 iwl_ht_conf(priv, vif);
1695
1696 if (priv->cfg->ops->hcmd->set_rxon_chain)
1697 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1698 }
1699
1700 if (changes & BSS_CHANGED_ASSOC) {
1701 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
1702 if (bss_conf->assoc) {
1703 priv->timestamp = bss_conf->timestamp;
1704
1705 iwl_led_associate(priv);
1706
1707 if (!iwl_is_rfkill(priv))
1708 priv->cfg->ops->lib->post_associate(priv, vif);
1709 } else
1710 iwl_set_no_assoc(priv, vif);
1711 }
1712
1713 if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
1714 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
1715 changes);
1716 ret = iwl_send_rxon_assoc(priv, ctx);
1717 if (!ret) {
1718 /* Sync active_rxon with latest change. */
1719 memcpy((void *)&ctx->active,
1720 &ctx->staging,
1721 sizeof(struct iwl_rxon_cmd));
1722 }
1723 }
1724 1360
1725 if (changes & BSS_CHANGED_BEACON_ENABLED) { 1361 ctx->is_active = true;
1726 if (vif->bss_conf.enable_beacon) {
1727 memcpy(ctx->staging.bssid_addr,
1728 bss_conf->bssid, ETH_ALEN);
1729 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1730 iwl_led_associate(priv);
1731 iwlcore_config_ap(priv, vif);
1732 } else
1733 iwl_set_no_assoc(priv, vif);
1734 }
1735 1362
1736 if (changes & BSS_CHANGED_IBSS) { 1363 err = iwl_set_mode(priv, ctx);
1737 ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif, 1364 if (err) {
1738 bss_conf->ibss_joined); 1365 if (!ctx->always_active)
1739 if (ret) 1366 ctx->is_active = false;
1740 IWL_ERR(priv, "failed to %s IBSS station %pM\n", 1367 return err;
1741 bss_conf->ibss_joined ? "add" : "remove",
1742 bss_conf->bssid);
1743 } 1368 }
1744 1369
1745 if (changes & BSS_CHANGED_IDLE && 1370 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist &&
1746 priv->cfg->ops->hcmd->set_pan_params) { 1371 vif->type == NL80211_IFTYPE_ADHOC) {
1747 if (priv->cfg->ops->hcmd->set_pan_params(priv)) 1372 /*
1748 IWL_ERR(priv, "failed to update PAN params\n"); 1373 * pretend to have high BT traffic as long as we
1374 * are operating in IBSS mode, as this will cause
1375 * the rate scaling etc. to behave as intended.
1376 */
1377 priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
1749 } 1378 }
1750 1379
1751 mutex_unlock(&priv->mutex); 1380 return 0;
1752
1753 IWL_DEBUG_MAC80211(priv, "leave\n");
1754}
1755EXPORT_SYMBOL(iwl_bss_info_changed);
1756
1757static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
1758{
1759 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1760
1761 iwl_connection_init_rx_config(priv, ctx);
1762
1763 if (priv->cfg->ops->hcmd->set_rxon_chain)
1764 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1765
1766 return iwlcore_commit_rxon(priv, ctx);
1767} 1381}
1768 1382
1769int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1383int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
@@ -1771,7 +1385,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1771 struct iwl_priv *priv = hw->priv; 1385 struct iwl_priv *priv = hw->priv;
1772 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1386 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1773 struct iwl_rxon_context *tmp, *ctx = NULL; 1387 struct iwl_rxon_context *tmp, *ctx = NULL;
1774 int err = 0; 1388 int err;
1775 1389
1776 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", 1390 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
1777 vif->type, vif->addr); 1391 vif->type, vif->addr);
@@ -1813,36 +1427,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1813 1427
1814 vif_priv->ctx = ctx; 1428 vif_priv->ctx = ctx;
1815 ctx->vif = vif; 1429 ctx->vif = vif;
1816 /*
1817 * This variable will be correct only when there's just
1818 * a single context, but all code using it is for hardware
1819 * that supports only one context.
1820 */
1821 priv->iw_mode = vif->type;
1822
1823 ctx->is_active = true;
1824
1825 err = iwl_set_mode(priv, vif);
1826 if (err) {
1827 if (!ctx->always_active)
1828 ctx->is_active = false;
1829 goto out_err;
1830 }
1831
1832 if (priv->cfg->bt_params &&
1833 priv->cfg->bt_params->advanced_bt_coexist &&
1834 vif->type == NL80211_IFTYPE_ADHOC) {
1835 /*
1836 * pretend to have high BT traffic as long as we
1837 * are operating in IBSS mode, as this will cause
1838 * the rate scaling etc. to behave as intended.
1839 */
1840 priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
1841 }
1842 1430
1843 goto out; 1431 err = iwl_setup_interface(priv, ctx);
1432 if (!err)
1433 goto out;
1844 1434
1845 out_err:
1846 ctx->vif = NULL; 1435 ctx->vif = NULL;
1847 priv->iw_mode = NL80211_IFTYPE_STATION; 1436 priv->iw_mode = NL80211_IFTYPE_STATION;
1848 out: 1437 out:
@@ -1853,27 +1442,24 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1853} 1442}
1854EXPORT_SYMBOL(iwl_mac_add_interface); 1443EXPORT_SYMBOL(iwl_mac_add_interface);
1855 1444
1856void iwl_mac_remove_interface(struct ieee80211_hw *hw, 1445static void iwl_teardown_interface(struct iwl_priv *priv,
1857 struct ieee80211_vif *vif) 1446 struct ieee80211_vif *vif,
1447 bool mode_change)
1858{ 1448{
1859 struct iwl_priv *priv = hw->priv;
1860 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1449 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1861 1450
1862 IWL_DEBUG_MAC80211(priv, "enter\n"); 1451 lockdep_assert_held(&priv->mutex);
1863
1864 mutex_lock(&priv->mutex);
1865
1866 WARN_ON(ctx->vif != vif);
1867 ctx->vif = NULL;
1868 1452
1869 if (priv->scan_vif == vif) { 1453 if (priv->scan_vif == vif) {
1870 iwl_scan_cancel_timeout(priv, 200); 1454 iwl_scan_cancel_timeout(priv, 200);
1871 iwl_force_scan_end(priv); 1455 iwl_force_scan_end(priv);
1872 } 1456 }
1873 iwl_set_mode(priv, vif);
1874 1457
1875 if (!ctx->always_active) 1458 if (!mode_change) {
1876 ctx->is_active = false; 1459 iwl_set_mode(priv, ctx);
1460 if (!ctx->always_active)
1461 ctx->is_active = false;
1462 }
1877 1463
1878 /* 1464 /*
1879 * When removing the IBSS interface, overwrite the 1465 * When removing the IBSS interface, overwrite the
@@ -1884,210 +1470,30 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1884 */ 1470 */
1885 if (vif->type == NL80211_IFTYPE_ADHOC) 1471 if (vif->type == NL80211_IFTYPE_ADHOC)
1886 priv->bt_traffic_load = priv->notif_bt_traffic_load; 1472 priv->bt_traffic_load = priv->notif_bt_traffic_load;
1887
1888 memset(priv->bssid, 0, ETH_ALEN);
1889 mutex_unlock(&priv->mutex);
1890
1891 IWL_DEBUG_MAC80211(priv, "leave\n");
1892
1893} 1473}
1894EXPORT_SYMBOL(iwl_mac_remove_interface);
1895
1896/**
1897 * iwl_mac_config - mac80211 config callback
1898 */
1899int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
1900{
1901 struct iwl_priv *priv = hw->priv;
1902 const struct iwl_channel_info *ch_info;
1903 struct ieee80211_conf *conf = &hw->conf;
1904 struct ieee80211_channel *channel = conf->channel;
1905 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1906 struct iwl_rxon_context *ctx;
1907 unsigned long flags = 0;
1908 int ret = 0;
1909 u16 ch;
1910 int scan_active = 0;
1911
1912 mutex_lock(&priv->mutex);
1913
1914 IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
1915 channel->hw_value, changed);
1916
1917 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
1918 test_bit(STATUS_SCANNING, &priv->status))) {
1919 scan_active = 1;
1920 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
1921 }
1922
1923 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
1924 IEEE80211_CONF_CHANGE_CHANNEL)) {
1925 /* mac80211 uses static for non-HT which is what we want */
1926 priv->current_ht_config.smps = conf->smps_mode;
1927
1928 /*
1929 * Recalculate chain counts.
1930 *
1931 * If monitor mode is enabled then mac80211 will
1932 * set up the SM PS mode to OFF if an HT channel is
1933 * configured.
1934 */
1935 if (priv->cfg->ops->hcmd->set_rxon_chain)
1936 for_each_context(priv, ctx)
1937 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1938 }
1939
1940 /* during scanning mac80211 will delay channel setting until
1941 * scan finish with changed = 0
1942 */
1943 if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
1944 if (scan_active)
1945 goto set_ch_out;
1946
1947 ch = channel->hw_value;
1948 ch_info = iwl_get_channel_info(priv, channel->band, ch);
1949 if (!is_channel_valid(ch_info)) {
1950 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
1951 ret = -EINVAL;
1952 goto set_ch_out;
1953 }
1954 1474
1955 spin_lock_irqsave(&priv->lock, flags); 1475void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1956 1476 struct ieee80211_vif *vif)
1957 for_each_context(priv, ctx) {
1958 /* Configure HT40 channels */
1959 ctx->ht.enabled = conf_is_ht(conf);
1960 if (ctx->ht.enabled) {
1961 if (conf_is_ht40_minus(conf)) {
1962 ctx->ht.extension_chan_offset =
1963 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
1964 ctx->ht.is_40mhz = true;
1965 } else if (conf_is_ht40_plus(conf)) {
1966 ctx->ht.extension_chan_offset =
1967 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
1968 ctx->ht.is_40mhz = true;
1969 } else {
1970 ctx->ht.extension_chan_offset =
1971 IEEE80211_HT_PARAM_CHA_SEC_NONE;
1972 ctx->ht.is_40mhz = false;
1973 }
1974 } else
1975 ctx->ht.is_40mhz = false;
1976
1977 /*
1978 * Default to no protection. Protection mode will
1979 * later be set from BSS config in iwl_ht_conf
1980 */
1981 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
1982
1983 /* if we are switching from ht to 2.4 clear flags
1984 * from any ht related info since 2.4 does not
1985 * support ht */
1986 if ((le16_to_cpu(ctx->staging.channel) != ch))
1987 ctx->staging.flags = 0;
1988
1989 iwl_set_rxon_channel(priv, channel, ctx);
1990 iwl_set_rxon_ht(priv, ht_conf);
1991
1992 iwl_set_flags_for_band(priv, ctx, channel->band,
1993 ctx->vif);
1994 }
1995
1996 spin_unlock_irqrestore(&priv->lock, flags);
1997
1998 if (priv->cfg->ops->lib->update_bcast_stations)
1999 ret = priv->cfg->ops->lib->update_bcast_stations(priv);
2000
2001 set_ch_out:
2002 /* The list of supported rates and rate mask can be different
2003 * for each band; since the band may have changed, reset
2004 * the rate mask to what mac80211 lists */
2005 iwl_set_rate(priv);
2006 }
2007
2008 if (changed & (IEEE80211_CONF_CHANGE_PS |
2009 IEEE80211_CONF_CHANGE_IDLE)) {
2010 ret = iwl_power_update_mode(priv, false);
2011 if (ret)
2012 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
2013 }
2014
2015 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2016 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
2017 priv->tx_power_user_lmt, conf->power_level);
2018
2019 iwl_set_tx_power(priv, conf->power_level, false);
2020 }
2021
2022 if (!iwl_is_ready(priv)) {
2023 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2024 goto out;
2025 }
2026
2027 if (scan_active)
2028 goto out;
2029
2030 for_each_context(priv, ctx) {
2031 if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
2032 iwlcore_commit_rxon(priv, ctx);
2033 else
2034 IWL_DEBUG_INFO(priv,
2035 "Not re-sending same RXON configuration.\n");
2036 }
2037
2038out:
2039 IWL_DEBUG_MAC80211(priv, "leave\n");
2040 mutex_unlock(&priv->mutex);
2041 return ret;
2042}
2043EXPORT_SYMBOL(iwl_mac_config);
2044
2045void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2046{ 1477{
2047 struct iwl_priv *priv = hw->priv; 1478 struct iwl_priv *priv = hw->priv;
2048 unsigned long flags; 1479 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
2049 /* IBSS can only be the IWL_RXON_CTX_BSS context */
2050 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2051 1480
2052 mutex_lock(&priv->mutex);
2053 IWL_DEBUG_MAC80211(priv, "enter\n"); 1481 IWL_DEBUG_MAC80211(priv, "enter\n");
2054 1482
2055 spin_lock_irqsave(&priv->lock, flags); 1483 mutex_lock(&priv->mutex);
2056 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
2057 spin_unlock_irqrestore(&priv->lock, flags);
2058
2059 spin_lock_irqsave(&priv->lock, flags);
2060
2061 /* new association get rid of ibss beacon skb */
2062 if (priv->beacon_skb)
2063 dev_kfree_skb(priv->beacon_skb);
2064
2065 priv->beacon_skb = NULL;
2066
2067 priv->timestamp = 0;
2068
2069 spin_unlock_irqrestore(&priv->lock, flags);
2070
2071 iwl_scan_cancel_timeout(priv, 100);
2072 if (!iwl_is_ready_rf(priv)) {
2073 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2074 mutex_unlock(&priv->mutex);
2075 return;
2076 }
2077 1484
2078 /* we are restarting association process 1485 WARN_ON(ctx->vif != vif);
2079 * clear RXON_FILTER_ASSOC_MSK bit 1486 ctx->vif = NULL;
2080 */
2081 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2082 iwlcore_commit_rxon(priv, ctx);
2083 1487
2084 iwl_set_rate(priv); 1488 iwl_teardown_interface(priv, vif, false);
2085 1489
1490 memset(priv->bssid, 0, ETH_ALEN);
2086 mutex_unlock(&priv->mutex); 1491 mutex_unlock(&priv->mutex);
2087 1492
2088 IWL_DEBUG_MAC80211(priv, "leave\n"); 1493 IWL_DEBUG_MAC80211(priv, "leave\n");
1494
2089} 1495}
2090EXPORT_SYMBOL(iwl_mac_reset_tsf); 1496EXPORT_SYMBOL(iwl_mac_remove_interface);
2091 1497
2092int iwl_alloc_txq_mem(struct iwl_priv *priv) 1498int iwl_alloc_txq_mem(struct iwl_priv *priv)
2093{ 1499{
@@ -2431,6 +1837,63 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
2431 return 0; 1837 return 0;
2432} 1838}
2433 1839
1840int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1841 enum nl80211_iftype newtype, bool newp2p)
1842{
1843 struct iwl_priv *priv = hw->priv;
1844 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1845 struct iwl_rxon_context *tmp;
1846 u32 interface_modes;
1847 int err;
1848
1849 newtype = ieee80211_iftype_p2p(newtype, newp2p);
1850
1851 mutex_lock(&priv->mutex);
1852
1853 interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
1854
1855 if (!(interface_modes & BIT(newtype))) {
1856 err = -EBUSY;
1857 goto out;
1858 }
1859
1860 if (ctx->exclusive_interface_modes & BIT(newtype)) {
1861 for_each_context(priv, tmp) {
1862 if (ctx == tmp)
1863 continue;
1864
1865 if (!tmp->vif)
1866 continue;
1867
1868 /*
1869 * The current mode switch would be exclusive, but
1870 * another context is active ... refuse the switch.
1871 */
1872 err = -EBUSY;
1873 goto out;
1874 }
1875 }
1876
1877 /* success */
1878 iwl_teardown_interface(priv, vif, true);
1879 vif->type = newtype;
1880 err = iwl_setup_interface(priv, ctx);
1881 WARN_ON(err);
1882 /*
1883 * We've switched internally, but submitting to the
1884 * device may have failed for some reason. Mask this
1885 * error, because otherwise mac80211 will not switch
1886 * (and set the interface type back) and we'll be
1887 * out of sync with it.
1888 */
1889 err = 0;
1890
1891 out:
1892 mutex_unlock(&priv->mutex);
1893 return err;
1894}
1895EXPORT_SYMBOL(iwl_mac_change_interface);
1896
2434/** 1897/**
2435 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover 1898 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
2436 * 1899 *
@@ -2584,8 +2047,9 @@ EXPORT_SYMBOL(iwl_add_beacon_time);
2584 2047
2585#ifdef CONFIG_PM 2048#ifdef CONFIG_PM
2586 2049
2587int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 2050int iwl_pci_suspend(struct device *device)
2588{ 2051{
2052 struct pci_dev *pdev = to_pci_dev(device);
2589 struct iwl_priv *priv = pci_get_drvdata(pdev); 2053 struct iwl_priv *priv = pci_get_drvdata(pdev);
2590 2054
2591 /* 2055 /*
@@ -2597,18 +2061,14 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2597 */ 2061 */
2598 iwl_apm_stop(priv); 2062 iwl_apm_stop(priv);
2599 2063
2600 pci_save_state(pdev);
2601 pci_disable_device(pdev);
2602 pci_set_power_state(pdev, PCI_D3hot);
2603
2604 return 0; 2064 return 0;
2605} 2065}
2606EXPORT_SYMBOL(iwl_pci_suspend); 2066EXPORT_SYMBOL(iwl_pci_suspend);
2607 2067
2608int iwl_pci_resume(struct pci_dev *pdev) 2068int iwl_pci_resume(struct device *device)
2609{ 2069{
2070 struct pci_dev *pdev = to_pci_dev(device);
2610 struct iwl_priv *priv = pci_get_drvdata(pdev); 2071 struct iwl_priv *priv = pci_get_drvdata(pdev);
2611 int ret;
2612 bool hw_rfkill = false; 2072 bool hw_rfkill = false;
2613 2073
2614 /* 2074 /*
@@ -2617,11 +2077,6 @@ int iwl_pci_resume(struct pci_dev *pdev)
2617 */ 2077 */
2618 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); 2078 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
2619 2079
2620 pci_set_power_state(pdev, PCI_D0);
2621 ret = pci_enable_device(pdev);
2622 if (ret)
2623 return ret;
2624 pci_restore_state(pdev);
2625 iwl_enable_interrupts(priv); 2080 iwl_enable_interrupts(priv);
2626 2081
2627 if (!(iwl_read32(priv, CSR_GP_CNTRL) & 2082 if (!(iwl_read32(priv, CSR_GP_CNTRL) &
@@ -2639,4 +2094,14 @@ int iwl_pci_resume(struct pci_dev *pdev)
2639} 2094}
2640EXPORT_SYMBOL(iwl_pci_resume); 2095EXPORT_SYMBOL(iwl_pci_resume);
2641 2096
2097const struct dev_pm_ops iwl_pm_ops = {
2098 .suspend = iwl_pci_suspend,
2099 .resume = iwl_pci_resume,
2100 .freeze = iwl_pci_suspend,
2101 .thaw = iwl_pci_resume,
2102 .poweroff = iwl_pci_suspend,
2103 .restore = iwl_pci_resume,
2104};
2105EXPORT_SYMBOL(iwl_pm_ops);
2106
2642#endif /* CONFIG_PM */ 2107#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 64527def059f..ee8cf240d65d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -120,6 +120,14 @@ struct iwl_apm_ops {
120 void (*config)(struct iwl_priv *priv); 120 void (*config)(struct iwl_priv *priv);
121}; 121};
122 122
123struct iwl_isr_ops {
124 irqreturn_t (*isr) (int irq, void *data);
125 void (*free)(struct iwl_priv *priv);
126 int (*alloc)(struct iwl_priv *priv);
127 int (*reset)(struct iwl_priv *priv);
128 void (*disable)(struct iwl_priv *priv);
129};
130
123struct iwl_debugfs_ops { 131struct iwl_debugfs_ops {
124 ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf, 132 ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
125 size_t count, loff_t *ppos); 133 size_t count, loff_t *ppos);
@@ -193,20 +201,15 @@ struct iwl_lib_ops {
193 /* power */ 201 /* power */
194 int (*send_tx_power) (struct iwl_priv *priv); 202 int (*send_tx_power) (struct iwl_priv *priv);
195 void (*update_chain_flags)(struct iwl_priv *priv); 203 void (*update_chain_flags)(struct iwl_priv *priv);
196 void (*post_associate)(struct iwl_priv *priv, 204
197 struct ieee80211_vif *vif); 205 /* isr */
198 void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif); 206 struct iwl_isr_ops isr_ops;
199 irqreturn_t (*isr) (int irq, void *data);
200 207
201 /* eeprom operations (as defined in iwl-eeprom.h) */ 208 /* eeprom operations (as defined in iwl-eeprom.h) */
202 struct iwl_eeprom_ops eeprom_ops; 209 struct iwl_eeprom_ops eeprom_ops;
203 210
204 /* temperature */ 211 /* temperature */
205 struct iwl_temp_ops temp_ops; 212 struct iwl_temp_ops temp_ops;
206 /* station management */
207 int (*manage_ibss_station)(struct iwl_priv *priv,
208 struct ieee80211_vif *vif, bool add);
209 int (*update_bcast_stations)(struct iwl_priv *priv);
210 /* recover from tx queue stall */ 213 /* recover from tx queue stall */
211 void (*recover_from_tx_stall)(unsigned long data); 214 void (*recover_from_tx_stall)(unsigned long data);
212 /* check for plcp health */ 215 /* check for plcp health */
@@ -235,12 +238,23 @@ struct iwl_nic_ops {
235 void (*additional_nic_config)(struct iwl_priv *priv); 238 void (*additional_nic_config)(struct iwl_priv *priv);
236}; 239};
237 240
241struct iwl_legacy_ops {
242 void (*post_associate)(struct iwl_priv *priv);
243 void (*config_ap)(struct iwl_priv *priv);
244 /* station management */
245 int (*update_bcast_stations)(struct iwl_priv *priv);
246 int (*manage_ibss_station)(struct iwl_priv *priv,
247 struct ieee80211_vif *vif, bool add);
248};
249
238struct iwl_ops { 250struct iwl_ops {
239 const struct iwl_lib_ops *lib; 251 const struct iwl_lib_ops *lib;
240 const struct iwl_hcmd_ops *hcmd; 252 const struct iwl_hcmd_ops *hcmd;
241 const struct iwl_hcmd_utils_ops *utils; 253 const struct iwl_hcmd_utils_ops *utils;
242 const struct iwl_led_ops *led; 254 const struct iwl_led_ops *led;
243 const struct iwl_nic_ops *nic; 255 const struct iwl_nic_ops *nic;
256 const struct iwl_legacy_ops *legacy;
257 const struct ieee80211_ops *ieee80211_ops;
244}; 258};
245 259
246struct iwl_mod_params { 260struct iwl_mod_params {
@@ -276,6 +290,7 @@ struct iwl_mod_params {
276 * sensitivity calibration operation 290 * sensitivity calibration operation
277 * @chain_noise_calib_by_driver: driver has the capability to perform 291 * @chain_noise_calib_by_driver: driver has the capability to perform
278 * chain noise calibration operation 292 * chain noise calibration operation
293 * @shadow_reg_enable: HW shadhow register bit
279*/ 294*/
280struct iwl_base_params { 295struct iwl_base_params {
281 int eeprom_size; 296 int eeprom_size;
@@ -306,6 +321,7 @@ struct iwl_base_params {
306 const bool ucode_tracing; 321 const bool ucode_tracing;
307 const bool sensitivity_calib_by_driver; 322 const bool sensitivity_calib_by_driver;
308 const bool chain_noise_calib_by_driver; 323 const bool chain_noise_calib_by_driver;
324 const bool shadow_reg_enable;
309}; 325};
310/* 326/*
311 * @advanced_bt_coexist: support advanced bt coexist 327 * @advanced_bt_coexist: support advanced bt coexist
@@ -396,8 +412,7 @@ struct iwl_cfg {
396 * L i b * 412 * L i b *
397 ***************************/ 413 ***************************/
398 414
399struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 415struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg);
400 struct ieee80211_ops *hw_ops);
401int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 416int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
402 const struct ieee80211_tx_queue_params *params); 417 const struct ieee80211_tx_queue_params *params);
403int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); 418int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -425,23 +440,16 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
425 u32 decrypt_res, 440 u32 decrypt_res,
426 struct ieee80211_rx_status *stats); 441 struct ieee80211_rx_status *stats);
427void iwl_irq_handle_error(struct iwl_priv *priv); 442void iwl_irq_handle_error(struct iwl_priv *priv);
428void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
429void iwl_bss_info_changed(struct ieee80211_hw *hw,
430 struct ieee80211_vif *vif,
431 struct ieee80211_bss_conf *bss_conf,
432 u32 changes);
433int iwl_mac_add_interface(struct ieee80211_hw *hw, 443int iwl_mac_add_interface(struct ieee80211_hw *hw,
434 struct ieee80211_vif *vif); 444 struct ieee80211_vif *vif);
435void iwl_mac_remove_interface(struct ieee80211_hw *hw, 445void iwl_mac_remove_interface(struct ieee80211_hw *hw,
436 struct ieee80211_vif *vif); 446 struct ieee80211_vif *vif);
437int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 447int iwl_mac_change_interface(struct ieee80211_hw *hw,
438void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif); 448 struct ieee80211_vif *vif,
439void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 449 enum nl80211_iftype newtype, bool newp2p);
440int iwl_alloc_txq_mem(struct iwl_priv *priv); 450int iwl_alloc_txq_mem(struct iwl_priv *priv);
441void iwl_free_txq_mem(struct iwl_priv *priv); 451void iwl_free_txq_mem(struct iwl_priv *priv);
442void iwlcore_tx_cmd_protection(struct iwl_priv *priv, 452
443 struct ieee80211_tx_info *info,
444 __le16 fc, __le32 *tx_flags);
445#ifdef CONFIG_IWLWIFI_DEBUGFS 453#ifdef CONFIG_IWLWIFI_DEBUGFS
446int iwl_alloc_traffic_mem(struct iwl_priv *priv); 454int iwl_alloc_traffic_mem(struct iwl_priv *priv);
447void iwl_free_traffic_mem(struct iwl_priv *priv); 455void iwl_free_traffic_mem(struct iwl_priv *priv);
@@ -598,7 +606,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
598/***************************************************** 606/*****************************************************
599 * PCI * 607 * PCI *
600 *****************************************************/ 608 *****************************************************/
601irqreturn_t iwl_isr_legacy(int irq, void *data);
602 609
603static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) 610static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
604{ 611{
@@ -615,9 +622,17 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
615 u32 addon, u32 beacon_interval); 622 u32 addon, u32 beacon_interval);
616 623
617#ifdef CONFIG_PM 624#ifdef CONFIG_PM
618int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); 625int iwl_pci_suspend(struct device *device);
619int iwl_pci_resume(struct pci_dev *pdev); 626int iwl_pci_resume(struct device *device);
620#endif /* CONFIG_PM */ 627extern const struct dev_pm_ops iwl_pm_ops;
628
629#define IWL_PM_OPS (&iwl_pm_ops)
630
631#else /* !CONFIG_PM */
632
633#define IWL_PM_OPS NULL
634
635#endif /* !CONFIG_PM */
621 636
622/***************************************************** 637/*****************************************************
623* Error Handling Debugging 638* Error Handling Debugging
@@ -724,11 +739,6 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
724{ 739{
725 return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); 740 return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
726} 741}
727static inline void iwlcore_config_ap(struct iwl_priv *priv,
728 struct ieee80211_vif *vif)
729{
730 priv->cfg->ops->lib->config_ap(priv, vif);
731}
732static inline const struct ieee80211_supported_band *iwl_get_hw_mode( 742static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
733 struct iwl_priv *priv, enum ieee80211_band band) 743 struct iwl_priv *priv, enum ieee80211_band band)
734{ 744{
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 2aa15ab13892..b80bf7dff55b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -132,6 +132,8 @@
132 132
133#define CSR_LED_REG (CSR_BASE+0x094) 133#define CSR_LED_REG (CSR_BASE+0x094)
134#define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0) 134#define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0)
135#define CSR_MAC_SHADOW_REG_CTRL (CSR_BASE+0x0A8) /* 6000 and up */
136
135 137
136/* GIO Chicken Bits (PCI Express bus link power management) */ 138/* GIO Chicken Bits (PCI Express bus link power management) */
137#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) 139#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 70e07fa48405..9fcaaf0cfe93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1162,6 +1162,8 @@ struct iwl_rxon_context {
1162 */ 1162 */
1163 bool always_active, is_active; 1163 bool always_active, is_active;
1164 1164
1165 bool ht_need_multiple_chains;
1166
1165 enum iwl_rxon_context_id ctxid; 1167 enum iwl_rxon_context_id ctxid;
1166 1168
1167 u32 interface_modes, exclusive_interface_modes; 1169 u32 interface_modes, exclusive_interface_modes;
@@ -1517,6 +1519,7 @@ struct iwl_priv {
1517 s8 tx_power_user_lmt; 1519 s8 tx_power_user_lmt;
1518 s8 tx_power_device_lmt; 1520 s8 tx_power_device_lmt;
1519 s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */ 1521 s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */
1522 s8 tx_power_next;
1520 1523
1521 1524
1522#ifdef CONFIG_IWLWIFI_DEBUG 1525#ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 86c2b6fed0c6..5a9129219c90 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -134,6 +134,7 @@ int iwl_led_associate(struct iwl_priv *priv)
134 134
135 return 0; 135 return 0;
136} 136}
137EXPORT_SYMBOL(iwl_led_associate);
137 138
138int iwl_led_disassociate(struct iwl_priv *priv) 139int iwl_led_disassociate(struct iwl_priv *priv)
139{ 140{
@@ -141,6 +142,7 @@ int iwl_led_disassociate(struct iwl_priv *priv)
141 142
142 return 0; 143 return 0;
143} 144}
145EXPORT_SYMBOL(iwl_led_disassociate);
144 146
145/* 147/*
146 * calculate blink rate according to last second Tx/Rx activities 148 * calculate blink rate according to last second Tx/Rx activities
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c
new file mode 100644
index 000000000000..a08b4e56e6b1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c
@@ -0,0 +1,662 @@
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#include <linux/kernel.h>
30#include <net/mac80211.h>
31
32#include "iwl-dev.h"
33#include "iwl-core.h"
34#include "iwl-helpers.h"
35#include "iwl-legacy.h"
36
37static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
38{
39 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
40 return;
41
42 if (!ctx->is_active)
43 return;
44
45 ctx->qos_data.def_qos_parm.qos_flags = 0;
46
47 if (ctx->qos_data.qos_active)
48 ctx->qos_data.def_qos_parm.qos_flags |=
49 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
50
51 if (ctx->ht.enabled)
52 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
53
54 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
55 ctx->qos_data.qos_active,
56 ctx->qos_data.def_qos_parm.qos_flags);
57
58 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
59 sizeof(struct iwl_qosparam_cmd),
60 &ctx->qos_data.def_qos_parm, NULL);
61}
62
63/**
64 * iwl_legacy_mac_config - mac80211 config callback
65 */
66int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
67{
68 struct iwl_priv *priv = hw->priv;
69 const struct iwl_channel_info *ch_info;
70 struct ieee80211_conf *conf = &hw->conf;
71 struct ieee80211_channel *channel = conf->channel;
72 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
73 struct iwl_rxon_context *ctx;
74 unsigned long flags = 0;
75 int ret = 0;
76 u16 ch;
77 int scan_active = 0;
78 bool ht_changed[NUM_IWL_RXON_CTX] = {};
79
80 if (WARN_ON(!priv->cfg->ops->legacy))
81 return -EOPNOTSUPP;
82
83 mutex_lock(&priv->mutex);
84
85 IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
86 channel->hw_value, changed);
87
88 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
89 test_bit(STATUS_SCANNING, &priv->status))) {
90 scan_active = 1;
91 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
92 }
93
94 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
95 IEEE80211_CONF_CHANGE_CHANNEL)) {
96 /* mac80211 uses static for non-HT which is what we want */
97 priv->current_ht_config.smps = conf->smps_mode;
98
99 /*
100 * Recalculate chain counts.
101 *
102 * If monitor mode is enabled then mac80211 will
103 * set up the SM PS mode to OFF if an HT channel is
104 * configured.
105 */
106 if (priv->cfg->ops->hcmd->set_rxon_chain)
107 for_each_context(priv, ctx)
108 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
109 }
110
111 /* during scanning mac80211 will delay channel setting until
112 * scan finish with changed = 0
113 */
114 if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
115 if (scan_active)
116 goto set_ch_out;
117
118 ch = channel->hw_value;
119 ch_info = iwl_get_channel_info(priv, channel->band, ch);
120 if (!is_channel_valid(ch_info)) {
121 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
122 ret = -EINVAL;
123 goto set_ch_out;
124 }
125
126 spin_lock_irqsave(&priv->lock, flags);
127
128 for_each_context(priv, ctx) {
129 /* Configure HT40 channels */
130 if (ctx->ht.enabled != conf_is_ht(conf)) {
131 ctx->ht.enabled = conf_is_ht(conf);
132 ht_changed[ctx->ctxid] = true;
133 }
134 if (ctx->ht.enabled) {
135 if (conf_is_ht40_minus(conf)) {
136 ctx->ht.extension_chan_offset =
137 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
138 ctx->ht.is_40mhz = true;
139 } else if (conf_is_ht40_plus(conf)) {
140 ctx->ht.extension_chan_offset =
141 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
142 ctx->ht.is_40mhz = true;
143 } else {
144 ctx->ht.extension_chan_offset =
145 IEEE80211_HT_PARAM_CHA_SEC_NONE;
146 ctx->ht.is_40mhz = false;
147 }
148 } else
149 ctx->ht.is_40mhz = false;
150
151 /*
152 * Default to no protection. Protection mode will
153 * later be set from BSS config in iwl_ht_conf
154 */
155 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
156
157 /* if we are switching from ht to 2.4 clear flags
158 * from any ht related info since 2.4 does not
159 * support ht */
160 if ((le16_to_cpu(ctx->staging.channel) != ch))
161 ctx->staging.flags = 0;
162
163 iwl_set_rxon_channel(priv, channel, ctx);
164 iwl_set_rxon_ht(priv, ht_conf);
165
166 iwl_set_flags_for_band(priv, ctx, channel->band,
167 ctx->vif);
168 }
169
170 spin_unlock_irqrestore(&priv->lock, flags);
171
172 if (priv->cfg->ops->legacy->update_bcast_stations)
173 ret = priv->cfg->ops->legacy->update_bcast_stations(priv);
174
175 set_ch_out:
176 /* The list of supported rates and rate mask can be different
177 * for each band; since the band may have changed, reset
178 * the rate mask to what mac80211 lists */
179 iwl_set_rate(priv);
180 }
181
182 if (changed & (IEEE80211_CONF_CHANGE_PS |
183 IEEE80211_CONF_CHANGE_IDLE)) {
184 ret = iwl_power_update_mode(priv, false);
185 if (ret)
186 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
187 }
188
189 if (changed & IEEE80211_CONF_CHANGE_POWER) {
190 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
191 priv->tx_power_user_lmt, conf->power_level);
192
193 iwl_set_tx_power(priv, conf->power_level, false);
194 }
195
196 if (!iwl_is_ready(priv)) {
197 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
198 goto out;
199 }
200
201 if (scan_active)
202 goto out;
203
204 for_each_context(priv, ctx) {
205 if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
206 iwlcore_commit_rxon(priv, ctx);
207 else
208 IWL_DEBUG_INFO(priv,
209 "Not re-sending same RXON configuration.\n");
210 if (ht_changed[ctx->ctxid])
211 iwl_update_qos(priv, ctx);
212 }
213
214out:
215 IWL_DEBUG_MAC80211(priv, "leave\n");
216 mutex_unlock(&priv->mutex);
217 return ret;
218}
219EXPORT_SYMBOL(iwl_legacy_mac_config);
220
221void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw)
222{
223 struct iwl_priv *priv = hw->priv;
224 unsigned long flags;
225 /* IBSS can only be the IWL_RXON_CTX_BSS context */
226 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
227
228 if (WARN_ON(!priv->cfg->ops->legacy))
229 return;
230
231 mutex_lock(&priv->mutex);
232 IWL_DEBUG_MAC80211(priv, "enter\n");
233
234 spin_lock_irqsave(&priv->lock, flags);
235 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
236 spin_unlock_irqrestore(&priv->lock, flags);
237
238 spin_lock_irqsave(&priv->lock, flags);
239
240 /* new association get rid of ibss beacon skb */
241 if (priv->beacon_skb)
242 dev_kfree_skb(priv->beacon_skb);
243
244 priv->beacon_skb = NULL;
245
246 priv->timestamp = 0;
247
248 spin_unlock_irqrestore(&priv->lock, flags);
249
250 iwl_scan_cancel_timeout(priv, 100);
251 if (!iwl_is_ready_rf(priv)) {
252 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
253 mutex_unlock(&priv->mutex);
254 return;
255 }
256
257 /* we are restarting association process
258 * clear RXON_FILTER_ASSOC_MSK bit
259 */
260 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
261 iwlcore_commit_rxon(priv, ctx);
262
263 iwl_set_rate(priv);
264
265 mutex_unlock(&priv->mutex);
266
267 IWL_DEBUG_MAC80211(priv, "leave\n");
268}
269EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf);
270
271static void iwl_ht_conf(struct iwl_priv *priv,
272 struct ieee80211_vif *vif)
273{
274 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
275 struct ieee80211_sta *sta;
276 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
277 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
278
279 IWL_DEBUG_ASSOC(priv, "enter:\n");
280
281 if (!ctx->ht.enabled)
282 return;
283
284 ctx->ht.protection =
285 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
286 ctx->ht.non_gf_sta_present =
287 !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
288
289 ht_conf->single_chain_sufficient = false;
290
291 switch (vif->type) {
292 case NL80211_IFTYPE_STATION:
293 rcu_read_lock();
294 sta = ieee80211_find_sta(vif, bss_conf->bssid);
295 if (sta) {
296 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
297 int maxstreams;
298
299 maxstreams = (ht_cap->mcs.tx_params &
300 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
301 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
302 maxstreams += 1;
303
304 if ((ht_cap->mcs.rx_mask[1] == 0) &&
305 (ht_cap->mcs.rx_mask[2] == 0))
306 ht_conf->single_chain_sufficient = true;
307 if (maxstreams <= 1)
308 ht_conf->single_chain_sufficient = true;
309 } else {
310 /*
311 * If at all, this can only happen through a race
312 * when the AP disconnects us while we're still
313 * setting up the connection, in that case mac80211
314 * will soon tell us about that.
315 */
316 ht_conf->single_chain_sufficient = true;
317 }
318 rcu_read_unlock();
319 break;
320 case NL80211_IFTYPE_ADHOC:
321 ht_conf->single_chain_sufficient = true;
322 break;
323 default:
324 break;
325 }
326
327 IWL_DEBUG_ASSOC(priv, "leave\n");
328}
329
330static inline void iwl_set_no_assoc(struct iwl_priv *priv,
331 struct ieee80211_vif *vif)
332{
333 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
334
335 iwl_led_disassociate(priv);
336 /*
337 * inform the ucode that there is no longer an
338 * association and that no more packets should be
339 * sent
340 */
341 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
342 ctx->staging.assoc_id = 0;
343 iwlcore_commit_rxon(priv, ctx);
344}
345
346static void iwlcore_beacon_update(struct ieee80211_hw *hw,
347 struct ieee80211_vif *vif)
348{
349 struct iwl_priv *priv = hw->priv;
350 unsigned long flags;
351 __le64 timestamp;
352 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
353
354 if (!skb)
355 return;
356
357 IWL_DEBUG_MAC80211(priv, "enter\n");
358
359 lockdep_assert_held(&priv->mutex);
360
361 if (!priv->beacon_ctx) {
362 IWL_ERR(priv, "update beacon but no beacon context!\n");
363 dev_kfree_skb(skb);
364 return;
365 }
366
367 spin_lock_irqsave(&priv->lock, flags);
368
369 if (priv->beacon_skb)
370 dev_kfree_skb(priv->beacon_skb);
371
372 priv->beacon_skb = skb;
373
374 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
375 priv->timestamp = le64_to_cpu(timestamp);
376
377 IWL_DEBUG_MAC80211(priv, "leave\n");
378 spin_unlock_irqrestore(&priv->lock, flags);
379
380 if (!iwl_is_ready_rf(priv)) {
381 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
382 return;
383 }
384
385 priv->cfg->ops->legacy->post_associate(priv);
386}
387
388void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
389 struct ieee80211_vif *vif,
390 struct ieee80211_bss_conf *bss_conf,
391 u32 changes)
392{
393 struct iwl_priv *priv = hw->priv;
394 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
395 int ret;
396
397 if (WARN_ON(!priv->cfg->ops->legacy))
398 return;
399
400 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
401
402 if (!iwl_is_alive(priv))
403 return;
404
405 mutex_lock(&priv->mutex);
406
407 if (changes & BSS_CHANGED_QOS) {
408 unsigned long flags;
409
410 spin_lock_irqsave(&priv->lock, flags);
411 ctx->qos_data.qos_active = bss_conf->qos;
412 iwl_update_qos(priv, ctx);
413 spin_unlock_irqrestore(&priv->lock, flags);
414 }
415
416 if (changes & BSS_CHANGED_BEACON_ENABLED) {
417 /*
418 * the add_interface code must make sure we only ever
419 * have a single interface that could be beaconing at
420 * any time.
421 */
422 if (vif->bss_conf.enable_beacon)
423 priv->beacon_ctx = ctx;
424 else
425 priv->beacon_ctx = NULL;
426 }
427
428 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
429 dev_kfree_skb(priv->beacon_skb);
430 priv->beacon_skb = ieee80211_beacon_get(hw, vif);
431 }
432
433 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
434 iwl_send_rxon_timing(priv, ctx);
435
436 if (changes & BSS_CHANGED_BSSID) {
437 IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
438
439 /*
440 * If there is currently a HW scan going on in the
441 * background then we need to cancel it else the RXON
442 * below/in post_associate will fail.
443 */
444 if (iwl_scan_cancel_timeout(priv, 100)) {
445 IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
446 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
447 mutex_unlock(&priv->mutex);
448 return;
449 }
450
451 /* mac80211 only sets assoc when in STATION mode */
452 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
453 memcpy(ctx->staging.bssid_addr,
454 bss_conf->bssid, ETH_ALEN);
455
456 /* currently needed in a few places */
457 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
458 } else {
459 ctx->staging.filter_flags &=
460 ~RXON_FILTER_ASSOC_MSK;
461 }
462
463 }
464
465 /*
466 * This needs to be after setting the BSSID in case
467 * mac80211 decides to do both changes at once because
468 * it will invoke post_associate.
469 */
470 if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
471 iwlcore_beacon_update(hw, vif);
472
473 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
474 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
475 bss_conf->use_short_preamble);
476 if (bss_conf->use_short_preamble)
477 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
478 else
479 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
480 }
481
482 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
483 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
484 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
485 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
486 else
487 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
488 if (bss_conf->use_cts_prot)
489 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
490 else
491 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
492 }
493
494 if (changes & BSS_CHANGED_BASIC_RATES) {
495 /* XXX use this information
496 *
497 * To do that, remove code from iwl_set_rate() and put something
498 * like this here:
499 *
500 if (A-band)
501 ctx->staging.ofdm_basic_rates =
502 bss_conf->basic_rates;
503 else
504 ctx->staging.ofdm_basic_rates =
505 bss_conf->basic_rates >> 4;
506 ctx->staging.cck_basic_rates =
507 bss_conf->basic_rates & 0xF;
508 */
509 }
510
511 if (changes & BSS_CHANGED_HT) {
512 iwl_ht_conf(priv, vif);
513
514 if (priv->cfg->ops->hcmd->set_rxon_chain)
515 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
516 }
517
518 if (changes & BSS_CHANGED_ASSOC) {
519 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
520 if (bss_conf->assoc) {
521 priv->timestamp = bss_conf->timestamp;
522
523 iwl_led_associate(priv);
524
525 if (!iwl_is_rfkill(priv))
526 priv->cfg->ops->legacy->post_associate(priv);
527 } else
528 iwl_set_no_assoc(priv, vif);
529 }
530
531 if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
532 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
533 changes);
534 ret = iwl_send_rxon_assoc(priv, ctx);
535 if (!ret) {
536 /* Sync active_rxon with latest change. */
537 memcpy((void *)&ctx->active,
538 &ctx->staging,
539 sizeof(struct iwl_rxon_cmd));
540 }
541 }
542
543 if (changes & BSS_CHANGED_BEACON_ENABLED) {
544 if (vif->bss_conf.enable_beacon) {
545 memcpy(ctx->staging.bssid_addr,
546 bss_conf->bssid, ETH_ALEN);
547 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
548 iwl_led_associate(priv);
549 priv->cfg->ops->legacy->config_ap(priv);
550 } else
551 iwl_set_no_assoc(priv, vif);
552 }
553
554 if (changes & BSS_CHANGED_IBSS) {
555 ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif,
556 bss_conf->ibss_joined);
557 if (ret)
558 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
559 bss_conf->ibss_joined ? "add" : "remove",
560 bss_conf->bssid);
561 }
562
563 mutex_unlock(&priv->mutex);
564
565 IWL_DEBUG_MAC80211(priv, "leave\n");
566}
567EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed);
568
569irqreturn_t iwl_isr_legacy(int irq, void *data)
570{
571 struct iwl_priv *priv = data;
572 u32 inta, inta_mask;
573 u32 inta_fh;
574 unsigned long flags;
575 if (!priv)
576 return IRQ_NONE;
577
578 spin_lock_irqsave(&priv->lock, flags);
579
580 /* Disable (but don't clear!) interrupts here to avoid
581 * back-to-back ISRs and sporadic interrupts from our NIC.
582 * If we have something to service, the tasklet will re-enable ints.
583 * If we *don't* have something, we'll re-enable before leaving here. */
584 inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
585 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
586
587 /* Discover which interrupts are active/pending */
588 inta = iwl_read32(priv, CSR_INT);
589 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
590
591 /* Ignore interrupt if there's nothing in NIC to service.
592 * This may be due to IRQ shared with another device,
593 * or due to sporadic interrupts thrown from our NIC. */
594 if (!inta && !inta_fh) {
595 IWL_DEBUG_ISR(priv,
596 "Ignore interrupt, inta == 0, inta_fh == 0\n");
597 goto none;
598 }
599
600 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
601 /* Hardware disappeared. It might have already raised
602 * an interrupt */
603 IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
604 goto unplugged;
605 }
606
607 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
608 inta, inta_mask, inta_fh);
609
610 inta &= ~CSR_INT_BIT_SCD;
611
612 /* iwl_irq_tasklet() will service interrupts and re-enable them */
613 if (likely(inta || inta_fh))
614 tasklet_schedule(&priv->irq_tasklet);
615
616unplugged:
617 spin_unlock_irqrestore(&priv->lock, flags);
618 return IRQ_HANDLED;
619
620none:
621 /* re-enable interrupts here since we don't have anything to service. */
622 /* only Re-enable if diabled by irq */
623 if (test_bit(STATUS_INT_ENABLED, &priv->status))
624 iwl_enable_interrupts(priv);
625 spin_unlock_irqrestore(&priv->lock, flags);
626 return IRQ_NONE;
627}
628EXPORT_SYMBOL(iwl_isr_legacy);
629
630/*
631 * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this
632 * function.
633 */
634void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
635 struct ieee80211_tx_info *info,
636 __le16 fc, __le32 *tx_flags)
637{
638 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
639 *tx_flags |= TX_CMD_FLG_RTS_MSK;
640 *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
641 *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
642
643 if (!ieee80211_is_mgmt(fc))
644 return;
645
646 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
647 case cpu_to_le16(IEEE80211_STYPE_AUTH):
648 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
649 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
650 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
651 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
652 *tx_flags |= TX_CMD_FLG_CTS_MSK;
653 break;
654 }
655 } else if (info->control.rates[0].flags &
656 IEEE80211_TX_RC_USE_CTS_PROTECT) {
657 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
658 *tx_flags |= TX_CMD_FLG_CTS_MSK;
659 *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
660 }
661}
662EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection);
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h
new file mode 100644
index 000000000000..9f7b2f935964
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h
@@ -0,0 +1,79 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_legacy_h__
64#define __iwl_legacy_h__
65
66/* mac80211 handlers */
67int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed);
68void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw);
69void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
70 struct ieee80211_vif *vif,
71 struct ieee80211_bss_conf *bss_conf,
72 u32 changes);
73void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
74 struct ieee80211_tx_info *info,
75 __le16 fc, __le32 *tx_flags);
76
77irqreturn_t iwl_isr_legacy(int irq, void *data);
78
79#endif /* __iwl_legacy_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 49d7788937a9..b7abd86676fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -263,70 +263,95 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
263 sizeof(struct iwl_powertable_cmd), cmd); 263 sizeof(struct iwl_powertable_cmd), cmd);
264} 264}
265 265
266/* priv->mutex must be held */ 266static void iwl_power_build_cmd(struct iwl_priv *priv,
267int iwl_power_update_mode(struct iwl_priv *priv, bool force) 267 struct iwl_powertable_cmd *cmd)
268{ 268{
269 int ret = 0;
270 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; 269 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
271 bool update_chains;
272 struct iwl_powertable_cmd cmd;
273 int dtimper; 270 int dtimper;
274 271
275 /* Don't update the RX chain when chain noise calibration is running */
276 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
277 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
278
279 dtimper = priv->hw->conf.ps_dtim_period ?: 1; 272 dtimper = priv->hw->conf.ps_dtim_period ?: 1;
280 273
281 if (priv->cfg->base_params->broken_powersave) 274 if (priv->cfg->base_params->broken_powersave)
282 iwl_power_sleep_cam_cmd(priv, &cmd); 275 iwl_power_sleep_cam_cmd(priv, cmd);
283 else if (priv->cfg->base_params->supports_idle && 276 else if (priv->cfg->base_params->supports_idle &&
284 priv->hw->conf.flags & IEEE80211_CONF_IDLE) 277 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
285 iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); 278 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
286 else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && 279 else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
287 priv->cfg->ops->lib->tt_ops.tt_power_mode && 280 priv->cfg->ops->lib->tt_ops.tt_power_mode &&
288 priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { 281 priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
289 /* in thermal throttling low power state */ 282 /* in thermal throttling low power state */
290 iwl_static_sleep_cmd(priv, &cmd, 283 iwl_static_sleep_cmd(priv, cmd,
291 priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); 284 priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
292 } else if (!enabled) 285 } else if (!enabled)
293 iwl_power_sleep_cam_cmd(priv, &cmd); 286 iwl_power_sleep_cam_cmd(priv, cmd);
294 else if (priv->power_data.debug_sleep_level_override >= 0) 287 else if (priv->power_data.debug_sleep_level_override >= 0)
295 iwl_static_sleep_cmd(priv, &cmd, 288 iwl_static_sleep_cmd(priv, cmd,
296 priv->power_data.debug_sleep_level_override, 289 priv->power_data.debug_sleep_level_override,
297 dtimper); 290 dtimper);
298 else if (no_sleep_autoadjust) 291 else if (no_sleep_autoadjust)
299 iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper); 292 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_1, dtimper);
300 else 293 else
301 iwl_power_fill_sleep_cmd(priv, &cmd, 294 iwl_power_fill_sleep_cmd(priv, cmd,
302 priv->hw->conf.dynamic_ps_timeout, 295 priv->hw->conf.dynamic_ps_timeout,
303 priv->hw->conf.max_sleep_period); 296 priv->hw->conf.max_sleep_period);
297}
298
299int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
300 bool force)
301{
302 int ret;
303 bool update_chains;
304
305 lockdep_assert_held(&priv->mutex);
306
307 /* Don't update the RX chain when chain noise calibration is running */
308 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
309 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
310
311 if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force)
312 return 0;
313
314 if (!iwl_is_ready_rf(priv))
315 return -EIO;
316
317 /* scan complete use sleep_power_next, need to be updated */
318 memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd));
319 if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
320 IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n");
321 return 0;
322 }
323
324 if (cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
325 set_bit(STATUS_POWER_PMI, &priv->status);
304 326
305 if (iwl_is_ready_rf(priv) && 327 ret = iwl_set_power(priv, cmd);
306 (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) { 328 if (!ret) {
307 if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK) 329 if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
308 set_bit(STATUS_POWER_PMI, &priv->status); 330 clear_bit(STATUS_POWER_PMI, &priv->status);
309 331
310 ret = iwl_set_power(priv, &cmd); 332 if (priv->cfg->ops->lib->update_chain_flags && update_chains)
311 if (!ret) { 333 priv->cfg->ops->lib->update_chain_flags(priv);
312 if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)) 334 else if (priv->cfg->ops->lib->update_chain_flags)
313 clear_bit(STATUS_POWER_PMI, &priv->status); 335 IWL_DEBUG_POWER(priv,
314
315 if (priv->cfg->ops->lib->update_chain_flags &&
316 update_chains)
317 priv->cfg->ops->lib->update_chain_flags(priv);
318 else if (priv->cfg->ops->lib->update_chain_flags)
319 IWL_DEBUG_POWER(priv,
320 "Cannot update the power, chain noise " 336 "Cannot update the power, chain noise "
321 "calibration running: %d\n", 337 "calibration running: %d\n",
322 priv->chain_noise_data.state); 338 priv->chain_noise_data.state);
323 memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)); 339
324 } else 340 memcpy(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd));
325 IWL_ERR(priv, "set power fail, ret = %d", ret); 341 } else
326 } 342 IWL_ERR(priv, "set power fail, ret = %d", ret);
327 343
328 return ret; 344 return ret;
329} 345}
346EXPORT_SYMBOL(iwl_power_set_mode);
347
348int iwl_power_update_mode(struct iwl_priv *priv, bool force)
349{
350 struct iwl_powertable_cmd cmd;
351
352 iwl_power_build_cmd(priv, &cmd);
353 return iwl_power_set_mode(priv, &cmd, force);
354}
330EXPORT_SYMBOL(iwl_power_update_mode); 355EXPORT_SYMBOL(iwl_power_update_mode);
331 356
332/* initialize to default */ 357/* initialize to default */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index df81565a7cc4..fe012032c28c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -41,10 +41,13 @@ enum iwl_power_level {
41 41
42struct iwl_power_mgr { 42struct iwl_power_mgr {
43 struct iwl_powertable_cmd sleep_cmd; 43 struct iwl_powertable_cmd sleep_cmd;
44 struct iwl_powertable_cmd sleep_cmd_next;
44 int debug_sleep_level_override; 45 int debug_sleep_level_override;
45 bool pci_pm; 46 bool pci_pm;
46}; 47};
47 48
49int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
50 bool force);
48int iwl_power_update_mode(struct iwl_priv *priv, bool force); 51int iwl_power_update_mode(struct iwl_priv *priv, bool force);
49void iwl_power_initialize(struct iwl_priv *priv); 52void iwl_power_initialize(struct iwl_priv *priv);
50 53
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index f436270ca39a..87a6fd84d4d2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -134,28 +134,37 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q
134 if (q->need_update == 0) 134 if (q->need_update == 0)
135 goto exit_unlock; 135 goto exit_unlock;
136 136
137 /* If power-saving is in use, make sure device is awake */ 137 if (priv->cfg->base_params->shadow_reg_enable) {
138 if (test_bit(STATUS_POWER_PMI, &priv->status)) { 138 /* shadow register enabled */
139 reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); 139 /* Device expects a multiple of 8 */
140 q->write_actual = (q->write & ~0x7);
141 iwl_write32(priv, rx_wrt_ptr_reg, q->write_actual);
142 } else {
143 /* If power-saving is in use, make sure device is awake */
144 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
145 reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
140 146
141 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { 147 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
142 IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n", 148 IWL_DEBUG_INFO(priv,
143 reg); 149 "Rx queue requesting wakeup,"
144 iwl_set_bit(priv, CSR_GP_CNTRL, 150 " GP1 = 0x%x\n", reg);
145 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 151 iwl_set_bit(priv, CSR_GP_CNTRL,
146 goto exit_unlock; 152 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
147 } 153 goto exit_unlock;
154 }
148 155
149 q->write_actual = (q->write & ~0x7); 156 q->write_actual = (q->write & ~0x7);
150 iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual); 157 iwl_write_direct32(priv, rx_wrt_ptr_reg,
158 q->write_actual);
151 159
152 /* Else device is assumed to be awake */ 160 /* Else device is assumed to be awake */
153 } else { 161 } else {
154 /* Device expects a multiple of 8 */ 162 /* Device expects a multiple of 8 */
155 q->write_actual = (q->write & ~0x7); 163 q->write_actual = (q->write & ~0x7);
156 iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual); 164 iwl_write_direct32(priv, rx_wrt_ptr_reg,
165 q->write_actual);
166 }
157 } 167 }
158
159 q->need_update = 0; 168 q->need_update = 0;
160 169
161 exit_unlock: 170 exit_unlock:
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 67da31295781..e1aa0e1daa5a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -603,13 +603,16 @@ out_settings:
603 if (!iwl_is_ready_rf(priv)) 603 if (!iwl_is_ready_rf(priv))
604 goto out; 604 goto out;
605 605
606 /* Since setting the TXPOWER may have been deferred while 606 /*
607 * performing the scan, fire one off */ 607 * We do not commit power settings while scan is pending,
608 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); 608 * do it now if the settings changed.
609 */
610 iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
611 iwl_set_tx_power(priv, priv->tx_power_next, false);
609 612
610 priv->cfg->ops->utils->post_scan(priv); 613 priv->cfg->ops->utils->post_scan(priv);
611 614
612 out: 615out:
613 mutex_unlock(&priv->mutex); 616 mutex_unlock(&priv->mutex);
614} 617}
615 618
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7261ee49f282..feaa3670c6bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -49,30 +49,39 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
49 if (txq->need_update == 0) 49 if (txq->need_update == 0)
50 return; 50 return;
51 51
52 /* if we're trying to save power */ 52 if (priv->cfg->base_params->shadow_reg_enable) {
53 if (test_bit(STATUS_POWER_PMI, &priv->status)) { 53 /* shadow register enabled */
54 /* wake up nic if it's powered down ...
55 * uCode will wake up, and interrupt us again, so next
56 * time we'll skip this part. */
57 reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
58
59 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
60 IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
61 txq_id, reg);
62 iwl_set_bit(priv, CSR_GP_CNTRL,
63 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
64 return;
65 }
66
67 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
68 txq->q.write_ptr | (txq_id << 8));
69
70 /* else not in power-save mode, uCode will never sleep when we're
71 * trying to tx (during RFKILL, we're not trying to tx). */
72 } else
73 iwl_write32(priv, HBUS_TARG_WRPTR, 54 iwl_write32(priv, HBUS_TARG_WRPTR,
74 txq->q.write_ptr | (txq_id << 8)); 55 txq->q.write_ptr | (txq_id << 8));
56 } else {
57 /* if we're trying to save power */
58 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
59 /* wake up nic if it's powered down ...
60 * uCode will wake up, and interrupt us again, so next
61 * time we'll skip this part. */
62 reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
63
64 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
65 IWL_DEBUG_INFO(priv,
66 "Tx queue %d requesting wakeup,"
67 " GP1 = 0x%x\n", txq_id, reg);
68 iwl_set_bit(priv, CSR_GP_CNTRL,
69 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
70 return;
71 }
72
73 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
74 txq->q.write_ptr | (txq_id << 8));
75 75
76 /*
77 * else not in power-save mode,
78 * uCode will never sleep when we're
79 * trying to tx (during RFKILL, we're not trying to tx).
80 */
81 } else
82 iwl_write32(priv, HBUS_TARG_WRPTR,
83 txq->q.write_ptr | (txq_id << 8));
84 }
76 txq->need_update = 0; 85 txq->need_update = 0;
77} 86}
78EXPORT_SYMBOL(iwl_txq_update_write_ptr); 87EXPORT_SYMBOL(iwl_txq_update_write_ptr);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 7edf8c2fb8c7..931c546367ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -61,6 +61,7 @@
61#include "iwl-helpers.h" 61#include "iwl-helpers.h"
62#include "iwl-dev.h" 62#include "iwl-dev.h"
63#include "iwl-spectrum.h" 63#include "iwl-spectrum.h"
64#include "iwl-legacy.h"
64 65
65/* 66/*
66 * module name, copyright, version, etc. 67 * module name, copyright, version, etc.
@@ -3057,22 +3058,22 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
3057 mutex_unlock(&priv->mutex); 3058 mutex_unlock(&priv->mutex);
3058} 3059}
3059 3060
3060void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) 3061void iwl3945_post_associate(struct iwl_priv *priv)
3061{ 3062{
3062 int rc = 0; 3063 int rc = 0;
3063 struct ieee80211_conf *conf = NULL; 3064 struct ieee80211_conf *conf = NULL;
3064 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 3065 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3065 3066
3066 if (!vif || !priv->is_open) 3067 if (!ctx->vif || !priv->is_open)
3067 return; 3068 return;
3068 3069
3069 if (vif->type == NL80211_IFTYPE_AP) { 3070 if (ctx->vif->type == NL80211_IFTYPE_AP) {
3070 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3071 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3071 return; 3072 return;
3072 } 3073 }
3073 3074
3074 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3075 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3075 vif->bss_conf.aid, ctx->active.bssid_addr); 3076 ctx->vif->bss_conf.aid, ctx->active.bssid_addr);
3076 3077
3077 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3078 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3078 return; 3079 return;
@@ -3091,18 +3092,18 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3091 3092
3092 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 3093 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3093 3094
3094 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); 3095 ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
3095 3096
3096 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3097 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3097 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3098 ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int);
3098 3099
3099 if (vif->bss_conf.use_short_preamble) 3100 if (ctx->vif->bss_conf.use_short_preamble)
3100 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3101 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3101 else 3102 else
3102 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3103 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3103 3104
3104 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { 3105 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3105 if (vif->bss_conf.use_short_slot) 3106 if (ctx->vif->bss_conf.use_short_slot)
3106 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 3107 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3107 else 3108 else
3108 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3109 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
@@ -3110,7 +3111,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3110 3111
3111 iwl3945_commit_rxon(priv, ctx); 3112 iwl3945_commit_rxon(priv, ctx);
3112 3113
3113 switch (vif->type) { 3114 switch (ctx->vif->type) {
3114 case NL80211_IFTYPE_STATION: 3115 case NL80211_IFTYPE_STATION:
3115 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); 3116 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
3116 break; 3117 break;
@@ -3119,7 +3120,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3119 break; 3120 break;
3120 default: 3121 default:
3121 IWL_ERR(priv, "%s Should not be called in %d mode\n", 3122 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3122 __func__, vif->type); 3123 __func__, ctx->vif->type);
3123 break; 3124 break;
3124 } 3125 }
3125} 3126}
@@ -3234,9 +3235,10 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3234 return NETDEV_TX_OK; 3235 return NETDEV_TX_OK;
3235} 3236}
3236 3237
3237void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3238void iwl3945_config_ap(struct iwl_priv *priv)
3238{ 3239{
3239 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 3240 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3241 struct ieee80211_vif *vif = ctx->vif;
3240 int rc = 0; 3242 int rc = 0;
3241 3243
3242 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3244 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -3407,9 +3409,9 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
3407 ctx->staging.filter_flags |= filter_or; 3409 ctx->staging.filter_flags |= filter_or;
3408 3410
3409 /* 3411 /*
3410 * Committing directly here breaks for some reason, 3412 * Not committing directly because hardware can perform a scan,
3411 * but we'll eventually commit the filter flags 3413 * but even if hw is ready, committing here breaks for some reason,
3412 * change anyway. 3414 * we'll eventually commit the filter flags change anyway.
3413 */ 3415 */
3414 3416
3415 mutex_unlock(&priv->mutex); 3417 mutex_unlock(&priv->mutex);
@@ -3824,18 +3826,19 @@ static struct attribute_group iwl3945_attribute_group = {
3824 .attrs = iwl3945_sysfs_entries, 3826 .attrs = iwl3945_sysfs_entries,
3825}; 3827};
3826 3828
3827static struct ieee80211_ops iwl3945_hw_ops = { 3829struct ieee80211_ops iwl3945_hw_ops = {
3828 .tx = iwl3945_mac_tx, 3830 .tx = iwl3945_mac_tx,
3829 .start = iwl3945_mac_start, 3831 .start = iwl3945_mac_start,
3830 .stop = iwl3945_mac_stop, 3832 .stop = iwl3945_mac_stop,
3831 .add_interface = iwl_mac_add_interface, 3833 .add_interface = iwl_mac_add_interface,
3832 .remove_interface = iwl_mac_remove_interface, 3834 .remove_interface = iwl_mac_remove_interface,
3833 .config = iwl_mac_config, 3835 .change_interface = iwl_mac_change_interface,
3836 .config = iwl_legacy_mac_config,
3834 .configure_filter = iwl3945_configure_filter, 3837 .configure_filter = iwl3945_configure_filter,
3835 .set_key = iwl3945_mac_set_key, 3838 .set_key = iwl3945_mac_set_key,
3836 .conf_tx = iwl_mac_conf_tx, 3839 .conf_tx = iwl_mac_conf_tx,
3837 .reset_tsf = iwl_mac_reset_tsf, 3840 .reset_tsf = iwl_legacy_mac_reset_tsf,
3838 .bss_info_changed = iwl_bss_info_changed, 3841 .bss_info_changed = iwl_legacy_mac_bss_info_changed,
3839 .hw_scan = iwl_mac_hw_scan, 3842 .hw_scan = iwl_mac_hw_scan,
3840 .sta_add = iwl3945_mac_sta_add, 3843 .sta_add = iwl3945_mac_sta_add,
3841 .sta_remove = iwl_mac_sta_remove, 3844 .sta_remove = iwl_mac_sta_remove,
@@ -3866,6 +3869,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3866 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3869 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3867 3870
3868 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 3871 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
3872 priv->tx_power_next = IWL_DEFAULT_TX_POWER;
3869 3873
3870 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3874 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
3871 IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", 3875 IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
@@ -3965,7 +3969,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3965 3969
3966 /* mac80211 allocates memory for this device instance, including 3970 /* mac80211 allocates memory for this device instance, including
3967 * space for this driver's private structure */ 3971 * space for this driver's private structure */
3968 hw = iwl_alloc_all(cfg, &iwl3945_hw_ops); 3972 hw = iwl_alloc_all(cfg);
3969 if (hw == NULL) { 3973 if (hw == NULL) {
3970 pr_err("Can not allocate network device\n"); 3974 pr_err("Can not allocate network device\n");
3971 err = -ENOMEM; 3975 err = -ENOMEM;
@@ -4117,7 +4121,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4117 4121
4118 pci_enable_msi(priv->pci_dev); 4122 pci_enable_msi(priv->pci_dev);
4119 4123
4120 err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr, 4124 err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
4121 IRQF_SHARED, DRV_NAME, priv); 4125 IRQF_SHARED, DRV_NAME, priv);
4122 if (err) { 4126 if (err) {
4123 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); 4127 IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4275,10 +4279,7 @@ static struct pci_driver iwl3945_driver = {
4275 .id_table = iwl3945_hw_card_ids, 4279 .id_table = iwl3945_hw_card_ids,
4276 .probe = iwl3945_pci_probe, 4280 .probe = iwl3945_pci_probe,
4277 .remove = __devexit_p(iwl3945_pci_remove), 4281 .remove = __devexit_p(iwl3945_pci_remove),
4278#ifdef CONFIG_PM 4282 .driver.pm = IWL_PM_OPS,
4279 .suspend = iwl_pci_suspend,
4280 .resume = iwl_pci_resume,
4281#endif
4282}; 4283};
4283 4284
4284static int __init iwl3945_init(void) 4285static int __init iwl3945_init(void)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7eaaa3bab547..454f045ddff3 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -309,6 +309,8 @@ struct mac80211_hwsim_data {
309 */ 309 */
310 u64 group; 310 u64 group;
311 struct dentry *debugfs_group; 311 struct dentry *debugfs_group;
312
313 int power_level;
312}; 314};
313 315
314 316
@@ -497,7 +499,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
497 rx_status.band = data->channel->band; 499 rx_status.band = data->channel->band;
498 rx_status.rate_idx = info->control.rates[0].idx; 500 rx_status.rate_idx = info->control.rates[0].idx;
499 /* TODO: simulate real signal strength (and optional packet loss) */ 501 /* TODO: simulate real signal strength (and optional packet loss) */
500 rx_status.signal = -50; 502 rx_status.signal = data->power_level - 50;
501 503
502 if (data->ps != PS_DISABLED) 504 if (data->ps != PS_DISABLED)
503 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); 505 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
@@ -698,6 +700,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
698 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); 700 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
699 701
700 data->channel = conf->channel; 702 data->channel = conf->channel;
703 data->power_level = conf->power_level;
701 if (!data->started || !data->beacon_int) 704 if (!data->started || !data->beacon_int)
702 del_timer(&data->beacon_timer); 705 del_timer(&data->beacon_timer);
703 else 706 else
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index f152a25be59f..1bbcd7c1d02a 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1125,10 +1125,12 @@ struct mwl8k_tx_desc {
1125 __le32 reserved; 1125 __le32 reserved;
1126 __le16 rate_info; 1126 __le16 rate_info;
1127 __u8 peer_id; 1127 __u8 peer_id;
1128 __u8 tx_frag_cnt; 1128 __u8 xmitcontrol;
1129} __packed; 1129} __packed;
1130 1130
1131#define MWL8K_TX_DESCS 128 1131#define MWL8K_TX_DESCS 128
1132#define MWL8K_XMITCONTROL_NON_AMPDU 0x04
1133
1132 1134
1133static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) 1135static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1134{ 1136{
@@ -1448,6 +1450,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1448 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; 1450 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
1449 else 1451 else
1450 tx->peer_id = 0; 1452 tx->peer_id = 0;
1453
1454 if (priv->ap_fw)
1455 tx->xmitcontrol = MWL8K_XMITCONTROL_NON_AMPDU;
1451 wmb(); 1456 wmb();
1452 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1457 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1453 1458
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 4f420a9ec5dc..9ec6691adf0d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -885,8 +885,7 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
885 885
886 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg); 886 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
887 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 887 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
888 (state == STATE_RADIO_RX_OFF) || 888 (state == STATE_RADIO_RX_OFF));
889 (state == STATE_RADIO_RX_OFF_LINK));
890 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); 889 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
891} 890}
892 891
@@ -989,9 +988,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
989 rt2400pci_disable_radio(rt2x00dev); 988 rt2400pci_disable_radio(rt2x00dev);
990 break; 989 break;
991 case STATE_RADIO_RX_ON: 990 case STATE_RADIO_RX_ON:
992 case STATE_RADIO_RX_ON_LINK:
993 case STATE_RADIO_RX_OFF: 991 case STATE_RADIO_RX_OFF:
994 case STATE_RADIO_RX_OFF_LINK:
995 rt2400pci_toggle_rx(rt2x00dev, state); 992 rt2400pci_toggle_rx(rt2x00dev, state);
996 break; 993 break;
997 case STATE_RADIO_IRQ_ON: 994 case STATE_RADIO_IRQ_ON:
@@ -1612,6 +1609,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1612 .get_tsf = rt2400pci_get_tsf, 1609 .get_tsf = rt2400pci_get_tsf,
1613 .tx_last_beacon = rt2400pci_tx_last_beacon, 1610 .tx_last_beacon = rt2400pci_tx_last_beacon,
1614 .rfkill_poll = rt2x00mac_rfkill_poll, 1611 .rfkill_poll = rt2x00mac_rfkill_poll,
1612 .flush = rt2x00mac_flush,
1615}; 1613};
1616 1614
1617static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { 1615static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
@@ -1640,28 +1638,28 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1640}; 1638};
1641 1639
1642static const struct data_queue_desc rt2400pci_queue_rx = { 1640static const struct data_queue_desc rt2400pci_queue_rx = {
1643 .entry_num = RX_ENTRIES, 1641 .entry_num = 24,
1644 .data_size = DATA_FRAME_SIZE, 1642 .data_size = DATA_FRAME_SIZE,
1645 .desc_size = RXD_DESC_SIZE, 1643 .desc_size = RXD_DESC_SIZE,
1646 .priv_size = sizeof(struct queue_entry_priv_pci), 1644 .priv_size = sizeof(struct queue_entry_priv_pci),
1647}; 1645};
1648 1646
1649static const struct data_queue_desc rt2400pci_queue_tx = { 1647static const struct data_queue_desc rt2400pci_queue_tx = {
1650 .entry_num = TX_ENTRIES, 1648 .entry_num = 24,
1651 .data_size = DATA_FRAME_SIZE, 1649 .data_size = DATA_FRAME_SIZE,
1652 .desc_size = TXD_DESC_SIZE, 1650 .desc_size = TXD_DESC_SIZE,
1653 .priv_size = sizeof(struct queue_entry_priv_pci), 1651 .priv_size = sizeof(struct queue_entry_priv_pci),
1654}; 1652};
1655 1653
1656static const struct data_queue_desc rt2400pci_queue_bcn = { 1654static const struct data_queue_desc rt2400pci_queue_bcn = {
1657 .entry_num = BEACON_ENTRIES, 1655 .entry_num = 1,
1658 .data_size = MGMT_FRAME_SIZE, 1656 .data_size = MGMT_FRAME_SIZE,
1659 .desc_size = TXD_DESC_SIZE, 1657 .desc_size = TXD_DESC_SIZE,
1660 .priv_size = sizeof(struct queue_entry_priv_pci), 1658 .priv_size = sizeof(struct queue_entry_priv_pci),
1661}; 1659};
1662 1660
1663static const struct data_queue_desc rt2400pci_queue_atim = { 1661static const struct data_queue_desc rt2400pci_queue_atim = {
1664 .entry_num = ATIM_ENTRIES, 1662 .entry_num = 8,
1665 .data_size = DATA_FRAME_SIZE, 1663 .data_size = DATA_FRAME_SIZE,
1666 .desc_size = TXD_DESC_SIZE, 1664 .desc_size = TXD_DESC_SIZE,
1667 .priv_size = sizeof(struct queue_entry_priv_pci), 1665 .priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index c048b18f4133..d3a4a68cc439 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -809,8 +809,8 @@
809/* 809/*
810 * DMA descriptor defines. 810 * DMA descriptor defines.
811 */ 811 */
812#define TXD_DESC_SIZE ( 8 * sizeof(__le32) ) 812#define TXD_DESC_SIZE (8 * sizeof(__le32))
813#define RXD_DESC_SIZE ( 8 * sizeof(__le32) ) 813#define RXD_DESC_SIZE (8 * sizeof(__le32))
814 814
815/* 815/*
816 * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. 816 * TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
@@ -948,6 +948,6 @@
948 ((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER) 948 ((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER)
949 949
950#define TXPOWER_TO_DEV(__txpower) \ 950#define TXPOWER_TO_DEV(__txpower) \
951 MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER) 951 (MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER))
952 952
953#endif /* RT2400PCI_H */ 953#endif /* RT2400PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 97feb7aef809..3e7f20346243 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1040,8 +1040,7 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
1040 1040
1041 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg); 1041 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
1042 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1042 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
1043 (state == STATE_RADIO_RX_OFF) || 1043 (state == STATE_RADIO_RX_OFF));
1044 (state == STATE_RADIO_RX_OFF_LINK));
1045 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); 1044 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
1046} 1045}
1047 1046
@@ -1144,9 +1143,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1144 rt2500pci_disable_radio(rt2x00dev); 1143 rt2500pci_disable_radio(rt2x00dev);
1145 break; 1144 break;
1146 case STATE_RADIO_RX_ON: 1145 case STATE_RADIO_RX_ON:
1147 case STATE_RADIO_RX_ON_LINK:
1148 case STATE_RADIO_RX_OFF: 1146 case STATE_RADIO_RX_OFF:
1149 case STATE_RADIO_RX_OFF_LINK:
1150 rt2500pci_toggle_rx(rt2x00dev, state); 1147 rt2500pci_toggle_rx(rt2x00dev, state);
1151 break; 1148 break;
1152 case STATE_RADIO_IRQ_ON: 1149 case STATE_RADIO_IRQ_ON:
@@ -1193,9 +1190,9 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry,
1193 1190
1194 rt2x00_desc_read(txd, 2, &word); 1191 rt2x00_desc_read(txd, 2, &word);
1195 rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); 1192 rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
1196 rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); 1193 rt2x00_set_field32(&word, TXD_W2_AIFS, entry->queue->aifs);
1197 rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); 1194 rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->queue->cw_min);
1198 rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); 1195 rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->queue->cw_max);
1199 rt2x00_desc_write(txd, 2, word); 1196 rt2x00_desc_write(txd, 2, word);
1200 1197
1201 rt2x00_desc_read(txd, 3, &word); 1198 rt2x00_desc_read(txd, 3, &word);
@@ -1909,6 +1906,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1909 .get_tsf = rt2500pci_get_tsf, 1906 .get_tsf = rt2500pci_get_tsf,
1910 .tx_last_beacon = rt2500pci_tx_last_beacon, 1907 .tx_last_beacon = rt2500pci_tx_last_beacon,
1911 .rfkill_poll = rt2x00mac_rfkill_poll, 1908 .rfkill_poll = rt2x00mac_rfkill_poll,
1909 .flush = rt2x00mac_flush,
1912}; 1910};
1913 1911
1914static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { 1912static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
@@ -1937,28 +1935,28 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1937}; 1935};
1938 1936
1939static const struct data_queue_desc rt2500pci_queue_rx = { 1937static const struct data_queue_desc rt2500pci_queue_rx = {
1940 .entry_num = RX_ENTRIES, 1938 .entry_num = 32,
1941 .data_size = DATA_FRAME_SIZE, 1939 .data_size = DATA_FRAME_SIZE,
1942 .desc_size = RXD_DESC_SIZE, 1940 .desc_size = RXD_DESC_SIZE,
1943 .priv_size = sizeof(struct queue_entry_priv_pci), 1941 .priv_size = sizeof(struct queue_entry_priv_pci),
1944}; 1942};
1945 1943
1946static const struct data_queue_desc rt2500pci_queue_tx = { 1944static const struct data_queue_desc rt2500pci_queue_tx = {
1947 .entry_num = TX_ENTRIES, 1945 .entry_num = 32,
1948 .data_size = DATA_FRAME_SIZE, 1946 .data_size = DATA_FRAME_SIZE,
1949 .desc_size = TXD_DESC_SIZE, 1947 .desc_size = TXD_DESC_SIZE,
1950 .priv_size = sizeof(struct queue_entry_priv_pci), 1948 .priv_size = sizeof(struct queue_entry_priv_pci),
1951}; 1949};
1952 1950
1953static const struct data_queue_desc rt2500pci_queue_bcn = { 1951static const struct data_queue_desc rt2500pci_queue_bcn = {
1954 .entry_num = BEACON_ENTRIES, 1952 .entry_num = 1,
1955 .data_size = MGMT_FRAME_SIZE, 1953 .data_size = MGMT_FRAME_SIZE,
1956 .desc_size = TXD_DESC_SIZE, 1954 .desc_size = TXD_DESC_SIZE,
1957 .priv_size = sizeof(struct queue_entry_priv_pci), 1955 .priv_size = sizeof(struct queue_entry_priv_pci),
1958}; 1956};
1959 1957
1960static const struct data_queue_desc rt2500pci_queue_atim = { 1958static const struct data_queue_desc rt2500pci_queue_atim = {
1961 .entry_num = ATIM_ENTRIES, 1959 .entry_num = 8,
1962 .data_size = DATA_FRAME_SIZE, 1960 .data_size = DATA_FRAME_SIZE,
1963 .desc_size = TXD_DESC_SIZE, 1961 .desc_size = TXD_DESC_SIZE,
1964 .priv_size = sizeof(struct queue_entry_priv_pci), 1962 .priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index d708031361ac..2aad7ba8a100 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1088,8 +1088,8 @@
1088/* 1088/*
1089 * DMA descriptor defines. 1089 * DMA descriptor defines.
1090 */ 1090 */
1091#define TXD_DESC_SIZE ( 11 * sizeof(__le32) ) 1091#define TXD_DESC_SIZE (11 * sizeof(__le32))
1092#define RXD_DESC_SIZE ( 11 * sizeof(__le32) ) 1092#define RXD_DESC_SIZE (11 * sizeof(__le32))
1093 1093
1094/* 1094/*
1095 * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. 1095 * TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 93e44c7f3a74..8152fec31753 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -39,7 +39,7 @@
39/* 39/*
40 * Allow hardware encryption to be disabled. 40 * Allow hardware encryption to be disabled.
41 */ 41 */
42static int modparam_nohwcrypt = 0; 42static int modparam_nohwcrypt;
43module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 43module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
44MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 44MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
45 45
@@ -938,8 +938,7 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
938 938
939 rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg); 939 rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
940 rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX, 940 rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX,
941 (state == STATE_RADIO_RX_OFF) || 941 (state == STATE_RADIO_RX_OFF));
942 (state == STATE_RADIO_RX_OFF_LINK));
943 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); 942 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
944} 943}
945 944
@@ -1019,9 +1018,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1019 rt2500usb_disable_radio(rt2x00dev); 1018 rt2500usb_disable_radio(rt2x00dev);
1020 break; 1019 break;
1021 case STATE_RADIO_RX_ON: 1020 case STATE_RADIO_RX_ON:
1022 case STATE_RADIO_RX_ON_LINK:
1023 case STATE_RADIO_RX_OFF: 1021 case STATE_RADIO_RX_OFF:
1024 case STATE_RADIO_RX_OFF_LINK:
1025 rt2500usb_toggle_rx(rt2x00dev, state); 1022 rt2500usb_toggle_rx(rt2x00dev, state);
1026 break; 1023 break;
1027 case STATE_RADIO_IRQ_ON: 1024 case STATE_RADIO_IRQ_ON:
@@ -1081,9 +1078,9 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry,
1081 1078
1082 rt2x00_desc_read(txd, 1, &word); 1079 rt2x00_desc_read(txd, 1, &word);
1083 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); 1080 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
1084 rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); 1081 rt2x00_set_field32(&word, TXD_W1_AIFS, entry->queue->aifs);
1085 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); 1082 rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
1086 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); 1083 rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
1087 rt2x00_desc_write(txd, 1, word); 1084 rt2x00_desc_write(txd, 1, word);
1088 1085
1089 rt2x00_desc_read(txd, 2, &word); 1086 rt2x00_desc_read(txd, 2, &word);
@@ -1801,6 +1798,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1801 .bss_info_changed = rt2x00mac_bss_info_changed, 1798 .bss_info_changed = rt2x00mac_bss_info_changed,
1802 .conf_tx = rt2x00mac_conf_tx, 1799 .conf_tx = rt2x00mac_conf_tx,
1803 .rfkill_poll = rt2x00mac_rfkill_poll, 1800 .rfkill_poll = rt2x00mac_rfkill_poll,
1801 .flush = rt2x00mac_flush,
1804}; 1802};
1805 1803
1806static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { 1804static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1829,28 +1827,28 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1829}; 1827};
1830 1828
1831static const struct data_queue_desc rt2500usb_queue_rx = { 1829static const struct data_queue_desc rt2500usb_queue_rx = {
1832 .entry_num = RX_ENTRIES, 1830 .entry_num = 32,
1833 .data_size = DATA_FRAME_SIZE, 1831 .data_size = DATA_FRAME_SIZE,
1834 .desc_size = RXD_DESC_SIZE, 1832 .desc_size = RXD_DESC_SIZE,
1835 .priv_size = sizeof(struct queue_entry_priv_usb), 1833 .priv_size = sizeof(struct queue_entry_priv_usb),
1836}; 1834};
1837 1835
1838static const struct data_queue_desc rt2500usb_queue_tx = { 1836static const struct data_queue_desc rt2500usb_queue_tx = {
1839 .entry_num = TX_ENTRIES, 1837 .entry_num = 32,
1840 .data_size = DATA_FRAME_SIZE, 1838 .data_size = DATA_FRAME_SIZE,
1841 .desc_size = TXD_DESC_SIZE, 1839 .desc_size = TXD_DESC_SIZE,
1842 .priv_size = sizeof(struct queue_entry_priv_usb), 1840 .priv_size = sizeof(struct queue_entry_priv_usb),
1843}; 1841};
1844 1842
1845static const struct data_queue_desc rt2500usb_queue_bcn = { 1843static const struct data_queue_desc rt2500usb_queue_bcn = {
1846 .entry_num = BEACON_ENTRIES, 1844 .entry_num = 1,
1847 .data_size = MGMT_FRAME_SIZE, 1845 .data_size = MGMT_FRAME_SIZE,
1848 .desc_size = TXD_DESC_SIZE, 1846 .desc_size = TXD_DESC_SIZE,
1849 .priv_size = sizeof(struct queue_entry_priv_usb_bcn), 1847 .priv_size = sizeof(struct queue_entry_priv_usb_bcn),
1850}; 1848};
1851 1849
1852static const struct data_queue_desc rt2500usb_queue_atim = { 1850static const struct data_queue_desc rt2500usb_queue_atim = {
1853 .entry_num = ATIM_ENTRIES, 1851 .entry_num = 8,
1854 .data_size = DATA_FRAME_SIZE, 1852 .data_size = DATA_FRAME_SIZE,
1855 .desc_size = TXD_DESC_SIZE, 1853 .desc_size = TXD_DESC_SIZE,
1856 .priv_size = sizeof(struct queue_entry_priv_usb), 1854 .priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index eb8b6cab9925..002224c9bb62 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -412,10 +412,22 @@
412#define BCN_OFFSET1_BCN7 FIELD32(0xff000000) 412#define BCN_OFFSET1_BCN7 FIELD32(0xff000000)
413 413
414/* 414/*
415 * PBF registers 415 * TXRXQ_PCNT: PBF register
416 * Most are for debug. Driver doesn't touch PBF register. 416 * PCNT_TX0Q: Page count for TX hardware queue 0
417 * PCNT_TX1Q: Page count for TX hardware queue 1
418 * PCNT_TX2Q: Page count for TX hardware queue 2
419 * PCNT_RX0Q: Page count for RX hardware queue
417 */ 420 */
418#define TXRXQ_PCNT 0x0438 421#define TXRXQ_PCNT 0x0438
422#define TXRXQ_PCNT_TX0Q FIELD32(0x000000ff)
423#define TXRXQ_PCNT_TX1Q FIELD32(0x0000ff00)
424#define TXRXQ_PCNT_TX2Q FIELD32(0x00ff0000)
425#define TXRXQ_PCNT_RX0Q FIELD32(0xff000000)
426
427/*
428 * PBF register
429 * Debug. Driver doesn't touch PBF register.
430 */
419#define PBF_DBG 0x043c 431#define PBF_DBG 0x043c
420 432
421/* 433/*
@@ -960,8 +972,31 @@
960 972
961/* 973/*
962 * TXOP_CTRL_CFG: 974 * TXOP_CTRL_CFG:
975 * TIMEOUT_TRUN_EN: Enable/Disable TXOP timeout truncation
976 * AC_TRUN_EN: Enable/Disable truncation for AC change
977 * TXRATEGRP_TRUN_EN: Enable/Disable truncation for TX rate group change
978 * USER_MODE_TRUN_EN: Enable/Disable truncation for user TXOP mode
979 * MIMO_PS_TRUN_EN: Enable/Disable truncation for MIMO PS RTS/CTS
980 * RESERVED_TRUN_EN: Reserved
981 * LSIG_TXOP_EN: Enable/Disable L-SIG TXOP protection
982 * EXT_CCA_EN: Enable/Disable extension channel CCA reference (Defer 40Mhz
983 * transmissions if extension CCA is clear).
984 * EXT_CCA_DLY: Extension CCA signal delay time (unit: us)
985 * EXT_CWMIN: CwMin for extension channel backoff
986 * 0: Disabled
987 *
963 */ 988 */
964#define TXOP_CTRL_CFG 0x1340 989#define TXOP_CTRL_CFG 0x1340
990#define TXOP_CTRL_CFG_TIMEOUT_TRUN_EN FIELD32(0x00000001)
991#define TXOP_CTRL_CFG_AC_TRUN_EN FIELD32(0x00000002)
992#define TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN FIELD32(0x00000004)
993#define TXOP_CTRL_CFG_USER_MODE_TRUN_EN FIELD32(0x00000008)
994#define TXOP_CTRL_CFG_MIMO_PS_TRUN_EN FIELD32(0x00000010)
995#define TXOP_CTRL_CFG_RESERVED_TRUN_EN FIELD32(0x00000020)
996#define TXOP_CTRL_CFG_LSIG_TXOP_EN FIELD32(0x00000040)
997#define TXOP_CTRL_CFG_EXT_CCA_EN FIELD32(0x00000080)
998#define TXOP_CTRL_CFG_EXT_CCA_DLY FIELD32(0x0000ff00)
999#define TXOP_CTRL_CFG_EXT_CWMIN FIELD32(0x000f0000)
965 1000
966/* 1001/*
967 * TX_RTS_CFG: 1002 * TX_RTS_CFG:
@@ -1485,17 +1520,17 @@
1485#define SHARED_KEY_MODE_BASE 0x7000 1520#define SHARED_KEY_MODE_BASE 0x7000
1486 1521
1487#define MAC_WCID_ENTRY(__idx) \ 1522#define MAC_WCID_ENTRY(__idx) \
1488 ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) ) 1523 (MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)))
1489#define PAIRWISE_KEY_ENTRY(__idx) \ 1524#define PAIRWISE_KEY_ENTRY(__idx) \
1490 ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) 1525 (PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)))
1491#define MAC_IVEIV_ENTRY(__idx) \ 1526#define MAC_IVEIV_ENTRY(__idx) \
1492 ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) ) 1527 (MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)))
1493#define MAC_WCID_ATTR_ENTRY(__idx) \ 1528#define MAC_WCID_ATTR_ENTRY(__idx) \
1494 ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) 1529 (MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)))
1495#define SHARED_KEY_ENTRY(__idx) \ 1530#define SHARED_KEY_ENTRY(__idx) \
1496 ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) 1531 (SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)))
1497#define SHARED_KEY_MODE_ENTRY(__idx) \ 1532#define SHARED_KEY_MODE_ENTRY(__idx) \
1498 ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) ) 1533 (SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)))
1499 1534
1500struct mac_wcid_entry { 1535struct mac_wcid_entry {
1501 u8 mac[6]; 1536 u8 mac[6];
@@ -1635,9 +1670,9 @@ struct mac_iveiv_entry {
1635#define HW_BEACON_BASE7 0x5bc0 1670#define HW_BEACON_BASE7 0x5bc0
1636 1671
1637#define HW_BEACON_OFFSET(__index) \ 1672#define HW_BEACON_OFFSET(__index) \
1638 ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \ 1673 (((__index) < 4) ? (HW_BEACON_BASE0 + (__index * 0x0200)) : \
1639 (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \ 1674 (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
1640 (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) ) 1675 (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
1641 1676
1642/* 1677/*
1643 * BBP registers. 1678 * BBP registers.
@@ -1987,8 +2022,8 @@ struct mac_iveiv_entry {
1987/* 2022/*
1988 * DMA descriptor defines. 2023 * DMA descriptor defines.
1989 */ 2024 */
1990#define TXWI_DESC_SIZE ( 4 * sizeof(__le32) ) 2025#define TXWI_DESC_SIZE (4 * sizeof(__le32))
1991#define RXWI_DESC_SIZE ( 4 * sizeof(__le32) ) 2026#define RXWI_DESC_SIZE (4 * sizeof(__le32))
1992 2027
1993/* 2028/*
1994 * TX WI structure 2029 * TX WI structure
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 5f00e00789d8..b5d2ebab6ea8 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -277,13 +277,17 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
277 unsigned int i; 277 unsigned int i;
278 u32 reg; 278 u32 reg;
279 279
280 /*
281 * Some devices are really slow to respond here. Wait a whole second
282 * before timing out.
283 */
280 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 284 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
281 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg); 285 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
282 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) && 286 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
283 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY)) 287 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
284 return 0; 288 return 0;
285 289
286 msleep(1); 290 msleep(10);
287 } 291 }
288 292
289 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n"); 293 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
@@ -483,7 +487,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
483 txdesc->key_idx : 0xff); 487 txdesc->key_idx : 0xff);
484 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, 488 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
485 txdesc->length); 489 txdesc->length);
486 rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid); 490 rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid);
487 rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); 491 rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1);
488 rt2x00_desc_write(txwi, 1, word); 492 rt2x00_desc_write(txwi, 1, word);
489 493
@@ -727,7 +731,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
727 * that the TX_STA_FIFO stack has a size of 16. We stick to our 731 * that the TX_STA_FIFO stack has a size of 16. We stick to our
728 * tx ring size for now. 732 * tx ring size for now.
729 */ 733 */
730 for (i = 0; i < TX_ENTRIES; i++) { 734 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
731 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg); 735 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
732 if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) 736 if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
733 break; 737 break;
@@ -824,7 +828,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
824} 828}
825EXPORT_SYMBOL_GPL(rt2800_write_beacon); 829EXPORT_SYMBOL_GPL(rt2800_write_beacon);
826 830
827static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, 831static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
828 unsigned int beacon_base) 832 unsigned int beacon_base)
829{ 833{
830 int i; 834 int i;
@@ -1144,6 +1148,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
1144 struct rt2x00intf_conf *conf, const unsigned int flags) 1148 struct rt2x00intf_conf *conf, const unsigned int flags)
1145{ 1149{
1146 u32 reg; 1150 u32 reg;
1151 bool update_bssid = false;
1147 1152
1148 if (flags & CONFIG_UPDATE_TYPE) { 1153 if (flags & CONFIG_UPDATE_TYPE) {
1149 /* 1154 /*
@@ -1173,6 +1178,16 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
1173 } 1178 }
1174 1179
1175 if (flags & CONFIG_UPDATE_MAC) { 1180 if (flags & CONFIG_UPDATE_MAC) {
1181 if (flags & CONFIG_UPDATE_TYPE &&
1182 conf->sync == TSF_SYNC_AP_NONE) {
1183 /*
1184 * The BSSID register has to be set to our own mac
1185 * address in AP mode.
1186 */
1187 memcpy(conf->bssid, conf->mac, sizeof(conf->mac));
1188 update_bssid = true;
1189 }
1190
1176 if (!is_zero_ether_addr((const u8 *)conf->mac)) { 1191 if (!is_zero_ether_addr((const u8 *)conf->mac)) {
1177 reg = le32_to_cpu(conf->mac[1]); 1192 reg = le32_to_cpu(conf->mac[1]);
1178 rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); 1193 rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
@@ -1183,7 +1198,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
1183 conf->mac, sizeof(conf->mac)); 1198 conf->mac, sizeof(conf->mac));
1184 } 1199 }
1185 1200
1186 if (flags & CONFIG_UPDATE_BSSID) { 1201 if ((flags & CONFIG_UPDATE_BSSID) || update_bssid) {
1187 if (!is_zero_ether_addr((const u8 *)conf->bssid)) { 1202 if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
1188 reg = le32_to_cpu(conf->bssid[1]); 1203 reg = le32_to_cpu(conf->bssid[1]);
1189 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3); 1204 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
@@ -2097,7 +2112,23 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
2097 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); 2112 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
2098 } 2113 }
2099 2114
2100 rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f); 2115 /*
2116 * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1
2117 * although it is reserved.
2118 */
2119 rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, &reg);
2120 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
2121 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
2122 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
2123 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
2124 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
2125 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
2126 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
2127 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
2128 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
2129 rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0);
2130 rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
2131
2101 rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002); 2132 rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
2102 2133
2103 rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg); 2134 rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b26739535986..5f3a018c088d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -328,8 +328,7 @@ static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
328 328
329 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg); 329 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
330 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 330 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
331 (state == STATE_RADIO_RX_ON) || 331 (state == STATE_RADIO_RX_ON));
332 (state == STATE_RADIO_RX_ON_LINK));
333 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 332 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
334} 333}
335 334
@@ -442,7 +441,7 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
442 * if the device is booting and wasn't asleep it will return 441 * if the device is booting and wasn't asleep it will return
443 * failure when attempting to wakeup. 442 * failure when attempting to wakeup.
444 */ 443 */
445 rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2); 444 rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2);
446 445
447 if (state == STATE_AWAKE) { 446 if (state == STATE_AWAKE) {
448 rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0); 447 rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0);
@@ -477,9 +476,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
477 rt2800pci_set_state(rt2x00dev, STATE_SLEEP); 476 rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
478 break; 477 break;
479 case STATE_RADIO_RX_ON: 478 case STATE_RADIO_RX_ON:
480 case STATE_RADIO_RX_ON_LINK:
481 case STATE_RADIO_RX_OFF: 479 case STATE_RADIO_RX_OFF:
482 case STATE_RADIO_RX_OFF_LINK:
483 rt2800pci_toggle_rx(rt2x00dev, state); 480 rt2800pci_toggle_rx(rt2x00dev, state);
484 break; 481 break;
485 case STATE_RADIO_IRQ_ON: 482 case STATE_RADIO_IRQ_ON:
@@ -777,7 +774,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
777 * Since we have only one producer and one consumer we don't 774 * Since we have only one producer and one consumer we don't
778 * need to lock the kfifo. 775 * need to lock the kfifo.
779 */ 776 */
780 for (i = 0; i < TX_ENTRIES; i++) { 777 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
781 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); 778 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
782 779
783 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) 780 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
@@ -943,6 +940,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
943 .get_tsf = rt2800_get_tsf, 940 .get_tsf = rt2800_get_tsf,
944 .rfkill_poll = rt2x00mac_rfkill_poll, 941 .rfkill_poll = rt2x00mac_rfkill_poll,
945 .ampdu_action = rt2800_ampdu_action, 942 .ampdu_action = rt2800_ampdu_action,
943 .flush = rt2x00mac_flush,
946}; 944};
947 945
948static const struct rt2800_ops rt2800pci_rt2800_ops = { 946static const struct rt2800_ops rt2800pci_rt2800_ops = {
@@ -991,21 +989,21 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
991}; 989};
992 990
993static const struct data_queue_desc rt2800pci_queue_rx = { 991static const struct data_queue_desc rt2800pci_queue_rx = {
994 .entry_num = RX_ENTRIES, 992 .entry_num = 128,
995 .data_size = AGGREGATION_SIZE, 993 .data_size = AGGREGATION_SIZE,
996 .desc_size = RXD_DESC_SIZE, 994 .desc_size = RXD_DESC_SIZE,
997 .priv_size = sizeof(struct queue_entry_priv_pci), 995 .priv_size = sizeof(struct queue_entry_priv_pci),
998}; 996};
999 997
1000static const struct data_queue_desc rt2800pci_queue_tx = { 998static const struct data_queue_desc rt2800pci_queue_tx = {
1001 .entry_num = TX_ENTRIES, 999 .entry_num = 64,
1002 .data_size = AGGREGATION_SIZE, 1000 .data_size = AGGREGATION_SIZE,
1003 .desc_size = TXD_DESC_SIZE, 1001 .desc_size = TXD_DESC_SIZE,
1004 .priv_size = sizeof(struct queue_entry_priv_pci), 1002 .priv_size = sizeof(struct queue_entry_priv_pci),
1005}; 1003};
1006 1004
1007static const struct data_queue_desc rt2800pci_queue_bcn = { 1005static const struct data_queue_desc rt2800pci_queue_bcn = {
1008 .entry_num = 8 * BEACON_ENTRIES, 1006 .entry_num = 8,
1009 .data_size = 0, /* No DMA required for beacons */ 1007 .data_size = 0, /* No DMA required for beacons */
1010 .desc_size = TXWI_DESC_SIZE, 1008 .desc_size = TXWI_DESC_SIZE,
1011 .priv_size = sizeof(struct queue_entry_priv_pci), 1009 .priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index 5a8dda9b5b5a..70e050d904c8 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -38,10 +38,10 @@
38 * Queue register offset macros 38 * Queue register offset macros
39 */ 39 */
40#define TX_QUEUE_REG_OFFSET 0x10 40#define TX_QUEUE_REG_OFFSET 0x10
41#define TX_BASE_PTR(__x) TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET) 41#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET))
42#define TX_MAX_CNT(__x) TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET) 42#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET))
43#define TX_CTX_IDX(__x) TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) 43#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
44#define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) 44#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
45 45
46/* 46/*
47 * 8051 firmware image. 47 * 8051 firmware image.
@@ -52,8 +52,8 @@
52/* 52/*
53 * DMA descriptor defines. 53 * DMA descriptor defines.
54 */ 54 */
55#define TXD_DESC_SIZE ( 4 * sizeof(__le32) ) 55#define TXD_DESC_SIZE (4 * sizeof(__le32))
56#define RXD_DESC_SIZE ( 4 * sizeof(__le32) ) 56#define RXD_DESC_SIZE (4 * sizeof(__le32))
57 57
58/* 58/*
59 * TX descriptor format for TX, PRIO and Beacon Ring. 59 * TX descriptor format for TX, PRIO and Beacon Ring.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3dff56ec195a..389ecba8e891 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 = 0; 48static int modparam_nohwcrypt;
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
@@ -114,8 +114,7 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
114 114
115 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg); 115 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
116 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 116 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
117 (state == STATE_RADIO_RX_ON) || 117 (state == STATE_RADIO_RX_ON));
118 (state == STATE_RADIO_RX_ON_LINK));
119 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 118 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
120} 119}
121 120
@@ -165,7 +164,8 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
165 * this limit so reduce the number to prevent errors. 164 * this limit so reduce the number to prevent errors.
166 */ 165 */
167 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT, 166 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
168 ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3); 167 ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE)
168 / 1024) - 3);
169 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1); 169 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
170 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1); 170 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
171 rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); 171 rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
@@ -183,9 +183,9 @@ static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
183 enum dev_state state) 183 enum dev_state state)
184{ 184{
185 if (state == STATE_AWAKE) 185 if (state == STATE_AWAKE)
186 rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); 186 rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 2);
187 else 187 else
188 rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2); 188 rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2);
189 189
190 return 0; 190 return 0;
191} 191}
@@ -215,9 +215,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
215 rt2800usb_set_state(rt2x00dev, STATE_SLEEP); 215 rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
216 break; 216 break;
217 case STATE_RADIO_RX_ON: 217 case STATE_RADIO_RX_ON:
218 case STATE_RADIO_RX_ON_LINK:
219 case STATE_RADIO_RX_OFF: 218 case STATE_RADIO_RX_OFF:
220 case STATE_RADIO_RX_OFF_LINK:
221 rt2800usb_toggle_rx(rt2x00dev, state); 219 rt2800usb_toggle_rx(rt2x00dev, state);
222 break; 220 break;
223 case STATE_RADIO_IRQ_ON: 221 case STATE_RADIO_IRQ_ON:
@@ -245,6 +243,49 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
245} 243}
246 244
247/* 245/*
246 * Watchdog handlers
247 */
248static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
249{
250 unsigned int i;
251 u32 reg;
252
253 rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
254 if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
255 WARNING(rt2x00dev, "TX HW queue 0 timed out,"
256 " invoke forced kick");
257
258 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
259
260 for (i = 0; i < 10; i++) {
261 udelay(10);
262 if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q))
263 break;
264 }
265
266 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
267 }
268
269 rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
270 if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
271 WARNING(rt2x00dev, "TX HW queue 1 timed out,"
272 " invoke forced kick");
273
274 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
275
276 for (i = 0; i < 10; i++) {
277 udelay(10);
278 if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q))
279 break;
280 }
281
282 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
283 }
284
285 rt2x00usb_watchdog(rt2x00dev);
286}
287
288/*
248 * TX descriptor initialization 289 * TX descriptor initialization
249 */ 290 */
250static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) 291static __le32 *rt2800usb_get_txwi(struct queue_entry *entry)
@@ -507,6 +548,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
507 .get_tsf = rt2800_get_tsf, 548 .get_tsf = rt2800_get_tsf,
508 .rfkill_poll = rt2x00mac_rfkill_poll, 549 .rfkill_poll = rt2x00mac_rfkill_poll,
509 .ampdu_action = rt2800_ampdu_action, 550 .ampdu_action = rt2800_ampdu_action,
551 .flush = rt2x00mac_flush,
510}; 552};
511 553
512static const struct rt2800_ops rt2800usb_rt2800_ops = { 554static const struct rt2800_ops rt2800usb_rt2800_ops = {
@@ -535,7 +577,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
535 .link_stats = rt2800_link_stats, 577 .link_stats = rt2800_link_stats,
536 .reset_tuner = rt2800_reset_tuner, 578 .reset_tuner = rt2800_reset_tuner,
537 .link_tuner = rt2800_link_tuner, 579 .link_tuner = rt2800_link_tuner,
538 .watchdog = rt2x00usb_watchdog, 580 .watchdog = rt2800usb_watchdog,
539 .write_tx_desc = rt2800usb_write_tx_desc, 581 .write_tx_desc = rt2800usb_write_tx_desc,
540 .write_tx_data = rt2800_write_tx_data, 582 .write_tx_data = rt2800_write_tx_data,
541 .write_beacon = rt2800_write_beacon, 583 .write_beacon = rt2800_write_beacon,
@@ -553,21 +595,21 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
553}; 595};
554 596
555static const struct data_queue_desc rt2800usb_queue_rx = { 597static const struct data_queue_desc rt2800usb_queue_rx = {
556 .entry_num = RX_ENTRIES, 598 .entry_num = 128,
557 .data_size = AGGREGATION_SIZE, 599 .data_size = AGGREGATION_SIZE,
558 .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE, 600 .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE,
559 .priv_size = sizeof(struct queue_entry_priv_usb), 601 .priv_size = sizeof(struct queue_entry_priv_usb),
560}; 602};
561 603
562static const struct data_queue_desc rt2800usb_queue_tx = { 604static const struct data_queue_desc rt2800usb_queue_tx = {
563 .entry_num = TX_ENTRIES, 605 .entry_num = 64,
564 .data_size = AGGREGATION_SIZE, 606 .data_size = AGGREGATION_SIZE,
565 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, 607 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
566 .priv_size = sizeof(struct queue_entry_priv_usb), 608 .priv_size = sizeof(struct queue_entry_priv_usb),
567}; 609};
568 610
569static const struct data_queue_desc rt2800usb_queue_bcn = { 611static const struct data_queue_desc rt2800usb_queue_bcn = {
570 .entry_num = 8 * BEACON_ENTRIES, 612 .entry_num = 8,
571 .data_size = MGMT_FRAME_SIZE, 613 .data_size = MGMT_FRAME_SIZE,
572 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, 614 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
573 .priv_size = sizeof(struct queue_entry_priv_usb), 615 .priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 0722badccf86..671ea3592610 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -40,8 +40,8 @@
40/* 40/*
41 * DMA descriptor defines. 41 * DMA descriptor defines.
42 */ 42 */
43#define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 43#define TXINFO_DESC_SIZE (1 * sizeof(__le32))
44#define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) 44#define RXINFO_DESC_SIZE (1 * sizeof(__le32))
45 45
46/* 46/*
47 * TX Info structure 47 * TX Info structure
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 94fe589acfaa..42bd3a96f23b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1133,6 +1133,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
1133int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 1133int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
1134 const struct ieee80211_tx_queue_params *params); 1134 const struct ieee80211_tx_queue_params *params);
1135void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); 1135void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
1136void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
1136 1137
1137/* 1138/*
1138 * Driver allocation handlers. 1139 * Driver allocation handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 54ffb5aeb34e..a238e908c854 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -133,7 +133,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
133 */ 133 */
134 if (!(ant->flags & ANTENNA_RX_DIVERSITY)) 134 if (!(ant->flags & ANTENNA_RX_DIVERSITY))
135 config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); 135 config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
136 else if(config.rx == ANTENNA_SW_DIVERSITY) 136 else if (config.rx == ANTENNA_SW_DIVERSITY)
137 config.rx = active->rx; 137 config.rx = active->rx;
138 138
139 if (!(ant->flags & ANTENNA_TX_DIVERSITY)) 139 if (!(ant->flags & ANTENNA_TX_DIVERSITY))
@@ -146,7 +146,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
146 * else the changes will be ignored by the device. 146 * else the changes will be ignored by the device.
147 */ 147 */
148 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 148 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
149 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); 149 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
150 STATE_RADIO_RX_OFF);
150 151
151 /* 152 /*
152 * Write new antenna setup to device and reset the link tuner. 153 * Write new antenna setup to device and reset the link tuner.
@@ -160,7 +161,8 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
160 memcpy(active, &config, sizeof(config)); 161 memcpy(active, &config, sizeof(config));
161 162
162 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 163 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
163 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); 164 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
165 STATE_RADIO_RX_ON);
164} 166}
165 167
166void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, 168void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index fcdb6b0dc40f..64dfb1f6823e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -162,11 +162,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
162 struct timeval timestamp; 162 struct timeval timestamp;
163 u32 data_len; 163 u32 data_len;
164 164
165 do_gettimeofday(&timestamp); 165 if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)))
166
167 if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
168 return; 166 return;
169 167
168 do_gettimeofday(&timestamp);
169
170 if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { 170 if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
171 DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); 171 DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
172 return; 172 return;
@@ -342,7 +342,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
342 sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); 342 sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
343 343
344 queue_for_each(intf->rt2x00dev, queue) { 344 queue_for_each(intf->rt2x00dev, queue) {
345 spin_lock_irqsave(&queue->lock, irqflags); 345 spin_lock_irqsave(&queue->index_lock, irqflags);
346 346
347 temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, 347 temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
348 queue->count, queue->limit, queue->length, 348 queue->count, queue->limit, queue->length,
@@ -350,7 +350,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
350 queue->index[Q_INDEX_DMA_DONE], 350 queue->index[Q_INDEX_DMA_DONE],
351 queue->index[Q_INDEX_DONE]); 351 queue->index[Q_INDEX_DONE]);
352 352
353 spin_unlock_irqrestore(&queue->lock, irqflags); 353 spin_unlock_irqrestore(&queue->index_lock, irqflags);
354 } 354 }
355 355
356 size = strlen(data); 356 size = strlen(data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5ba79b935f09..3afa2a3ebee4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -68,7 +68,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
68 /* 68 /*
69 * Enable RX. 69 * Enable RX.
70 */ 70 */
71 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); 71 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
72 rt2x00link_start_tuner(rt2x00dev);
72 73
73 /* 74 /*
74 * Start watchdog monitoring. 75 * Start watchdog monitoring.
@@ -102,7 +103,8 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
102 /* 103 /*
103 * Disable RX. 104 * Disable RX.
104 */ 105 */
105 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); 106 rt2x00link_stop_tuner(rt2x00dev);
107 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
106 108
107 /* 109 /*
108 * Disable radio. 110 * Disable radio.
@@ -113,23 +115,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
113 rt2x00leds_led_radio(rt2x00dev, false); 115 rt2x00leds_led_radio(rt2x00dev, false);
114} 116}
115 117
116void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
117{
118 /*
119 * When we are disabling the RX, we should also stop the link tuner.
120 */
121 if (state == STATE_RADIO_RX_OFF)
122 rt2x00link_stop_tuner(rt2x00dev);
123
124 rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
125
126 /*
127 * When we are enabling the RX, we should also start the link tuner.
128 */
129 if (state == STATE_RADIO_RX_ON)
130 rt2x00link_start_tuner(rt2x00dev);
131}
132
133static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, 118static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
134 struct ieee80211_vif *vif) 119 struct ieee80211_vif *vif)
135{ 120{
@@ -483,6 +468,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
483 unsigned int header_length; 468 unsigned int header_length;
484 int rate_idx; 469 int rate_idx;
485 470
471 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
472 !test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
473 goto submit_entry;
474
486 if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) 475 if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
487 goto submit_entry; 476 goto submit_entry;
488 477
@@ -567,9 +556,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry)
567 entry->skb = skb; 556 entry->skb = skb;
568 557
569submit_entry: 558submit_entry:
570 rt2x00dev->ops->lib->clear_entry(entry); 559 entry->flags = 0;
571 rt2x00queue_index_inc(entry->queue, Q_INDEX);
572 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 560 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
561 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
562 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
563 rt2x00dev->ops->lib->clear_entry(entry);
564 rt2x00queue_index_inc(entry->queue, Q_INDEX);
565 }
573} 566}
574EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); 567EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
575 568
@@ -678,7 +671,7 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry,
678{ 671{
679 entry->flags = 0; 672 entry->flags = 0;
680 entry->bitrate = rate->bitrate; 673 entry->bitrate = rate->bitrate;
681 entry->hw_value =index; 674 entry->hw_value = index;
682 entry->hw_value_short = index; 675 entry->hw_value_short = index;
683 676
684 if (rate->flags & DEV_RATE_SHORT_PREAMBLE) 677 if (rate->flags & DEV_RATE_SHORT_PREAMBLE)
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 619da23b7b56..2cf68f82674b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -57,7 +57,7 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
57} 57}
58 58
59#define RATE_MCS(__mode, __mcs) \ 59#define RATE_MCS(__mode, __mcs) \
60 ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) ) 60 ((((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff))
61 61
62static inline int rt2x00_get_rate_mcs(const u16 mcs_value) 62static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
63{ 63{
@@ -69,7 +69,6 @@ static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
69 */ 69 */
70int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); 70int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
71void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev); 71void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
72void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
73 72
74/* 73/*
75 * Initialization handlers. 74 * Initialization handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index b971d8798ebf..bfda60eaf4ef 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -67,7 +67,7 @@
67 (__avg).avg_weight ? \ 67 (__avg).avg_weight ? \
68 ((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \ 68 ((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \
69 ((__val) * (AVG_FACTOR))) / \ 69 ((__val) * (AVG_FACTOR))) / \
70 (AVG_SAMPLES) ) : \ 70 (AVG_SAMPLES)) : \
71 ((__val) * (AVG_FACTOR)); \ 71 ((__val) * (AVG_FACTOR)); \
72 __new.avg = __new.avg_weight / (AVG_FACTOR); \ 72 __new.avg = __new.avg_weight / (AVG_FACTOR); \
73 __new; \ 73 __new; \
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c3c206a97d54..829bf4be9bc3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -283,14 +283,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
283 * invalid behavior in the device. 283 * invalid behavior in the device.
284 */ 284 */
285 memcpy(&intf->mac, vif->addr, ETH_ALEN); 285 memcpy(&intf->mac, vif->addr, ETH_ALEN);
286 if (vif->type == NL80211_IFTYPE_AP) { 286 rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
287 memcpy(&intf->bssid, vif->addr, ETH_ALEN); 287 intf->mac, NULL);
288 rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
289 intf->mac, intf->bssid);
290 } else {
291 rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
292 intf->mac, NULL);
293 }
294 288
295 /* 289 /*
296 * Some filters depend on the current working mode. We can force 290 * Some filters depend on the current working mode. We can force
@@ -358,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
358 * if for any reason the link tuner must be reset, this will be 352 * if for any reason the link tuner must be reset, this will be
359 * handled by rt2x00lib_config(). 353 * handled by rt2x00lib_config().
360 */ 354 */
361 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); 355 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF);
362 356
363 /* 357 /*
364 * When we've just turned on the radio, we want to reprogram 358 * When we've just turned on the radio, we want to reprogram
@@ -376,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
376 rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); 370 rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
377 371
378 /* Turn RX back on */ 372 /* Turn RX back on */
379 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); 373 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON);
380 374
381 return 0; 375 return 0;
382} 376}
@@ -719,3 +713,41 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
719 wiphy_rfkill_set_hw_state(hw->wiphy, !active); 713 wiphy_rfkill_set_hw_state(hw->wiphy, !active);
720} 714}
721EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); 715EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
716
717void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
718{
719 struct rt2x00_dev *rt2x00dev = hw->priv;
720 struct data_queue *queue;
721 unsigned int i = 0;
722
723 ieee80211_stop_queues(hw);
724
725 /*
726 * Run over all queues to kick them, this will force
727 * any pending frames to be transmitted.
728 */
729 tx_queue_for_each(rt2x00dev, queue) {
730 rt2x00dev->ops->lib->kick_tx_queue(queue);
731 }
732
733 /**
734 * All queues have been kicked, now wait for each queue
735 * to become empty. With a bit of luck, we only have to wait
736 * for the first queue to become empty, because while waiting
737 * for the that queue, the other queues will have transmitted
738 * all their frames as well (since they were already kicked).
739 */
740 tx_queue_for_each(rt2x00dev, queue) {
741 for (i = 0; i < 10; i++) {
742 if (rt2x00queue_empty(queue))
743 break;
744 msleep(100);
745 }
746
747 if (!rt2x00queue_empty(queue))
748 WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid);
749 }
750
751 ieee80211_wake_queues(hw);
752}
753EXPORT_SYMBOL_GPL(rt2x00mac_flush);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 2449d785cf8d..868ca19b13ea 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -105,7 +105,7 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
105 */ 105 */
106 addr = dma_alloc_coherent(rt2x00dev->dev, 106 addr = dma_alloc_coherent(rt2x00dev->dev,
107 queue->limit * queue->desc_size, 107 queue->limit * queue->desc_size,
108 &dma, GFP_KERNEL | GFP_DMA); 108 &dma, GFP_KERNEL);
109 if (!addr) 109 if (!addr)
110 return -ENOMEM; 110 return -ENOMEM;
111 111
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e360d287defb..dc543174dfad 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -311,14 +311,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
311 memset(txdesc, 0, sizeof(*txdesc)); 311 memset(txdesc, 0, sizeof(*txdesc));
312 312
313 /* 313 /*
314 * Initialize information from queue
315 */
316 txdesc->qid = entry->queue->qid;
317 txdesc->cw_min = entry->queue->cw_min;
318 txdesc->cw_max = entry->queue->cw_max;
319 txdesc->aifs = entry->queue->aifs;
320
321 /*
322 * Header and frame information. 314 * Header and frame information.
323 */ 315 */
324 txdesc->length = entry->skb->len; 316 txdesc->length = entry->skb->len;
@@ -460,12 +452,9 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
460 rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); 452 rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
461} 453}
462 454
463static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, 455static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
464 struct txentry_desc *txdesc) 456 struct txentry_desc *txdesc)
465{ 457{
466 struct data_queue *queue = entry->queue;
467 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
468
469 /* 458 /*
470 * Check if we need to kick the queue, there are however a few rules 459 * Check if we need to kick the queue, there are however a few rules
471 * 1) Don't kick unless this is the last in frame in a burst. 460 * 1) Don't kick unless this is the last in frame in a burst.
@@ -477,7 +466,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
477 */ 466 */
478 if (rt2x00queue_threshold(queue) || 467 if (rt2x00queue_threshold(queue) ||
479 !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) 468 !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
480 rt2x00dev->ops->lib->kick_tx_queue(queue); 469 queue->rt2x00dev->ops->lib->kick_tx_queue(queue);
481} 470}
482 471
483int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, 472int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -567,7 +556,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
567 556
568 rt2x00queue_index_inc(queue, Q_INDEX); 557 rt2x00queue_index_inc(queue, Q_INDEX);
569 rt2x00queue_write_tx_descriptor(entry, &txdesc); 558 rt2x00queue_write_tx_descriptor(entry, &txdesc);
570 rt2x00queue_kick_tx_queue(entry, &txdesc); 559 rt2x00queue_kick_tx_queue(queue, &txdesc);
571 560
572 return 0; 561 return 0;
573} 562}
@@ -649,10 +638,10 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
649 * it should not be kicked during this run, since it 638 * it should not be kicked during this run, since it
650 * is part of another TX operation. 639 * is part of another TX operation.
651 */ 640 */
652 spin_lock_irqsave(&queue->lock, irqflags); 641 spin_lock_irqsave(&queue->index_lock, irqflags);
653 index_start = queue->index[start]; 642 index_start = queue->index[start];
654 index_end = queue->index[end]; 643 index_end = queue->index[end];
655 spin_unlock_irqrestore(&queue->lock, irqflags); 644 spin_unlock_irqrestore(&queue->index_lock, irqflags);
656 645
657 /* 646 /*
658 * Start from the TX done pointer, this guarentees that we will 647 * Start from the TX done pointer, this guarentees that we will
@@ -706,11 +695,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
706 return NULL; 695 return NULL;
707 } 696 }
708 697
709 spin_lock_irqsave(&queue->lock, irqflags); 698 spin_lock_irqsave(&queue->index_lock, irqflags);
710 699
711 entry = &queue->entries[queue->index[index]]; 700 entry = &queue->entries[queue->index[index]];
712 701
713 spin_unlock_irqrestore(&queue->lock, irqflags); 702 spin_unlock_irqrestore(&queue->index_lock, irqflags);
714 703
715 return entry; 704 return entry;
716} 705}
@@ -726,7 +715,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
726 return; 715 return;
727 } 716 }
728 717
729 spin_lock_irqsave(&queue->lock, irqflags); 718 spin_lock_irqsave(&queue->index_lock, irqflags);
730 719
731 queue->index[index]++; 720 queue->index[index]++;
732 if (queue->index[index] >= queue->limit) 721 if (queue->index[index] >= queue->limit)
@@ -741,7 +730,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
741 queue->count++; 730 queue->count++;
742 } 731 }
743 732
744 spin_unlock_irqrestore(&queue->lock, irqflags); 733 spin_unlock_irqrestore(&queue->index_lock, irqflags);
745} 734}
746 735
747static void rt2x00queue_reset(struct data_queue *queue) 736static void rt2x00queue_reset(struct data_queue *queue)
@@ -749,7 +738,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
749 unsigned long irqflags; 738 unsigned long irqflags;
750 unsigned int i; 739 unsigned int i;
751 740
752 spin_lock_irqsave(&queue->lock, irqflags); 741 spin_lock_irqsave(&queue->index_lock, irqflags);
753 742
754 queue->count = 0; 743 queue->count = 0;
755 queue->length = 0; 744 queue->length = 0;
@@ -759,7 +748,7 @@ static void rt2x00queue_reset(struct data_queue *queue)
759 queue->last_action[i] = jiffies; 748 queue->last_action[i] = jiffies;
760 } 749 }
761 750
762 spin_unlock_irqrestore(&queue->lock, irqflags); 751 spin_unlock_irqrestore(&queue->index_lock, irqflags);
763} 752}
764 753
765void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) 754void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
@@ -809,8 +798,8 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
809 return -ENOMEM; 798 return -ENOMEM;
810 799
811#define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \ 800#define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \
812 ( ((char *)(__base)) + ((__limit) * (__esize)) + \ 801 (((char *)(__base)) + ((__limit) * (__esize)) + \
813 ((__index) * (__psize)) ) 802 ((__index) * (__psize)))
814 803
815 for (i = 0; i < queue->limit; i++) { 804 for (i = 0; i < queue->limit; i++) {
816 entries[i].flags = 0; 805 entries[i].flags = 0;
@@ -911,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
911static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, 900static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
912 struct data_queue *queue, enum data_queue_qid qid) 901 struct data_queue *queue, enum data_queue_qid qid)
913{ 902{
914 spin_lock_init(&queue->lock); 903 spin_lock_init(&queue->index_lock);
915 904
916 queue->rt2x00dev = rt2x00dev; 905 queue->rt2x00dev = rt2x00dev;
917 queue->qid = qid; 906 queue->qid = qid;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index d81d85f34866..29b051ac6401 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -43,22 +43,6 @@
43#define AGGREGATION_SIZE 3840 43#define AGGREGATION_SIZE 3840
44 44
45/** 45/**
46 * DOC: Number of entries per queue
47 *
48 * Under normal load without fragmentation, 12 entries are sufficient
49 * without the queue being filled up to the maximum. When using fragmentation
50 * and the queue threshold code, we need to add some additional margins to
51 * make sure the queue will never (or only under extreme load) fill up
52 * completely.
53 * Since we don't use preallocated DMA, having a large number of queue entries
54 * will have minimal impact on the memory requirements for the queue.
55 */
56#define RX_ENTRIES 24
57#define TX_ENTRIES 24
58#define BEACON_ENTRIES 1
59#define ATIM_ENTRIES 8
60
61/**
62 * enum data_queue_qid: Queue identification 46 * enum data_queue_qid: Queue identification
63 * 47 *
64 * @QID_AC_BE: AC BE queue 48 * @QID_AC_BE: AC BE queue
@@ -296,7 +280,6 @@ enum txentry_desc_flags {
296 * Summary of information for the frame descriptor before sending a TX frame. 280 * Summary of information for the frame descriptor before sending a TX frame.
297 * 281 *
298 * @flags: Descriptor flags (See &enum queue_entry_flags). 282 * @flags: Descriptor flags (See &enum queue_entry_flags).
299 * @qid: Queue identification (See &enum data_queue_qid).
300 * @length: Length of the entire frame. 283 * @length: Length of the entire frame.
301 * @header_length: Length of 802.11 header. 284 * @header_length: Length of 802.11 header.
302 * @length_high: PLCP length high word. 285 * @length_high: PLCP length high word.
@@ -309,11 +292,8 @@ enum txentry_desc_flags {
309 * @rate_mode: Rate mode (See @enum rate_modulation). 292 * @rate_mode: Rate mode (See @enum rate_modulation).
310 * @mpdu_density: MDPU density. 293 * @mpdu_density: MDPU density.
311 * @retry_limit: Max number of retries. 294 * @retry_limit: Max number of retries.
312 * @aifs: AIFS value.
313 * @ifs: IFS value. 295 * @ifs: IFS value.
314 * @txop: IFS value for 11n capable chips. 296 * @txop: IFS value for 11n capable chips.
315 * @cw_min: cwmin value.
316 * @cw_max: cwmax value.
317 * @cipher: Cipher type used for encryption. 297 * @cipher: Cipher type used for encryption.
318 * @key_idx: Key index used for encryption. 298 * @key_idx: Key index used for encryption.
319 * @iv_offset: Position where IV should be inserted by hardware. 299 * @iv_offset: Position where IV should be inserted by hardware.
@@ -322,8 +302,6 @@ enum txentry_desc_flags {
322struct txentry_desc { 302struct txentry_desc {
323 unsigned long flags; 303 unsigned long flags;
324 304
325 enum data_queue_qid qid;
326
327 u16 length; 305 u16 length;
328 u16 header_length; 306 u16 header_length;
329 307
@@ -339,11 +317,8 @@ struct txentry_desc {
339 u16 mpdu_density; 317 u16 mpdu_density;
340 318
341 short retry_limit; 319 short retry_limit;
342 short aifs;
343 short ifs; 320 short ifs;
344 short txop; 321 short txop;
345 short cw_min;
346 short cw_max;
347 322
348 enum cipher cipher; 323 enum cipher cipher;
349 u16 key_idx; 324 u16 key_idx;
@@ -423,7 +398,7 @@ enum queue_index {
423 * @entries: Base address of the &struct queue_entry which are 398 * @entries: Base address of the &struct queue_entry which are
424 * part of this queue. 399 * part of this queue.
425 * @qid: The queue identification, see &enum data_queue_qid. 400 * @qid: The queue identification, see &enum data_queue_qid.
426 * @lock: Spinlock to protect index handling. Whenever @index, @index_done or 401 * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or
427 * @index_crypt needs to be changed this lock should be grabbed to prevent 402 * @index_crypt needs to be changed this lock should be grabbed to prevent
428 * index corruption due to concurrency. 403 * index corruption due to concurrency.
429 * @count: Number of frames handled in the queue. 404 * @count: Number of frames handled in the queue.
@@ -447,7 +422,7 @@ struct data_queue {
447 422
448 enum data_queue_qid qid; 423 enum data_queue_qid qid;
449 424
450 spinlock_t lock; 425 spinlock_t index_lock;
451 unsigned int count; 426 unsigned int count;
452 unsigned short limit; 427 unsigned short limit;
453 unsigned short threshold; 428 unsigned short threshold;
@@ -618,10 +593,10 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
618} 593}
619 594
620/** 595/**
621 * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts 596 * rt2x00queue_status_timeout - Check if a timeout occured for STATUS reports
622 * @queue: Queue to check. 597 * @queue: Queue to check.
623 */ 598 */
624static inline int rt2x00queue_timeout(struct data_queue *queue) 599static inline int rt2x00queue_status_timeout(struct data_queue *queue)
625{ 600{
626 return time_after(queue->last_action[Q_INDEX_DMA_DONE], 601 return time_after(queue->last_action[Q_INDEX_DMA_DONE],
627 queue->last_action[Q_INDEX_DONE] + (HZ / 10)); 602 queue->last_action[Q_INDEX_DONE] + (HZ / 10));
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index cef94621cef7..ed71be95136d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -85,8 +85,6 @@ enum dev_state {
85 STATE_RADIO_OFF, 85 STATE_RADIO_OFF,
86 STATE_RADIO_RX_ON, 86 STATE_RADIO_RX_ON,
87 STATE_RADIO_RX_OFF, 87 STATE_RADIO_RX_OFF,
88 STATE_RADIO_RX_ON_LINK,
89 STATE_RADIO_RX_OFF_LINK,
90 STATE_RADIO_IRQ_ON, 88 STATE_RADIO_IRQ_ON,
91 STATE_RADIO_IRQ_OFF, 89 STATE_RADIO_IRQ_OFF,
92 STATE_RADIO_IRQ_ON_ISR, 90 STATE_RADIO_IRQ_ON_ISR,
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index b3317df7a7d4..9ac14598e2a0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -226,9 +226,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
226 * Schedule the delayed work for reading the TX status 226 * Schedule the delayed work for reading the TX status
227 * from the device. 227 * from the device.
228 */ 228 */
229 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && 229 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
230 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
231 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
232} 230}
233 231
234static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) 232static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -323,21 +321,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
323 rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); 321 rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
324 322
325 /* 323 /*
326 * Security measure: if the driver did override the
327 * txdone_work function, and the hardware did arrive
328 * in a state which causes it to malfunction, it is
329 * possible that the driver couldn't handle the txdone
330 * event correctly. So after giving the driver the
331 * chance to cleanup, we now force a cleanup of any
332 * leftovers.
333 */
334 if (!rt2x00queue_empty(queue)) {
335 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
336 " status handling failed, invoke hard reset", queue->qid);
337 rt2x00usb_work_txdone(&rt2x00dev->txdone_work);
338 }
339
340 /*
341 * The queue has been reset, and mac80211 is allowed to use the 324 * The queue has been reset, and mac80211 is allowed to use the
342 * queue again. 325 * queue again.
343 */ 326 */
@@ -361,7 +344,7 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
361 if (!rt2x00queue_empty(queue)) { 344 if (!rt2x00queue_empty(queue)) {
362 if (rt2x00queue_dma_timeout(queue)) 345 if (rt2x00queue_dma_timeout(queue))
363 rt2x00usb_watchdog_tx_dma(queue); 346 rt2x00usb_watchdog_tx_dma(queue);
364 if (rt2x00queue_timeout(queue)) 347 if (rt2x00queue_status_timeout(queue))
365 rt2x00usb_watchdog_tx_status(queue); 348 rt2x00usb_watchdog_tx_status(queue);
366 } 349 }
367 } 350 }
@@ -424,9 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
424 * Schedule the delayed work for reading the RX status 407 * Schedule the delayed work for reading the RX status
425 * from the device. 408 * from the device.
426 */ 409 */
427 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && 410 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
428 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
429 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
430} 411}
431 412
432/* 413/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index af548c87f108..6b09b01f634f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1623,8 +1623,7 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
1623 1623
1624 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg); 1624 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
1625 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1625 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
1626 (state == STATE_RADIO_RX_OFF) || 1626 (state == STATE_RADIO_RX_OFF));
1627 (state == STATE_RADIO_RX_OFF_LINK));
1628 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); 1627 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
1629} 1628}
1630 1629
@@ -1745,9 +1744,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1745 rt61pci_disable_radio(rt2x00dev); 1744 rt61pci_disable_radio(rt2x00dev);
1746 break; 1745 break;
1747 case STATE_RADIO_RX_ON: 1746 case STATE_RADIO_RX_ON:
1748 case STATE_RADIO_RX_ON_LINK:
1749 case STATE_RADIO_RX_OFF: 1747 case STATE_RADIO_RX_OFF:
1750 case STATE_RADIO_RX_OFF_LINK:
1751 rt61pci_toggle_rx(rt2x00dev, state); 1748 rt61pci_toggle_rx(rt2x00dev, state);
1752 break; 1749 break;
1753 case STATE_RADIO_IRQ_ON: 1750 case STATE_RADIO_IRQ_ON:
@@ -1789,10 +1786,10 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
1789 * Start writing the descriptor words. 1786 * Start writing the descriptor words.
1790 */ 1787 */
1791 rt2x00_desc_read(txd, 1, &word); 1788 rt2x00_desc_read(txd, 1, &word);
1792 rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); 1789 rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
1793 rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); 1790 rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
1794 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); 1791 rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
1795 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); 1792 rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
1796 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); 1793 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
1797 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1794 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
1798 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); 1795 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
@@ -1820,7 +1817,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
1820 rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); 1817 rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
1821 rt2x00_desc_write(txd, 5, word); 1818 rt2x00_desc_write(txd, 5, word);
1822 1819
1823 if (txdesc->qid != QID_BEACON) { 1820 if (entry->queue->qid != QID_BEACON) {
1824 rt2x00_desc_read(txd, 6, &word); 1821 rt2x00_desc_read(txd, 6, &word);
1825 rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, 1822 rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
1826 skbdesc->skb_dma); 1823 skbdesc->skb_dma);
@@ -1866,8 +1863,8 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
1866 * Register descriptor details in skb frame descriptor. 1863 * Register descriptor details in skb frame descriptor.
1867 */ 1864 */
1868 skbdesc->desc = txd; 1865 skbdesc->desc = txd;
1869 skbdesc->desc_len = 1866 skbdesc->desc_len = (entry->queue->qid == QID_BEACON) ? TXINFO_SIZE :
1870 (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; 1867 TXD_DESC_SIZE;
1871} 1868}
1872 1869
1873/* 1870/*
@@ -2078,7 +2075,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2078 * that the TX_STA_FIFO stack has a size of 16. We stick to our 2075 * that the TX_STA_FIFO stack has a size of 16. We stick to our
2079 * tx ring size for now. 2076 * tx ring size for now.
2080 */ 2077 */
2081 for (i = 0; i < TX_ENTRIES; i++) { 2078 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
2082 rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg); 2079 rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg);
2083 if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) 2080 if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
2084 break; 2081 break;
@@ -2824,6 +2821,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2824 .conf_tx = rt61pci_conf_tx, 2821 .conf_tx = rt61pci_conf_tx,
2825 .get_tsf = rt61pci_get_tsf, 2822 .get_tsf = rt61pci_get_tsf,
2826 .rfkill_poll = rt2x00mac_rfkill_poll, 2823 .rfkill_poll = rt2x00mac_rfkill_poll,
2824 .flush = rt2x00mac_flush,
2827}; 2825};
2828 2826
2829static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { 2827static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -2857,21 +2855,21 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2857}; 2855};
2858 2856
2859static const struct data_queue_desc rt61pci_queue_rx = { 2857static const struct data_queue_desc rt61pci_queue_rx = {
2860 .entry_num = RX_ENTRIES, 2858 .entry_num = 32,
2861 .data_size = DATA_FRAME_SIZE, 2859 .data_size = DATA_FRAME_SIZE,
2862 .desc_size = RXD_DESC_SIZE, 2860 .desc_size = RXD_DESC_SIZE,
2863 .priv_size = sizeof(struct queue_entry_priv_pci), 2861 .priv_size = sizeof(struct queue_entry_priv_pci),
2864}; 2862};
2865 2863
2866static const struct data_queue_desc rt61pci_queue_tx = { 2864static const struct data_queue_desc rt61pci_queue_tx = {
2867 .entry_num = TX_ENTRIES, 2865 .entry_num = 32,
2868 .data_size = DATA_FRAME_SIZE, 2866 .data_size = DATA_FRAME_SIZE,
2869 .desc_size = TXD_DESC_SIZE, 2867 .desc_size = TXD_DESC_SIZE,
2870 .priv_size = sizeof(struct queue_entry_priv_pci), 2868 .priv_size = sizeof(struct queue_entry_priv_pci),
2871}; 2869};
2872 2870
2873static const struct data_queue_desc rt61pci_queue_bcn = { 2871static const struct data_queue_desc rt61pci_queue_bcn = {
2874 .entry_num = 4 * BEACON_ENTRIES, 2872 .entry_num = 4,
2875 .data_size = 0, /* No DMA required for beacons */ 2873 .data_size = 0, /* No DMA required for beacons */
2876 .desc_size = TXINFO_SIZE, 2874 .desc_size = TXINFO_SIZE,
2877 .priv_size = sizeof(struct queue_entry_priv_pci), 2875 .priv_size = sizeof(struct queue_entry_priv_pci),
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index e2e728ab0b2e..afc803b7959f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -412,7 +412,7 @@ struct hw_pairwise_ta_entry {
412 * DROP_VERSION_ERROR: Drop version error frame. 412 * DROP_VERSION_ERROR: Drop version error frame.
413 * DROP_MULTICAST: Drop multicast frames. 413 * DROP_MULTICAST: Drop multicast frames.
414 * DROP_BORADCAST: Drop broadcast frames. 414 * DROP_BORADCAST: Drop broadcast frames.
415 * ROP_ACK_CTS: Drop received ACK and CTS. 415 * DROP_ACK_CTS: Drop received ACK and CTS.
416 */ 416 */
417#define TXRX_CSR0 0x3040 417#define TXRX_CSR0 0x3040
418#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) 418#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 9be8089317e4..6f04552f5819 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -40,7 +40,7 @@
40/* 40/*
41 * Allow hardware encryption to be disabled. 41 * Allow hardware encryption to be disabled.
42 */ 42 */
43static int modparam_nohwcrypt = 0; 43static int modparam_nohwcrypt;
44module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 44module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
45MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 45MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
46 46
@@ -1331,8 +1331,7 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
1331 1331
1332 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg); 1332 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
1333 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1333 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
1334 (state == STATE_RADIO_RX_OFF) || 1334 (state == STATE_RADIO_RX_OFF));
1335 (state == STATE_RADIO_RX_OFF_LINK));
1336 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); 1335 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
1337} 1336}
1338 1337
@@ -1403,9 +1402,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1403 rt73usb_disable_radio(rt2x00dev); 1402 rt73usb_disable_radio(rt2x00dev);
1404 break; 1403 break;
1405 case STATE_RADIO_RX_ON: 1404 case STATE_RADIO_RX_ON:
1406 case STATE_RADIO_RX_ON_LINK:
1407 case STATE_RADIO_RX_OFF: 1405 case STATE_RADIO_RX_OFF:
1408 case STATE_RADIO_RX_OFF_LINK:
1409 rt73usb_toggle_rx(rt2x00dev, state); 1406 rt73usb_toggle_rx(rt2x00dev, state);
1410 break; 1407 break;
1411 case STATE_RADIO_IRQ_ON: 1408 case STATE_RADIO_IRQ_ON:
@@ -1472,10 +1469,10 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry,
1472 rt2x00_desc_write(txd, 0, word); 1469 rt2x00_desc_write(txd, 0, word);
1473 1470
1474 rt2x00_desc_read(txd, 1, &word); 1471 rt2x00_desc_read(txd, 1, &word);
1475 rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); 1472 rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, entry->queue->qid);
1476 rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); 1473 rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->queue->aifs);
1477 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); 1474 rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->queue->cw_min);
1478 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); 1475 rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->queue->cw_max);
1479 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); 1476 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
1480 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1477 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
1481 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); 1478 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
@@ -2264,6 +2261,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2264 .conf_tx = rt73usb_conf_tx, 2261 .conf_tx = rt73usb_conf_tx,
2265 .get_tsf = rt73usb_get_tsf, 2262 .get_tsf = rt73usb_get_tsf,
2266 .rfkill_poll = rt2x00mac_rfkill_poll, 2263 .rfkill_poll = rt2x00mac_rfkill_poll,
2264 .flush = rt2x00mac_flush,
2267}; 2265};
2268 2266
2269static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { 2267static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2296,21 +2294,21 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2296}; 2294};
2297 2295
2298static const struct data_queue_desc rt73usb_queue_rx = { 2296static const struct data_queue_desc rt73usb_queue_rx = {
2299 .entry_num = RX_ENTRIES, 2297 .entry_num = 32,
2300 .data_size = DATA_FRAME_SIZE, 2298 .data_size = DATA_FRAME_SIZE,
2301 .desc_size = RXD_DESC_SIZE, 2299 .desc_size = RXD_DESC_SIZE,
2302 .priv_size = sizeof(struct queue_entry_priv_usb), 2300 .priv_size = sizeof(struct queue_entry_priv_usb),
2303}; 2301};
2304 2302
2305static const struct data_queue_desc rt73usb_queue_tx = { 2303static const struct data_queue_desc rt73usb_queue_tx = {
2306 .entry_num = TX_ENTRIES, 2304 .entry_num = 32,
2307 .data_size = DATA_FRAME_SIZE, 2305 .data_size = DATA_FRAME_SIZE,
2308 .desc_size = TXD_DESC_SIZE, 2306 .desc_size = TXD_DESC_SIZE,
2309 .priv_size = sizeof(struct queue_entry_priv_usb), 2307 .priv_size = sizeof(struct queue_entry_priv_usb),
2310}; 2308};
2311 2309
2312static const struct data_queue_desc rt73usb_queue_bcn = { 2310static const struct data_queue_desc rt73usb_queue_bcn = {
2313 .entry_num = 4 * BEACON_ENTRIES, 2311 .entry_num = 4,
2314 .data_size = MGMT_FRAME_SIZE, 2312 .data_size = MGMT_FRAME_SIZE,
2315 .desc_size = TXINFO_SIZE, 2313 .desc_size = TXINFO_SIZE,
2316 .priv_size = sizeof(struct queue_entry_priv_usb), 2314 .priv_size = sizeof(struct queue_entry_priv_usb),
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 44d5b2bebd39..1315ce5c992f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -322,7 +322,7 @@ struct hw_pairwise_ta_entry {
322 * DROP_VERSION_ERROR: Drop version error frame. 322 * DROP_VERSION_ERROR: Drop version error frame.
323 * DROP_MULTICAST: Drop multicast frames. 323 * DROP_MULTICAST: Drop multicast frames.
324 * DROP_BORADCAST: Drop broadcast frames. 324 * DROP_BORADCAST: Drop broadcast frames.
325 * ROP_ACK_CTS: Drop received ACK and CTS. 325 * DROP_ACK_CTS: Drop received ACK and CTS.
326 */ 326 */
327#define TXRX_CSR0 0x3040 327#define TXRX_CSR0 0x3040
328#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) 328#define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff)
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 38fa8244cc96..eeee244fcaab 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -553,6 +553,46 @@ static int rtl8187b_init_status_urb(struct ieee80211_hw *dev)
553 return ret; 553 return ret;
554} 554}
555 555
556static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon)
557{
558 u32 anaparam, anaparam2;
559 u8 anaparam3, reg;
560
561 if (!priv->is_rtl8187b) {
562 if (rfon) {
563 anaparam = RTL8187_RTL8225_ANAPARAM_ON;
564 anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON;
565 } else {
566 anaparam = RTL8187_RTL8225_ANAPARAM_OFF;
567 anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF;
568 }
569 } else {
570 if (rfon) {
571 anaparam = RTL8187B_RTL8225_ANAPARAM_ON;
572 anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON;
573 anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON;
574 } else {
575 anaparam = RTL8187B_RTL8225_ANAPARAM_OFF;
576 anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF;
577 anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF;
578 }
579 }
580
581 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
582 RTL818X_EEPROM_CMD_CONFIG);
583 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
584 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
585 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
586 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
587 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
588 if (priv->is_rtl8187b)
589 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3);
590 reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
591 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
592 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
593 RTL818X_EEPROM_CMD_NORMAL);
594}
595
556static int rtl8187_cmd_reset(struct ieee80211_hw *dev) 596static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
557{ 597{
558 struct rtl8187_priv *priv = dev->priv; 598 struct rtl8187_priv *priv = dev->priv;
@@ -603,19 +643,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
603 int res; 643 int res;
604 644
605 /* reset */ 645 /* reset */
606 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, 646 rtl8187_set_anaparam(priv, true);
607 RTL818X_EEPROM_CMD_CONFIG);
608 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
609 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg |
610 RTL818X_CONFIG3_ANAPARAM_WRITE);
611 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
612 RTL8187_RTL8225_ANAPARAM_ON);
613 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
614 RTL8187_RTL8225_ANAPARAM2_ON);
615 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg &
616 ~RTL818X_CONFIG3_ANAPARAM_WRITE);
617 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
618 RTL818X_EEPROM_CMD_NORMAL);
619 647
620 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 648 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
621 649
@@ -629,17 +657,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
629 if (res) 657 if (res)
630 return res; 658 return res;
631 659
632 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 660 rtl8187_set_anaparam(priv, true);
633 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
634 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
635 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
636 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
637 RTL8187_RTL8225_ANAPARAM_ON);
638 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
639 RTL8187_RTL8225_ANAPARAM2_ON);
640 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
641 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
642 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
643 661
644 /* setup card */ 662 /* setup card */
645 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0); 663 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
@@ -712,10 +730,9 @@ static const u8 rtl8187b_reg_table[][3] = {
712 730
713 {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1}, 731 {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
714 {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1}, 732 {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
715 {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1}, 733 {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1},
716 {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1}, 734 {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1},
717 {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1}, 735 {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
718 {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
719 736
720 {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2}, 737 {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
721 {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2}, 738 {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
@@ -723,14 +740,13 @@ static const u8 rtl8187b_reg_table[][3] = {
723 {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2}, 740 {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
724 {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2}, 741 {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
725 {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2}, 742 {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
726 {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2}, 743 {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2},
727 {0x73, 0x9A, 2},
728 744
729 {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0}, 745 {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0},
730 {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, 746 {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0},
731 {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0}, 747 {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0},
732 {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, 748 {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0},
733 {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, 749 {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
734 750
735 {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0}, 751 {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
736 {0x8F, 0x00, 0} 752 {0x8F, 0x00, 0}
@@ -742,48 +758,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
742 int res, i; 758 int res, i;
743 u8 reg; 759 u8 reg;
744 760
745 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, 761 rtl8187_set_anaparam(priv, true);
746 RTL818X_EEPROM_CMD_CONFIG);
747
748 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
749 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
750 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
751 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
752 RTL8187B_RTL8225_ANAPARAM2_ON);
753 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
754 RTL8187B_RTL8225_ANAPARAM_ON);
755 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
756 RTL8187B_RTL8225_ANAPARAM3_ON);
757 762
763 /* Reset PLL sequence on 8187B. Realtek note: reduces power
764 * consumption about 30 mA */
758 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); 765 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
759 reg = rtl818x_ioread8(priv, (u8 *)0xFF62); 766 reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
760 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5)); 767 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
761 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5)); 768 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
762 769
763 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
764 reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
765 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
766
767 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
768 RTL818X_EEPROM_CMD_NORMAL);
769
770 res = rtl8187_cmd_reset(dev); 770 res = rtl8187_cmd_reset(dev);
771 if (res) 771 if (res)
772 return res; 772 return res;
773 773
774 rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF); 774 rtl8187_set_anaparam(priv, true);
775
776 /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as
777 * RESP_RATE on 8187L in Realtek sources: each bit should be each
778 * one of the 12 rates, all are enabled */
779 rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF);
780
775 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); 781 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
776 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; 782 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
777 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); 783 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
778 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
779 reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
780 RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
781 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
782 784
785 /* Auto Rate Fallback Register (ARFR): 1M-54M setting */
783 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); 786 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
787 rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1);
784 788
785 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
786 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
787 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1); 789 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
788 790
789 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, 791 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
@@ -811,16 +813,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
811 813
812 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001); 814 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
813 815
816 /* RFSW_CTRL register */
814 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2); 817 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
815 818
816 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
817 RTL818X_EEPROM_CMD_CONFIG);
818 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
819 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
820 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
821 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
822 RTL818X_EEPROM_CMD_NORMAL);
823
824 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 819 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
825 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488); 820 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
826 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 821 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
@@ -929,6 +924,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
929 priv->rx_conf = reg; 924 priv->rx_conf = reg;
930 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); 925 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
931 926
927 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
928 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
929 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
930 reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
931 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
932
932 rtl818x_iowrite32(priv, &priv->map->TX_CONF, 933 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
933 RTL818X_TX_CONF_HW_SEQNUM | 934 RTL818X_TX_CONF_HW_SEQNUM |
934 RTL818X_TX_CONF_DISREQQSIZE | 935 RTL818X_TX_CONF_DISREQQSIZE |
@@ -1002,6 +1003,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
1002 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 1003 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
1003 1004
1004 priv->rf->stop(dev); 1005 priv->rf->stop(dev);
1006 rtl8187_set_anaparam(priv, false);
1005 1007
1006 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 1008 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1007 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); 1009 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 97eebdcf7eb9..5c6666f09ac1 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -898,29 +898,7 @@ static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
898 898
899static void rtl8225_rf_stop(struct ieee80211_hw *dev) 899static void rtl8225_rf_stop(struct ieee80211_hw *dev)
900{ 900{
901 u8 reg;
902 struct rtl8187_priv *priv = dev->priv;
903
904 rtl8225_write(dev, 0x4, 0x1f); 901 rtl8225_write(dev, 0x4, 0x1f);
905
906 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
907 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
908 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
909 if (!priv->is_rtl8187b) {
910 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
911 RTL8187_RTL8225_ANAPARAM2_OFF);
912 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
913 RTL8187_RTL8225_ANAPARAM_OFF);
914 } else {
915 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
916 RTL8187B_RTL8225_ANAPARAM2_OFF);
917 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
918 RTL8187B_RTL8225_ANAPARAM_OFF);
919 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
920 RTL8187B_RTL8225_ANAPARAM3_OFF);
921 }
922 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
923 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
924} 902}
925 903
926static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, 904static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 7a8762553cdc..012e1a4016fe 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -52,14 +52,14 @@ void wl1251_disable_interrupts(struct wl1251 *wl)
52 wl->if_ops->disable_irq(wl); 52 wl->if_ops->disable_irq(wl);
53} 53}
54 54
55static void wl1251_power_off(struct wl1251 *wl) 55static int wl1251_power_off(struct wl1251 *wl)
56{ 56{
57 wl->set_power(false); 57 return wl->if_ops->power(wl, false);
58} 58}
59 59
60static void wl1251_power_on(struct wl1251 *wl) 60static int wl1251_power_on(struct wl1251 *wl)
61{ 61{
62 wl->set_power(true); 62 return wl->if_ops->power(wl, true);
63} 63}
64 64
65static int wl1251_fetch_firmware(struct wl1251 *wl) 65static int wl1251_fetch_firmware(struct wl1251 *wl)
@@ -152,9 +152,12 @@ static void wl1251_fw_wakeup(struct wl1251 *wl)
152 152
153static int wl1251_chip_wakeup(struct wl1251 *wl) 153static int wl1251_chip_wakeup(struct wl1251 *wl)
154{ 154{
155 int ret = 0; 155 int ret;
156
157 ret = wl1251_power_on(wl);
158 if (ret < 0)
159 return ret;
156 160
157 wl1251_power_on(wl);
158 msleep(WL1251_POWER_ON_SLEEP); 161 msleep(WL1251_POWER_ON_SLEEP);
159 wl->if_ops->reset(wl); 162 wl->if_ops->reset(wl);
160 163
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 74ba9ced5393..596d90ecba33 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -26,6 +26,7 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/wl12xx.h> 27#include <linux/wl12xx.h>
28#include <linux/irq.h> 28#include <linux/irq.h>
29#include <linux/pm_runtime.h>
29 30
30#include "wl1251.h" 31#include "wl1251.h"
31 32
@@ -42,8 +43,6 @@ struct wl1251_sdio {
42 u32 elp_val; 43 u32 elp_val;
43}; 44};
44 45
45static struct wl12xx_platform_data *wl12xx_board_data;
46
47static struct sdio_func *wl_to_func(struct wl1251 *wl) 46static struct sdio_func *wl_to_func(struct wl1251 *wl)
48{ 47{
49 struct wl1251_sdio *wl_sdio = wl->if_priv; 48 struct wl1251_sdio *wl_sdio = wl->if_priv;
@@ -171,8 +170,42 @@ static void wl1251_disable_line_irq(struct wl1251 *wl)
171 return disable_irq(wl->irq); 170 return disable_irq(wl->irq);
172} 171}
173 172
174static void wl1251_sdio_set_power(bool enable) 173static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
175{ 174{
175 struct sdio_func *func = wl_to_func(wl);
176 int ret;
177
178 if (enable) {
179 /*
180 * Power is controlled by runtime PM, but we still call board
181 * callback in case it wants to do any additional setup,
182 * for example enabling clock buffer for the module.
183 */
184 if (wl->set_power)
185 wl->set_power(true);
186
187 ret = pm_runtime_get_sync(&func->dev);
188 if (ret < 0)
189 goto out;
190
191 sdio_claim_host(func);
192 sdio_enable_func(func);
193 sdio_release_host(func);
194 } else {
195 sdio_claim_host(func);
196 sdio_disable_func(func);
197 sdio_release_host(func);
198
199 ret = pm_runtime_put_sync(&func->dev);
200 if (ret < 0)
201 goto out;
202
203 if (wl->set_power)
204 wl->set_power(false);
205 }
206
207out:
208 return ret;
176} 209}
177 210
178static struct wl1251_if_operations wl1251_sdio_ops = { 211static struct wl1251_if_operations wl1251_sdio_ops = {
@@ -181,30 +214,7 @@ static struct wl1251_if_operations wl1251_sdio_ops = {
181 .write_elp = wl1251_sdio_write_elp, 214 .write_elp = wl1251_sdio_write_elp,
182 .read_elp = wl1251_sdio_read_elp, 215 .read_elp = wl1251_sdio_read_elp,
183 .reset = wl1251_sdio_reset, 216 .reset = wl1251_sdio_reset,
184}; 217 .power = wl1251_sdio_set_power,
185
186static int wl1251_platform_probe(struct platform_device *pdev)
187{
188 if (pdev->id != -1) {
189 wl1251_error("can only handle single device");
190 return -ENODEV;
191 }
192
193 wl12xx_board_data = pdev->dev.platform_data;
194 return 0;
195}
196
197/*
198 * Dummy platform_driver for passing platform_data to this driver,
199 * until we have a way to pass this through SDIO subsystem or
200 * some other way.
201 */
202static struct platform_driver wl1251_platform_driver = {
203 .driver = {
204 .name = "wl1251_data",
205 .owner = THIS_MODULE,
206 },
207 .probe = wl1251_platform_probe,
208}; 218};
209 219
210static int wl1251_sdio_probe(struct sdio_func *func, 220static int wl1251_sdio_probe(struct sdio_func *func,
@@ -214,6 +224,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
214 struct wl1251 *wl; 224 struct wl1251 *wl;
215 struct ieee80211_hw *hw; 225 struct ieee80211_hw *hw;
216 struct wl1251_sdio *wl_sdio; 226 struct wl1251_sdio *wl_sdio;
227 const struct wl12xx_platform_data *wl12xx_board_data;
217 228
218 hw = wl1251_alloc_hw(); 229 hw = wl1251_alloc_hw();
219 if (IS_ERR(hw)) 230 if (IS_ERR(hw))
@@ -239,8 +250,8 @@ static int wl1251_sdio_probe(struct sdio_func *func,
239 wl_sdio->func = func; 250 wl_sdio->func = func;
240 wl->if_priv = wl_sdio; 251 wl->if_priv = wl_sdio;
241 wl->if_ops = &wl1251_sdio_ops; 252 wl->if_ops = &wl1251_sdio_ops;
242 wl->set_power = wl1251_sdio_set_power;
243 253
254 wl12xx_board_data = wl12xx_get_platform_data();
244 if (wl12xx_board_data != NULL) { 255 if (wl12xx_board_data != NULL) {
245 wl->set_power = wl12xx_board_data->set_power; 256 wl->set_power = wl12xx_board_data->set_power;
246 wl->irq = wl12xx_board_data->irq; 257 wl->irq = wl12xx_board_data->irq;
@@ -273,6 +284,10 @@ static int wl1251_sdio_probe(struct sdio_func *func,
273 goto out_free_irq; 284 goto out_free_irq;
274 285
275 sdio_set_drvdata(func, wl); 286 sdio_set_drvdata(func, wl);
287
288 /* Tell PM core that we don't need the card to be powered now */
289 pm_runtime_put_noidle(&func->dev);
290
276 return ret; 291 return ret;
277 292
278out_free_irq: 293out_free_irq:
@@ -294,6 +309,9 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
294 struct wl1251 *wl = sdio_get_drvdata(func); 309 struct wl1251 *wl = sdio_get_drvdata(func);
295 struct wl1251_sdio *wl_sdio = wl->if_priv; 310 struct wl1251_sdio *wl_sdio = wl->if_priv;
296 311
312 /* Undo decrement done above in wl1251_probe */
313 pm_runtime_get_noresume(&func->dev);
314
297 if (wl->irq) 315 if (wl->irq)
298 free_irq(wl->irq, wl); 316 free_irq(wl->irq, wl);
299 kfree(wl_sdio); 317 kfree(wl_sdio);
@@ -305,23 +323,37 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
305 sdio_release_host(func); 323 sdio_release_host(func);
306} 324}
307 325
326static int wl1251_suspend(struct device *dev)
327{
328 /*
329 * Tell MMC/SDIO core it's OK to power down the card
330 * (if it isn't already), but not to remove it completely.
331 */
332 return 0;
333}
334
335static int wl1251_resume(struct device *dev)
336{
337 return 0;
338}
339
340static const struct dev_pm_ops wl1251_sdio_pm_ops = {
341 .suspend = wl1251_suspend,
342 .resume = wl1251_resume,
343};
344
308static struct sdio_driver wl1251_sdio_driver = { 345static struct sdio_driver wl1251_sdio_driver = {
309 .name = "wl1251_sdio", 346 .name = "wl1251_sdio",
310 .id_table = wl1251_devices, 347 .id_table = wl1251_devices,
311 .probe = wl1251_sdio_probe, 348 .probe = wl1251_sdio_probe,
312 .remove = __devexit_p(wl1251_sdio_remove), 349 .remove = __devexit_p(wl1251_sdio_remove),
350 .drv.pm = &wl1251_sdio_pm_ops,
313}; 351};
314 352
315static int __init wl1251_sdio_init(void) 353static int __init wl1251_sdio_init(void)
316{ 354{
317 int err; 355 int err;
318 356
319 err = platform_driver_register(&wl1251_platform_driver);
320 if (err) {
321 wl1251_error("failed to register platform driver: %d", err);
322 return err;
323 }
324
325 err = sdio_register_driver(&wl1251_sdio_driver); 357 err = sdio_register_driver(&wl1251_sdio_driver);
326 if (err) 358 if (err)
327 wl1251_error("failed to register sdio driver: %d", err); 359 wl1251_error("failed to register sdio driver: %d", err);
@@ -331,7 +363,6 @@ static int __init wl1251_sdio_init(void)
331static void __exit wl1251_sdio_exit(void) 363static void __exit wl1251_sdio_exit(void)
332{ 364{
333 sdio_unregister_driver(&wl1251_sdio_driver); 365 sdio_unregister_driver(&wl1251_sdio_driver);
334 platform_driver_unregister(&wl1251_platform_driver);
335 wl1251_notice("unloaded"); 366 wl1251_notice("unloaded");
336} 367}
337 368
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c
index 88fa8e69d0d1..ac872b38960f 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -215,12 +215,21 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
215 return disable_irq(wl->irq); 215 return disable_irq(wl->irq);
216} 216}
217 217
218static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
219{
220 if (wl->set_power)
221 wl->set_power(enable);
222
223 return 0;
224}
225
218static const struct wl1251_if_operations wl1251_spi_ops = { 226static const struct wl1251_if_operations wl1251_spi_ops = {
219 .read = wl1251_spi_read, 227 .read = wl1251_spi_read,
220 .write = wl1251_spi_write, 228 .write = wl1251_spi_write,
221 .reset = wl1251_spi_reset_wake, 229 .reset = wl1251_spi_reset_wake,
222 .enable_irq = wl1251_spi_enable_irq, 230 .enable_irq = wl1251_spi_enable_irq,
223 .disable_irq = wl1251_spi_disable_irq, 231 .disable_irq = wl1251_spi_disable_irq,
232 .power = wl1251_spi_set_power,
224}; 233};
225 234
226static int __devinit wl1251_spi_probe(struct spi_device *spi) 235static int __devinit wl1251_spi_probe(struct spi_device *spi)
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index e113d4c1fb35..13fbeeccf609 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -256,6 +256,7 @@ struct wl1251_if_operations {
256 void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); 256 void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
257 void (*read_elp)(struct wl1251 *wl, int addr, u32 *val); 257 void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
258 void (*write_elp)(struct wl1251 *wl, int addr, u32 val); 258 void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
259 int (*power)(struct wl1251 *wl, bool enable);
259 void (*reset)(struct wl1251 *wl); 260 void (*reset)(struct wl1251 *wl);
260 void (*enable_irq)(struct wl1251 *wl); 261 void (*enable_irq)(struct wl1251 *wl);
261 void (*disable_irq)(struct wl1251 *wl); 262 void (*disable_irq)(struct wl1251 *wl);
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index b447559f1db5..02ad4bc15976 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -18,6 +18,16 @@ config WL1271
18 If you choose to build a module, it'll be called wl1271. Say N if 18 If you choose to build a module, it'll be called wl1271. Say N if
19 unsure. 19 unsure.
20 20
21config WL1271_HT
22 bool "TI wl1271 802.11 HT support (EXPERIMENTAL)"
23 depends on WL1271 && EXPERIMENTAL
24 default n
25 ---help---
26 This will enable 802.11 HT support for TI wl1271 chipset.
27
28 That configuration is temporary due to the code incomplete and
29 still in testing process.
30
21config WL1271_SPI 31config WL1271_SPI
22 tristate "TI wl1271 SPI support" 32 tristate "TI wl1271 SPI support"
23 depends on WL1271 && SPI_MASTER 33 depends on WL1271 && SPI_MASTER
@@ -42,5 +52,5 @@ config WL1271_SDIO
42 52
43config WL12XX_PLATFORM_DATA 53config WL12XX_PLATFORM_DATA
44 bool 54 bool
45 depends on WL1271_SDIO != n 55 depends on WL1271_SDIO != n || WL1251_SDIO != n
46 default y 56 default y
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 8a4cd763e5a2..ab53162b4343 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -351,6 +351,7 @@ struct wl1271 {
351#define WL1271_FLAG_IDLE_REQUESTED (11) 351#define WL1271_FLAG_IDLE_REQUESTED (11)
352#define WL1271_FLAG_PSPOLL_FAILURE (12) 352#define WL1271_FLAG_PSPOLL_FAILURE (12)
353#define WL1271_FLAG_STA_STATE_SENT (13) 353#define WL1271_FLAG_STA_STATE_SENT (13)
354#define WL1271_FLAG_FW_TX_BUSY (14)
354 unsigned long flags; 355 unsigned long flags;
355 356
356 struct wl1271_partition_set part; 357 struct wl1271_partition_set part;
@@ -397,6 +398,7 @@ struct wl1271 {
397 struct work_struct tx_work; 398 struct work_struct tx_work;
398 399
399 /* Pending TX frames */ 400 /* Pending TX frames */
401 unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
400 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; 402 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
401 int tx_frames_cnt; 403 int tx_frames_cnt;
402 404
@@ -432,7 +434,12 @@ struct wl1271 {
432 /* Our association ID */ 434 /* Our association ID */
433 u16 aid; 435 u16 aid;
434 436
435 /* currently configured rate set */ 437 /*
438 * currently configured rate set:
439 * bits 0-15 - 802.11abg rates
440 * bits 16-23 - 802.11n MCS index mask
441 * support only 1 stream, thus only 8 bits for the MCS rates (0-7).
442 */
436 u32 sta_rate_set; 443 u32 sta_rate_set;
437 u32 basic_rate_set; 444 u32 basic_rate_set;
438 u32 basic_rate; 445 u32 basic_rate;
@@ -509,4 +516,8 @@ int wl1271_plt_stop(struct wl1271 *wl);
509#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ 516#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
510#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ 517#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
511 518
519/* Macros to handle wl1271.sta_rate_set */
520#define HW_BG_RATES_MASK 0xffff
521#define HW_HT_RATES_OFFSET 16
522
512#endif 523#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 618993405262..bd7f95f4eef3 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -1226,6 +1226,89 @@ out:
1226 return ret; 1226 return ret;
1227} 1227}
1228 1228
1229int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1230 struct ieee80211_sta_ht_cap *ht_cap,
1231 bool allow_ht_operation)
1232{
1233 struct wl1271_acx_ht_capabilities *acx;
1234 u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1235 int ret = 0;
1236
1237 wl1271_debug(DEBUG_ACX, "acx ht capabilities setting");
1238
1239 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1240 if (!acx) {
1241 ret = -ENOMEM;
1242 goto out;
1243 }
1244
1245 /* Allow HT Operation ? */
1246 if (allow_ht_operation) {
1247 acx->ht_capabilites =
1248 WL1271_ACX_FW_CAP_HT_OPERATION;
1249 if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD)
1250 acx->ht_capabilites |=
1251 WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT;
1252 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
1253 acx->ht_capabilites |=
1254 WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS;
1255 if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT)
1256 acx->ht_capabilites |=
1257 WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION;
1258
1259 /* get data from A-MPDU parameters field */
1260 acx->ampdu_max_length = ht_cap->ampdu_factor;
1261 acx->ampdu_min_spacing = ht_cap->ampdu_density;
1262
1263 memcpy(acx->mac_address, mac_address, ETH_ALEN);
1264 } else { /* HT operations are not allowed */
1265 acx->ht_capabilites = 0;
1266 }
1267
1268 ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx));
1269 if (ret < 0) {
1270 wl1271_warning("acx ht capabilities setting failed: %d", ret);
1271 goto out;
1272 }
1273
1274out:
1275 kfree(acx);
1276 return ret;
1277}
1278
1279int wl1271_acx_set_ht_information(struct wl1271 *wl,
1280 u16 ht_operation_mode)
1281{
1282 struct wl1271_acx_ht_information *acx;
1283 int ret = 0;
1284
1285 wl1271_debug(DEBUG_ACX, "acx ht information setting");
1286
1287 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1288 if (!acx) {
1289 ret = -ENOMEM;
1290 goto out;
1291 }
1292
1293 acx->ht_protection =
1294 (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION);
1295 acx->rifs_mode = 0;
1296 acx->gf_protection = 0;
1297 acx->ht_tx_burst_limit = 0;
1298 acx->dual_cts_protection = 0;
1299
1300 ret = wl1271_cmd_configure(wl, ACX_HT_BSS_OPERATION, acx, sizeof(*acx));
1301
1302 if (ret < 0) {
1303 wl1271_warning("acx ht information setting failed: %d", ret);
1304 goto out;
1305 }
1306
1307out:
1308 kfree(acx);
1309 return ret;
1310}
1311
1229int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) 1312int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
1230{ 1313{
1231 struct wl1271_acx_fw_tsf_information *tsf_info; 1314 struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index ebb341d36e8c..b7c490845f3e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -61,7 +61,8 @@
61 WL1271_ACX_INTR_HW_AVAILABLE | \ 61 WL1271_ACX_INTR_HW_AVAILABLE | \
62 WL1271_ACX_INTR_DATA) 62 WL1271_ACX_INTR_DATA)
63 63
64#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \ 64#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
65 WL1271_ACX_INTR_EVENT_A | \
65 WL1271_ACX_INTR_EVENT_B | \ 66 WL1271_ACX_INTR_EVENT_B | \
66 WL1271_ACX_INTR_HW_AVAILABLE | \ 67 WL1271_ACX_INTR_HW_AVAILABLE | \
67 WL1271_ACX_INTR_DATA) 68 WL1271_ACX_INTR_DATA)
@@ -964,6 +965,87 @@ struct wl1271_acx_rssi_snr_avg_weights {
964 u8 snr_data; 965 u8 snr_data;
965}; 966};
966 967
968/*
969 * ACX_PEER_HT_CAP
970 * Configure HT capabilities - declare the capabilities of the peer
971 * we are connected to.
972 */
973struct wl1271_acx_ht_capabilities {
974 struct acx_header header;
975
976 /*
977 * bit 0 - Allow HT Operation
978 * bit 1 - Allow Greenfield format in TX
979 * bit 2 - Allow Short GI in TX
980 * bit 3 - Allow L-SIG TXOP Protection in TX
981 * bit 4 - Allow HT Control fields in TX.
982 * Note, driver will still leave space for HT control in packets
983 * regardless of the value of this field. FW will be responsible
984 * to drop the HT field from any frame when this Bit set to 0.
985 * bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD.
986 * Exact policy setting for this feature is TBD.
987 * Note, this bit can only be set to 1 if bit 3 is set to 1.
988 */
989 __le32 ht_capabilites;
990
991 /*
992 * Indicates to which peer these capabilities apply.
993 * For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance
994 * for all peers.
995 * Only valid for IBSS/DLS operation.
996 */
997 u8 mac_address[ETH_ALEN];
998
999 /*
1000 * This the maximum A-MPDU length supported by the AP. The FW may not
1001 * exceed this length when sending A-MPDUs
1002 */
1003 u8 ampdu_max_length;
1004
1005 /* This is the minimal spacing required when sending A-MPDUs to the AP*/
1006 u8 ampdu_min_spacing;
1007} __packed;
1008
1009/* HT Capabilites Fw Bit Mask Mapping */
1010#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0)
1011#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1)
1012#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2)
1013#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3)
1014#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4)
1015#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5)
1016
1017
1018/*
1019 * ACX_HT_BSS_OPERATION
1020 * Configure HT capabilities - AP rules for behavior in the BSS.
1021 */
1022struct wl1271_acx_ht_information {
1023 struct acx_header header;
1024
1025 /* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
1026 u8 rifs_mode;
1027
1028 /* Values: 0 - 3 like in spec */
1029 u8 ht_protection;
1030
1031 /* Values: 0 - GF protection not required, 1 - GF protection required */
1032 u8 gf_protection;
1033
1034 /*Values: 0 - TX Burst limit not required, 1 - TX Burst Limit required*/
1035 u8 ht_tx_burst_limit;
1036
1037 /*
1038 * Values: 0 - Dual CTS protection not required,
1039 * 1 - Dual CTS Protection required
1040 * Note: When this value is set to 1 FW will protect all TXOP with RTS
1041 * frame and will not use CTS-to-self regardless of the value of the
1042 * ACX_CTS_PROTECTION information element
1043 */
1044 u8 dual_cts_protection;
1045
1046 u8 padding[3];
1047} __packed;
1048
967struct wl1271_acx_fw_tsf_information { 1049struct wl1271_acx_fw_tsf_information {
968 struct acx_header header; 1050 struct acx_header header;
969 1051
@@ -1093,6 +1175,11 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
1093int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, 1175int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
1094 s16 thold, u8 hyst); 1176 s16 thold, u8 hyst);
1095int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); 1177int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);
1178int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
1179 struct ieee80211_sta_ht_cap *ht_cap,
1180 bool allow_ht_operation);
1181int wl1271_acx_set_ht_information(struct wl1271 *wl,
1182 u16 ht_operation_mode);
1096int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); 1183int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
1097 1184
1098#endif /* __WL1271_ACX_H__ */ 1185#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index b91021242098..5b190728ca55 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -471,20 +471,19 @@ int wl1271_boot(struct wl1271 *wl)
471{ 471{
472 int ret = 0; 472 int ret = 0;
473 u32 tmp, clk, pause; 473 u32 tmp, clk, pause;
474 int ref_clock = wl->ref_clock;
475 474
476 wl1271_boot_hw_version(wl); 475 wl1271_boot_hw_version(wl);
477 476
478 if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4) 477 if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4)
479 /* ref clk: 19.2/38.4/38.4-XTAL */ 478 /* ref clk: 19.2/38.4/38.4-XTAL */
480 clk = 0x3; 479 clk = 0x3;
481 else if (ref_clock == 1 || ref_clock == 3) 480 else if (wl->ref_clock == 1 || wl->ref_clock == 3)
482 /* ref clk: 26/52 */ 481 /* ref clk: 26/52 */
483 clk = 0x5; 482 clk = 0x5;
484 else 483 else
485 return -EINVAL; 484 return -EINVAL;
486 485
487 if (ref_clock != 0) { 486 if (wl->ref_clock != 0) {
488 u16 val; 487 u16 val;
489 /* Set clock type (open drain) */ 488 /* Set clock type (open drain) */
490 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); 489 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -529,8 +528,7 @@ int wl1271_boot(struct wl1271 *wl)
529 528
530 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); 529 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
531 530
532 /* 2 */ 531 clk |= (wl->ref_clock << 1) << 4;
533 clk |= (ref_clock << 1) << 4;
534 wl1271_write32(wl, DRPW_SCRATCH_START, clk); 532 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
535 533
536 wl1271_set_partition(wl, &part_table[PART_WORK]); 534 wl1271_set_partition(wl, &part_table[PART_WORK]);
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index 66c2b90ddfd4..3468b849852e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -35,17 +35,28 @@
35#define WL1271_DEBUGFS_STATS_LIFETIME 1000 35#define WL1271_DEBUGFS_STATS_LIFETIME 1000
36 36
37/* debugfs macros idea from mac80211 */ 37/* debugfs macros idea from mac80211 */
38#define DEBUGFS_FORMAT_BUFFER_SIZE 100
39static int wl1271_format_buffer(char __user *userbuf, size_t count,
40 loff_t *ppos, char *fmt, ...)
41{
42 va_list args;
43 char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
44 int res;
38 45
39#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ 46 va_start(args, fmt);
47 res = vscnprintf(buf, sizeof(buf), fmt, args);
48 va_end(args);
49
50 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
51}
52
53#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
40static ssize_t name## _read(struct file *file, char __user *userbuf, \ 54static ssize_t name## _read(struct file *file, char __user *userbuf, \
41 size_t count, loff_t *ppos) \ 55 size_t count, loff_t *ppos) \
42{ \ 56{ \
43 struct wl1271 *wl = file->private_data; \ 57 struct wl1271 *wl = file->private_data; \
44 char buf[buflen]; \ 58 return wl1271_format_buffer(userbuf, count, ppos, \
45 int res; \ 59 fmt "\n", ##value); \
46 \
47 res = scnprintf(buf, buflen, fmt "\n", ##value); \
48 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
49} \ 60} \
50 \ 61 \
51static const struct file_operations name## _ops = { \ 62static const struct file_operations name## _ops = { \
@@ -69,20 +80,17 @@ static const struct file_operations name## _ops = { \
69 wl->debugfs.name = NULL; \ 80 wl->debugfs.name = NULL; \
70 } while (0) 81 } while (0)
71 82
72#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \ 83#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
73static ssize_t sub## _ ##name## _read(struct file *file, \ 84static ssize_t sub## _ ##name## _read(struct file *file, \
74 char __user *userbuf, \ 85 char __user *userbuf, \
75 size_t count, loff_t *ppos) \ 86 size_t count, loff_t *ppos) \
76{ \ 87{ \
77 struct wl1271 *wl = file->private_data; \ 88 struct wl1271 *wl = file->private_data; \
78 char buf[buflen]; \
79 int res; \
80 \ 89 \
81 wl1271_debugfs_update_stats(wl); \ 90 wl1271_debugfs_update_stats(wl); \
82 \ 91 \
83 res = scnprintf(buf, buflen, fmt "\n", \ 92 return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \
84 wl->stats.fw_stats->sub.name); \ 93 wl->stats.fw_stats->sub.name); \
85 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
86} \ 94} \
87 \ 95 \
88static const struct file_operations sub## _ ##name## _ops = { \ 96static const struct file_operations sub## _ ##name## _ops = { \
@@ -126,100 +134,99 @@ static int wl1271_open_file_generic(struct inode *inode, struct file *file)
126 return 0; 134 return 0;
127} 135}
128 136
129DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u"); 137DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u");
130 138
131DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u"); 139DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u");
132DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u"); 140DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u");
133DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u"); 141DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u");
134DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u"); 142DEBUGFS_FWSTATS_FILE(rx, dropped, "%u");
135DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u"); 143DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u");
136DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u"); 144DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u");
137DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u"); 145DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u");
138DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u"); 146DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u");
139 147
140DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u"); 148DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u");
141DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u"); 149DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u");
142DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u"); 150DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u");
143DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u"); 151DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u");
144 152
145DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u"); 153DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u");
146DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u"); 154DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u");
147DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u"); 155DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u");
148DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u"); 156DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u");
149DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u"); 157DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u");
150DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u"); 158DEBUGFS_FWSTATS_FILE(isr, irqs, "%u");
151DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u"); 159DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u");
152DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u"); 160DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u");
153DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u"); 161DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u");
154DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u"); 162DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u");
155DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u"); 163DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u");
156DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u"); 164DEBUGFS_FWSTATS_FILE(isr, commands, "%u");
157DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u"); 165DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u");
158DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u"); 166DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u");
159DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u"); 167DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u");
160DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u"); 168DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u");
161DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u"); 169DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u");
162DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u"); 170DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u");
163 171
164DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u"); 172DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u");
165DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u"); 173DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u");
166/* skipping wep.reserved */ 174/* skipping wep.reserved */
167DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u"); 175DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u");
168DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u"); 176DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u");
169DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u"); 177DEBUGFS_FWSTATS_FILE(wep, packets, "%u");
170DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u"); 178DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u");
171 179
172DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u"); 180DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u");
173DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u"); 181DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u");
174DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u"); 182DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u");
175DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u"); 183DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u");
176DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u"); 184DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u");
177DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u"); 185DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u");
178DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u"); 186DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u");
179DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u"); 187DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u");
180DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u"); 188DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u");
181DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u"); 189DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u");
182DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u"); 190DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u");
183DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u"); 191DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u");
184/* skipping cont_miss_bcns_spread for now */ 192/* skipping cont_miss_bcns_spread for now */
185DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u"); 193DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u");
186 194
187DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u"); 195DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u");
188DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u"); 196DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u");
189 197
190DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u"); 198DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u");
191DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u"); 199DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u");
192DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u"); 200DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u");
193DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u"); 201DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u");
194DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u"); 202DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u");
195DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u"); 203DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u");
196 204
197DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u"); 205DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u");
198DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u"); 206DEBUGFS_FWSTATS_FILE(event, calibration, "%u");
199DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u"); 207DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u");
200DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u"); 208DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u");
201DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u"); 209DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u");
202DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u"); 210DEBUGFS_FWSTATS_FILE(event, oom_late, "%u");
203DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u"); 211DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u");
204DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u"); 212DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u");
205 213
206DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u"); 214DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u");
207DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u"); 215DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u");
208DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u"); 216DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u");
209DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u"); 217DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u");
210DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u"); 218DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u");
211DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u"); 219DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u");
212DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u"); 220DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u");
213 221
214DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u"); 222DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u");
215DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u"); 223DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u");
216DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, 224DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u");
217 20, "%u"); 225DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u");
218DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u"); 226DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u");
219DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u"); 227
220 228DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count);
221DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count); 229DEBUGFS_READONLY_FILE(excessive_retries, "%u",
222DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
223 wl->stats.excessive_retries); 230 wl->stats.excessive_retries);
224 231
225static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, 232static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 7b3f50382963..38ccef7d73a5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -134,8 +134,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
134 134
135 /* go to extremely low power mode */ 135 /* go to extremely low power mode */
136 wl1271_ps_elp_sleep(wl); 136 wl1271_ps_elp_sleep(wl);
137 if (ret < 0)
138 break;
139 break; 137 break;
140 case EVENT_EXIT_POWER_SAVE_FAIL: 138 case EVENT_EXIT_POWER_SAVE_FAIL:
141 wl1271_debug(DEBUG_PSM, "PSM exit failed"); 139 wl1271_debug(DEBUG_PSM, "PSM exit failed");
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 48a4b9961ae6..f5b1d19bc88d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -481,9 +481,9 @@ static void wl1271_fw_status(struct wl1271 *wl,
481 total += cnt; 481 total += cnt;
482 } 482 }
483 483
484 /* if more blocks are available now, schedule some tx work */ 484 /* if more blocks are available now, tx work can be scheduled */
485 if (total && !skb_queue_empty(&wl->tx_queue)) 485 if (total)
486 ieee80211_queue_work(wl->hw, &wl->tx_work); 486 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
487 487
488 /* update the host-chipset time offset */ 488 /* update the host-chipset time offset */
489 getnstimeofday(&ts); 489 getnstimeofday(&ts);
@@ -529,6 +529,15 @@ static void wl1271_irq_work(struct work_struct *work)
529 529
530 intr &= WL1271_INTR_MASK; 530 intr &= WL1271_INTR_MASK;
531 531
532 if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
533 wl1271_error("watchdog interrupt received! "
534 "starting recovery.");
535 ieee80211_queue_work(wl->hw, &wl->recovery_work);
536
537 /* restarting the chip. ignore any other interrupt. */
538 goto out;
539 }
540
532 if (intr & WL1271_ACX_INTR_DATA) { 541 if (intr & WL1271_ACX_INTR_DATA) {
533 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); 542 wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
534 543
@@ -537,6 +546,16 @@ static void wl1271_irq_work(struct work_struct *work)
537 (wl->tx_results_count & 0xff)) 546 (wl->tx_results_count & 0xff))
538 wl1271_tx_complete(wl); 547 wl1271_tx_complete(wl);
539 548
549 /* Check if any tx blocks were freed */
550 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
551 !skb_queue_empty(&wl->tx_queue)) {
552 /*
553 * In order to avoid starvation of the TX path,
554 * call the work function directly.
555 */
556 wl1271_tx_work_locked(wl);
557 }
558
540 wl1271_rx(wl, wl->fw_status); 559 wl1271_rx(wl, wl->fw_status);
541 } 560 }
542 561
@@ -851,12 +870,32 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
851 struct ieee80211_sta *sta = txinfo->control.sta; 870 struct ieee80211_sta *sta = txinfo->control.sta;
852 unsigned long flags; 871 unsigned long flags;
853 872
854 /* peek into the rates configured in the STA entry */ 873 /*
874 * peek into the rates configured in the STA entry.
875 * The rates set after connection stage, The first block only BG sets:
876 * the compare is for bit 0-16 of sta_rate_set. The second block add
877 * HT rates in case of HT supported.
878 */
855 spin_lock_irqsave(&wl->wl_lock, flags); 879 spin_lock_irqsave(&wl->wl_lock, flags);
856 if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) { 880 if (sta &&
881 (sta->supp_rates[conf->channel->band] !=
882 (wl->sta_rate_set & HW_BG_RATES_MASK))) {
857 wl->sta_rate_set = sta->supp_rates[conf->channel->band]; 883 wl->sta_rate_set = sta->supp_rates[conf->channel->band];
858 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); 884 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
859 } 885 }
886
887#ifdef CONFIG_WL1271_HT
888 if (sta &&
889 sta->ht_cap.ht_supported &&
890 ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
891 sta->ht_cap.mcs.rx_mask[0])) {
892 /* Clean MCS bits before setting them */
893 wl->sta_rate_set &= HW_BG_RATES_MASK;
894 wl->sta_rate_set |=
895 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
896 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
897 }
898#endif
860 spin_unlock_irqrestore(&wl->wl_lock, flags); 899 spin_unlock_irqrestore(&wl->wl_lock, flags);
861 900
862 /* queue the packet */ 901 /* queue the packet */
@@ -867,7 +906,8 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
867 * before that, the tx_work will not be initialized! 906 * before that, the tx_work will not be initialized!
868 */ 907 */
869 908
870 ieee80211_queue_work(wl->hw, &wl->tx_work); 909 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
910 ieee80211_queue_work(wl->hw, &wl->tx_work);
871 911
872 /* 912 /*
873 * The workqueue is slow to process the tx_queue and we need stop 913 * The workqueue is slow to process the tx_queue and we need stop
@@ -919,18 +959,19 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
919 struct wiphy *wiphy = hw->wiphy; 959 struct wiphy *wiphy = hw->wiphy;
920 int retries = WL1271_BOOT_RETRIES; 960 int retries = WL1271_BOOT_RETRIES;
921 int ret = 0; 961 int ret = 0;
962 bool booted = false;
922 963
923 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 964 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
924 vif->type, vif->addr); 965 vif->type, vif->addr);
925 966
926 mutex_lock(&wl->mutex); 967 mutex_lock(&wl->mutex);
927 if (wl->vif) { 968 if (wl->vif) {
969 wl1271_debug(DEBUG_MAC80211,
970 "multiple vifs are not supported yet");
928 ret = -EBUSY; 971 ret = -EBUSY;
929 goto out; 972 goto out;
930 } 973 }
931 974
932 wl->vif = vif;
933
934 switch (vif->type) { 975 switch (vif->type) {
935 case NL80211_IFTYPE_STATION: 976 case NL80211_IFTYPE_STATION:
936 wl->bss_type = BSS_TYPE_STA_BSS; 977 wl->bss_type = BSS_TYPE_STA_BSS;
@@ -968,15 +1009,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
968 if (ret < 0) 1009 if (ret < 0)
969 goto irq_disable; 1010 goto irq_disable;
970 1011
971 wl->state = WL1271_STATE_ON; 1012 booted = true;
972 wl1271_info("firmware booted (%s)", wl->chip.fw_ver); 1013 break;
973
974 /* update hw/fw version info in wiphy struct */
975 wiphy->hw_version = wl->chip.id;
976 strncpy(wiphy->fw_version, wl->chip.fw_ver,
977 sizeof(wiphy->fw_version));
978
979 goto out;
980 1014
981irq_disable: 1015irq_disable:
982 wl1271_disable_interrupts(wl); 1016 wl1271_disable_interrupts(wl);
@@ -994,8 +1028,21 @@ power_off:
994 wl1271_power_off(wl); 1028 wl1271_power_off(wl);
995 } 1029 }
996 1030
997 wl1271_error("firmware boot failed despite %d retries", 1031 if (!booted) {
998 WL1271_BOOT_RETRIES); 1032 wl1271_error("firmware boot failed despite %d retries",
1033 WL1271_BOOT_RETRIES);
1034 goto out;
1035 }
1036
1037 wl->vif = vif;
1038 wl->state = WL1271_STATE_ON;
1039 wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
1040
1041 /* update hw/fw version info in wiphy struct */
1042 wiphy->hw_version = wl->chip.id;
1043 strncpy(wiphy->fw_version, wl->chip.fw_ver,
1044 sizeof(wiphy->fw_version));
1045
999out: 1046out:
1000 mutex_unlock(&wl->mutex); 1047 mutex_unlock(&wl->mutex);
1001 1048
@@ -1025,6 +1072,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1025 wl->scan.state = WL1271_SCAN_STATE_IDLE; 1072 wl->scan.state = WL1271_SCAN_STATE_IDLE;
1026 kfree(wl->scan.scanned_ch); 1073 kfree(wl->scan.scanned_ch);
1027 wl->scan.scanned_ch = NULL; 1074 wl->scan.scanned_ch = NULL;
1075 wl->scan.req = NULL;
1028 ieee80211_scan_completed(wl->hw, true); 1076 ieee80211_scan_completed(wl->hw, true);
1029 } 1077 }
1030 1078
@@ -1312,8 +1360,10 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1312 1360
1313 mutex_lock(&wl->mutex); 1361 mutex_lock(&wl->mutex);
1314 1362
1315 if (unlikely(wl->state == WL1271_STATE_OFF)) 1363 if (unlikely(wl->state == WL1271_STATE_OFF)) {
1364 ret = -EAGAIN;
1316 goto out; 1365 goto out;
1366 }
1317 1367
1318 ret = wl1271_ps_elp_wakeup(wl, false); 1368 ret = wl1271_ps_elp_wakeup(wl, false);
1319 if (ret < 0) 1369 if (ret < 0)
@@ -1536,6 +1586,11 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
1536 1586
1537 mutex_lock(&wl->mutex); 1587 mutex_lock(&wl->mutex);
1538 1588
1589 if (unlikely(wl->state == WL1271_STATE_OFF)) {
1590 ret = -EAGAIN;
1591 goto out_unlock;
1592 }
1593
1539 ret = wl1271_ps_elp_wakeup(wl, false); 1594 ret = wl1271_ps_elp_wakeup(wl, false);
1540 if (ret < 0) 1595 if (ret < 0)
1541 goto out_unlock; 1596 goto out_unlock;
@@ -1645,6 +1700,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1645 1700
1646 mutex_lock(&wl->mutex); 1701 mutex_lock(&wl->mutex);
1647 1702
1703 if (wl->state == WL1271_STATE_OFF) {
1704 /*
1705 * We cannot return -EBUSY here because cfg80211 will expect
1706 * a call to ieee80211_scan_completed if we do - in this case
1707 * there won't be any call.
1708 */
1709 ret = -EAGAIN;
1710 goto out;
1711 }
1712
1648 ret = wl1271_ps_elp_wakeup(wl, false); 1713 ret = wl1271_ps_elp_wakeup(wl, false);
1649 if (ret < 0) 1714 if (ret < 0)
1650 goto out; 1715 goto out;
@@ -1666,8 +1731,10 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1666 1731
1667 mutex_lock(&wl->mutex); 1732 mutex_lock(&wl->mutex);
1668 1733
1669 if (unlikely(wl->state == WL1271_STATE_OFF)) 1734 if (unlikely(wl->state == WL1271_STATE_OFF)) {
1735 ret = -EAGAIN;
1670 goto out; 1736 goto out;
1737 }
1671 1738
1672 ret = wl1271_ps_elp_wakeup(wl, false); 1739 ret = wl1271_ps_elp_wakeup(wl, false);
1673 if (ret < 0) 1740 if (ret < 0)
@@ -1709,6 +1776,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1709{ 1776{
1710 enum wl1271_cmd_ps_mode mode; 1777 enum wl1271_cmd_ps_mode mode;
1711 struct wl1271 *wl = hw->priv; 1778 struct wl1271 *wl = hw->priv;
1779 struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid);
1712 bool do_join = false; 1780 bool do_join = false;
1713 bool set_assoc = false; 1781 bool set_assoc = false;
1714 int ret; 1782 int ret;
@@ -1717,6 +1785,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1717 1785
1718 mutex_lock(&wl->mutex); 1786 mutex_lock(&wl->mutex);
1719 1787
1788 if (unlikely(wl->state == WL1271_STATE_OFF))
1789 goto out;
1790
1720 ret = wl1271_ps_elp_wakeup(wl, false); 1791 ret = wl1271_ps_elp_wakeup(wl, false);
1721 if (ret < 0) 1792 if (ret < 0)
1722 goto out; 1793 goto out;
@@ -1927,6 +1998,37 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1927 } 1998 }
1928 } 1999 }
1929 2000
2001 /*
2002 * Takes care of: New association with HT enable,
2003 * HT information change in beacon.
2004 */
2005 if (sta &&
2006 (changed & BSS_CHANGED_HT) &&
2007 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
2008 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true);
2009 if (ret < 0) {
2010 wl1271_warning("Set ht cap true failed %d", ret);
2011 goto out_sleep;
2012 }
2013 ret = wl1271_acx_set_ht_information(wl,
2014 bss_conf->ht_operation_mode);
2015 if (ret < 0) {
2016 wl1271_warning("Set ht information failed %d", ret);
2017 goto out_sleep;
2018 }
2019 }
2020 /*
2021 * Takes care of: New association without HT,
2022 * Disassociation.
2023 */
2024 else if (sta && (changed & BSS_CHANGED_ASSOC)) {
2025 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false);
2026 if (ret < 0) {
2027 wl1271_warning("Set ht cap false failed %d", ret);
2028 goto out_sleep;
2029 }
2030 }
2031
1930 if (changed & BSS_CHANGED_ARP_FILTER) { 2032 if (changed & BSS_CHANGED_ARP_FILTER) {
1931 __be32 addr = bss_conf->arp_addr_list[0]; 2033 __be32 addr = bss_conf->arp_addr_list[0];
1932 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); 2034 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
@@ -1966,6 +2068,11 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1966 2068
1967 wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); 2069 wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
1968 2070
2071 if (unlikely(wl->state == WL1271_STATE_OFF)) {
2072 ret = -EAGAIN;
2073 goto out;
2074 }
2075
1969 ret = wl1271_ps_elp_wakeup(wl, false); 2076 ret = wl1271_ps_elp_wakeup(wl, false);
1970 if (ret < 0) 2077 if (ret < 0)
1971 goto out; 2078 goto out;
@@ -2009,6 +2116,9 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
2009 2116
2010 mutex_lock(&wl->mutex); 2117 mutex_lock(&wl->mutex);
2011 2118
2119 if (unlikely(wl->state == WL1271_STATE_OFF))
2120 goto out;
2121
2012 ret = wl1271_ps_elp_wakeup(wl, false); 2122 ret = wl1271_ps_elp_wakeup(wl, false);
2013 if (ret < 0) 2123 if (ret < 0)
2014 goto out; 2124 goto out;
@@ -2030,14 +2140,14 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
2030{ 2140{
2031 struct wl1271 *wl = hw->priv; 2141 struct wl1271 *wl = hw->priv;
2032 struct ieee80211_conf *conf = &hw->conf; 2142 struct ieee80211_conf *conf = &hw->conf;
2033 2143
2034 if (idx != 0) 2144 if (idx != 0)
2035 return -ENOENT; 2145 return -ENOENT;
2036 2146
2037 survey->channel = conf->channel; 2147 survey->channel = conf->channel;
2038 survey->filled = SURVEY_INFO_NOISE_DBM; 2148 survey->filled = SURVEY_INFO_NOISE_DBM;
2039 survey->noise = wl->noise; 2149 survey->noise = wl->noise;
2040 2150
2041 return 0; 2151 return 0;
2042} 2152}
2043 2153
@@ -2107,14 +2217,14 @@ static struct ieee80211_channel wl1271_channels[] = {
2107/* mapping to indexes for wl1271_rates */ 2217/* mapping to indexes for wl1271_rates */
2108static const u8 wl1271_rate_to_idx_2ghz[] = { 2218static const u8 wl1271_rate_to_idx_2ghz[] = {
2109 /* MCS rates are used only with 11n */ 2219 /* MCS rates are used only with 11n */
2110 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ 2220 7, /* CONF_HW_RXTX_RATE_MCS7 */
2111 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ 2221 6, /* CONF_HW_RXTX_RATE_MCS6 */
2112 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ 2222 5, /* CONF_HW_RXTX_RATE_MCS5 */
2113 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ 2223 4, /* CONF_HW_RXTX_RATE_MCS4 */
2114 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ 2224 3, /* CONF_HW_RXTX_RATE_MCS3 */
2115 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ 2225 2, /* CONF_HW_RXTX_RATE_MCS2 */
2116 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ 2226 1, /* CONF_HW_RXTX_RATE_MCS1 */
2117 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ 2227 0, /* CONF_HW_RXTX_RATE_MCS0 */
2118 2228
2119 11, /* CONF_HW_RXTX_RATE_54 */ 2229 11, /* CONF_HW_RXTX_RATE_54 */
2120 10, /* CONF_HW_RXTX_RATE_48 */ 2230 10, /* CONF_HW_RXTX_RATE_48 */
@@ -2134,12 +2244,34 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
2134 0 /* CONF_HW_RXTX_RATE_1 */ 2244 0 /* CONF_HW_RXTX_RATE_1 */
2135}; 2245};
2136 2246
2247/* 11n STA capabilities */
2248#define HW_RX_HIGHEST_RATE 72
2249
2250#ifdef CONFIG_WL1271_HT
2251#define WL1271_HT_CAP { \
2252 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
2253 .ht_supported = true, \
2254 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
2255 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
2256 .mcs = { \
2257 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
2258 .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
2259 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
2260 }, \
2261}
2262#else
2263#define WL1271_HT_CAP { \
2264 .ht_supported = false, \
2265}
2266#endif
2267
2137/* can't be const, mac80211 writes to this */ 2268/* can't be const, mac80211 writes to this */
2138static struct ieee80211_supported_band wl1271_band_2ghz = { 2269static struct ieee80211_supported_band wl1271_band_2ghz = {
2139 .channels = wl1271_channels, 2270 .channels = wl1271_channels,
2140 .n_channels = ARRAY_SIZE(wl1271_channels), 2271 .n_channels = ARRAY_SIZE(wl1271_channels),
2141 .bitrates = wl1271_rates, 2272 .bitrates = wl1271_rates,
2142 .n_bitrates = ARRAY_SIZE(wl1271_rates), 2273 .n_bitrates = ARRAY_SIZE(wl1271_rates),
2274 .ht_cap = WL1271_HT_CAP,
2143}; 2275};
2144 2276
2145/* 5 GHz data rates for WL1273 */ 2277/* 5 GHz data rates for WL1273 */
@@ -2222,14 +2354,14 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
2222/* mapping to indexes for wl1271_rates_5ghz */ 2354/* mapping to indexes for wl1271_rates_5ghz */
2223static const u8 wl1271_rate_to_idx_5ghz[] = { 2355static const u8 wl1271_rate_to_idx_5ghz[] = {
2224 /* MCS rates are used only with 11n */ 2356 /* MCS rates are used only with 11n */
2225 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ 2357 7, /* CONF_HW_RXTX_RATE_MCS7 */
2226 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ 2358 6, /* CONF_HW_RXTX_RATE_MCS6 */
2227 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ 2359 5, /* CONF_HW_RXTX_RATE_MCS5 */
2228 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ 2360 4, /* CONF_HW_RXTX_RATE_MCS4 */
2229 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ 2361 3, /* CONF_HW_RXTX_RATE_MCS3 */
2230 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ 2362 2, /* CONF_HW_RXTX_RATE_MCS2 */
2231 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ 2363 1, /* CONF_HW_RXTX_RATE_MCS1 */
2232 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ 2364 0, /* CONF_HW_RXTX_RATE_MCS0 */
2233 2365
2234 7, /* CONF_HW_RXTX_RATE_54 */ 2366 7, /* CONF_HW_RXTX_RATE_54 */
2235 6, /* CONF_HW_RXTX_RATE_48 */ 2367 6, /* CONF_HW_RXTX_RATE_48 */
@@ -2254,6 +2386,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
2254 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), 2386 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
2255 .bitrates = wl1271_rates_5ghz, 2387 .bitrates = wl1271_rates_5ghz,
2256 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 2388 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
2389 .ht_cap = WL1271_HT_CAP,
2257}; 2390};
2258 2391
2259static const u8 *wl1271_band_rate_to_idx[] = { 2392static const u8 *wl1271_band_rate_to_idx[] = {
@@ -2281,18 +2414,18 @@ static const struct ieee80211_ops wl1271_ops = {
2281}; 2414};
2282 2415
2283 2416
2284u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate) 2417u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band)
2285{ 2418{
2286 u8 idx; 2419 u8 idx;
2287 2420
2288 BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); 2421 BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
2289 2422
2290 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { 2423 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
2291 wl1271_error("Illegal RX rate from HW: %d", rate); 2424 wl1271_error("Illegal RX rate from HW: %d", rate);
2292 return 0; 2425 return 0;
2293 } 2426 }
2294 2427
2295 idx = wl1271_band_rate_to_idx[wl->band][rate]; 2428 idx = wl1271_band_rate_to_idx[band][rate];
2296 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { 2429 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
2297 wl1271_error("Unsupported RX rate from HW: %d", rate); 2430 wl1271_error("Unsupported RX rate from HW: %d", rate);
2298 return 0; 2431 return 0;
@@ -2521,6 +2654,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2521 wl->sg_enabled = true; 2654 wl->sg_enabled = true;
2522 wl->hw_pg_ver = -1; 2655 wl->hw_pg_ver = -1;
2523 2656
2657 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
2524 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 2658 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
2525 wl->tx_frames[i] = NULL; 2659 wl->tx_frames[i] = NULL;
2526 2660
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index bea133b6e489..cacfee56a0d0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -48,10 +48,24 @@ static void wl1271_rx_status(struct wl1271 *wl,
48 struct ieee80211_rx_status *status, 48 struct ieee80211_rx_status *status,
49 u8 beacon) 49 u8 beacon)
50{ 50{
51 enum ieee80211_band desc_band;
52
51 memset(status, 0, sizeof(struct ieee80211_rx_status)); 53 memset(status, 0, sizeof(struct ieee80211_rx_status));
52 54
53 status->band = wl->band; 55 status->band = wl->band;
54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); 56
57 if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
58 desc_band = IEEE80211_BAND_2GHZ;
59 else
60 desc_band = IEEE80211_BAND_5GHZ;
61
62 status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band);
63
64#ifdef CONFIG_WL1271_HT
65 /* 11n support */
66 if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
67 status->flag |= RX_FLAG_HT;
68#endif
55 69
56 status->signal = desc->rssi; 70 status->signal = desc->rssi;
57 71
@@ -170,10 +184,14 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
170 while (pkt_offset < buf_size) { 184 while (pkt_offset < buf_size) {
171 pkt_length = wl1271_rx_get_buf_size(status, 185 pkt_length = wl1271_rx_get_buf_size(status,
172 drv_rx_counter); 186 drv_rx_counter);
173 if (wl1271_rx_handle_data(wl, 187 /*
174 wl->aggr_buf + pkt_offset, 188 * the handle data call can only fail in memory-outage
175 pkt_length) < 0) 189 * conditions, in that case the received frame will just
176 break; 190 * be dropped.
191 */
192 wl1271_rx_handle_data(wl,
193 wl->aggr_buf + pkt_offset,
194 pkt_length);
177 wl->rx_counter++; 195 wl->rx_counter++;
178 drv_rx_counter++; 196 drv_rx_counter++;
179 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; 197 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h
index 13a232333b13..6d41981ce53f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.h
@@ -116,6 +116,6 @@ struct wl1271_rx_descriptor {
116} __packed; 116} __packed;
117 117
118void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); 118void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
119u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); 119u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
120 120
121#endif 121#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
index 909bb47995b6..e0661a543a35 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
@@ -48,14 +48,15 @@ void wl1271_scan_complete_work(struct work_struct *work)
48 wl->scan.state = WL1271_SCAN_STATE_IDLE; 48 wl->scan.state = WL1271_SCAN_STATE_IDLE;
49 kfree(wl->scan.scanned_ch); 49 kfree(wl->scan.scanned_ch);
50 wl->scan.scanned_ch = NULL; 50 wl->scan.scanned_ch = NULL;
51 mutex_unlock(&wl->mutex); 51 wl->scan.req = NULL;
52
53 ieee80211_scan_completed(wl->hw, false); 52 ieee80211_scan_completed(wl->hw, false);
54 53
55 if (wl->scan.failed) { 54 if (wl->scan.failed) {
56 wl1271_info("Scan completed due to error."); 55 wl1271_info("Scan completed due to error.");
57 ieee80211_queue_work(wl->hw, &wl->recovery_work); 56 ieee80211_queue_work(wl->hw, &wl->recovery_work);
58 } 57 }
58 mutex_unlock(&wl->mutex);
59
59} 60}
60 61
61 62
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index a3aa84386c88..55ec4428922b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -37,6 +37,7 @@ enum wl1271_tm_commands {
37 WL1271_TM_CMD_CONFIGURE, 37 WL1271_TM_CMD_CONFIGURE,
38 WL1271_TM_CMD_NVS_PUSH, 38 WL1271_TM_CMD_NVS_PUSH,
39 WL1271_TM_CMD_SET_PLT_MODE, 39 WL1271_TM_CMD_SET_PLT_MODE,
40 WL1271_TM_CMD_RECOVER,
40 41
41 __WL1271_TM_CMD_AFTER_LAST 42 __WL1271_TM_CMD_AFTER_LAST
42}; 43};
@@ -248,6 +249,15 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
248 return ret; 249 return ret;
249} 250}
250 251
252static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
253{
254 wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover");
255
256 ieee80211_queue_work(wl->hw, &wl->recovery_work);
257
258 return 0;
259}
260
251int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) 261int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
252{ 262{
253 struct wl1271 *wl = hw->priv; 263 struct wl1271 *wl = hw->priv;
@@ -272,6 +282,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
272 return wl1271_tm_cmd_nvs_push(wl, tb); 282 return wl1271_tm_cmd_nvs_push(wl, tb);
273 case WL1271_TM_CMD_SET_PLT_MODE: 283 case WL1271_TM_CMD_SET_PLT_MODE:
274 return wl1271_tm_cmd_set_plt_mode(wl, tb); 284 return wl1271_tm_cmd_set_plt_mode(wl, tb);
285 case WL1271_TM_CMD_RECOVER:
286 return wl1271_tm_cmd_recover(wl, tb);
275 default: 287 default:
276 return -EOPNOTSUPP; 288 return -EOPNOTSUPP;
277 } 289 }
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index e3dc13c4d01a..279be5b98d9f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -30,17 +30,26 @@
30#include "wl1271_ps.h" 30#include "wl1271_ps.h"
31#include "wl1271_tx.h" 31#include "wl1271_tx.h"
32 32
33static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb) 33static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
34{ 34{
35 int i; 35 int id;
36 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 36
37 if (wl->tx_frames[i] == NULL) { 37 id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS);
38 wl->tx_frames[i] = skb; 38 if (id >= ACX_TX_DESCRIPTORS)
39 wl->tx_frames_cnt++; 39 return -EBUSY;
40 return i; 40
41 } 41 __set_bit(id, wl->tx_frames_map);
42 wl->tx_frames[id] = skb;
43 wl->tx_frames_cnt++;
44 return id;
45}
42 46
43 return -EBUSY; 47static void wl1271_free_tx_id(struct wl1271 *wl, int id)
48{
49 if (__test_and_clear_bit(id, wl->tx_frames_map)) {
50 wl->tx_frames[id] = NULL;
51 wl->tx_frames_cnt--;
52 }
44} 53}
45 54
46static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, 55static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
@@ -52,10 +61,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
52 int id, ret = -EBUSY; 61 int id, ret = -EBUSY;
53 62
54 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) 63 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
55 return -EBUSY; 64 return -EAGAIN;
56 65
57 /* allocate free identifier for the packet */ 66 /* allocate free identifier for the packet */
58 id = wl1271_tx_id(wl, skb); 67 id = wl1271_alloc_tx_id(wl, skb);
59 if (id < 0) 68 if (id < 0)
60 return id; 69 return id;
61 70
@@ -79,8 +88,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
79 "tx_allocate: size: %d, blocks: %d, id: %d", 88 "tx_allocate: size: %d, blocks: %d, id: %d",
80 total_len, total_blocks, id); 89 total_len, total_blocks, id);
81 } else { 90 } else {
82 wl->tx_frames[id] = NULL; 91 wl1271_free_tx_id(wl, id);
83 wl->tx_frames_cnt--;
84 } 92 }
85 93
86 return ret; 94 return ret;
@@ -201,41 +209,67 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
201 rate_set >>= 1; 209 rate_set >>= 1;
202 } 210 }
203 211
212#ifdef CONFIG_WL1271_HT
213 /* MCS rates indication are on bits 16 - 23 */
214 rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
215
216 for (bit = 0; bit < 8; bit++) {
217 if (rate_set & 0x1)
218 enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
219 rate_set >>= 1;
220 }
221#endif
222
204 return enabled_rates; 223 return enabled_rates;
205} 224}
206 225
207void wl1271_tx_work(struct work_struct *work) 226static void handle_tx_low_watermark(struct wl1271 *wl)
227{
228 unsigned long flags;
229
230 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
231 skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
232 /* firmware buffer has space, restart queues */
233 spin_lock_irqsave(&wl->wl_lock, flags);
234 ieee80211_wake_queues(wl->hw);
235 clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
236 spin_unlock_irqrestore(&wl->wl_lock, flags);
237 }
238}
239
240void wl1271_tx_work_locked(struct wl1271 *wl)
208{ 241{
209 struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
210 struct sk_buff *skb; 242 struct sk_buff *skb;
211 bool woken_up = false; 243 bool woken_up = false;
212 u32 sta_rates = 0; 244 u32 sta_rates = 0;
213 u32 buf_offset; 245 u32 buf_offset = 0;
246 bool sent_packets = false;
214 int ret; 247 int ret;
215 248
216 /* check if the rates supported by the AP have changed */ 249 /* check if the rates supported by the AP have changed */
217 if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, 250 if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
218 &wl->flags))) { 251 &wl->flags))) {
219 unsigned long flags; 252 unsigned long flags;
253
220 spin_lock_irqsave(&wl->wl_lock, flags); 254 spin_lock_irqsave(&wl->wl_lock, flags);
221 sta_rates = wl->sta_rate_set; 255 sta_rates = wl->sta_rate_set;
222 spin_unlock_irqrestore(&wl->wl_lock, flags); 256 spin_unlock_irqrestore(&wl->wl_lock, flags);
223 } 257 }
224 258
225 mutex_lock(&wl->mutex);
226
227 if (unlikely(wl->state == WL1271_STATE_OFF)) 259 if (unlikely(wl->state == WL1271_STATE_OFF))
228 goto out; 260 goto out;
229 261
230 /* if rates have changed, re-configure the rate policy */ 262 /* if rates have changed, re-configure the rate policy */
231 if (unlikely(sta_rates)) { 263 if (unlikely(sta_rates)) {
264 ret = wl1271_ps_elp_wakeup(wl, false);
265 if (ret < 0)
266 goto out;
267 woken_up = true;
268
232 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); 269 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
233 wl1271_acx_rate_policies(wl); 270 wl1271_acx_rate_policies(wl);
234 } 271 }
235 272
236 /* Prepare the transfer buffer, by aggregating all
237 * available packets */
238 buf_offset = 0;
239 while ((skb = skb_dequeue(&wl->tx_queue))) { 273 while ((skb = skb_dequeue(&wl->tx_queue))) {
240 if (!woken_up) { 274 if (!woken_up) {
241 ret = wl1271_ps_elp_wakeup(wl, false); 275 ret = wl1271_ps_elp_wakeup(wl, false);
@@ -245,13 +279,25 @@ void wl1271_tx_work(struct work_struct *work)
245 } 279 }
246 280
247 ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); 281 ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
248 if (ret == -EBUSY) { 282 if (ret == -EAGAIN) {
283 /*
284 * Aggregation buffer is full.
285 * Flush buffer and try again.
286 */
287 skb_queue_head(&wl->tx_queue, skb);
288 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
289 buf_offset, true);
290 sent_packets = true;
291 buf_offset = 0;
292 continue;
293 } else if (ret == -EBUSY) {
249 /* 294 /*
250 * Either the firmware buffer is full, or the 295 * Firmware buffer is full.
251 * aggregation buffer is.
252 * Queue back last skb, and stop aggregating. 296 * Queue back last skb, and stop aggregating.
253 */ 297 */
254 skb_queue_head(&wl->tx_queue, skb); 298 skb_queue_head(&wl->tx_queue, skb);
299 /* No work left, avoid scheduling redundant tx work */
300 set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
255 goto out_ack; 301 goto out_ack;
256 } else if (ret < 0) { 302 } else if (ret < 0) {
257 dev_kfree_skb(skb); 303 dev_kfree_skb(skb);
@@ -265,14 +311,25 @@ out_ack:
265 if (buf_offset) { 311 if (buf_offset) {
266 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 312 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
267 buf_offset, true); 313 buf_offset, true);
314 sent_packets = true;
315 }
316 if (sent_packets) {
268 /* interrupt the firmware with the new packets */ 317 /* interrupt the firmware with the new packets */
269 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); 318 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
319 handle_tx_low_watermark(wl);
270 } 320 }
271 321
272out: 322out:
273 if (woken_up) 323 if (woken_up)
274 wl1271_ps_elp_sleep(wl); 324 wl1271_ps_elp_sleep(wl);
325}
326
327void wl1271_tx_work(struct work_struct *work)
328{
329 struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
275 330
331 mutex_lock(&wl->mutex);
332 wl1271_tx_work_locked(wl);
276 mutex_unlock(&wl->mutex); 333 mutex_unlock(&wl->mutex);
277} 334}
278 335
@@ -298,7 +355,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
298 if (result->status == TX_SUCCESS) { 355 if (result->status == TX_SUCCESS) {
299 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 356 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
300 info->flags |= IEEE80211_TX_STAT_ACK; 357 info->flags |= IEEE80211_TX_STAT_ACK;
301 rate = wl1271_rate_to_idx(wl, result->rate_class_index); 358 rate = wl1271_rate_to_idx(result->rate_class_index, wl->band);
302 retries = result->ack_failures; 359 retries = result->ack_failures;
303 } else if (result->status == TX_RETRY_EXCEEDED) { 360 } else if (result->status == TX_RETRY_EXCEEDED) {
304 wl->stats.excessive_retries++; 361 wl->stats.excessive_retries++;
@@ -335,8 +392,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
335 392
336 /* return the packet to the stack */ 393 /* return the packet to the stack */
337 ieee80211_tx_status(wl->hw, skb); 394 ieee80211_tx_status(wl->hw, skb);
338 wl->tx_frames[result->id] = NULL; 395 wl1271_free_tx_id(wl, result->id);
339 wl->tx_frames_cnt--;
340} 396}
341 397
342/* Called upon reception of a TX complete interrupt */ 398/* Called upon reception of a TX complete interrupt */
@@ -375,19 +431,6 @@ void wl1271_tx_complete(struct wl1271 *wl)
375 431
376 wl->tx_results_count++; 432 wl->tx_results_count++;
377 } 433 }
378
379 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
380 skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) {
381 unsigned long flags;
382
383 /* firmware buffer has space, restart queues */
384 wl1271_debug(DEBUG_TX, "tx_complete: waking queues");
385 spin_lock_irqsave(&wl->wl_lock, flags);
386 ieee80211_wake_queues(wl->hw);
387 clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags);
388 spin_unlock_irqrestore(&wl->wl_lock, flags);
389 ieee80211_queue_work(wl->hw, &wl->tx_work);
390 }
391} 434}
392 435
393/* caller must hold wl->mutex */ 436/* caller must hold wl->mutex */
@@ -402,14 +445,19 @@ void wl1271_tx_reset(struct wl1271 *wl)
402 ieee80211_tx_status(wl->hw, skb); 445 ieee80211_tx_status(wl->hw, skb);
403 } 446 }
404 447
448 /*
449 * Make sure the driver is at a consistent state, in case this
450 * function is called from a context other than interface removal.
451 */
452 handle_tx_low_watermark(wl);
453
405 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 454 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
406 if (wl->tx_frames[i] != NULL) { 455 if (wl->tx_frames[i] != NULL) {
407 skb = wl->tx_frames[i]; 456 skb = wl->tx_frames[i];
408 wl->tx_frames[i] = NULL; 457 wl1271_free_tx_id(wl, i);
409 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 458 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
410 ieee80211_tx_status(wl->hw, skb); 459 ieee80211_tx_status(wl->hw, skb);
411 } 460 }
412 wl->tx_frames_cnt = 0;
413} 461}
414 462
415#define WL1271_TX_FLUSH_TIMEOUT 500000 463#define WL1271_TX_FLUSH_TIMEOUT 500000
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index d12a129ad11c..9dc6f228c0de 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -140,10 +140,11 @@ static inline int wl1271_tx_get_queue(int queue)
140} 140}
141 141
142void wl1271_tx_work(struct work_struct *work); 142void wl1271_tx_work(struct work_struct *work);
143void wl1271_tx_work_locked(struct wl1271 *wl);
143void wl1271_tx_complete(struct wl1271 *wl); 144void wl1271_tx_complete(struct wl1271 *wl);
144void wl1271_tx_reset(struct wl1271 *wl); 145void wl1271_tx_reset(struct wl1271 *wl);
145void wl1271_tx_flush(struct wl1271 *wl); 146void wl1271_tx_flush(struct wl1271 *wl);
146u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); 147u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
147u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); 148u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
148 149
149#endif 150#endif
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 390d77f762c4..b97aa9c78a96 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -30,6 +30,7 @@ static struct usb_device_id zd1201_table[] = {
30 {USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */ 30 {USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */
31 {USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */ 31 {USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */
32 {USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */ 32 {USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */
33 {USB_DEVICE(0x1044, 0x8004)}, /* Gigabyte GN-WLBZ101 */
33 {USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */ 34 {USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */
34 {} 35 {}
35}; 36};
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 818e1480ca93..06041cb1c422 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -55,6 +55,7 @@ static struct usb_device_id usb_ids[] = {
55 { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, 55 { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
56 { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, 56 { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
57 { USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 }, 57 { USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 },
58 { USB_DEVICE(0x14ea, 0xab10), .driver_info = DEVICE_ZD1211 },
58 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, 59 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
59 { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, 60 { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
60 { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 }, 61 { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
@@ -92,6 +93,7 @@ static struct usb_device_id usb_ids[] = {
92 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, 93 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
93 { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, 94 { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
94 { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B }, 95 { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
96 { USB_DEVICE(0x2019, 0xed01), .driver_info = DEVICE_ZD1211B },
95 /* "Driverless" devices that need ejecting */ 97 /* "Driverless" devices that need ejecting */
96 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, 98 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
97 { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, 99 { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index 6536a041d90d..f6c8c81a0025 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -59,6 +59,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
59 struct ssb_bus *ssb; 59 struct ssb_bus *ssb;
60 int err = -ENOMEM; 60 int err = -ENOMEM;
61 const char *name; 61 const char *name;
62 u32 val;
62 63
63 ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); 64 ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
64 if (!ssb) 65 if (!ssb)
@@ -74,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
74 goto err_pci_disable; 75 goto err_pci_disable;
75 pci_set_master(dev); 76 pci_set_master(dev);
76 77
78 /* Disable the RETRY_TIMEOUT register (0x41) to keep
79 * PCI Tx retries from interfering with C3 CPU state */
80 pci_read_config_dword(dev, 0x40, &val);
81 if ((val & 0x0000ff00) != 0)
82 pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
83
77 err = ssb_bus_pcibus_register(ssb, dev); 84 err = ssb_bus_pcibus_register(ssb, dev);
78 if (err) 85 if (err)
79 goto err_pci_release_regions; 86 goto err_pci_release_regions;
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 827cc95711ef..2184c6b97aeb 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -109,6 +109,17 @@ static inline __u8 ror8(__u8 word, unsigned int shift)
109 return (word >> shift) | (word << (8 - shift)); 109 return (word >> shift) | (word << (8 - shift));
110} 110}
111 111
112/**
113 * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit
114 * @value: value to sign extend
115 * @index: 0 based bit index (0<=index<32) to sign bit
116 */
117static inline __s32 sign_extend32(__u32 value, int index)
118{
119 __u8 shift = 31 - index;
120 return (__s32)(value << shift) >> shift;
121}
122
112static inline unsigned fls_long(unsigned long l) 123static inline unsigned fls_long(unsigned long l)
113{ 124{
114 if (sizeof(l) == 4) 125 if (sizeof(l) == 4)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 0edb2566c14c..fb877b5621b7 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1307,7 +1307,11 @@ enum nl80211_bitrate_attr {
1307 * wireless core it thinks its knows the regulatory domain we should be in. 1307 * wireless core it thinks its knows the regulatory domain we should be in.
1308 * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an 1308 * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
1309 * 802.11 country information element with regulatory information it 1309 * 802.11 country information element with regulatory information it
1310 * thinks we should consider. 1310 * thinks we should consider. cfg80211 only processes the country
1311 * code from the IE, and relies on the regulatory domain information
1312 * structure pased by userspace (CRDA) from our wireless-regdb.
1313 * If a channel is enabled but the country code indicates it should
1314 * be disabled we disable the channel and re-enable it upon disassociation.
1311 */ 1315 */
1312enum nl80211_reg_initiator { 1316enum nl80211_reg_initiator {
1313 NL80211_REGDOM_SET_BY_CORE, 1317 NL80211_REGDOM_SET_BY_CORE,
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 08c32e4f261a..c6c608482cba 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -354,37 +354,6 @@ static inline bool rfkill_blocked(struct rfkill *rfkill)
354} 354}
355#endif /* RFKILL || RFKILL_MODULE */ 355#endif /* RFKILL || RFKILL_MODULE */
356 356
357
358#ifdef CONFIG_RFKILL_LEDS
359/**
360 * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED.
361 * This function might return a NULL pointer if registering of the
362 * LED trigger failed. Use this as "default_trigger" for the LED.
363 */
364const char *rfkill_get_led_trigger_name(struct rfkill *rfkill);
365
366/**
367 * rfkill_set_led_trigger_name -- set the LED trigger name
368 * @rfkill: rfkill struct
369 * @name: LED trigger name
370 *
371 * This function sets the LED trigger name of the radio LED
372 * trigger that rfkill creates. It is optional, but if called
373 * must be called before rfkill_register() to be effective.
374 */
375void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name);
376#else
377static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
378{
379 return NULL;
380}
381
382static inline void
383rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
384{
385}
386#endif
387
388#endif /* __KERNEL__ */ 357#endif /* __KERNEL__ */
389 358
390#endif /* RFKILL_H */ 359#endif /* RFKILL_H */
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index 4f902e1908aa..bebb8efea0a6 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -24,6 +24,14 @@
24#ifndef _LINUX_WL12XX_H 24#ifndef _LINUX_WL12XX_H
25#define _LINUX_WL12XX_H 25#define _LINUX_WL12XX_H
26 26
27/* The board reference clock values */
28enum {
29 WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
30 WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
31 WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
32 WL12XX_REFCLOCK_54 = 3, /* 54 MHz */
33};
34
27struct wl12xx_platform_data { 35struct wl12xx_platform_data {
28 void (*set_power)(bool enable); 36 void (*set_power)(bool enable);
29 /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ 37 /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2a7936d7851d..e5702f5ac57c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1321,13 +1321,14 @@ struct cfg80211_ops {
1321 * initiator is %REGDOM_SET_BY_CORE). 1321 * initiator is %REGDOM_SET_BY_CORE).
1322 * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will 1322 * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will
1323 * ignore regulatory domain settings until it gets its own regulatory 1323 * ignore regulatory domain settings until it gets its own regulatory
1324 * domain via its regulatory_hint(). After its gets its own regulatory 1324 * domain via its regulatory_hint() unless the regulatory hint is
1325 * domain it will only allow further regulatory domain settings to 1325 * from a country IE. After its gets its own regulatory domain it will
1326 * further enhance compliance. For example if channel 13 and 14 are 1326 * only allow further regulatory domain settings to further enhance
1327 * disabled by this regulatory domain no user regulatory domain can 1327 * compliance. For example if channel 13 and 14 are disabled by this
1328 * enable these channels at a later time. This can be used for devices 1328 * regulatory domain no user regulatory domain can enable these channels
1329 * which do not have calibration information gauranteed for frequencies 1329 * at a later time. This can be used for devices which do not have
1330 * or settings outside of its regulatory domain. 1330 * calibration information guaranteed for frequencies or settings
1331 * outside of its regulatory domain.
1331 * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure 1332 * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure
1332 * that passive scan flags and beaconing flags may not be lifted by 1333 * that passive scan flags and beaconing flags may not be lifted by
1333 * cfg80211 due to regulatory beacon hints. For more information on beacon 1334 * cfg80211 due to regulatory beacon hints. For more information on beacon
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index d2b03e0851ef..4bd6ef0be380 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -147,6 +147,5 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
147 147
148void ieee80211_aes_key_free(struct crypto_cipher *tfm) 148void ieee80211_aes_key_free(struct crypto_cipher *tfm)
149{ 149{
150 if (tfm) 150 crypto_free_cipher(tfm);
151 crypto_free_cipher(tfm);
152} 151}
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index b4d66cca76d6..d502b2684a66 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -128,6 +128,5 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
128 128
129void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) 129void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm)
130{ 130{
131 if (tfm) 131 crypto_free_cipher(tfm);
132 crypto_free_cipher(tfm);
133} 132}
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 18260aa99c56..1f02e599a318 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -21,16 +21,30 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file)
21 return 0; 21 return 0;
22} 22}
23 23
24#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ 24#define DEBUGFS_FORMAT_BUFFER_SIZE 100
25
26int mac80211_format_buffer(char __user *userbuf, size_t count,
27 loff_t *ppos, char *fmt, ...)
28{
29 va_list args;
30 char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
31 int res;
32
33 va_start(args, fmt);
34 res = vscnprintf(buf, sizeof(buf), fmt, args);
35 va_end(args);
36
37 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
38}
39
40#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
25static ssize_t name## _read(struct file *file, char __user *userbuf, \ 41static ssize_t name## _read(struct file *file, char __user *userbuf, \
26 size_t count, loff_t *ppos) \ 42 size_t count, loff_t *ppos) \
27{ \ 43{ \
28 struct ieee80211_local *local = file->private_data; \ 44 struct ieee80211_local *local = file->private_data; \
29 char buf[buflen]; \
30 int res; \
31 \ 45 \
32 res = scnprintf(buf, buflen, fmt "\n", ##value); \ 46 return mac80211_format_buffer(userbuf, count, ppos, \
33 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 47 fmt "\n", ##value); \
34} \ 48} \
35 \ 49 \
36static const struct file_operations name## _ops = { \ 50static const struct file_operations name## _ops = { \
@@ -46,13 +60,13 @@ static const struct file_operations name## _ops = { \
46 debugfs_create_file(#name, mode, phyd, local, &name## _ops); 60 debugfs_create_file(#name, mode, phyd, local, &name## _ops);
47 61
48 62
49DEBUGFS_READONLY_FILE(frequency, 20, "%d", 63DEBUGFS_READONLY_FILE(frequency, "%d",
50 local->hw.conf.channel->center_freq); 64 local->hw.conf.channel->center_freq);
51DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", 65DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
52 local->total_ps_buffered); 66 local->total_ps_buffered);
53DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", 67DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
54 local->wep_iv & 0xffffff); 68 local->wep_iv & 0xffffff);
55DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", 69DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
56 local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); 70 local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
57 71
58static ssize_t tsf_read(struct file *file, char __user *user_buf, 72static ssize_t tsf_read(struct file *file, char __user *user_buf,
@@ -60,13 +74,11 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf,
60{ 74{
61 struct ieee80211_local *local = file->private_data; 75 struct ieee80211_local *local = file->private_data;
62 u64 tsf; 76 u64 tsf;
63 char buf[100];
64 77
65 tsf = drv_get_tsf(local); 78 tsf = drv_get_tsf(local);
66 79
67 snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf); 80 return mac80211_format_buffer(user_buf, count, ppos, "0x%016llx\n",
68 81 (unsigned long long) tsf);
69 return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
70} 82}
71 83
72static ssize_t tsf_write(struct file *file, 84static ssize_t tsf_write(struct file *file,
@@ -131,12 +143,9 @@ static ssize_t noack_read(struct file *file, char __user *user_buf,
131 size_t count, loff_t *ppos) 143 size_t count, loff_t *ppos)
132{ 144{
133 struct ieee80211_local *local = file->private_data; 145 struct ieee80211_local *local = file->private_data;
134 int res;
135 char buf[10];
136 146
137 res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test); 147 return mac80211_format_buffer(user_buf, count, ppos, "%d\n",
138 148 local->wifi_wme_noack_test);
139 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
140} 149}
141 150
142static ssize_t noack_write(struct file *file, 151static ssize_t noack_write(struct file *file,
@@ -168,12 +177,8 @@ static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
168 size_t count, loff_t *ppos) 177 size_t count, loff_t *ppos)
169{ 178{
170 struct ieee80211_local *local = file->private_data; 179 struct ieee80211_local *local = file->private_data;
171 int res; 180 return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
172 char buf[10]; 181 local->uapsd_queues);
173
174 res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues);
175
176 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
177} 182}
178 183
179static ssize_t uapsd_queues_write(struct file *file, 184static ssize_t uapsd_queues_write(struct file *file,
@@ -215,12 +220,9 @@ static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
215 size_t count, loff_t *ppos) 220 size_t count, loff_t *ppos)
216{ 221{
217 struct ieee80211_local *local = file->private_data; 222 struct ieee80211_local *local = file->private_data;
218 int res;
219 char buf[10];
220 223
221 res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len); 224 return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
222 225 local->uapsd_max_sp_len);
223 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
224} 226}
225 227
226static ssize_t uapsd_max_sp_len_write(struct file *file, 228static ssize_t uapsd_max_sp_len_write(struct file *file,
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h
index 09cc9be34796..7c87529630f5 100644
--- a/net/mac80211/debugfs.h
+++ b/net/mac80211/debugfs.h
@@ -4,6 +4,8 @@
4#ifdef CONFIG_MAC80211_DEBUGFS 4#ifdef CONFIG_MAC80211_DEBUGFS
5extern void debugfs_hw_add(struct ieee80211_local *local); 5extern void debugfs_hw_add(struct ieee80211_local *local);
6extern int mac80211_open_file_generic(struct inode *inode, struct file *file); 6extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
7extern int mac80211_format_buffer(char __user *userbuf, size_t count,
8 loff_t *ppos, char *fmt, ...);
7#else 9#else
8static inline void debugfs_hw_add(struct ieee80211_local *local) 10static inline void debugfs_hw_add(struct ieee80211_local *local)
9{ 11{
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 1243d1db5c59..5822a6ce7671 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -15,18 +15,17 @@
15#include "debugfs.h" 15#include "debugfs.h"
16#include "debugfs_key.h" 16#include "debugfs_key.h"
17 17
18#define KEY_READ(name, prop, buflen, format_string) \ 18#define KEY_READ(name, prop, format_string) \
19static ssize_t key_##name##_read(struct file *file, \ 19static ssize_t key_##name##_read(struct file *file, \
20 char __user *userbuf, \ 20 char __user *userbuf, \
21 size_t count, loff_t *ppos) \ 21 size_t count, loff_t *ppos) \
22{ \ 22{ \
23 char buf[buflen]; \
24 struct ieee80211_key *key = file->private_data; \ 23 struct ieee80211_key *key = file->private_data; \
25 int res = scnprintf(buf, buflen, format_string, key->prop); \ 24 return mac80211_format_buffer(userbuf, count, ppos, \
26 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 25 format_string, key->prop); \
27} 26}
28#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n") 27#define KEY_READ_D(name) KEY_READ(name, name, "%d\n")
29#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n") 28#define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n")
30 29
31#define KEY_OPS(name) \ 30#define KEY_OPS(name) \
32static const struct file_operations key_ ##name## _ops = { \ 31static const struct file_operations key_ ##name## _ops = { \
@@ -39,9 +38,9 @@ static const struct file_operations key_ ##name## _ops = { \
39 KEY_READ_##format(name) \ 38 KEY_READ_##format(name) \
40 KEY_OPS(name) 39 KEY_OPS(name)
41 40
42#define KEY_CONF_READ(name, buflen, format_string) \ 41#define KEY_CONF_READ(name, format_string) \
43 KEY_READ(conf_##name, conf.name, buflen, format_string) 42 KEY_READ(conf_##name, conf.name, format_string)
44#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n") 43#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n")
45 44
46#define KEY_CONF_OPS(name) \ 45#define KEY_CONF_OPS(name) \
47static const struct file_operations key_ ##name## _ops = { \ 46static const struct file_operations key_ ##name## _ops = { \
@@ -59,7 +58,7 @@ KEY_CONF_FILE(keyidx, D);
59KEY_CONF_FILE(hw_key_idx, D); 58KEY_CONF_FILE(hw_key_idx, D);
60KEY_FILE(flags, X); 59KEY_FILE(flags, X);
61KEY_FILE(tx_rx_count, D); 60KEY_FILE(tx_rx_count, D);
62KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n"); 61KEY_READ(ifindex, sdata->name, "%s\n");
63KEY_OPS(ifindex); 62KEY_OPS(ifindex);
64 63
65static ssize_t key_algorithm_read(struct file *file, 64static ssize_t key_algorithm_read(struct file *file,
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 4601fea1784d..f0fce37f4069 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -17,20 +17,18 @@
17 17
18/* sta attributtes */ 18/* sta attributtes */
19 19
20#define STA_READ(name, buflen, field, format_string) \ 20#define STA_READ(name, field, format_string) \
21static ssize_t sta_ ##name## _read(struct file *file, \ 21static ssize_t sta_ ##name## _read(struct file *file, \
22 char __user *userbuf, \ 22 char __user *userbuf, \
23 size_t count, loff_t *ppos) \ 23 size_t count, loff_t *ppos) \
24{ \ 24{ \
25 int res; \
26 struct sta_info *sta = file->private_data; \ 25 struct sta_info *sta = file->private_data; \
27 char buf[buflen]; \ 26 return mac80211_format_buffer(userbuf, count, ppos, \
28 res = scnprintf(buf, buflen, format_string, sta->field); \ 27 format_string, sta->field); \
29 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
30} 28}
31#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n") 29#define STA_READ_D(name, field) STA_READ(name, field, "%d\n")
32#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n") 30#define STA_READ_U(name, field) STA_READ(name, field, "%u\n")
33#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") 31#define STA_READ_S(name, field) STA_READ(name, field, "%s\n")
34 32
35#define STA_OPS(name) \ 33#define STA_OPS(name) \
36static const struct file_operations sta_ ##name## _ops = { \ 34static const struct file_operations sta_ ##name## _ops = { \
@@ -79,22 +77,18 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file,
79 char __user *userbuf, 77 char __user *userbuf,
80 size_t count, loff_t *ppos) 78 size_t count, loff_t *ppos)
81{ 79{
82 char buf[20];
83 struct sta_info *sta = file->private_data; 80 struct sta_info *sta = file->private_data;
84 int res = scnprintf(buf, sizeof(buf), "%u\n", 81 return mac80211_format_buffer(userbuf, count, ppos, "%u\n",
85 skb_queue_len(&sta->ps_tx_buf)); 82 skb_queue_len(&sta->ps_tx_buf));
86 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
87} 83}
88STA_OPS(num_ps_buf_frames); 84STA_OPS(num_ps_buf_frames);
89 85
90static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, 86static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
91 size_t count, loff_t *ppos) 87 size_t count, loff_t *ppos)
92{ 88{
93 char buf[20];
94 struct sta_info *sta = file->private_data; 89 struct sta_info *sta = file->private_data;
95 int res = scnprintf(buf, sizeof(buf), "%d\n", 90 return mac80211_format_buffer(userbuf, count, ppos, "%d\n",
96 jiffies_to_msecs(jiffies - sta->last_rx)); 91 jiffies_to_msecs(jiffies - sta->last_rx));
97 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
98} 92}
99STA_OPS(inactive_ms); 93STA_OPS(inactive_ms);
100 94
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 2a18d6602d4a..2d6f0259e0c6 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -407,8 +407,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
407 mi->ampdu_len += info->status.ampdu_len; 407 mi->ampdu_len += info->status.ampdu_len;
408 408
409 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { 409 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
410 mi->sample_wait = 4 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); 410 mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
411 mi->sample_tries = 3; 411 mi->sample_tries = 2;
412 mi->sample_count--; 412 mi->sample_count--;
413 } 413 }
414 414
@@ -506,7 +506,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
506 if (!mr->retry_updated) 506 if (!mr->retry_updated)
507 minstrel_calc_retransmit(mp, mi, index); 507 minstrel_calc_retransmit(mp, mi, index);
508 508
509 if (mr->probability < MINSTREL_FRAC(20, 100)) 509 if (sample)
510 rate->count = 1;
511 else if (mr->probability < MINSTREL_FRAC(20, 100))
510 rate->count = 2; 512 rate->count = 2;
511 else if (rtscts) 513 else if (rtscts)
512 rate->count = mr->retry_count_rtscts; 514 rate->count = mr->retry_count_rtscts;
@@ -562,7 +564,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
562 */ 564 */
563 if (minstrel_get_duration(sample_idx) > 565 if (minstrel_get_duration(sample_idx) >
564 minstrel_get_duration(mi->max_tp_rate)) { 566 minstrel_get_duration(mi->max_tp_rate)) {
565 if (mr->sample_skipped < 10) 567 if (mr->sample_skipped < 20)
566 goto next; 568 goto next;
567 569
568 if (mi->sample_slow++ > 2) 570 if (mi->sample_slow++ > 2)
@@ -586,6 +588,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
586 struct minstrel_ht_sta *mi = &msp->ht; 588 struct minstrel_ht_sta *mi = &msp->ht;
587 struct minstrel_priv *mp = priv; 589 struct minstrel_priv *mp = priv;
588 int sample_idx; 590 int sample_idx;
591 bool sample = false;
589 592
590 if (rate_control_send_low(sta, priv_sta, txrc)) 593 if (rate_control_send_low(sta, priv_sta, txrc))
591 return; 594 return;
@@ -596,10 +599,11 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
596 info->flags |= mi->tx_flags; 599 info->flags |= mi->tx_flags;
597 sample_idx = minstrel_get_sample_rate(mp, mi); 600 sample_idx = minstrel_get_sample_rate(mp, mi);
598 if (sample_idx >= 0) { 601 if (sample_idx >= 0) {
602 sample = true;
599 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, 603 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
600 txrc, true, false); 604 txrc, true, false);
601 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, 605 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
602 txrc, false, true); 606 txrc, false, false);
603 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 607 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
604 } else { 608 } else {
605 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, 609 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,
@@ -607,7 +611,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
607 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, 611 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
608 txrc, false, true); 612 txrc, false, true);
609 } 613 }
610 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, true); 614 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, !sample);
611 615
612 ar[3].count = 0; 616 ar[3].count = 0;
613 ar[3].idx = -1; 617 ar[3].idx = -1;
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 04f599089e6d..0198191b756d 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -149,20 +149,6 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
149 rfkill_led_trigger_event(rfkill); 149 rfkill_led_trigger_event(rfkill);
150} 150}
151 151
152const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
153{
154 return rfkill->led_trigger.name;
155}
156EXPORT_SYMBOL(rfkill_get_led_trigger_name);
157
158void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
159{
160 BUG_ON(!rfkill);
161
162 rfkill->ledtrigname = name;
163}
164EXPORT_SYMBOL(rfkill_set_led_trigger_name);
165
166static int rfkill_led_trigger_register(struct rfkill *rfkill) 152static int rfkill_led_trigger_register(struct rfkill *rfkill)
167{ 153{
168 rfkill->led_trigger.name = rfkill->ledtrigname 154 rfkill->led_trigger.name = rfkill->ledtrigname
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4b9f8912526c..3be18d9a944f 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -48,7 +48,7 @@
48#ifdef CONFIG_CFG80211_REG_DEBUG 48#ifdef CONFIG_CFG80211_REG_DEBUG
49#define REG_DBG_PRINT(format, args...) \ 49#define REG_DBG_PRINT(format, args...) \
50 do { \ 50 do { \
51 printk(KERN_DEBUG format , ## args); \ 51 printk(KERN_DEBUG "cfg80211: " format , ## args); \
52 } while (0) 52 } while (0)
53#else 53#else
54#define REG_DBG_PRINT(args...) 54#define REG_DBG_PRINT(args...)
@@ -711,6 +711,60 @@ int freq_reg_info(struct wiphy *wiphy,
711} 711}
712EXPORT_SYMBOL(freq_reg_info); 712EXPORT_SYMBOL(freq_reg_info);
713 713
714#ifdef CONFIG_CFG80211_REG_DEBUG
715static const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
716{
717 switch (initiator) {
718 case NL80211_REGDOM_SET_BY_CORE:
719 return "Set by core";
720 case NL80211_REGDOM_SET_BY_USER:
721 return "Set by user";
722 case NL80211_REGDOM_SET_BY_DRIVER:
723 return "Set by driver";
724 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
725 return "Set by country IE";
726 default:
727 WARN_ON(1);
728 return "Set by bug";
729 }
730}
731
732static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
733 u32 desired_bw_khz,
734 const struct ieee80211_reg_rule *reg_rule)
735{
736 const struct ieee80211_power_rule *power_rule;
737 const struct ieee80211_freq_range *freq_range;
738 char max_antenna_gain[32];
739
740 power_rule = &reg_rule->power_rule;
741 freq_range = &reg_rule->freq_range;
742
743 if (!power_rule->max_antenna_gain)
744 snprintf(max_antenna_gain, 32, "N/A");
745 else
746 snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);
747
748 REG_DBG_PRINT("Updating information on frequency %d MHz "
749 "for %d a MHz width channel with regulatory rule:\n",
750 chan->center_freq,
751 KHZ_TO_MHZ(desired_bw_khz));
752
753 REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n",
754 freq_range->start_freq_khz,
755 freq_range->end_freq_khz,
756 max_antenna_gain,
757 power_rule->max_eirp);
758}
759#else
760static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
761 u32 desired_bw_khz,
762 const struct ieee80211_reg_rule *reg_rule)
763{
764 return;
765}
766#endif
767
714/* 768/*
715 * Note that right now we assume the desired channel bandwidth 769 * Note that right now we assume the desired channel bandwidth
716 * is always 20 MHz for each individual channel (HT40 uses 20 MHz 770 * is always 20 MHz for each individual channel (HT40 uses 20 MHz
@@ -720,7 +774,9 @@ EXPORT_SYMBOL(freq_reg_info);
720 * on the wiphy with the target_bw specified. Then we can simply use 774 * on the wiphy with the target_bw specified. Then we can simply use
721 * that below for the desired_bw_khz below. 775 * that below for the desired_bw_khz below.
722 */ 776 */
723static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, 777static void handle_channel(struct wiphy *wiphy,
778 enum nl80211_reg_initiator initiator,
779 enum ieee80211_band band,
724 unsigned int chan_idx) 780 unsigned int chan_idx)
725{ 781{
726 int r; 782 int r;
@@ -748,8 +804,27 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
748 desired_bw_khz, 804 desired_bw_khz,
749 &reg_rule); 805 &reg_rule);
750 806
751 if (r) 807 if (r) {
808 /*
809 * We will disable all channels that do not match our
810 * recieved regulatory rule unless the hint is coming
811 * from a Country IE and the Country IE had no information
812 * about a band. The IEEE 802.11 spec allows for an AP
813 * to send only a subset of the regulatory rules allowed,
814 * so an AP in the US that only supports 2.4 GHz may only send
815 * a country IE with information for the 2.4 GHz band
816 * while 5 GHz is still supported.
817 */
818 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
819 r == -ERANGE)
820 return;
821
822 REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
823 chan->flags = IEEE80211_CHAN_DISABLED;
752 return; 824 return;
825 }
826
827 chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);
753 828
754 power_rule = &reg_rule->power_rule; 829 power_rule = &reg_rule->power_rule;
755 freq_range = &reg_rule->freq_range; 830 freq_range = &reg_rule->freq_range;
@@ -784,7 +859,9 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
784 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); 859 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
785} 860}
786 861
787static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) 862static void handle_band(struct wiphy *wiphy,
863 enum ieee80211_band band,
864 enum nl80211_reg_initiator initiator)
788{ 865{
789 unsigned int i; 866 unsigned int i;
790 struct ieee80211_supported_band *sband; 867 struct ieee80211_supported_band *sband;
@@ -793,24 +870,42 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
793 sband = wiphy->bands[band]; 870 sband = wiphy->bands[band];
794 871
795 for (i = 0; i < sband->n_channels; i++) 872 for (i = 0; i < sband->n_channels; i++)
796 handle_channel(wiphy, band, i); 873 handle_channel(wiphy, initiator, band, i);
797} 874}
798 875
799static bool ignore_reg_update(struct wiphy *wiphy, 876static bool ignore_reg_update(struct wiphy *wiphy,
800 enum nl80211_reg_initiator initiator) 877 enum nl80211_reg_initiator initiator)
801{ 878{
802 if (!last_request) 879 if (!last_request) {
880 REG_DBG_PRINT("Ignoring regulatory request %s since "
881 "last_request is not set\n",
882 reg_initiator_name(initiator));
803 return true; 883 return true;
884 }
885
804 if (initiator == NL80211_REGDOM_SET_BY_CORE && 886 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
805 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) 887 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
888 REG_DBG_PRINT("Ignoring regulatory request %s "
889 "since the driver uses its own custom "
890 "regulatory domain ",
891 reg_initiator_name(initiator));
806 return true; 892 return true;
893 }
894
807 /* 895 /*
808 * wiphy->regd will be set once the device has its own 896 * wiphy->regd will be set once the device has its own
809 * desired regulatory domain set 897 * desired regulatory domain set
810 */ 898 */
811 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && 899 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd &&
812 !is_world_regdom(last_request->alpha2)) 900 initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
901 !is_world_regdom(last_request->alpha2)) {
902 REG_DBG_PRINT("Ignoring regulatory request %s "
903 "since the driver requires its own regulaotry "
904 "domain to be set first",
905 reg_initiator_name(initiator));
813 return true; 906 return true;
907 }
908
814 return false; 909 return false;
815} 910}
816 911
@@ -1030,7 +1125,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
1030 goto out; 1125 goto out;
1031 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1126 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1032 if (wiphy->bands[band]) 1127 if (wiphy->bands[band])
1033 handle_band(wiphy, band); 1128 handle_band(wiphy, band, initiator);
1034 } 1129 }
1035out: 1130out:
1036 reg_process_beacons(wiphy); 1131 reg_process_beacons(wiphy);
@@ -1066,10 +1161,17 @@ static void handle_channel_custom(struct wiphy *wiphy,
1066 regd); 1161 regd);
1067 1162
1068 if (r) { 1163 if (r) {
1164 REG_DBG_PRINT("Disabling freq %d MHz as custom "
1165 "regd has no rule that fits a %d MHz "
1166 "wide channel\n",
1167 chan->center_freq,
1168 KHZ_TO_MHZ(desired_bw_khz));
1069 chan->flags = IEEE80211_CHAN_DISABLED; 1169 chan->flags = IEEE80211_CHAN_DISABLED;
1070 return; 1170 return;
1071 } 1171 }
1072 1172
1173 chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);
1174
1073 power_rule = &reg_rule->power_rule; 1175 power_rule = &reg_rule->power_rule;
1074 freq_range = &reg_rule->freq_range; 1176 freq_range = &reg_rule->freq_range;
1075 1177
@@ -1559,7 +1661,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1559 if (is_user_regdom_saved()) { 1661 if (is_user_regdom_saved()) {
1560 /* Unless we're asked to ignore it and reset it */ 1662 /* Unless we're asked to ignore it and reset it */
1561 if (reset_user) { 1663 if (reset_user) {
1562 REG_DBG_PRINT("cfg80211: Restoring regulatory settings " 1664 REG_DBG_PRINT("Restoring regulatory settings "
1563 "including user preference\n"); 1665 "including user preference\n");
1564 user_alpha2[0] = '9'; 1666 user_alpha2[0] = '9';
1565 user_alpha2[1] = '7'; 1667 user_alpha2[1] = '7';
@@ -1570,7 +1672,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1570 * back as they were for a full restore. 1672 * back as they were for a full restore.
1571 */ 1673 */
1572 if (!is_world_regdom(ieee80211_regdom)) { 1674 if (!is_world_regdom(ieee80211_regdom)) {
1573 REG_DBG_PRINT("cfg80211: Keeping preference on " 1675 REG_DBG_PRINT("Keeping preference on "
1574 "module parameter ieee80211_regdom: %c%c\n", 1676 "module parameter ieee80211_regdom: %c%c\n",
1575 ieee80211_regdom[0], 1677 ieee80211_regdom[0],
1576 ieee80211_regdom[1]); 1678 ieee80211_regdom[1]);
@@ -1578,7 +1680,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1578 alpha2[1] = ieee80211_regdom[1]; 1680 alpha2[1] = ieee80211_regdom[1];
1579 } 1681 }
1580 } else { 1682 } else {
1581 REG_DBG_PRINT("cfg80211: Restoring regulatory settings " 1683 REG_DBG_PRINT("Restoring regulatory settings "
1582 "while preserving user preference for: %c%c\n", 1684 "while preserving user preference for: %c%c\n",
1583 user_alpha2[0], 1685 user_alpha2[0],
1584 user_alpha2[1]); 1686 user_alpha2[1]);
@@ -1586,14 +1688,14 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1586 alpha2[1] = user_alpha2[1]; 1688 alpha2[1] = user_alpha2[1];
1587 } 1689 }
1588 } else if (!is_world_regdom(ieee80211_regdom)) { 1690 } else if (!is_world_regdom(ieee80211_regdom)) {
1589 REG_DBG_PRINT("cfg80211: Keeping preference on " 1691 REG_DBG_PRINT("Keeping preference on "
1590 "module parameter ieee80211_regdom: %c%c\n", 1692 "module parameter ieee80211_regdom: %c%c\n",
1591 ieee80211_regdom[0], 1693 ieee80211_regdom[0],
1592 ieee80211_regdom[1]); 1694 ieee80211_regdom[1]);
1593 alpha2[0] = ieee80211_regdom[0]; 1695 alpha2[0] = ieee80211_regdom[0];
1594 alpha2[1] = ieee80211_regdom[1]; 1696 alpha2[1] = ieee80211_regdom[1];
1595 } else 1697 } else
1596 REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n"); 1698 REG_DBG_PRINT("Restoring regulatory settings\n");
1597} 1699}
1598 1700
1599/* 1701/*
@@ -1661,7 +1763,7 @@ static void restore_regulatory_settings(bool reset_user)
1661 1763
1662void regulatory_hint_disconnect(void) 1764void regulatory_hint_disconnect(void)
1663{ 1765{
1664 REG_DBG_PRINT("cfg80211: All devices are disconnected, going to " 1766 REG_DBG_PRINT("All devices are disconnected, going to "
1665 "restore regulatory settings\n"); 1767 "restore regulatory settings\n");
1666 restore_regulatory_settings(false); 1768 restore_regulatory_settings(false);
1667} 1769}
@@ -1691,7 +1793,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
1691 if (!reg_beacon) 1793 if (!reg_beacon)
1692 return -ENOMEM; 1794 return -ENOMEM;
1693 1795
1694 REG_DBG_PRINT("cfg80211: Found new beacon on " 1796 REG_DBG_PRINT("Found new beacon on "
1695 "frequency: %d MHz (Ch %d) on %s\n", 1797 "frequency: %d MHz (Ch %d) on %s\n",
1696 beacon_chan->center_freq, 1798 beacon_chan->center_freq,
1697 ieee80211_frequency_to_channel(beacon_chan->center_freq), 1799 ieee80211_frequency_to_channel(beacon_chan->center_freq),