aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-04 11:58:14 -0500
commit10be7eb36b93364b98688831ee7d26f58402bb96 (patch)
treeeb13ae80fcaa8baacd804a721c5a4962a501a2a4 /drivers/net/wireless
parent90c30335a70e96b8b8493b7deb15e6b30e6d9fce (diff)
parent5ffaf8a361b4c9025963959a744f21d8173c7669 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/airo.c34
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c22
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c39
-rw-r--r--drivers/net/wireless/ath/debug.h8
-rw-r--r--drivers/net/wireless/b43/main.c28
-rw-r--r--drivers/net/wireless/b43/phy_common.c45
-rw-r--r--drivers/net/wireless/b43/phy_common.h10
-rw-r--r--drivers/net/wireless/b43/phy_lp.c52
-rw-r--r--drivers/net/wireless/b43/phy_n.c1264
-rw-r--r--drivers/net/wireless/b43/phy_n.h7
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c167
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h27
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig14
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c78
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-fh.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c149
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c1267
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c104
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c192
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c198
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c150
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c57
-rw-r--r--drivers/net/wireless/libertas/assoc.c78
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwl8k.c14
-rw-r--r--drivers/net/wireless/p54/p54pci.c74
-rw-r--r--drivers/net/wireless/p54/p54pci.h6
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c9
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c11
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c25
88 files changed, 3202 insertions, 1631 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 37e4ab737f2a..ef6b78da370f 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
5254 WepKeyRid wkr; 5254 WepKeyRid wkr;
5255 int rc; 5255 int rc;
5256 5256
5257 if (keylen == 0) { 5257 WARN_ON(keylen == 0);
5258 airo_print_err(ai->dev->name, "%s: key length to set was zero",
5259 __func__);
5260 return -1;
5261 }
5262 5258
5263 memset(&wkr, 0, sizeof(wkr)); 5259 memset(&wkr, 0, sizeof(wkr));
5264 wkr.len = cpu_to_le16(sizeof(wkr)); 5260 wkr.len = cpu_to_le16(sizeof(wkr));
@@ -6405,11 +6401,7 @@ static int airo_set_encode(struct net_device *dev,
6405 if (dwrq->length > MIN_KEY_SIZE) 6401 if (dwrq->length > MIN_KEY_SIZE)
6406 key.len = MAX_KEY_SIZE; 6402 key.len = MAX_KEY_SIZE;
6407 else 6403 else
6408 if (dwrq->length > 0) 6404 key.len = MIN_KEY_SIZE;
6409 key.len = MIN_KEY_SIZE;
6410 else
6411 /* Disable the key */
6412 key.len = 0;
6413 /* Check if the key is not marked as invalid */ 6405 /* Check if the key is not marked as invalid */
6414 if(!(dwrq->flags & IW_ENCODE_NOKEY)) { 6406 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6415 /* Cleanup */ 6407 /* Cleanup */
@@ -6590,12 +6582,22 @@ static int airo_set_encodeext(struct net_device *dev,
6590 default: 6582 default:
6591 return -EINVAL; 6583 return -EINVAL;
6592 } 6584 }
6593 /* Send the key to the card */ 6585 if (key.len == 0) {
6594 rc = set_wep_key(local, idx, key.key, key.len, perm, 1); 6586 rc = set_wep_tx_idx(local, idx, perm, 1);
6595 if (rc < 0) { 6587 if (rc < 0) {
6596 airo_print_err(local->dev->name, "failed to set WEP key" 6588 airo_print_err(local->dev->name,
6597 " at index %d: %d.", idx, rc); 6589 "failed to set WEP transmit index to %d: %d.",
6598 return rc; 6590 idx, rc);
6591 return rc;
6592 }
6593 } else {
6594 rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
6595 if (rc < 0) {
6596 airo_print_err(local->dev->name,
6597 "failed to set WEP key at index %d: %d.",
6598 idx, rc);
6599 return rc;
6600 }
6599 } 6601 }
6600 } 6602 }
6601 6603
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 9e05648356fe..71fc960814f0 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -74,7 +74,6 @@ struct ath_common;
74 74
75struct ath_bus_ops { 75struct ath_bus_ops {
76 void (*read_cachesize)(struct ath_common *common, int *csz); 76 void (*read_cachesize)(struct ath_common *common, int *csz);
77 void (*cleanup)(struct ath_common *common);
78 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); 77 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
79 void (*bt_coex_prep)(struct ath_common *common); 78 void (*bt_coex_prep)(struct ath_common *common);
80}; 79};
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 66bcb506a112..ad4d446f0264 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -535,7 +535,7 @@ struct ath5k_txq_info {
535 u32 tqi_cbr_period; /* Constant bit rate period */ 535 u32 tqi_cbr_period; /* Constant bit rate period */
536 u32 tqi_cbr_overflow_limit; 536 u32 tqi_cbr_overflow_limit;
537 u32 tqi_burst_time; 537 u32 tqi_burst_time;
538 u32 tqi_ready_time; /* Not used */ 538 u32 tqi_ready_time; /* Time queue waits after an event */
539}; 539};
540 540
541/* 541/*
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 5577bcc80eac..edb6c90e376f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1516,7 +1516,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1516 1516
1517 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); 1517 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
1518 if (ret) 1518 if (ret)
1519 return ret; 1519 goto err;
1520
1520 if (sc->opmode == NL80211_IFTYPE_AP || 1521 if (sc->opmode == NL80211_IFTYPE_AP ||
1521 sc->opmode == NL80211_IFTYPE_MESH_POINT) { 1522 sc->opmode == NL80211_IFTYPE_MESH_POINT) {
1522 /* 1523 /*
@@ -1543,10 +1544,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
1543 if (ret) { 1544 if (ret) {
1544 ATH5K_ERR(sc, "%s: unable to update parameters for beacon " 1545 ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
1545 "hardware queue!\n", __func__); 1546 "hardware queue!\n", __func__);
1546 return ret; 1547 goto err;
1547 } 1548 }
1549 ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
1550 if (ret)
1551 goto err;
1548 1552
1549 return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; 1553 /* reconfigure cabq with ready time to 80% of beacon_interval */
1554 ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1555 if (ret)
1556 goto err;
1557
1558 qi.tqi_ready_time = (sc->bintval * 80) / 100;
1559 ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
1560 if (ret)
1561 goto err;
1562
1563 ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB);
1564err:
1565 return ret;
1550} 1566}
1551 1567
1552static void 1568static void
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 60f547503d75..67aa52e9bf94 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -77,6 +77,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
77 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, 77 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
78 /* HP Compaq C700 (nitrousnrg@gmail.com) */ 78 /* HP Compaq C700 (nitrousnrg@gmail.com) */
79 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, 79 { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
80 /* LiteOn AR5BXB63 (magooz@salug.it) */
81 { ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
80 /* IBM-specific AR5212 (all others) */ 82 /* IBM-specific AR5212 (all others) */
81 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, 83 { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
82 /* Dell Vostro A860 (shahar@shahar-or.co.il) */ 84 /* Dell Vostro A860 (shahar@shahar-or.co.il) */
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index abe36c0d139c..9122a8556f45 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
408 break; 408 break;
409 409
410 case AR5K_TX_QUEUE_CAB: 410 case AR5K_TX_QUEUE_CAB:
411 /* XXX: use BCN_SENT_GT, if we can figure out how */
411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 412 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
412 AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | 413 AR5K_QCU_MISC_FRSHED_DBA_GT |
413 AR5K_QCU_MISC_CBREXP_DIS | 414 AR5K_QCU_MISC_CBREXP_DIS |
414 AR5K_QCU_MISC_CBREXP_BCN_DIS); 415 AR5K_QCU_MISC_CBREXP_BCN_DIS);
415 416
416 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - 417 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
417 (AR5K_TUNE_SW_BEACON_RESP - 418 (AR5K_TUNE_SW_BEACON_RESP -
418 AR5K_TUNE_DMA_BEACON_RESP) - 419 AR5K_TUNE_DMA_BEACON_RESP) -
419 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | 420 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 6690923fd78c..a35a7db0fc4c 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1374,8 +1374,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1374 * Set clocks to 32KHz operation and use an 1374 * Set clocks to 32KHz operation and use an
1375 * external 32KHz crystal when sleeping if one 1375 * external 32KHz crystal when sleeping if one
1376 * exists */ 1376 * exists */
1377 if (ah->ah_version == AR5K_AR5212) 1377 if (ah->ah_version == AR5K_AR5212 &&
1378 ath5k_hw_set_sleep_clock(ah, true); 1378 ah->ah_op_mode != NL80211_IFTYPE_AP)
1379 ath5k_hw_set_sleep_clock(ah, true);
1379 1380
1380 /* 1381 /*
1381 * Disable beacons and reset the register 1382 * Disable beacons and reset the register
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 9e62a569e816..ca4994f13151 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
27 *csz = L1_CACHE_BYTES >> 2; 27 *csz = L1_CACHE_BYTES >> 2;
28} 28}
29 29
30static void ath_ahb_cleanup(struct ath_common *common)
31{
32 struct ath_softc *sc = (struct ath_softc *)common->priv;
33 iounmap(sc->mem);
34}
35
36static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) 30static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
37{ 31{
38 struct ath_softc *sc = (struct ath_softc *)common->priv; 32 struct ath_softc *sc = (struct ath_softc *)common->priv;
@@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
54 48
55static struct ath_bus_ops ath_ahb_bus_ops = { 49static struct ath_bus_ops ath_ahb_bus_ops = {
56 .read_cachesize = ath_ahb_read_cachesize, 50 .read_cachesize = ath_ahb_read_cachesize,
57 .cleanup = ath_ahb_cleanup,
58
59 .eeprom_read = ath_ahb_eeprom_read, 51 .eeprom_read = ath_ahb_eeprom_read,
60}; 52};
61 53
@@ -164,12 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev)
164 if (hw) { 156 if (hw) {
165 struct ath_wiphy *aphy = hw->priv; 157 struct ath_wiphy *aphy = hw->priv;
166 struct ath_softc *sc = aphy->sc; 158 struct ath_softc *sc = aphy->sc;
167 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 159 void __iomem *mem = sc->mem;
168 160
169 ath9k_deinit_device(sc); 161 ath9k_deinit_device(sc);
170 free_irq(sc->irq, sc); 162 free_irq(sc->irq, sc);
171 ieee80211_free_hw(sc->hw); 163 ieee80211_free_hw(sc->hw);
172 ath_bus_cleanup(common); 164 iounmap(mem);
173 platform_set_drvdata(pdev, NULL); 165 platform_set_drvdata(pdev, NULL);
174 } 166 }
175 167
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index bf3d4c4bfa52..0ea340fd071c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -364,6 +364,7 @@ struct ath_btcoex {
364 int bt_stomp_type; /* Types of BT stomping */ 364 int bt_stomp_type; /* Types of BT stomping */
365 u32 btcoex_no_stomp; /* in usec */ 365 u32 btcoex_no_stomp; /* in usec */
366 u32 btcoex_period; /* in usec */ 366 u32 btcoex_period; /* in usec */
367 u32 btscan_no_stomp; /* in usec */
367 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ 368 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
368}; 369};
369 370
@@ -429,6 +430,7 @@ void ath_deinit_leds(struct ath_softc *sc);
429#define SC_OP_SCANNING BIT(10) 430#define SC_OP_SCANNING BIT(10)
430#define SC_OP_TSF_RESET BIT(11) 431#define SC_OP_TSF_RESET BIT(11)
431#define SC_OP_BT_PRIORITY_DETECTED BIT(12) 432#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
433#define SC_OP_BT_SCAN BIT(13)
432 434
433/* Powersave flags */ 435/* Powersave flags */
434#define PS_WAIT_FOR_BEACON BIT(0) 436#define PS_WAIT_FOR_BEACON BIT(0)
@@ -478,6 +480,7 @@ struct ath_softc {
478 u8 nbcnvifs; 480 u8 nbcnvifs;
479 u16 nvifs; 481 u16 nvifs;
480 bool ps_enabled; 482 bool ps_enabled;
483 bool ps_idle;
481 unsigned long ps_usecount; 484 unsigned long ps_usecount;
482 enum ath9k_int imask; 485 enum ath9k_int imask;
483 486
@@ -535,11 +538,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
535 common->bus_ops->read_cachesize(common, csz); 538 common->bus_ops->read_cachesize(common, csz);
536} 539}
537 540
538static inline void ath_bus_cleanup(struct ath_common *common)
539{
540 common->bus_ops->cleanup(common);
541}
542
543extern struct ieee80211_ops ath9k_ops; 541extern struct ieee80211_ops ath9k_ops;
544extern int modparam_nohwcrypt; 542extern int modparam_nohwcrypt;
545 543
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 1ba31a73317c..1ee5a15ccbb1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -25,10 +25,12 @@
25 25
26#define ATH_BTCOEX_DEF_BT_PERIOD 45 26#define ATH_BTCOEX_DEF_BT_PERIOD 45
27#define ATH_BTCOEX_DEF_DUTY_CYCLE 55 27#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
28#define ATH_BTCOEX_BTSCAN_DUTY_CYCLE 90
28#define ATH_BTCOEX_BMISS_THRESH 50 29#define ATH_BTCOEX_BMISS_THRESH 50
29 30
30#define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */ 31#define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */
31#define ATH_BT_CNT_THRESHOLD 3 32#define ATH_BT_CNT_THRESHOLD 3
33#define ATH_BT_CNT_SCAN_THRESHOLD 15
32 34
33enum ath_btcoex_scheme { 35enum ath_btcoex_scheme {
34 ATH_BTCOEX_CFG_NONE, 36 ATH_BTCOEX_CFG_NONE,
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9489b6b25b5f..42d2a506845a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -75,17 +75,24 @@ static const struct file_operations fops_debug = {
75 75
76#endif 76#endif
77 77
78#define DMA_BUF_LEN 1024
79
78static ssize_t read_file_dma(struct file *file, char __user *user_buf, 80static ssize_t read_file_dma(struct file *file, char __user *user_buf,
79 size_t count, loff_t *ppos) 81 size_t count, loff_t *ppos)
80{ 82{
81 struct ath_softc *sc = file->private_data; 83 struct ath_softc *sc = file->private_data;
82 struct ath_hw *ah = sc->sc_ah; 84 struct ath_hw *ah = sc->sc_ah;
83 char buf[1024]; 85 char *buf;
86 int retval;
84 unsigned int len = 0; 87 unsigned int len = 0;
85 u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; 88 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
86 int i, qcuOffset = 0, dcuOffset = 0; 89 int i, qcuOffset = 0, dcuOffset = 0;
87 u32 *qcuBase = &val[0], *dcuBase = &val[4]; 90 u32 *qcuBase = &val[0], *dcuBase = &val[4];
88 91
92 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
93 if (!buf)
94 return 0;
95
89 ath9k_ps_wakeup(sc); 96 ath9k_ps_wakeup(sc);
90 97
91 REG_WRITE_D(ah, AR_MACMISC, 98 REG_WRITE_D(ah, AR_MACMISC,
@@ -93,20 +100,20 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
93 (AR_MACMISC_MISC_OBS_BUS_1 << 100 (AR_MACMISC_MISC_OBS_BUS_1 <<
94 AR_MACMISC_MISC_OBS_BUS_MSB_S))); 101 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
95 102
96 len += snprintf(buf + len, sizeof(buf) - len, 103 len += snprintf(buf + len, DMA_BUF_LEN - len,
97 "Raw DMA Debug values:\n"); 104 "Raw DMA Debug values:\n");
98 105
99 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { 106 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
100 if (i % 4 == 0) 107 if (i % 4 == 0)
101 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 108 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
102 109
103 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); 110 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
104 len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", 111 len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
105 i, val[i]); 112 i, val[i]);
106 } 113 }
107 114
108 len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); 115 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
109 len += snprintf(buf + len, sizeof(buf) - len, 116 len += snprintf(buf + len, DMA_BUF_LEN - len,
110 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); 117 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
111 118
112 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { 119 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
@@ -120,7 +127,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
120 dcuBase++; 127 dcuBase++;
121 } 128 }
122 129
123 len += snprintf(buf + len, sizeof(buf) - len, 130 len += snprintf(buf + len, DMA_BUF_LEN - len,
124 "%2d %2x %1x %2x %2x\n", 131 "%2d %2x %1x %2x %2x\n",
125 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, 132 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
126 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), 133 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
@@ -128,35 +135,37 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
128 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); 135 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
129 } 136 }
130 137
131 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 138 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
132 139
133 len += snprintf(buf + len, sizeof(buf) - len, 140 len += snprintf(buf + len, DMA_BUF_LEN - len,
134 "qcu_stitch state: %2x qcu_fetch state: %2x\n", 141 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
135 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); 142 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
136 len += snprintf(buf + len, sizeof(buf) - len, 143 len += snprintf(buf + len, DMA_BUF_LEN - len,
137 "qcu_complete state: %2x dcu_complete state: %2x\n", 144 "qcu_complete state: %2x dcu_complete state: %2x\n",
138 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); 145 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
139 len += snprintf(buf + len, sizeof(buf) - len, 146 len += snprintf(buf + len, DMA_BUF_LEN - len,
140 "dcu_arb state: %2x dcu_fp state: %2x\n", 147 "dcu_arb state: %2x dcu_fp state: %2x\n",
141 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); 148 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
142 len += snprintf(buf + len, sizeof(buf) - len, 149 len += snprintf(buf + len, DMA_BUF_LEN - len,
143 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", 150 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
144 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); 151 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
145 len += snprintf(buf + len, sizeof(buf) - len, 152 len += snprintf(buf + len, DMA_BUF_LEN - len,
146 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", 153 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
147 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); 154 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
148 len += snprintf(buf + len, sizeof(buf) - len, 155 len += snprintf(buf + len, DMA_BUF_LEN - len,
149 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 156 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
150 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 157 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
151 158
152 len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", 159 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n",
153 REG_READ_D(ah, AR_OBS_BUS_1)); 160 REG_READ_D(ah, AR_OBS_BUS_1));
154 len += snprintf(buf + len, sizeof(buf) - len, 161 len += snprintf(buf + len, DMA_BUF_LEN - len,
155 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); 162 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR));
156 163
157 ath9k_ps_restore(sc); 164 ath9k_ps_restore(sc);
158 165
159 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 166 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
167 kfree(buf);
168 return retval;
160} 169}
161 170
162static const struct file_operations fops_dma = { 171static const struct file_operations fops_dma = {
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index e204bd25ff65..deab8beb0680 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -230,12 +230,17 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
230 230
231 if (time_after(jiffies, btcoex->bt_priority_time + 231 if (time_after(jiffies, btcoex->bt_priority_time +
232 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { 232 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
233 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { 233 sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
234 /* Detect if colocated bt started scanning */
235 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
236 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
237 "BT scan detected");
238 sc->sc_flags |= (SC_OP_BT_SCAN |
239 SC_OP_BT_PRIORITY_DETECTED);
240 } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
234 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, 241 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
235 "BT priority traffic detected"); 242 "BT priority traffic detected");
236 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; 243 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
237 } else {
238 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
239 } 244 }
240 245
241 btcoex->bt_priority_cnt = 0; 246 btcoex->bt_priority_cnt = 0;
@@ -316,12 +321,17 @@ static void ath_btcoex_period_timer(unsigned long data)
316 struct ath_softc *sc = (struct ath_softc *) data; 321 struct ath_softc *sc = (struct ath_softc *) data;
317 struct ath_hw *ah = sc->sc_ah; 322 struct ath_hw *ah = sc->sc_ah;
318 struct ath_btcoex *btcoex = &sc->btcoex; 323 struct ath_btcoex *btcoex = &sc->btcoex;
324 u32 timer_period;
325 bool is_btscan;
319 326
320 ath_detect_bt_priority(sc); 327 ath_detect_bt_priority(sc);
321 328
329 is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
330
322 spin_lock_bh(&btcoex->btcoex_lock); 331 spin_lock_bh(&btcoex->btcoex_lock);
323 332
324 ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); 333 ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL :
334 btcoex->bt_stomp_type);
325 335
326 spin_unlock_bh(&btcoex->btcoex_lock); 336 spin_unlock_bh(&btcoex->btcoex_lock);
327 337
@@ -329,11 +339,12 @@ static void ath_btcoex_period_timer(unsigned long data)
329 if (btcoex->hw_timer_enabled) 339 if (btcoex->hw_timer_enabled)
330 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); 340 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
331 341
342 timer_period = is_btscan ? btcoex->btscan_no_stomp :
343 btcoex->btcoex_no_stomp;
332 ath9k_gen_timer_start(ah, 344 ath9k_gen_timer_start(ah,
333 btcoex->no_stomp_timer, 345 btcoex->no_stomp_timer,
334 (ath9k_hw_gettsf32(ah) + 346 (ath9k_hw_gettsf32(ah) +
335 btcoex->btcoex_no_stomp), 347 timer_period), timer_period * 10);
336 btcoex->btcoex_no_stomp * 10);
337 btcoex->hw_timer_enabled = true; 348 btcoex->hw_timer_enabled = true;
338 } 349 }
339 350
@@ -350,13 +361,14 @@ static void ath_btcoex_no_stomp_timer(void *arg)
350 struct ath_softc *sc = (struct ath_softc *)arg; 361 struct ath_softc *sc = (struct ath_softc *)arg;
351 struct ath_hw *ah = sc->sc_ah; 362 struct ath_hw *ah = sc->sc_ah;
352 struct ath_btcoex *btcoex = &sc->btcoex; 363 struct ath_btcoex *btcoex = &sc->btcoex;
364 bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
353 365
354 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, 366 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
355 "no stomp timer running \n"); 367 "no stomp timer running \n");
356 368
357 spin_lock_bh(&btcoex->btcoex_lock); 369 spin_lock_bh(&btcoex->btcoex_lock);
358 370
359 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) 371 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
360 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); 372 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
361 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) 373 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
362 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); 374 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
@@ -371,6 +383,8 @@ int ath_init_btcoex_timer(struct ath_softc *sc)
371 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; 383 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
372 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 384 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
373 btcoex->btcoex_period / 100; 385 btcoex->btcoex_period / 100;
386 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
387 btcoex->btcoex_period / 100;
374 388
375 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, 389 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
376 (unsigned long) sc); 390 (unsigned long) sc);
@@ -405,7 +419,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
405 419
406 btcoex->bt_priority_cnt = 0; 420 btcoex->bt_priority_cnt = 0;
407 btcoex->bt_priority_time = jiffies; 421 btcoex->bt_priority_time = jiffies;
408 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; 422 sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN);
409 423
410 mod_timer(&btcoex->period_timer, jiffies); 424 mod_timer(&btcoex->period_timer, jiffies);
411} 425}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1a27f39c1adc..f15fee76a4e2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -334,7 +334,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
334 ah->config.pcie_clock_req = 0; 334 ah->config.pcie_clock_req = 0;
335 ah->config.pcie_waen = 0; 335 ah->config.pcie_waen = 0;
336 ah->config.analog_shiftreg = 1; 336 ah->config.analog_shiftreg = 1;
337 ah->config.ht_enable = 1;
338 ah->config.ofdm_trig_low = 200; 337 ah->config.ofdm_trig_low = 200;
339 ah->config.ofdm_trig_high = 500; 338 ah->config.ofdm_trig_high = 500;
340 ah->config.cck_trig_high = 200; 339 ah->config.cck_trig_high = 200;
@@ -346,6 +345,11 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
346 ah->config.spurchans[i][1] = AR_NO_SPUR; 345 ah->config.spurchans[i][1] = AR_NO_SPUR;
347 } 346 }
348 347
348 if (ah->hw_version.devid != AR2427_DEVID_PCIE)
349 ah->config.ht_enable = 1;
350 else
351 ah->config.ht_enable = 0;
352
349 ah->config.rx_intr_mitigation = true; 353 ah->config.rx_intr_mitigation = true;
350 354
351 /* 355 /*
@@ -542,6 +546,7 @@ static bool ath9k_hw_devid_supported(u16 devid)
542 case AR5416_DEVID_AR9287_PCI: 546 case AR5416_DEVID_AR9287_PCI:
543 case AR5416_DEVID_AR9287_PCIE: 547 case AR5416_DEVID_AR9287_PCIE:
544 case AR9271_USB: 548 case AR9271_USB:
549 case AR2427_DEVID_PCIE:
545 return true; 550 return true;
546 default: 551 default:
547 break; 552 break;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ab1f1981d857..dbbf7ca5f97d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -40,6 +40,7 @@
40#define AR9280_DEVID_PCI 0x0029 40#define AR9280_DEVID_PCI 0x0029
41#define AR9280_DEVID_PCIE 0x002a 41#define AR9280_DEVID_PCIE 0x002a
42#define AR9285_DEVID_PCIE 0x002b 42#define AR9285_DEVID_PCIE 0x002b
43#define AR2427_DEVID_PCIE 0x002c
43 44
44#define AR5416_AR9100_DEVID 0x000b 45#define AR5416_AR9100_DEVID 0x000b
45 46
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 5f78d7a5ff22..4b5e54848683 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -620,11 +620,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
620 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | 620 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
621 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 621 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
622 IEEE80211_HW_SIGNAL_DBM | 622 IEEE80211_HW_SIGNAL_DBM |
623 IEEE80211_HW_AMPDU_AGGREGATION |
624 IEEE80211_HW_SUPPORTS_PS | 623 IEEE80211_HW_SUPPORTS_PS |
625 IEEE80211_HW_PS_NULLFUNC_STACK | 624 IEEE80211_HW_PS_NULLFUNC_STACK |
626 IEEE80211_HW_SPECTRUM_MGMT; 625 IEEE80211_HW_SPECTRUM_MGMT;
627 626
627 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
628 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
629
628 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) 630 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
629 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 631 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
630 632
@@ -640,8 +642,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
640 hw->max_rates = 4; 642 hw->max_rates = 4;
641 hw->channel_change_time = 5000; 643 hw->channel_change_time = 5000;
642 hw->max_listen_interval = 10; 644 hw->max_listen_interval = 10;
643 /* Hardware supports 10 but we use 4 */ 645 hw->max_rate_tries = 10;
644 hw->max_rate_tries = 4;
645 hw->sta_data_size = sizeof(struct ath_node); 646 hw->sta_data_size = sizeof(struct ath_node);
646 hw->vif_data_size = sizeof(struct ath_vif); 647 hw->vif_data_size = sizeof(struct ath_vif);
647 648
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6aaca0026da8..6796d5cdc293 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -143,8 +143,10 @@ void ath9k_ps_restore(struct ath_softc *sc)
143 if (--sc->ps_usecount != 0) 143 if (--sc->ps_usecount != 0)
144 goto unlock; 144 goto unlock;
145 145
146 if (sc->ps_enabled && 146 if (sc->ps_idle)
147 !(sc->ps_flags & (PS_WAIT_FOR_BEACON | 147 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
148 else if (sc->ps_enabled &&
149 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
148 PS_WAIT_FOR_CAB | 150 PS_WAIT_FOR_CAB |
149 PS_WAIT_FOR_PSPOLL_DATA | 151 PS_WAIT_FOR_PSPOLL_DATA |
150 PS_WAIT_FOR_TX_ACK))) 152 PS_WAIT_FOR_TX_ACK)))
@@ -204,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
204 r = ath9k_hw_reset(ah, hchan, fastcc); 206 r = ath9k_hw_reset(ah, hchan, fastcc);
205 if (r) { 207 if (r) {
206 ath_print(common, ATH_DBG_FATAL, 208 ath_print(common, ATH_DBG_FATAL,
207 "Unable to reset channel (%u Mhz) " 209 "Unable to reset channel (%u MHz), "
208 "reset status %d\n", 210 "reset status %d\n",
209 channel->center_freq, r); 211 channel->center_freq, r);
210 spin_unlock_bh(&sc->sc_resetlock); 212 spin_unlock_bh(&sc->sc_resetlock);
@@ -867,7 +869,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
867 r = ath9k_hw_reset(ah, ah->curchan, false); 869 r = ath9k_hw_reset(ah, ah->curchan, false);
868 if (r) { 870 if (r) {
869 ath_print(common, ATH_DBG_FATAL, 871 ath_print(common, ATH_DBG_FATAL,
870 "Unable to reset channel %u (%uMhz) ", 872 "Unable to reset channel (%u MHz), "
871 "reset status %d\n", 873 "reset status %d\n",
872 channel->center_freq, r); 874 channel->center_freq, r);
873 } 875 }
@@ -922,7 +924,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
922 r = ath9k_hw_reset(ah, ah->curchan, false); 924 r = ath9k_hw_reset(ah, ah->curchan, false);
923 if (r) { 925 if (r) {
924 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 926 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
925 "Unable to reset channel %u (%uMhz) " 927 "Unable to reset channel (%u MHz), "
926 "reset status %d\n", 928 "reset status %d\n",
927 channel->center_freq, r); 929 channel->center_freq, r);
928 } 930 }
@@ -1528,6 +1530,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1528 spin_unlock_bh(&sc->wiphy_lock); 1530 spin_unlock_bh(&sc->wiphy_lock);
1529 1531
1530 if (enable_radio) { 1532 if (enable_radio) {
1533 sc->ps_idle = false;
1531 ath_radio_enable(sc, hw); 1534 ath_radio_enable(sc, hw);
1532 ath_print(common, ATH_DBG_CONFIG, 1535 ath_print(common, ATH_DBG_CONFIG,
1533 "not-idle: enabling radio\n"); 1536 "not-idle: enabling radio\n");
@@ -1624,8 +1627,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1624 } 1627 }
1625 1628
1626skip_chan_change: 1629skip_chan_change:
1627 if (changed & IEEE80211_CONF_CHANGE_POWER) 1630 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1628 sc->config.txpowlimit = 2 * conf->power_level; 1631 sc->config.txpowlimit = 2 * conf->power_level;
1632 ath_update_txpow(sc);
1633 }
1629 1634
1630 spin_lock_bh(&sc->wiphy_lock); 1635 spin_lock_bh(&sc->wiphy_lock);
1631 disable_radio = ath9k_all_wiphys_idle(sc); 1636 disable_radio = ath9k_all_wiphys_idle(sc);
@@ -1633,6 +1638,7 @@ skip_chan_change:
1633 1638
1634 if (disable_radio) { 1639 if (disable_radio) {
1635 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); 1640 ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
1641 sc->ps_idle = true;
1636 ath_radio_disable(sc, hw); 1642 ath_radio_disable(sc, hw);
1637 } 1643 }
1638 1644
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index fe2c3a644a6e..9441c6718a30 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -25,6 +25,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
25 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ 25 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
26 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ 26 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
27 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ 27 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
28 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
28 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 29 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
29 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 30 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
30 { 0 } 31 { 0 }
@@ -49,16 +50,6 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
49 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ 50 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
50} 51}
51 52
52static void ath_pci_cleanup(struct ath_common *common)
53{
54 struct ath_softc *sc = (struct ath_softc *) common->priv;
55 struct pci_dev *pdev = to_pci_dev(sc->dev);
56
57 pci_iounmap(pdev, sc->mem);
58 pci_disable_device(pdev);
59 pci_release_region(pdev, 0);
60}
61
62static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) 53static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
63{ 54{
64 struct ath_hw *ah = (struct ath_hw *) common->ah; 55 struct ath_hw *ah = (struct ath_hw *) common->ah;
@@ -98,7 +89,6 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
98 89
99static const struct ath_bus_ops ath_pci_bus_ops = { 90static const struct ath_bus_ops ath_pci_bus_ops = {
100 .read_cachesize = ath_pci_read_cachesize, 91 .read_cachesize = ath_pci_read_cachesize,
101 .cleanup = ath_pci_cleanup,
102 .eeprom_read = ath_pci_eeprom_read, 92 .eeprom_read = ath_pci_eeprom_read,
103 .bt_coex_prep = ath_pci_bt_coex_prep, 93 .bt_coex_prep = ath_pci_bt_coex_prep,
104}; 94};
@@ -245,12 +235,15 @@ static void ath_pci_remove(struct pci_dev *pdev)
245 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 235 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
246 struct ath_wiphy *aphy = hw->priv; 236 struct ath_wiphy *aphy = hw->priv;
247 struct ath_softc *sc = aphy->sc; 237 struct ath_softc *sc = aphy->sc;
248 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 238 void __iomem *mem = sc->mem;
249 239
250 ath9k_deinit_device(sc); 240 ath9k_deinit_device(sc);
251 free_irq(sc->irq, sc); 241 free_irq(sc->irq, sc);
252 ieee80211_free_hw(sc->hw); 242 ieee80211_free_hw(sc->hw);
253 ath_bus_cleanup(common); 243
244 pci_iounmap(pdev, mem);
245 pci_disable_device(pdev);
246 pci_release_region(pdev, 0);
254} 247}
255 248
256#ifdef CONFIG_PM 249#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 70fdb9d8db82..11968843c773 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -678,13 +678,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
678 * For Multi Rate Retry we use a different number of 678 * For Multi Rate Retry we use a different number of
679 * retry attempt counts. This ends up looking like this: 679 * retry attempt counts. This ends up looking like this:
680 * 680 *
681 * MRR[0] = 2 681 * MRR[0] = 4
682 * MRR[1] = 2 682 * MRR[1] = 4
683 * MRR[2] = 2 683 * MRR[2] = 4
684 * MRR[3] = 4 684 * MRR[3] = 8
685 * 685 *
686 */ 686 */
687 try_per_rate = sc->hw->max_rate_tries; 687 try_per_rate = 4;
688 688
689 rate_table = sc->cur_rate_table; 689 rate_table = sc->cur_rate_table;
690 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 690 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
@@ -714,7 +714,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
714 for ( ; i < 4; i++) { 714 for ( ; i < 4; i++) {
715 /* Use twice the number of tries for the last MRR segment. */ 715 /* Use twice the number of tries for the last MRR segment. */
716 if (i + 1 == 4) 716 if (i + 1 == 4)
717 try_per_rate = 4; 717 try_per_rate = 8;
718 718
719 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); 719 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
720 /* All other rates in the series have RTS enabled */ 720 /* All other rates in the series have RTS enabled */
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 40b5d05edcce..1ca42e5148c8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -429,7 +429,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
429 sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; 429 sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
430 ath_print(common, ATH_DBG_PS, 430 ath_print(common, ATH_DBG_PS,
431 "Going back to sleep after having received " 431 "Going back to sleep after having received "
432 "PS-Poll data (0x%x)\n", 432 "PS-Poll data (0x%lx)\n",
433 sc->ps_flags & (PS_WAIT_FOR_BEACON | 433 sc->ps_flags & (PS_WAIT_FOR_BEACON |
434 PS_WAIT_FOR_CAB | 434 PS_WAIT_FOR_CAB |
435 PS_WAIT_FOR_PSPOLL_DATA | 435 PS_WAIT_FOR_PSPOLL_DATA |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8e653fb937a1..72cfa8ebd9ae 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1547,9 +1547,9 @@ enum {
1547 1547
1548#define AR_BT_COEX_WEIGHT 0x8174 1548#define AR_BT_COEX_WEIGHT 0x8174
1549#define AR_BT_COEX_WGHT 0xff55 1549#define AR_BT_COEX_WGHT 0xff55
1550#define AR_STOMP_ALL_WLAN_WGHT 0xffcc 1550#define AR_STOMP_ALL_WLAN_WGHT 0xfcfc
1551#define AR_STOMP_LOW_WLAN_WGHT 0xaaa8 1551#define AR_STOMP_LOW_WLAN_WGHT 0xa8a8
1552#define AR_STOMP_NONE_WLAN_WGHT 0xaa00 1552#define AR_STOMP_NONE_WLAN_WGHT 0x0000
1553#define AR_BTCOEX_BT_WGHT 0x0000ffff 1553#define AR_BTCOEX_BT_WGHT 0x0000ffff
1554#define AR_BTCOEX_BT_WGHT_S 0 1554#define AR_BTCOEX_BT_WGHT_S 0
1555#define AR_BTCOEX_WL_WGHT 0xffff0000 1555#define AR_BTCOEX_WL_WGHT 0xffff0000
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index a821bb687b3b..3c790a4f38f7 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1498 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) 1498 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
1499 ctsrate |= rate->hw_value_short; 1499 ctsrate |= rate->hw_value_short;
1500 1500
1501 /*
1502 * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
1503 * Check the first rate in the series to decide whether RTS/CTS
1504 * or CTS-to-self has to be used.
1505 */
1506 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1507 flags = ATH9K_TXDESC_CTSENA;
1508 else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
1509 flags = ATH9K_TXDESC_RTSENA;
1510
1511 /* FIXME: Handle aggregation protection */
1512 if (sc->config.ath_aggr_prot &&
1513 (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
1514 flags = ATH9K_TXDESC_RTSENA;
1515 }
1516
1517 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
1518 if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
1519 flags &= ~(ATH9K_TXDESC_RTSENA);
1520
1521 for (i = 0; i < 4; i++) { 1501 for (i = 0; i < 4; i++) {
1522 bool is_40, is_sgi, is_sp; 1502 bool is_40, is_sgi, is_sp;
1523 int phy; 1503 int phy;
@@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1529 series[i].Tries = rates[i].count; 1509 series[i].Tries = rates[i].count;
1530 series[i].ChSel = common->tx_chainmask; 1510 series[i].ChSel = common->tx_chainmask;
1531 1511
1532 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) 1512 if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
1513 (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
1533 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; 1514 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1515 flags |= ATH9K_TXDESC_RTSENA;
1516 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
1517 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1518 flags |= ATH9K_TXDESC_CTSENA;
1519 }
1520
1534 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1521 if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1535 series[i].RateFlags |= ATH9K_RATESERIES_2040; 1522 series[i].RateFlags |= ATH9K_RATESERIES_2040;
1536 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) 1523 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
@@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
1568 phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); 1555 phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
1569 } 1556 }
1570 1557
1558 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
1559 if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
1560 flags &= ~ATH9K_TXDESC_RTSENA;
1561
1562 /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
1563 if (flags & ATH9K_TXDESC_RTSENA)
1564 flags &= ~ATH9K_TXDESC_CTSENA;
1565
1571 /* set dur_update_en for l-sig computation except for PS-Poll frames */ 1566 /* set dur_update_en for l-sig computation except for PS-Poll frames */
1572 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, 1567 ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
1573 bf->bf_lastbf->bf_desc, 1568 bf->bf_lastbf->bf_desc,
@@ -1862,7 +1857,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1862 sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; 1857 sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
1863 ath_print(common, ATH_DBG_PS, 1858 ath_print(common, ATH_DBG_PS,
1864 "Going back to sleep after having " 1859 "Going back to sleep after having "
1865 "received TX status (0x%x)\n", 1860 "received TX status (0x%lx)\n",
1866 sc->ps_flags & (PS_WAIT_FOR_BEACON | 1861 sc->ps_flags & (PS_WAIT_FOR_BEACON |
1867 PS_WAIT_FOR_CAB | 1862 PS_WAIT_FOR_CAB |
1868 PS_WAIT_FOR_PSPOLL_DATA | 1863 PS_WAIT_FOR_PSPOLL_DATA |
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index d6b685a06c5e..8263633c003c 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -65,11 +65,11 @@ enum ATH_DEBUG {
65#define ATH_DBG_DEFAULT (ATH_DBG_FATAL) 65#define ATH_DBG_DEFAULT (ATH_DBG_FATAL)
66 66
67#ifdef CONFIG_ATH_DEBUG 67#ifdef CONFIG_ATH_DEBUG
68void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...); 68void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
69 __attribute__ ((format (printf, 3, 4)));
69#else 70#else
70static inline void ath_print(struct ath_common *common, 71static inline void __attribute__ ((format (printf, 3, 4)))
71 int dbg_mask, 72ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
72 const char *fmt, ...)
73{ 73{
74} 74}
75#endif /* CONFIG_ATH_DEBUG */ 75#endif /* CONFIG_ATH_DEBUG */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9c5c7c9ad530..316a913860d7 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -844,8 +844,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
844} 844}
845 845
846static void b43_op_update_tkip_key(struct ieee80211_hw *hw, 846static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
847 struct ieee80211_key_conf *keyconf, const u8 *addr, 847 struct ieee80211_vif *vif,
848 u32 iv32, u16 *phase1key) 848 struct ieee80211_key_conf *keyconf,
849 struct ieee80211_sta *sta,
850 u32 iv32, u16 *phase1key)
849{ 851{
850 struct b43_wl *wl = hw_to_b43_wl(hw); 852 struct b43_wl *wl = hw_to_b43_wl(hw);
851 struct b43_wldev *dev; 853 struct b43_wldev *dev;
@@ -854,19 +856,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
854 if (B43_WARN_ON(!modparam_hwtkip)) 856 if (B43_WARN_ON(!modparam_hwtkip))
855 return; 857 return;
856 858
857 mutex_lock(&wl->mutex); 859 /* This is only called from the RX path through mac80211, where
858 860 * our mutex is already locked. */
861 B43_WARN_ON(!mutex_is_locked(&wl->mutex));
859 dev = wl->current_dev; 862 dev = wl->current_dev;
860 if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) 863 B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
861 goto out_unlock;
862 864
863 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ 865 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
864 866
865 rx_tkip_phase1_write(dev, index, iv32, phase1key); 867 rx_tkip_phase1_write(dev, index, iv32, phase1key);
866 keymac_write(dev, index, addr); 868 /* only pairwise TKIP keys are supported right now */
867 869 if (WARN_ON(!sta))
868out_unlock: 870 return;
869 mutex_unlock(&wl->mutex); 871 keymac_write(dev, index, sta->addr);
870} 872}
871 873
872static void do_key_write(struct b43_wldev *dev, 874static void do_key_write(struct b43_wldev *dev,
@@ -3571,6 +3573,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3571 dev = wl->current_dev; 3573 dev = wl->current_dev;
3572 phy = &dev->phy; 3574 phy = &dev->phy;
3573 3575
3576 if (conf_is_ht(conf))
3577 phy->is_40mhz =
3578 (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
3579 else
3580 phy->is_40mhz = false;
3581
3574 b43_mac_suspend(dev); 3582 b43_mac_suspend(dev);
3575 3583
3576 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) 3584 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 75b26e175e8f..8f7d7eff2d80 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -421,3 +421,48 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
421{ 421{
422 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); 422 b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4);
423} 423}
424
425/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */
426struct b43_c32 b43_cordic(int theta)
427{
428 u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
429 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
430 229, 115, 57, 29, };
431 u8 i;
432 s32 tmp;
433 s8 signx = 1;
434 u32 angle = 0;
435 struct b43_c32 ret = { .i = 39797, .q = 0, };
436
437 while (theta > (180 << 16))
438 theta -= (360 << 16);
439 while (theta < -(180 << 16))
440 theta += (360 << 16);
441
442 if (theta > (90 << 16)) {
443 theta -= (180 << 16);
444 signx = -1;
445 } else if (theta < -(90 << 16)) {
446 theta += (180 << 16);
447 signx = -1;
448 }
449
450 for (i = 0; i <= 17; i++) {
451 if (theta > angle) {
452 tmp = ret.i - (ret.q >> i);
453 ret.q += ret.i >> i;
454 ret.i = tmp;
455 angle += arctg[i];
456 } else {
457 tmp = ret.i + (ret.q >> i);
458 ret.q -= ret.i >> i;
459 ret.i = tmp;
460 angle -= arctg[i];
461 }
462 }
463
464 ret.i *= signx;
465 ret.q *= signx;
466
467 return ret;
468}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 9edd4e8e0c85..bd480b481bfc 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -5,6 +5,12 @@
5 5
6struct b43_wldev; 6struct b43_wldev;
7 7
8/* Complex number using 2 32-bit signed integers */
9struct b43_c32 { s32 i, q; };
10
11#define CORDIC_CONVERT(value) (((value) >= 0) ? \
12 ((((value) >> 15) + 1) >> 1) : \
13 -((((-(value)) >> 15) + 1) >> 1))
8 14
9/* PHY register routing bits */ 15/* PHY register routing bits */
10#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ 16#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
@@ -212,6 +218,9 @@ struct b43_phy {
212 bool supports_2ghz; 218 bool supports_2ghz;
213 bool supports_5ghz; 219 bool supports_5ghz;
214 220
221 /* HT info */
222 bool is_40mhz;
223
215 /* GMODE bit enabled? */ 224 /* GMODE bit enabled? */
216 bool gmode; 225 bool gmode;
217 226
@@ -418,5 +427,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
418 */ 427 */
419void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); 428void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
420 429
430struct b43_c32 b43_cordic(int theta);
421 431
422#endif /* LINUX_B43_PHY_COMMON_H_ */ 432#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index b58d6cf26580..185219e0a552 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1767,47 +1767,6 @@ out:
1767 return ret; 1767 return ret;
1768} 1768}
1769 1769
1770/* Complex number using 2 32-bit signed integers */
1771typedef struct {s32 i, q;} lpphy_c32;
1772
1773static lpphy_c32 lpphy_cordic(int theta)
1774{
1775 u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304,
1776 58666, 29335, 14668, 7334, 3667, 1833, 917, 458,
1777 229, 115, 57, 29, };
1778 int i, tmp, signx = 1, angle = 0;
1779 lpphy_c32 ret = { .i = 39797, .q = 0, };
1780
1781 theta = clamp_t(int, theta, -180, 180);
1782
1783 if (theta > 90) {
1784 theta -= 180;
1785 signx = -1;
1786 } else if (theta < -90) {
1787 theta += 180;
1788 signx = -1;
1789 }
1790
1791 for (i = 0; i <= 17; i++) {
1792 if (theta > angle) {
1793 tmp = ret.i - (ret.q >> i);
1794 ret.q += ret.i >> i;
1795 ret.i = tmp;
1796 angle += arctg[i];
1797 } else {
1798 tmp = ret.i + (ret.q >> i);
1799 ret.q -= ret.i >> i;
1800 ret.i = tmp;
1801 angle -= arctg[i];
1802 }
1803 }
1804
1805 ret.i *= signx;
1806 ret.q *= signx;
1807
1808 return ret;
1809}
1810
1811static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, 1770static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops,
1812 u16 wait) 1771 u16 wait)
1813{ 1772{
@@ -1825,8 +1784,9 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1825{ 1784{
1826 struct b43_phy_lp *lpphy = dev->phy.lp; 1785 struct b43_phy_lp *lpphy = dev->phy.lp;
1827 u16 buf[64]; 1786 u16 buf[64];
1828 int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; 1787 int i, samples = 0, angle = 0;
1829 lpphy_c32 sample; 1788 int rotation = (((36 * freq) / 20) << 16) / 100;
1789 struct b43_c32 sample;
1830 1790
1831 lpphy->tx_tone_freq = freq; 1791 lpphy->tx_tone_freq = freq;
1832 1792
@@ -1842,10 +1802,10 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max)
1842 } 1802 }
1843 1803
1844 for (i = 0; i < samples; i++) { 1804 for (i = 0; i < samples; i++) {
1845 sample = lpphy_cordic(angle); 1805 sample = b43_cordic(angle);
1846 angle += rotation; 1806 angle += rotation;
1847 buf[i] = ((sample.i * max) & 0xFF) << 8; 1807 buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8;
1848 buf[i] |= (sample.q * max) & 0xFF; 1808 buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF);
1849 } 1809 }
1850 1810
1851 b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); 1811 b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf);
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 4a817e3da163..6392da25efed 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -55,6 +55,20 @@ struct nphy_iq_est {
55 u32 q1_pwr; 55 u32 q1_pwr;
56}; 56};
57 57
58enum b43_nphy_rf_sequence {
59 B43_RFSEQ_RX2TX,
60 B43_RFSEQ_TX2RX,
61 B43_RFSEQ_RESET2RX,
62 B43_RFSEQ_UPDATE_GAINH,
63 B43_RFSEQ_UPDATE_GAINL,
64 B43_RFSEQ_UPDATE_GAINU,
65};
66
67static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
68 u8 *events, u8 *delays, u8 length);
69static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
70 enum b43_nphy_rf_sequence seq);
71
58void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 72void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
59{//TODO 73{//TODO
60} 74}
@@ -234,110 +248,6 @@ static void b43_nphy_tables_init(struct b43_wldev *dev)
234 b43_nphy_rev3plus_tables_init(dev); 248 b43_nphy_rev3plus_tables_init(dev);
235} 249}
236 250
237static void b43_nphy_workarounds(struct b43_wldev *dev)
238{
239 struct b43_phy *phy = &dev->phy;
240 unsigned int i;
241
242 b43_phy_set(dev, B43_NPHY_IQFLIP,
243 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
244 if (1 /* FIXME band is 2.4GHz */) {
245 b43_phy_set(dev, B43_NPHY_CLASSCTL,
246 B43_NPHY_CLASSCTL_CCKEN);
247 } else {
248 b43_phy_mask(dev, B43_NPHY_CLASSCTL,
249 ~B43_NPHY_CLASSCTL_CCKEN);
250 }
251 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
252 b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8);
253
254 /* Fixup some tables */
255 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA);
256 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA);
257 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
258 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
259 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0);
260 b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0);
261 b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
262 b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
263 b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800);
264 b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800);
265
266 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
267 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
268 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
269 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
270
271 //TODO set RF sequence
272
273 /* Set narrowband clip threshold */
274 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66);
275 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66);
276
277 /* Set wideband clip 2 threshold */
278 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
279 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
280 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT);
281 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
282 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
283 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT);
284
285 /* Set Clip 2 detect */
286 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
287 B43_NPHY_C1_CGAINI_CL2DETECT);
288 b43_phy_set(dev, B43_NPHY_C2_CGAINI,
289 B43_NPHY_C2_CGAINI_CL2DETECT);
290
291 if (0 /*FIXME*/) {
292 /* Set dwell lengths */
293 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43);
294 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43);
295 b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9);
296 b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9);
297
298 /* Set gain backoff */
299 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
300 ~B43_NPHY_C1_CGAINI_GAINBKOFF,
301 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT);
302 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
303 ~B43_NPHY_C2_CGAINI_GAINBKOFF,
304 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT);
305
306 /* Set HPVGA2 index */
307 b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
308 ~B43_NPHY_C1_INITGAIN_HPVGA2,
309 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
310 b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
311 ~B43_NPHY_C2_INITGAIN_HPVGA2,
312 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
313
314 //FIXME verify that the specs really mean to use autoinc here.
315 for (i = 0; i < 3; i++)
316 b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673);
317 }
318
319 /* Set minimum gain value */
320 b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN,
321 ~B43_NPHY_C1_MINGAIN,
322 23 << B43_NPHY_C1_MINGAIN_SHIFT);
323 b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN,
324 ~B43_NPHY_C2_MINGAIN,
325 23 << B43_NPHY_C2_MINGAIN_SHIFT);
326
327 if (phy->rev < 2) {
328 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
329 ~B43_NPHY_SCRAM_SIGCTL_SCM);
330 }
331
332 /* Set phase track alpha and beta */
333 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
334 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
335 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
336 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
337 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
338 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
339}
340
341/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ 251/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
342static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) 252static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
343{ 253{
@@ -421,7 +331,49 @@ static void b43_nphy_reset_cca(struct b43_wldev *dev)
421 udelay(1); 331 udelay(1);
422 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); 332 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
423 b43_nphy_bmac_clock_fgc(dev, 0); 333 b43_nphy_bmac_clock_fgc(dev, 0);
424 /* TODO: N PHY Force RF Seq with argument 2 */ 334 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
335}
336
337/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
338static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
339{
340 u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG);
341
342 mimocfg |= B43_NPHY_MIMOCFG_AUTO;
343 if (preamble == 1)
344 mimocfg |= B43_NPHY_MIMOCFG_GFMIX;
345 else
346 mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX;
347
348 b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg);
349}
350
351/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
352static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
353{
354 struct b43_phy_n *nphy = dev->phy.n;
355
356 bool override = false;
357 u16 chain = 0x33;
358
359 if (nphy->txrx_chain == 0) {
360 chain = 0x11;
361 override = true;
362 } else if (nphy->txrx_chain == 1) {
363 chain = 0x22;
364 override = true;
365 }
366
367 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
368 ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
369 chain);
370
371 if (override)
372 b43_phy_set(dev, B43_NPHY_RFSEQMODE,
373 B43_NPHY_RFSEQMODE_CAOVER);
374 else
375 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
376 ~B43_NPHY_RFSEQMODE_CAOVER);
425} 377}
426 378
427/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ 379/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
@@ -480,6 +432,88 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
480 } 432 }
481} 433}
482 434
435/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
436static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
437{
438 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
439
440 b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]);
441 if (core == 0) {
442 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]);
443 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
444 } else {
445 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
446 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
447 }
448 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]);
449 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]);
450 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]);
451 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]);
452 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]);
453 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]);
454 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
455 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
456}
457
458/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
459static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
460{
461 u8 rxval, txval;
462 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
463
464 regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
465 if (core == 0) {
466 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
467 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
468 } else {
469 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
470 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
471 }
472 regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
473 regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
474 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
475 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
476 regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1);
477 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
478 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
479 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
480
481 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
482 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
483
484 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS,
485 ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
486 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
487 ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT));
488 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
489 (core << B43_NPHY_RFSEQCA_RXEN_SHIFT));
490 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS,
491 (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT));
492
493 if (core == 0) {
494 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007);
495 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007);
496 } else {
497 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007);
498 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
499 }
500
501 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */
502 /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */
503 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
504
505 if (core == 0) {
506 rxval = 1;
507 txval = 8;
508 } else {
509 rxval = 4;
510 txval = 2;
511 }
512
513 /* TODO: Call N PHY RF Ctrl Intc Override with 1, rxval, (core + 1) */
514 /* TODO: Call N PHY RF Ctrl Intc Override with 1, txval, (2 - core) */
515}
516
483/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ 517/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
484static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) 518static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
485{ 519{
@@ -653,6 +687,386 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
653 } 687 }
654} 688}
655 689
690/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
691static void b43_nphy_stop_playback(struct b43_wldev *dev)
692{
693 struct b43_phy_n *nphy = dev->phy.n;
694 u16 tmp;
695
696 if (nphy->hang_avoid)
697 b43_nphy_stay_in_carrier_search(dev, 1);
698
699 tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
700 if (tmp & 0x1)
701 b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
702 else if (tmp & 0x2)
703 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000);
704
705 b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
706
707 if (nphy->bb_mult_save & 0x80000000) {
708 tmp = nphy->bb_mult_save & 0xFFFF;
709 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
710 nphy->bb_mult_save = 0;
711 }
712
713 if (nphy->hang_avoid)
714 b43_nphy_stay_in_carrier_search(dev, 0);
715}
716
717/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
718static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
719{
720 struct b43_phy_n *nphy = dev->phy.n;
721 u8 i, j;
722 u8 code;
723
724 /* TODO: for PHY >= 3
725 s8 *lna1_gain, *lna2_gain;
726 u8 *gain_db, *gain_bits;
727 u16 *rfseq_init;
728 u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 };
729 u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 };
730 */
731
732 u8 rfseq_events[3] = { 6, 8, 7 };
733 u8 rfseq_delays[3] = { 10, 30, 1 };
734
735 if (dev->phy.rev >= 3) {
736 /* TODO */
737 } else {
738 /* Set Clip 2 detect */
739 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
740 B43_NPHY_C1_CGAINI_CL2DETECT);
741 b43_phy_set(dev, B43_NPHY_C2_CGAINI,
742 B43_NPHY_C2_CGAINI_CL2DETECT);
743
744 /* Set narrowband clip threshold */
745 b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
746 b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
747
748 if (!dev->phy.is_40mhz) {
749 /* Set dwell lengths */
750 b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
751 b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
752 b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
753 b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
754 }
755
756 /* Set wideband clip 2 threshold */
757 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
758 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
759 21);
760 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
761 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
762 21);
763
764 if (!dev->phy.is_40mhz) {
765 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
766 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
767 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
768 ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1);
769 b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI,
770 ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1);
771 b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI,
772 ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
773 }
774
775 b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
776
777 if (nphy->gain_boost) {
778 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
779 dev->phy.is_40mhz)
780 code = 4;
781 else
782 code = 5;
783 } else {
784 code = dev->phy.is_40mhz ? 6 : 7;
785 }
786
787 /* Set HPVGA2 index */
788 b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
789 ~B43_NPHY_C1_INITGAIN_HPVGA2,
790 code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
791 b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
792 ~B43_NPHY_C2_INITGAIN_HPVGA2,
793 code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
794
795 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
796 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
797 (code << 8 | 0x7C));
798 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
799 (code << 8 | 0x7C));
800
801 /* TODO: b43_nphy_adjust_lna_gain_table(dev); */
802
803 if (nphy->elna_gain_config) {
804 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
805 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
806 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
807 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
808 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
809
810 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08);
811 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
812 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
813 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
814 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
815
816 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
817 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
818 (code << 8 | 0x74));
819 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
820 (code << 8 | 0x74));
821 }
822
823 if (dev->phy.rev == 2) {
824 for (i = 0; i < 4; i++) {
825 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
826 (0x0400 * i) + 0x0020);
827 for (j = 0; j < 21; j++)
828 b43_phy_write(dev,
829 B43_NPHY_TABLE_DATALO, 3 * j);
830 }
831
832 b43_nphy_set_rf_sequence(dev, 5,
833 rfseq_events, rfseq_delays, 3);
834 b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
835 (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV,
836 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
837
838 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
839 b43_phy_maskset(dev, B43_PHY_N(0xC5D),
840 0xFF80, 4);
841 }
842 }
843}
844
845/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
846static void b43_nphy_workarounds(struct b43_wldev *dev)
847{
848 struct ssb_bus *bus = dev->dev->bus;
849 struct b43_phy *phy = &dev->phy;
850 struct b43_phy_n *nphy = phy->n;
851
852 u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 };
853 u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 };
854
855 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
856 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
857
858 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
859 b43_nphy_classifier(dev, 1, 0);
860 else
861 b43_nphy_classifier(dev, 1, 1);
862
863 if (nphy->hang_avoid)
864 b43_nphy_stay_in_carrier_search(dev, 1);
865
866 b43_phy_set(dev, B43_NPHY_IQFLIP,
867 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
868
869 if (dev->phy.rev >= 3) {
870 /* TODO */
871 } else {
872 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
873 nphy->band5g_pwrgain) {
874 b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
875 b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
876 } else {
877 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
878 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
879 }
880
881 /* TODO: convert to b43_ntab_write? */
882 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000);
883 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
884 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010);
885 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
886 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
887 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
888 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
889 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
890
891 if (dev->phy.rev < 2) {
892 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008);
893 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
894 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018);
895 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000);
896 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007);
897 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
898 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
899 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
900 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
901 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
902 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
903 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
904 }
905
906 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
907 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
908 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
909 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
910
911 if (bus->sprom.boardflags2_lo & 0x100 &&
912 bus->boardinfo.type == 0x8B) {
913 delays1[0] = 0x1;
914 delays1[5] = 0x14;
915 }
916 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
917 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
918
919 b43_nphy_gain_crtl_workarounds(dev);
920
921 if (dev->phy.rev < 2) {
922 if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
923 ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/
924 } else if (dev->phy.rev == 2) {
925 b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
926 b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
927 }
928
929 if (dev->phy.rev < 2)
930 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
931 ~B43_NPHY_SCRAM_SIGCTL_SCM);
932
933 /* Set phase track alpha and beta */
934 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
935 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
936 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
937 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
938 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
939 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
940
941 b43_phy_mask(dev, B43_NPHY_PIL_DW1,
942 (u16)~B43_NPHY_PIL_DW_64QAM);
943 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
944 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
945 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
946
947 if (dev->phy.rev == 2)
948 b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
949 B43_NPHY_FINERX2_CGC_DECGC);
950 }
951
952 if (nphy->hang_avoid)
953 b43_nphy_stay_in_carrier_search(dev, 0);
954}
955
956/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
957static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
958 bool test)
959{
960 int i;
961 u16 bw, len, rot, angle;
962 struct b43_c32 *samples;
963
964
965 bw = (dev->phy.is_40mhz) ? 40 : 20;
966 len = bw << 3;
967
968 if (test) {
969 if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX)
970 bw = 82;
971 else
972 bw = 80;
973
974 if (dev->phy.is_40mhz)
975 bw <<= 1;
976
977 len = bw << 1;
978 }
979
980 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL);
981 rot = (((freq * 36) / bw) << 16) / 100;
982 angle = 0;
983
984 for (i = 0; i < len; i++) {
985 samples[i] = b43_cordic(angle);
986 angle += rot;
987 samples[i].q = CORDIC_CONVERT(samples[i].q * max);
988 samples[i].i = CORDIC_CONVERT(samples[i].i * max);
989 }
990
991 /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */
992 kfree(samples);
993 return len;
994}
995
996/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
997static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
998 u16 wait, bool iqmode, bool dac_test)
999{
1000 struct b43_phy_n *nphy = dev->phy.n;
1001 int i;
1002 u16 seq_mode;
1003 u32 tmp;
1004
1005 if (nphy->hang_avoid)
1006 b43_nphy_stay_in_carrier_search(dev, true);
1007
1008 if ((nphy->bb_mult_save & 0x80000000) == 0) {
1009 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1010 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1011 }
1012
1013 if (!dev->phy.is_40mhz)
1014 tmp = 0x6464;
1015 else
1016 tmp = 0x4747;
1017 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1018
1019 if (nphy->hang_avoid)
1020 b43_nphy_stay_in_carrier_search(dev, false);
1021
1022 b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1023
1024 if (loops != 0xFFFF)
1025 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1));
1026 else
1027 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops);
1028
1029 b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait);
1030
1031 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
1032
1033 b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER);
1034 if (iqmode) {
1035 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1036 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1037 } else {
1038 if (dac_test)
1039 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1040 else
1041 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1042 }
1043 for (i = 0; i < 100; i++) {
1044 if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) {
1045 i = 0;
1046 break;
1047 }
1048 udelay(10);
1049 }
1050 if (i)
1051 b43err(dev->wl, "run samples timeout\n");
1052
1053 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
1054}
1055
1056/*
1057 * Transmits a known value for LO calibration
1058 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
1059 */
1060static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
1061 bool iqmode, bool dac_test)
1062{
1063 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
1064 if (samp == 0)
1065 return -1;
1066 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
1067 return 0;
1068}
1069
656/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ 1070/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
657static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) 1071static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
658{ 1072{
@@ -666,8 +1080,7 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
666 if (nphy->hang_avoid) 1080 if (nphy->hang_avoid)
667 b43_nphy_stay_in_carrier_search(dev, true); 1081 b43_nphy_stay_in_carrier_search(dev, true);
668 1082
669 /* TODO: Read an N PHY Table with ID 15, length 7, offset 80, 1083 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
670 width 16, and data pointer buffer */
671 1084
672 for (i = 0; i < 2; i++) { 1085 for (i = 0; i < 2; i++) {
673 tmp = ((buffer[i * 2] & 0x3FF) << 10) | 1086 tmp = ((buffer[i * 2] & 0x3FF) << 10) |
@@ -720,15 +1133,32 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
720 b43_nphy_stay_in_carrier_search(dev, false); 1133 b43_nphy_stay_in_carrier_search(dev, false);
721} 1134}
722 1135
723enum b43_nphy_rf_sequence { 1136/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
724 B43_RFSEQ_RX2TX, 1137static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
725 B43_RFSEQ_TX2RX, 1138 u8 *events, u8 *delays, u8 length)
726 B43_RFSEQ_RESET2RX, 1139{
727 B43_RFSEQ_UPDATE_GAINH, 1140 struct b43_phy_n *nphy = dev->phy.n;
728 B43_RFSEQ_UPDATE_GAINL, 1141 u8 i;
729 B43_RFSEQ_UPDATE_GAINU, 1142 u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F;
730}; 1143 u16 offset1 = cmd << 4;
1144 u16 offset2 = offset1 + 0x80;
731 1145
1146 if (nphy->hang_avoid)
1147 b43_nphy_stay_in_carrier_search(dev, true);
1148
1149 b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events);
1150 b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays);
1151
1152 for (i = length; i < 16; i++) {
1153 b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end);
1154 b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1);
1155 }
1156
1157 if (nphy->hang_avoid)
1158 b43_nphy_stay_in_carrier_search(dev, false);
1159}
1160
1161/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
732static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 1162static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
733 enum b43_nphy_rf_sequence seq) 1163 enum b43_nphy_rf_sequence seq)
734{ 1164{
@@ -741,6 +1171,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
741 [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, 1171 [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU,
742 }; 1172 };
743 int i; 1173 int i;
1174 u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
744 1175
745 B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); 1176 B43_WARN_ON(seq >= ARRAY_SIZE(trigger));
746 1177
@@ -754,8 +1185,83 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
754 } 1185 }
755 b43err(dev->wl, "RF sequence status timeout\n"); 1186 b43err(dev->wl, "RF sequence status timeout\n");
756ok: 1187ok:
757 b43_phy_mask(dev, B43_NPHY_RFSEQMODE, 1188 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
758 ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); 1189}
1190
1191/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
1192static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
1193 u16 value, u8 core, bool off)
1194{
1195 int i;
1196 u8 index = fls(field);
1197 u8 addr, en_addr, val_addr;
1198 /* we expect only one bit set */
1199 B43_WARN_ON(field & (~(1 << (index - 1))));
1200
1201 if (dev->phy.rev >= 3) {
1202 const struct nphy_rf_control_override_rev3 *rf_ctrl;
1203 for (i = 0; i < 2; i++) {
1204 if (index == 0 || index == 16) {
1205 b43err(dev->wl,
1206 "Unsupported RF Ctrl Override call\n");
1207 return;
1208 }
1209
1210 rf_ctrl = &tbl_rf_control_override_rev3[index - 1];
1211 en_addr = B43_PHY_N((i == 0) ?
1212 rf_ctrl->en_addr0 : rf_ctrl->en_addr1);
1213 val_addr = B43_PHY_N((i == 0) ?
1214 rf_ctrl->val_addr0 : rf_ctrl->val_addr1);
1215
1216 if (off) {
1217 b43_phy_mask(dev, en_addr, ~(field));
1218 b43_phy_mask(dev, val_addr,
1219 ~(rf_ctrl->val_mask));
1220 } else {
1221 if (core == 0 || ((1 << core) & i) != 0) {
1222 b43_phy_set(dev, en_addr, field);
1223 b43_phy_maskset(dev, val_addr,
1224 ~(rf_ctrl->val_mask),
1225 (value << rf_ctrl->val_shift));
1226 }
1227 }
1228 }
1229 } else {
1230 const struct nphy_rf_control_override_rev2 *rf_ctrl;
1231 if (off) {
1232 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field));
1233 value = 0;
1234 } else {
1235 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field);
1236 }
1237
1238 for (i = 0; i < 2; i++) {
1239 if (index <= 1 || index == 16) {
1240 b43err(dev->wl,
1241 "Unsupported RF Ctrl Override call\n");
1242 return;
1243 }
1244
1245 if (index == 2 || index == 10 ||
1246 (index >= 13 && index <= 15)) {
1247 core = 1;
1248 }
1249
1250 rf_ctrl = &tbl_rf_control_override_rev2[index - 2];
1251 addr = B43_PHY_N((i == 0) ?
1252 rf_ctrl->addr0 : rf_ctrl->addr1);
1253
1254 if ((core & (1 << i)) != 0)
1255 b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask),
1256 (value << rf_ctrl->shift));
1257
1258 b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
1259 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1260 B43_NPHY_RFCTL_CMD_START);
1261 udelay(1);
1262 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE);
1263 }
1264 }
759} 1265}
760 1266
761static void b43_nphy_bphy_init(struct b43_wldev *dev) 1267static void b43_nphy_bphy_init(struct b43_wldev *dev)
@@ -837,66 +1343,151 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
837 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); 1343 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
838} 1344}
839 1345
840/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ 1346static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
841static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
842{ 1347{
843 u16 val; 1348 u16 val;
844 1349
845 if (dev->phy.rev >= 3) { 1350 if (type < 3)
846 /* TODO */ 1351 val = 0;
847 } else { 1352 else if (type == 6)
848 if (type < 3) 1353 val = 1;
849 val = 0; 1354 else if (type == 3)
850 else if (type == 6) 1355 val = 2;
851 val = 1; 1356 else
852 else if (type == 3) 1357 val = 3;
853 val = 2;
854 else
855 val = 3;
856 1358
857 val = (val << 12) | (val << 14); 1359 val = (val << 12) | (val << 14);
858 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); 1360 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val);
859 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); 1361 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val);
860 1362
1363 if (type < 3) {
1364 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF,
1365 (type + 1) << 4);
1366 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF,
1367 (type + 1) << 4);
1368 }
1369
1370 /* TODO use some definitions */
1371 if (code == 0) {
1372 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
1373 if (type < 3) {
1374 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0);
1375 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0);
1376 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0);
1377 udelay(20);
1378 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
1379 }
1380 } else {
1381 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
1382 0x3000);
861 if (type < 3) { 1383 if (type < 3) {
862 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, 1384 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
863 (type + 1) << 4); 1385 0xFEC7, 0x0180);
864 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, 1386 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
865 (type + 1) << 4); 1387 0xEFDC, (code << 1 | 0x1021));
1388 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1);
1389 udelay(20);
1390 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0);
866 } 1391 }
1392 }
1393}
1394
1395static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1396{
1397 struct b43_phy_n *nphy = dev->phy.n;
1398 u8 i;
1399 u16 reg, val;
1400
1401 if (code == 0) {
1402 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF);
1403 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF);
1404 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF);
1405 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF);
1406 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF);
1407 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF);
1408 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3);
1409 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3);
1410 } else {
1411 for (i = 0; i < 2; i++) {
1412 if ((code == 1 && i == 1) || (code == 2 && !i))
1413 continue;
1414
1415 reg = (i == 0) ?
1416 B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER;
1417 b43_phy_maskset(dev, reg, 0xFDFF, 0x0200);
867 1418
868 /* TODO use some definitions */
869 if (code == 0) {
870 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
871 if (type < 3) {
872 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
873 0xFEC7, 0);
874 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
875 0xEFDC, 0);
876 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
877 0xFFFE, 0);
878 udelay(20);
879 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
880 0xFFFE, 0);
881 }
882 } else {
883 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
884 0x3000);
885 if (type < 3) { 1419 if (type < 3) {
886 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 1420 reg = (i == 0) ?
887 0xFEC7, 0x0180); 1421 B43_NPHY_AFECTL_C1 :
888 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 1422 B43_NPHY_AFECTL_C2;
889 0xEFDC, (code << 1 | 0x1021)); 1423 b43_phy_maskset(dev, reg, 0xFCFF, 0);
890 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 1424
891 0xFFFE, 0x0001); 1425 reg = (i == 0) ?
892 udelay(20); 1426 B43_NPHY_RFCTL_LUT_TRSW_UP1 :
893 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 1427 B43_NPHY_RFCTL_LUT_TRSW_UP2;
894 0xFFFE, 0); 1428 b43_phy_maskset(dev, reg, 0xFFC3, 0);
1429
1430 if (type == 0)
1431 val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8;
1432 else if (type == 1)
1433 val = 16;
1434 else
1435 val = 32;
1436 b43_phy_set(dev, reg, val);
1437
1438 reg = (i == 0) ?
1439 B43_NPHY_TXF_40CO_B1S0 :
1440 B43_NPHY_TXF_40CO_B32S1;
1441 b43_phy_set(dev, reg, 0x0020);
1442 } else {
1443 if (type == 6)
1444 val = 0x0100;
1445 else if (type == 3)
1446 val = 0x0200;
1447 else
1448 val = 0x0300;
1449
1450 reg = (i == 0) ?
1451 B43_NPHY_AFECTL_C1 :
1452 B43_NPHY_AFECTL_C2;
1453
1454 b43_phy_maskset(dev, reg, 0xFCFF, val);
1455 b43_phy_maskset(dev, reg, 0xF3FF, val << 2);
1456
1457 if (type != 3 && type != 6) {
1458 enum ieee80211_band band =
1459 b43_current_band(dev->wl);
1460
1461 if ((nphy->ipa2g_on &&
1462 band == IEEE80211_BAND_2GHZ) ||
1463 (nphy->ipa5g_on &&
1464 band == IEEE80211_BAND_5GHZ))
1465 val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1466 else
1467 val = 0x11;
1468 reg = (i == 0) ? 0x2000 : 0x3000;
1469 reg |= B2055_PADDRV;
1470 b43_radio_write16(dev, reg, val);
1471
1472 reg = (i == 0) ?
1473 B43_NPHY_AFECTL_OVER1 :
1474 B43_NPHY_AFECTL_OVER;
1475 b43_phy_set(dev, reg, 0x0200);
1476 }
895 } 1477 }
896 } 1478 }
897 } 1479 }
898} 1480}
899 1481
1482/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
1483static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1484{
1485 if (dev->phy.rev >= 3)
1486 b43_nphy_rev3_rssi_select(dev, code, type);
1487 else
1488 b43_nphy_rev2_rssi_select(dev, code, type);
1489}
1490
900/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ 1491/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
901static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) 1492static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
902{ 1493{
@@ -1239,9 +1830,60 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
1239{ 1830{
1240 struct b43_phy_n *nphy = dev->phy.n; 1831 struct b43_phy_n *nphy = dev->phy.n;
1241 u16 *save = nphy->tx_rx_cal_radio_saveregs; 1832 u16 *save = nphy->tx_rx_cal_radio_saveregs;
1833 u16 tmp;
1834 u8 offset, i;
1242 1835
1243 if (dev->phy.rev >= 3) { 1836 if (dev->phy.rev >= 3) {
1244 /* TODO */ 1837 for (i = 0; i < 2; i++) {
1838 tmp = (i == 0) ? 0x2000 : 0x3000;
1839 offset = i * 11;
1840
1841 save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL);
1842 save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL);
1843 save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS);
1844 save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS);
1845 save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS);
1846 save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV);
1847 save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1);
1848 save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2);
1849 save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL);
1850 save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC);
1851 save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1);
1852
1853 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1854 b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A);
1855 b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
1856 b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
1857 b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
1858 b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
1859 if (nphy->ipa5g_on) {
1860 b43_radio_write16(dev, tmp | B2055_PADDRV, 4);
1861 b43_radio_write16(dev, tmp | B2055_XOCTL1, 1);
1862 } else {
1863 b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
1864 b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F);
1865 }
1866 b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
1867 } else {
1868 b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06);
1869 b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40);
1870 b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55);
1871 b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0);
1872 b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0);
1873 b43_radio_write16(dev, tmp | B2055_XOCTL1, 0);
1874 if (nphy->ipa2g_on) {
1875 b43_radio_write16(dev, tmp | B2055_PADDRV, 6);
1876 b43_radio_write16(dev, tmp | B2055_XOCTL2,
1877 (dev->phy.rev < 5) ? 0x11 : 0x01);
1878 } else {
1879 b43_radio_write16(dev, tmp | B2055_PADDRV, 0);
1880 b43_radio_write16(dev, tmp | B2055_XOCTL2, 0);
1881 }
1882 }
1883 b43_radio_write16(dev, tmp | B2055_XOREGUL, 0);
1884 b43_radio_write16(dev, tmp | B2055_XOMISC, 0);
1885 b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0);
1886 }
1245 } else { 1887 } else {
1246 save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); 1888 save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1);
1247 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); 1889 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29);
@@ -1330,16 +1972,51 @@ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
1330 for (i = 0; i < 18; i++) { 1972 for (i = 0; i < 18; i++) {
1331 scale = (ladder_lo[i].percent * tmp) / 100; 1973 scale = (ladder_lo[i].percent * tmp) / 100;
1332 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env; 1974 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env;
1333 /* TODO: Write an N PHY Table with ID 15, length 1, 1975 b43_ntab_write(dev, B43_NTAB16(15, i), entry);
1334 offset i, width 16, and data entry */
1335 1976
1336 scale = (ladder_iq[i].percent * tmp) / 100; 1977 scale = (ladder_iq[i].percent * tmp) / 100;
1337 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env; 1978 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env;
1338 /* TODO: Write an N PHY Table with ID 15, length 1, 1979 b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry);
1339 offset i + 32, width 16, and data entry */
1340 } 1980 }
1341} 1981}
1342 1982
1983/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
1984static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
1985{
1986 int i;
1987 for (i = 0; i < 15; i++)
1988 b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
1989 tbl_tx_filter_coef_rev4[2][i]);
1990}
1991
1992/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
1993static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
1994{
1995 int i, j;
1996 /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
1997 u16 offset[] = { 0x186, 0x195, 0x2C5 };
1998
1999 for (i = 0; i < 3; i++)
2000 for (j = 0; j < 15; j++)
2001 b43_phy_write(dev, B43_PHY_N(offset[i] + j),
2002 tbl_tx_filter_coef_rev4[i][j]);
2003
2004 if (dev->phy.is_40mhz) {
2005 for (j = 0; j < 15; j++)
2006 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2007 tbl_tx_filter_coef_rev4[3][j]);
2008 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2009 for (j = 0; j < 15; j++)
2010 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2011 tbl_tx_filter_coef_rev4[5][j]);
2012 }
2013
2014 if (dev->phy.channel == 14)
2015 for (j = 0; j < 15; j++)
2016 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2017 tbl_tx_filter_coef_rev4[6][j]);
2018}
2019
1343/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */ 2020/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
1344static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) 2021static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1345{ 2022{
@@ -1354,8 +2031,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1354 2031
1355 if (nphy->hang_avoid) 2032 if (nphy->hang_avoid)
1356 b43_nphy_stay_in_carrier_search(dev, true); 2033 b43_nphy_stay_in_carrier_search(dev, true);
1357 /* TODO: Read an N PHY Table with ID 7, length 2, 2034 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain);
1358 offset 0x110, width 16, and curr_gain */
1359 if (nphy->hang_avoid) 2035 if (nphy->hang_avoid)
1360 b43_nphy_stay_in_carrier_search(dev, false); 2036 b43_nphy_stay_in_carrier_search(dev, false);
1361 2037
@@ -1423,6 +2099,101 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1423 return target; 2099 return target;
1424} 2100}
1425 2101
2102/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
2103static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
2104{
2105 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2106
2107 if (dev->phy.rev >= 3) {
2108 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]);
2109 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
2110 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
2111 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]);
2112 b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]);
2113 b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]);
2114 b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]);
2115 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]);
2116 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]);
2117 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
2118 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
2119 b43_nphy_reset_cca(dev);
2120 } else {
2121 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]);
2122 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]);
2123 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
2124 b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]);
2125 b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]);
2126 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]);
2127 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]);
2128 }
2129}
2130
2131/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
2132static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2133{
2134 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2135 u16 tmp;
2136
2137 regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
2138 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
2139 if (dev->phy.rev >= 3) {
2140 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00);
2141 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00);
2142
2143 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
2144 regs[2] = tmp;
2145 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600);
2146
2147 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2148 regs[3] = tmp;
2149 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600);
2150
2151 regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG);
2152 b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX);
2153
2154 tmp = b43_ntab_read(dev, B43_NTAB16(8, 3));
2155 regs[5] = tmp;
2156 b43_ntab_write(dev, B43_NTAB16(8, 3), 0);
2157
2158 tmp = b43_ntab_read(dev, B43_NTAB16(8, 19));
2159 regs[6] = tmp;
2160 b43_ntab_write(dev, B43_NTAB16(8, 19), 0);
2161 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2162 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2163
2164 /* TODO: Call N PHY RF Ctrl Intc Override with 2, 1, 3 */
2165 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 2, 1 */
2166 /* TODO: Call N PHY RF Ctrl Intc Override with 1, 8, 2 */
2167
2168 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
2169 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
2170 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
2171 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
2172 } else {
2173 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
2174 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
2175 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2176 regs[2] = tmp;
2177 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000);
2178 tmp = b43_ntab_read(dev, B43_NTAB16(8, 2));
2179 regs[3] = tmp;
2180 tmp |= 0x2000;
2181 b43_ntab_write(dev, B43_NTAB16(8, 2), tmp);
2182 tmp = b43_ntab_read(dev, B43_NTAB16(8, 18));
2183 regs[4] = tmp;
2184 tmp |= 0x2000;
2185 b43_ntab_write(dev, B43_NTAB16(8, 18), tmp);
2186 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2187 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2188 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2189 tmp = 0x0180;
2190 else
2191 tmp = 0x0120;
2192 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
2193 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
2194 }
2195}
2196
1426/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ 2197/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
1427static void b43_nphy_restore_cal(struct b43_wldev *dev) 2198static void b43_nphy_restore_cal(struct b43_wldev *dev)
1428{ 2199{
@@ -1448,8 +2219,7 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
1448 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 2219 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
1449 } 2220 }
1450 2221
1451 /* TODO: Write an N PHY table with ID 15, length 4, offset 80, 2222 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table);
1452 width 16, and data from table */
1453 2223
1454 for (i = 0; i < 4; i++) { 2224 for (i = 0; i < 4; i++) {
1455 if (dev->phy.rev >= 3) 2225 if (dev->phy.rev >= 3)
@@ -1458,12 +2228,9 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
1458 coef[i] = 0; 2228 coef[i] = 0;
1459 } 2229 }
1460 2230
1461 /* TODO: Write an N PHY table with ID 15, length 4, offset 88, 2231 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef);
1462 width 16, and data from coef */ 2232 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft);
1463 /* TODO: Write an N PHY table with ID 15, length 2, offset 85, 2233 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft);
1464 width 16 and data from loft */
1465 /* TODO: Write an N PHY table with ID 15, length 2, offset 93,
1466 width 16 and data from loft */
1467 2234
1468 if (dev->phy.rev < 2) 2235 if (dev->phy.rev < 2)
1469 b43_nphy_tx_iq_workaround(dev); 2236 b43_nphy_tx_iq_workaround(dev);
@@ -1524,39 +2291,47 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1524 nphy->hang_avoid = 0; 2291 nphy->hang_avoid = 0;
1525 } 2292 }
1526 2293
1527 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, 2294 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
1528 width 16, and data pointer save */
1529 2295
1530 for (i = 0; i < 2; i++) { 2296 for (i = 0; i < 2; i++) {
1531 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]); 2297 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]);
1532 gain[i] = params[i].cal_gain; 2298 gain[i] = params[i].cal_gain;
1533 } 2299 }
1534 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2300
1535 width 16, and data pointer gain */ 2301 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain);
1536 2302
1537 b43_nphy_tx_cal_radio_setup(dev); 2303 b43_nphy_tx_cal_radio_setup(dev);
1538 /* TODO: Call N PHY TX Cal PHY Setup */ 2304 b43_nphy_tx_cal_phy_setup(dev);
1539 2305
1540 phy6or5x = dev->phy.rev >= 6 || 2306 phy6or5x = dev->phy.rev >= 6 ||
1541 (dev->phy.rev == 5 && nphy->ipa2g_on && 2307 (dev->phy.rev == 5 && nphy->ipa2g_on &&
1542 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); 2308 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
1543 if (phy6or5x) { 2309 if (phy6or5x) {
1544 /* TODO */ 2310 if (dev->phy.is_40mhz) {
2311 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2312 tbl_tx_iqlo_cal_loft_ladder_40);
2313 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2314 tbl_tx_iqlo_cal_iqimb_ladder_40);
2315 } else {
2316 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2317 tbl_tx_iqlo_cal_loft_ladder_20);
2318 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2319 tbl_tx_iqlo_cal_iqimb_ladder_20);
2320 }
1545 } 2321 }
1546 2322
1547 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); 2323 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
1548 2324
1549 if (1 /* FIXME: the band width is 20 MHz */) 2325 if (!dev->phy.is_40mhz)
1550 freq = 2500; 2326 freq = 2500;
1551 else 2327 else
1552 freq = 5000; 2328 freq = 5000;
1553 2329
1554 if (nphy->mphase_cal_phase_id > 2) 2330 if (nphy->mphase_cal_phase_id > 2)
1555 ;/* TODO: Call N PHY Run Samples with (band width * 8), 2331 b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
1556 0xFFFF, 0, 1, 0 as arguments */ 2332 0xFFFF, 0, true, false);
1557 else 2333 else
1558 ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments 2334 error = b43_nphy_tx_tone(dev, freq, 250, true, false);
1559 and save result as error */
1560 2335
1561 if (error == 0) { 2336 if (error == 0) {
1562 if (nphy->mphase_cal_phase_id > 2) { 2337 if (nphy->mphase_cal_phase_id > 2) {
@@ -1582,8 +2357,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1582 } 2357 }
1583 } 2358 }
1584 2359
1585 /* TODO: Write an N PHY Table with ID 15, length from above, 2360 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table);
1586 offset 64, width 16, and the data pointer from above */
1587 2361
1588 if (full) { 2362 if (full) {
1589 if (dev->phy.rev >= 3) 2363 if (dev->phy.rev >= 3)
@@ -1631,14 +2405,12 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1631 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); 2405 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp);
1632 2406
1633 if (type == 1 || type == 3 || type == 4) { 2407 if (type == 1 || type == 3 || type == 4) {
1634 /* TODO: Read an N PHY Table with ID 15, 2408 buffer[0] = b43_ntab_read(dev,
1635 length 1, offset 69 + core, 2409 B43_NTAB16(15, 69 + core));
1636 width 16, and data pointer buffer */
1637 diq_start = buffer[0]; 2410 diq_start = buffer[0];
1638 buffer[0] = 0; 2411 buffer[0] = 0;
1639 /* TODO: Write an N PHY Table with ID 15, 2412 b43_ntab_write(dev, B43_NTAB16(15, 69 + core),
1640 length 1, offset 69 + core, width 16, 2413 0);
1641 and data of 0 */
1642 } 2414 }
1643 2415
1644 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); 2416 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd);
@@ -1649,12 +2421,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1649 udelay(10); 2421 udelay(10);
1650 } 2422 }
1651 2423
1652 /* TODO: Read an N PHY Table with ID 15, 2424 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
1653 length table_length, offset 96, width 16, 2425 buffer);
1654 and data pointer buffer */ 2426 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length,
1655 /* TODO: Write an N PHY Table with ID 15, 2427 buffer);
1656 length table_length, offset 64, width 16,
1657 and data pointer buffer */
1658 2428
1659 if (type == 1 || type == 3 || type == 4) 2429 if (type == 1 || type == 3 || type == 4)
1660 buffer[0] = diq_start; 2430 buffer[0] = diq_start;
@@ -1666,30 +2436,27 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1666 last = (dev->phy.rev < 3) ? 6 : 7; 2436 last = (dev->phy.rev < 3) ? 6 : 7;
1667 2437
1668 if (!mphase || nphy->mphase_cal_phase_id == last) { 2438 if (!mphase || nphy->mphase_cal_phase_id == last) {
1669 /* TODO: Write an N PHY Table with ID 15, length 4, 2439 b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer);
1670 offset 96, width 16, and data pointer buffer */ 2440 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer);
1671 /* TODO: Read an N PHY Table with ID 15, length 4,
1672 offset 80, width 16, and data pointer buffer */
1673 if (dev->phy.rev < 3) { 2441 if (dev->phy.rev < 3) {
1674 buffer[0] = 0; 2442 buffer[0] = 0;
1675 buffer[1] = 0; 2443 buffer[1] = 0;
1676 buffer[2] = 0; 2444 buffer[2] = 0;
1677 buffer[3] = 0; 2445 buffer[3] = 0;
1678 } 2446 }
1679 /* TODO: Write an N PHY Table with ID 15, length 4, 2447 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
1680 offset 88, width 16, and data pointer buffer */ 2448 buffer);
1681 /* TODO: Read an N PHY Table with ID 15, length 2, 2449 b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2,
1682 offset 101, width 16, and data pointer buffer*/ 2450 buffer);
1683 /* TODO: Write an N PHY Table with ID 15, length 2, 2451 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
1684 offset 85, width 16, and data pointer buffer */ 2452 buffer);
1685 /* TODO: Write an N PHY Table with ID 15, length 2, 2453 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
1686 offset 93, width 16, and data pointer buffer */ 2454 buffer);
1687 length = 11; 2455 length = 11;
1688 if (dev->phy.rev < 3) 2456 if (dev->phy.rev < 3)
1689 length -= 2; 2457 length -= 2;
1690 /* TODO: Read an N PHY Table with ID 15, length length, 2458 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
1691 offset 96, width 16, and data pointer 2459 nphy->txiqlocal_bestc);
1692 nphy->txiqlocal_bestc */
1693 nphy->txiqlocal_coeffsvalid = true; 2460 nphy->txiqlocal_coeffsvalid = true;
1694 /* TODO: Set nphy->txiqlocal_chanspec to 2461 /* TODO: Set nphy->txiqlocal_chanspec to
1695 the current channel */ 2462 the current channel */
@@ -1697,18 +2464,16 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1697 length = 11; 2464 length = 11;
1698 if (dev->phy.rev < 3) 2465 if (dev->phy.rev < 3)
1699 length -= 2; 2466 length -= 2;
1700 /* TODO: Read an N PHY Table with ID 5, length length, 2467 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
1701 offset 96, width 16, and data pointer 2468 nphy->mphase_txcal_bestcoeffs);
1702 nphy->mphase_txcal_bestcoeffs */
1703 } 2469 }
1704 2470
1705 /* TODO: Call N PHY Stop Playback */ 2471 b43_nphy_stop_playback(dev);
1706 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); 2472 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0);
1707 } 2473 }
1708 2474
1709 /* TODO: Call N PHY TX Cal PHY Cleanup */ 2475 b43_nphy_tx_cal_phy_cleanup(dev);
1710 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2476 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
1711 width 16, and data from save */
1712 2477
1713 if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) 2478 if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last))
1714 b43_nphy_tx_iq_workaround(dev); 2479 b43_nphy_tx_iq_workaround(dev);
@@ -1739,7 +2504,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1739 u16 lna[3] = { 3, 3, 1 }; 2504 u16 lna[3] = { 3, 3, 1 };
1740 u16 hpf1[3] = { 7, 2, 0 }; 2505 u16 hpf1[3] = { 7, 2, 0 };
1741 u16 hpf2[3] = { 2, 0, 0 }; 2506 u16 hpf2[3] = { 2, 0, 0 };
1742 u32 power[3]; 2507 u32 power[3] = { };
1743 u16 gain_save[2]; 2508 u16 gain_save[2];
1744 u16 cal_gain[2]; 2509 u16 cal_gain[2];
1745 struct nphy_iqcal_params cal_params[2]; 2510 struct nphy_iqcal_params cal_params[2];
@@ -1752,14 +2517,12 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1752 2517
1753 if (dev->phy.rev < 2) 2518 if (dev->phy.rev < 2)
1754 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ 2519 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */
1755 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, 2520 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
1756 width 16, and data gain_save */
1757 for (i = 0; i < 2; i++) { 2521 for (i = 0; i < 2; i++) {
1758 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); 2522 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
1759 cal_gain[i] = cal_params[i].cal_gain; 2523 cal_gain[i] = cal_params[i].cal_gain;
1760 } 2524 }
1761 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2525 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain);
1762 width 16, and data from cal_gain */
1763 2526
1764 for (i = 0; i < 2; i++) { 2527 for (i = 0; i < 2; i++) {
1765 if (i == 0) { 2528 if (i == 0) {
@@ -1846,19 +2609,19 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1846 2609
1847 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | 2610 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
1848 (cur_lna << 2)); 2611 (cur_lna << 2));
1849 /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], 2612 b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3,
1850 3, 0 as arguments */ 2613 false);
1851 /* TODO: Call N PHY Force RF Seq with 2 as argument */ 2614 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1852 /* TODO: Call N PHT Stop Playback */ 2615 b43_nphy_stop_playback(dev);
1853 2616
1854 if (playtone) { 2617 if (playtone) {
1855 /* TODO: Call N PHY TX Tone with 4000, 2618 ret = b43_nphy_tx_tone(dev, 4000,
1856 (nphy_rxcalparams & 0xffff), 0, 0 2619 (nphy->rxcalparams & 0xFFFF),
1857 as arguments and save result as ret */ 2620 false, false);
1858 playtone = false; 2621 playtone = false;
1859 } else { 2622 } else {
1860 /* TODO: Call N PHY Run Samples with 160, 2623 b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
1861 0xFFFF, 0, 0, 0 as arguments */ 2624 false, false);
1862 } 2625 }
1863 2626
1864 if (ret == 0) { 2627 if (ret == 0) {
@@ -1876,7 +2639,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1876 } else { 2639 } else {
1877 b43_nphy_calc_rx_iq_comp(dev, 1 << i); 2640 b43_nphy_calc_rx_iq_comp(dev, 1 << i);
1878 } 2641 }
1879 /* TODO: Call N PHY Stop Playback */ 2642 b43_nphy_stop_playback(dev);
1880 } 2643 }
1881 2644
1882 if (ret != 0) 2645 if (ret != 0)
@@ -1895,10 +2658,9 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1895 break; 2658 break;
1896 } 2659 }
1897 2660
1898 /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ 2661 b43_nphy_rf_control_override(dev, 0x400, 0, 3, true);
1899 /* TODO: Call N PHY Force RF Seq with 2 as argument */ 2662 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1900 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, 2663 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
1901 width 16, and data from gain_save */
1902 2664
1903 b43_nphy_stay_in_carrier_search(dev, 0); 2665 b43_nphy_stay_in_carrier_search(dev, 0);
1904 2666
@@ -1990,8 +2752,8 @@ int b43_phy_initn(struct b43_wldev *dev)
1990 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); 2752 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
1991 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); 2753 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
1992 2754
1993 /* TODO MIMO-Config */ 2755 b43_nphy_update_mimo_config(dev, nphy->preamble_override);
1994 /* TODO Update TX/RX chain */ 2756 b43_nphy_update_txrx_chain(dev);
1995 2757
1996 if (phy->rev < 2) { 2758 if (phy->rev < 2) {
1997 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); 2759 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
@@ -2007,9 +2769,9 @@ int b43_phy_initn(struct b43_wldev *dev)
2007 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1); 2769 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1);
2008 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F, 2770 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F,
2009 nphy->papd_epsilon_offset[1] << 7); 2771 nphy->papd_epsilon_offset[1] << 7);
2010 /* TODO N PHY IPA Set TX Dig Filters */ 2772 b43_nphy_int_pa_set_tx_dig_filters(dev);
2011 } else if (phy->rev >= 5) { 2773 } else if (phy->rev >= 5) {
2012 /* TODO N PHY Ext PA Set TX Dig Filters */ 2774 b43_nphy_ext_pa_set_tx_dig_filters(dev);
2013 } 2775 }
2014 2776
2015 b43_nphy_workarounds(dev); 2777 b43_nphy_workarounds(dev);
@@ -2040,8 +2802,10 @@ int b43_phy_initn(struct b43_wldev *dev)
2040 if (phy->rev >= 3) { 2802 if (phy->rev >= 3) {
2041 /* TODO */ 2803 /* TODO */
2042 } else { 2804 } else {
2043 /* TODO Write an N PHY table with ID 26, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ 2805 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128,
2044 /* TODO Write an N PHY table with ID 27, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ 2806 b43_ntab_tx_gain_rev0_1_2);
2807 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128,
2808 b43_ntab_tx_gain_rev0_1_2);
2045 } 2809 }
2046 2810
2047 if (nphy->phyrxchain != 3) 2811 if (nphy->phyrxchain != 3)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 4572866756fc..ae82f0fc2096 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -973,6 +973,12 @@ struct b43_phy_n {
973 bool hang_avoid; 973 bool hang_avoid;
974 bool mute; 974 bool mute;
975 u16 papd_epsilon_offset[2]; 975 u16 papd_epsilon_offset[2];
976 s32 preamble_override;
977 u32 bb_mult_save;
978
979 bool gain_boost;
980 bool elna_gain_config;
981 bool band5g_pwrgain;
976 982
977 u8 mphase_cal_phase_id; 983 u8 mphase_cal_phase_id;
978 u16 mphase_txcal_cmdidx; 984 u16 mphase_txcal_cmdidx;
@@ -985,6 +991,7 @@ struct b43_phy_n {
985 bool txiqlocal_coeffsvalid; 991 bool txiqlocal_coeffsvalid;
986 struct b43_phy_n_txpwrindex txpwrindex[2]; 992 struct b43_phy_n_txpwrindex txpwrindex[2];
987 993
994 u8 txrx_chain;
988 u16 tx_rx_cal_phy_saveregs[11]; 995 u16 tx_rx_cal_phy_saveregs[11];
989 u16 tx_rx_cal_radio_saveregs[22]; 996 u16 tx_rx_cal_radio_saveregs[22];
990 997
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 7dff853ab962..a00d509150f7 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2883,6 +2883,67 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
2883 0x9084, 0x9267, 0x9056, 0x9234 2883 0x9084, 0x9267, 0x9056, 0x9234
2884}; 2884};
2885 2885
2886const s16 tbl_tx_filter_coef_rev4[7][15] = {
2887 { -377, 137, -407, 208, -1527,
2888 956, 93, 186, 93, 230,
2889 -44, 230, 20, -191, 201 },
2890 { -77, 20, -98, 49, -93,
2891 60, 56, 111, 56, 26,
2892 -5, 26, 34, -32, 34 },
2893 { -360, 164, -376, 164, -1533,
2894 576, 308, -314, 308, 121,
2895 -73, 121, 91, 124, 91 },
2896 { -295, 200, -363, 142, -1391,
2897 826, 151, 301, 151, 151,
2898 301, 151, 602, -752, 602 },
2899 { -92, 58, -96, 49, -104,
2900 44, 17, 35, 17, 12,
2901 25, 12, 13, 27, 13 },
2902 { -375, 136, -399, 209, -1479,
2903 949, 130, 260, 130, 230,
2904 -44, 230, 201, -191, 201 },
2905 { 0xed9, 0xc8, 0xe95, 0x8e, 0xa91,
2906 0x33a, 0x97, 0x12d, 0x97, 0x97,
2907 0x12d, 0x97, 0x25a, 0xd10, 0x25a }
2908};
2909
2910/* addr0, addr1, bmask, shift */
2911const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = {
2912 { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */
2913 { 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */
2914 { 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */
2915 { 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */
2916 { 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */
2917 { 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */
2918 { 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */
2919 { 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */
2920 { 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */
2921 { 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */
2922 { 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */
2923 { 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */
2924 { 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */
2925 { 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */
2926};
2927
2928/* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */
2929const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
2930 { 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */
2931 { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */
2932 { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */
2933 { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */
2934 { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
2935 { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */
2936 { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */
2937 { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
2938 { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
2939 { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */
2940 { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */
2941 { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */
2942 { 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */
2943 { 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */
2944 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */
2945};
2946
2886static inline void assert_ntab_array_sizes(void) 2947static inline void assert_ntab_array_sizes(void)
2887{ 2948{
2888#undef check 2949#undef check
@@ -2919,6 +2980,72 @@ static inline void assert_ntab_array_sizes(void)
2919#undef check 2980#undef check
2920} 2981}
2921 2982
2983u32 b43_ntab_read(struct b43_wldev *dev, u32 offset)
2984{
2985 u32 type, value;
2986
2987 type = offset & B43_NTAB_TYPEMASK;
2988 offset &= ~B43_NTAB_TYPEMASK;
2989 B43_WARN_ON(offset > 0xFFFF);
2990
2991 switch (type) {
2992 case B43_NTAB_8BIT:
2993 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
2994 value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
2995 break;
2996 case B43_NTAB_16BIT:
2997 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
2998 value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
2999 break;
3000 case B43_NTAB_32BIT:
3001 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
3002 value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
3003 value <<= 16;
3004 value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
3005 break;
3006 default:
3007 B43_WARN_ON(1);
3008 value = 0;
3009 }
3010
3011 return value;
3012}
3013
3014void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
3015 unsigned int nr_elements, void *_data)
3016{
3017 u32 type;
3018 u8 *data = _data;
3019 unsigned int i;
3020
3021 type = offset & B43_NTAB_TYPEMASK;
3022 offset &= ~B43_NTAB_TYPEMASK;
3023 B43_WARN_ON(offset > 0xFFFF);
3024
3025 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
3026
3027 for (i = 0; i < nr_elements; i++) {
3028 switch (type) {
3029 case B43_NTAB_8BIT:
3030 *data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
3031 data++;
3032 break;
3033 case B43_NTAB_16BIT:
3034 *((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
3035 data += 2;
3036 break;
3037 case B43_NTAB_32BIT:
3038 *((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
3039 *((u32 *)data) <<= 16;
3040 *((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
3041 data += 4;
3042 break;
3043 default:
3044 B43_WARN_ON(1);
3045 }
3046 }
3047}
3048
2922void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) 3049void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2923{ 3050{
2924 u32 type; 3051 u32 type;
@@ -2952,6 +3079,46 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2952 assert_ntab_array_sizes(); 3079 assert_ntab_array_sizes();
2953} 3080}
2954 3081
3082void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
3083 unsigned int nr_elements, const void *_data)
3084{
3085 u32 type, value;
3086 const u8 *data = _data;
3087 unsigned int i;
3088
3089 type = offset & B43_NTAB_TYPEMASK;
3090 offset &= ~B43_NTAB_TYPEMASK;
3091 B43_WARN_ON(offset > 0xFFFF);
3092
3093 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
3094
3095 for (i = 0; i < nr_elements; i++) {
3096 switch (type) {
3097 case B43_NTAB_8BIT:
3098 value = *data;
3099 data++;
3100 B43_WARN_ON(value & ~0xFF);
3101 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
3102 break;
3103 case B43_NTAB_16BIT:
3104 value = *((u16 *)data);
3105 data += 2;
3106 B43_WARN_ON(value & ~0xFFFF);
3107 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
3108 break;
3109 case B43_NTAB_32BIT:
3110 value = *((u32 *)data);
3111 data += 4;
3112 b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16);
3113 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
3114 value & 0xFFFF);
3115 break;
3116 default:
3117 B43_WARN_ON(1);
3118 }
3119 }
3120}
3121
2955#define ntab_upload(dev, offset, data) do { \ 3122#define ntab_upload(dev, offset, data) do { \
2956 unsigned int i; \ 3123 unsigned int i; \
2957 for (i = 0; i < (offset##_SIZE); i++) \ 3124 for (i = 0; i < (offset##_SIZE); i++) \
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 51636d02f8b1..9c1c6ecd3672 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -51,6 +51,22 @@ struct nphy_txiqcal_ladder {
51 u8 g_env; 51 u8 g_env;
52}; 52};
53 53
54struct nphy_rf_control_override_rev2 {
55 u8 addr0;
56 u8 addr1;
57 u16 bmask;
58 u8 shift;
59};
60
61struct nphy_rf_control_override_rev3 {
62 u16 val_mask;
63 u8 val_shift;
64 u8 en_addr0;
65 u8 val_addr0;
66 u8 en_addr1;
67 u8 val_addr1;
68};
69
54/* Upload the default register value table. 70/* Upload the default register value table.
55 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz 71 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
56 * table is uploaded. If "ignore_uploadflag" is true, we upload any value 72 * table is uploaded. If "ignore_uploadflag" is true, we upload any value
@@ -142,7 +158,12 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel);
142#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10 158#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10
143#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 159#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12
144 160
161u32 b43_ntab_read(struct b43_wldev *dev, u32 offset);
162void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
163 unsigned int nr_elements, void *_data);
145void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); 164void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
165void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
166 unsigned int nr_elements, const void *_data);
146 167
147void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); 168void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
148void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); 169void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
@@ -172,5 +193,11 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
172extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; 193extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
173extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; 194extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
174extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; 195extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[];
196extern const s16 tbl_tx_filter_coef_rev4[7][15];
197
198extern const struct nphy_rf_control_override_rev2
199 tbl_rf_control_override_rev2[];
200extern const struct nphy_rf_control_override_rev3
201 tbl_rf_control_override_rev3[];
175 202
176#endif /* B43_TABLES_NPHY_H_ */ 203#endif /* B43_TABLES_NPHY_H_ */
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b16b06c2031f..dc8ed1527666 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,14 +1,8 @@
1config IWLWIFI 1config IWLWIFI
2 tristate "Intel Wireless Wifi" 2 tristate "Intel Wireless Wifi"
3 depends on PCI && MAC80211 && EXPERIMENTAL 3 depends on PCI && MAC80211
4 select FW_LOADER 4 select FW_LOADER
5 5
6config IWLWIFI_SPECTRUM_MEASUREMENT
7 bool "Enable Spectrum Measurement in iwlagn driver"
8 depends on IWLWIFI
9 ---help---
10 This option will enable spectrum measurement for the iwlagn driver.
11
12config IWLWIFI_DEBUG 6config IWLWIFI_DEBUG
13 bool "Enable full debugging output in iwlagn and iwl3945 drivers" 7 bool "Enable full debugging output in iwlagn and iwl3945 drivers"
14 depends on IWLWIFI 8 depends on IWLWIFI
@@ -120,9 +114,3 @@ config IWL3945
120 inserted in and removed from the running kernel whenever you want), 114 inserted in and removed from the running kernel whenever you want),
121 say M here and read <file:Documentation/kbuild/modules.txt>. The 115 say M here and read <file:Documentation/kbuild/modules.txt>. The
122 module will be called iwl3945. 116 module will be called iwl3945.
123
124config IWL3945_SPECTRUM_MEASUREMENT
125 bool "Enable Spectrum Measurement in iwl3945 driver"
126 depends on IWL3945
127 ---help---
128 This option will enable spectrum measurement for the iwl3945 driver.
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 7f82044af242..4e378faee650 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -3,7 +3,6 @@ iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o 3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
4iwlcore-objs += iwl-scan.o iwl-led.o 4iwlcore-objs += iwl-scan.o iwl-led.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
7iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 6iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
8 7
9CFLAGS_iwl-devtrace.o := -I$(src) 8CFLAGS_iwl-devtrace.o := -I$(src)
@@ -20,3 +19,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
20# 3945 19# 3945
21obj-$(CONFIG_IWL3945) += iwl3945.o 20obj-$(CONFIG_IWL3945) += iwl3945.o
22iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o 21iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
22
23ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 0db1fda94a65..9d1820676f30 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -89,8 +89,78 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
89 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); 89 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
90} 90}
91 91
92static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
93 .min_nrg_cck = 95,
94 .max_nrg_cck = 0, /* not used, set to 0 */
95 .auto_corr_min_ofdm = 90,
96 .auto_corr_min_ofdm_mrc = 170,
97 .auto_corr_min_ofdm_x1 = 120,
98 .auto_corr_min_ofdm_mrc_x1 = 240,
99
100 .auto_corr_max_ofdm = 120,
101 .auto_corr_max_ofdm_mrc = 210,
102 .auto_corr_max_ofdm_x1 = 155,
103 .auto_corr_max_ofdm_mrc_x1 = 290,
104
105 .auto_corr_min_cck = 125,
106 .auto_corr_max_cck = 200,
107 .auto_corr_min_cck_mrc = 170,
108 .auto_corr_max_cck_mrc = 400,
109 .nrg_th_cck = 95,
110 .nrg_th_ofdm = 95,
111
112 .barker_corr_th_min = 190,
113 .barker_corr_th_min_mrc = 390,
114 .nrg_th_cca = 62,
115};
116
117static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
118{
119 if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
120 priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
121 priv->cfg->num_of_queues =
122 priv->cfg->mod_params->num_of_queues;
123
124 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
125 priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
126 priv->hw_params.scd_bc_tbls_size =
127 priv->cfg->num_of_queues *
128 sizeof(struct iwl5000_scd_bc_tbl);
129 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
130 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
131 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
132
133 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
134 priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
135
136 priv->hw_params.max_bsm_size = 0;
137 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
138 BIT(IEEE80211_BAND_5GHZ);
139 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
140
141 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
142 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
143 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
144 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
145
146 if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
147 priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
148
149 /* Set initial sensitivity parameters */
150 /* Set initial calibration set */
151 priv->hw_params.sens = &iwl1000_sensitivity;
152 priv->hw_params.calib_init_cfg =
153 BIT(IWL_CALIB_XTAL) |
154 BIT(IWL_CALIB_LO) |
155 BIT(IWL_CALIB_TX_IQ) |
156 BIT(IWL_CALIB_TX_IQ_PERD) |
157 BIT(IWL_CALIB_BASE_BAND);
158
159 return 0;
160}
161
92static struct iwl_lib_ops iwl1000_lib = { 162static struct iwl_lib_ops iwl1000_lib = {
93 .set_hw_params = iwl5000_hw_set_hw_params, 163 .set_hw_params = iwl1000_hw_set_hw_params,
94 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 164 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
95 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 165 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
96 .txq_set_sched = iwl5000_txq_set_sched, 166 .txq_set_sched = iwl5000_txq_set_sched,
@@ -106,6 +176,7 @@ static struct iwl_lib_ops iwl1000_lib = {
106 .dump_nic_event_log = iwl_dump_nic_event_log, 176 .dump_nic_event_log = iwl_dump_nic_event_log,
107 .dump_nic_error_log = iwl_dump_nic_error_log, 177 .dump_nic_error_log = iwl_dump_nic_error_log,
108 .dump_csr = iwl_dump_csr, 178 .dump_csr = iwl_dump_csr,
179 .dump_fh = iwl_dump_fh,
109 .init_alive_start = iwl5000_init_alive_start, 180 .init_alive_start = iwl5000_init_alive_start,
110 .alive_notify = iwl5000_alive_notify, 181 .alive_notify = iwl5000_alive_notify,
111 .send_tx_power = iwl5000_send_tx_power, 182 .send_tx_power = iwl5000_send_tx_power,
@@ -139,6 +210,7 @@ static struct iwl_lib_ops iwl1000_lib = {
139 .temperature = iwl5000_temperature, 210 .temperature = iwl5000_temperature,
140 .set_ct_kill = iwl1000_set_ct_threshold, 211 .set_ct_kill = iwl1000_set_ct_threshold,
141 }, 212 },
213 .add_bcast_station = iwl_add_bcast_station,
142}; 214};
143 215
144static const struct iwl_ops iwl1000_ops = { 216static const struct iwl_ops iwl1000_ops = {
@@ -174,6 +246,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
174 .use_rts_for_ht = true, /* use rts/cts protection */ 246 .use_rts_for_ht = true, /* use rts/cts protection */
175 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 247 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
176 .support_ct_kill_exit = true, 248 .support_ct_kill_exit = true,
249 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
177}; 250};
178 251
179struct iwl_cfg iwl1000_bg_cfg = { 252struct iwl_cfg iwl1000_bg_cfg = {
@@ -200,6 +273,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
200 .led_compensation = 51, 273 .led_compensation = 51,
201 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 274 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
202 .support_ct_kill_exit = true, 275 .support_ct_kill_exit = true,
276 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
203}; 277};
204 278
205MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 279MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
index 08ce259a0e60..042f6bc0df13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6fd10d443ba3..3a876a8ece38 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index a871d09d598f..abe2b739c4dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 5a1033ca7aaa..ce990adc51e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index d4b49883b30e..47909f94271e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 6cde661ce0bc..6940f086823c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -1951,11 +1951,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1951 } 1951 }
1952 1952
1953 /* Add the broadcast address so we can send broadcast frames */ 1953 /* Add the broadcast address so we can send broadcast frames */
1954 if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) == 1954 priv->cfg->ops->lib->add_bcast_station(priv);
1955 IWL_INVALID_STATION) {
1956 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
1957 return -EIO;
1958 }
1959 1955
1960 /* If we have set the ASSOC_MSK and we are in BSS mode then 1956 /* If we have set the ASSOC_MSK and we are in BSS mode then
1961 * add the IWL_AP_ID to the station rate table */ 1957 * add the IWL_AP_ID to the station rate table */
@@ -2796,6 +2792,7 @@ static struct iwl_lib_ops iwl3945_lib = {
2796 .post_associate = iwl3945_post_associate, 2792 .post_associate = iwl3945_post_associate,
2797 .isr = iwl_isr_legacy, 2793 .isr = iwl_isr_legacy,
2798 .config_ap = iwl3945_config_ap, 2794 .config_ap = iwl3945_config_ap,
2795 .add_bcast_station = iwl3945_add_bcast_station,
2799}; 2796};
2800 2797
2801static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2798static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2830,6 +2827,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2830 .ht_greenfield_support = false, 2827 .ht_greenfield_support = false,
2831 .led_compensation = 64, 2828 .led_compensation = 64,
2832 .broken_powersave = true, 2829 .broken_powersave = true,
2830 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2833}; 2831};
2834 2832
2835static struct iwl_cfg iwl3945_abg_cfg = { 2833static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2847,6 +2845,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2847 .ht_greenfield_support = false, 2845 .ht_greenfield_support = false,
2848 .led_compensation = 64, 2846 .led_compensation = 64,
2849 .broken_powersave = true, 2847 .broken_powersave = true,
2848 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2850}; 2849};
2851 2850
2852DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2851DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bc532ff4f883..8f553f36d270 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index c606366b582c..67ef562e8db1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 6a004abb5973..aebe8c51d3e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -2206,6 +2206,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2206 .temperature = iwl4965_temperature_calib, 2206 .temperature = iwl4965_temperature_calib,
2207 .set_ct_kill = iwl4965_set_ct_threshold, 2207 .set_ct_kill = iwl4965_set_ct_threshold,
2208 }, 2208 },
2209 .add_bcast_station = iwl_add_bcast_station,
2209}; 2210};
2210 2211
2211static const struct iwl_ops iwl4965_ops = { 2212static const struct iwl_ops iwl4965_ops = {
@@ -2239,6 +2240,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2240 .broken_powersave = true,
2240 .led_compensation = 61, 2241 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2242 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2243 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2242}; 2244};
2243 2245
2244/* Module firmware */ 2246/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index bc056e9ab85f..714e032f6217 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index c6120f0b8f98..6d5988901341 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -263,8 +263,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
263 263
264 .auto_corr_max_ofdm = 120, 264 .auto_corr_max_ofdm = 120,
265 .auto_corr_max_ofdm_mrc = 210, 265 .auto_corr_max_ofdm_mrc = 210,
266 .auto_corr_max_ofdm_x1 = 155, 266 .auto_corr_max_ofdm_x1 = 120,
267 .auto_corr_max_ofdm_mrc_x1 = 290, 267 .auto_corr_max_ofdm_mrc_x1 = 240,
268 268
269 .auto_corr_min_cck = 125, 269 .auto_corr_min_cck = 125,
270 .auto_corr_max_cck = 200, 270 .auto_corr_max_cck = 200,
@@ -412,12 +412,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
412/* 412/*
413 * ucode 413 * ucode
414 */ 414 */
415static int iwl5000_load_section(struct iwl_priv *priv, 415static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
416 struct fw_desc *image, 416 struct fw_desc *image, u32 dst_addr)
417 u32 dst_addr)
418{ 417{
419 dma_addr_t phy_addr = image->p_addr; 418 dma_addr_t phy_addr = image->p_addr;
420 u32 byte_cnt = image->len; 419 u32 byte_cnt = image->len;
420 int ret;
421
422 priv->ucode_write_complete = 0;
421 423
422 iwl_write_direct32(priv, 424 iwl_write_direct32(priv,
423 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 425 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -447,57 +449,36 @@ static int iwl5000_load_section(struct iwl_priv *priv,
447 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 449 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
448 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 450 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
449 451
450 return 0; 452 IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
451}
452
453static int iwl5000_load_given_ucode(struct iwl_priv *priv,
454 struct fw_desc *inst_image,
455 struct fw_desc *data_image)
456{
457 int ret = 0;
458
459 ret = iwl5000_load_section(priv, inst_image,
460 IWL50_RTC_INST_LOWER_BOUND);
461 if (ret)
462 return ret;
463
464 IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
465 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 453 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
466 priv->ucode_write_complete, 5 * HZ); 454 priv->ucode_write_complete, 5 * HZ);
467 if (ret == -ERESTARTSYS) { 455 if (ret == -ERESTARTSYS) {
468 IWL_ERR(priv, "Could not load the INST uCode section due " 456 IWL_ERR(priv, "Could not load the %s uCode section due "
469 "to interrupt\n"); 457 "to interrupt\n", name);
470 return ret; 458 return ret;
471 } 459 }
472 if (!ret) { 460 if (!ret) {
473 IWL_ERR(priv, "Could not load the INST uCode section\n"); 461 IWL_ERR(priv, "Could not load the %s uCode section\n",
462 name);
474 return -ETIMEDOUT; 463 return -ETIMEDOUT;
475 } 464 }
476 465
477 priv->ucode_write_complete = 0; 466 return 0;
478 467}
479 ret = iwl5000_load_section(
480 priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
481 if (ret)
482 return ret;
483 468
484 IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n"); 469static int iwl5000_load_given_ucode(struct iwl_priv *priv,
470 struct fw_desc *inst_image,
471 struct fw_desc *data_image)
472{
473 int ret = 0;
485 474
486 ret = wait_event_interruptible_timeout(priv->wait_command_queue, 475 ret = iwl5000_load_section(priv, "INST", inst_image,
487 priv->ucode_write_complete, 5 * HZ); 476 IWL50_RTC_INST_LOWER_BOUND);
488 if (ret == -ERESTARTSYS) { 477 if (ret)
489 IWL_ERR(priv, "Could not load the INST uCode section due "
490 "to interrupt\n");
491 return ret; 478 return ret;
492 } else if (!ret) {
493 IWL_ERR(priv, "Could not load the DATA uCode section\n");
494 return -ETIMEDOUT;
495 } else
496 ret = 0;
497
498 priv->ucode_write_complete = 0;
499 479
500 return ret; 480 return iwl5000_load_section(priv, "DATA", data_image,
481 IWL50_RTC_DATA_LOWER_BOUND);
501} 482}
502 483
503int iwl5000_load_ucode(struct iwl_priv *priv) 484int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -1467,6 +1448,7 @@ struct iwl_lib_ops iwl5000_lib = {
1467 .dump_nic_event_log = iwl_dump_nic_event_log, 1448 .dump_nic_event_log = iwl_dump_nic_event_log,
1468 .dump_nic_error_log = iwl_dump_nic_error_log, 1449 .dump_nic_error_log = iwl_dump_nic_error_log,
1469 .dump_csr = iwl_dump_csr, 1450 .dump_csr = iwl_dump_csr,
1451 .dump_fh = iwl_dump_fh,
1470 .load_ucode = iwl5000_load_ucode, 1452 .load_ucode = iwl5000_load_ucode,
1471 .init_alive_start = iwl5000_init_alive_start, 1453 .init_alive_start = iwl5000_init_alive_start,
1472 .alive_notify = iwl5000_alive_notify, 1454 .alive_notify = iwl5000_alive_notify,
@@ -1502,6 +1484,7 @@ struct iwl_lib_ops iwl5000_lib = {
1502 .temperature = iwl5000_temperature, 1484 .temperature = iwl5000_temperature,
1503 .set_ct_kill = iwl5000_set_ct_threshold, 1485 .set_ct_kill = iwl5000_set_ct_threshold,
1504 }, 1486 },
1487 .add_bcast_station = iwl_add_bcast_station,
1505}; 1488};
1506 1489
1507static struct iwl_lib_ops iwl5150_lib = { 1490static struct iwl_lib_ops iwl5150_lib = {
@@ -1555,6 +1538,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1555 .temperature = iwl5150_temperature, 1538 .temperature = iwl5150_temperature,
1556 .set_ct_kill = iwl5150_set_ct_threshold, 1539 .set_ct_kill = iwl5150_set_ct_threshold,
1557 }, 1540 },
1541 .add_bcast_station = iwl_add_bcast_station,
1558}; 1542};
1559 1543
1560static const struct iwl_ops iwl5000_ops = { 1544static const struct iwl_ops iwl5000_ops = {
@@ -1602,6 +1586,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
1602 .led_compensation = 51, 1586 .led_compensation = 51,
1603 .use_rts_for_ht = true, /* use rts/cts protection */ 1587 .use_rts_for_ht = true, /* use rts/cts protection */
1604 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1588 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1589 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605}; 1590};
1606 1591
1607struct iwl_cfg iwl5100_bgn_cfg = { 1592struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1626,6 +1611,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1626 .led_compensation = 51, 1611 .led_compensation = 51,
1627 .use_rts_for_ht = true, /* use rts/cts protection */ 1612 .use_rts_for_ht = true, /* use rts/cts protection */
1628 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1613 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1614 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1629}; 1615};
1630 1616
1631struct iwl_cfg iwl5100_abg_cfg = { 1617struct iwl_cfg iwl5100_abg_cfg = {
@@ -1648,6 +1634,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
1648 .use_bsm = false, 1634 .use_bsm = false,
1649 .led_compensation = 51, 1635 .led_compensation = 51,
1650 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1636 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1637 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1651}; 1638};
1652 1639
1653struct iwl_cfg iwl5100_agn_cfg = { 1640struct iwl_cfg iwl5100_agn_cfg = {
@@ -1672,6 +1659,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
1672 .led_compensation = 51, 1659 .led_compensation = 51,
1673 .use_rts_for_ht = true, /* use rts/cts protection */ 1660 .use_rts_for_ht = true, /* use rts/cts protection */
1674 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1661 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1662 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1675}; 1663};
1676 1664
1677struct iwl_cfg iwl5350_agn_cfg = { 1665struct iwl_cfg iwl5350_agn_cfg = {
@@ -1696,6 +1684,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
1696 .led_compensation = 51, 1684 .led_compensation = 51,
1697 .use_rts_for_ht = true, /* use rts/cts protection */ 1685 .use_rts_for_ht = true, /* use rts/cts protection */
1698 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1686 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1687 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1699}; 1688};
1700 1689
1701struct iwl_cfg iwl5150_agn_cfg = { 1690struct iwl_cfg iwl5150_agn_cfg = {
@@ -1720,6 +1709,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
1720 .led_compensation = 51, 1709 .led_compensation = 51,
1721 .use_rts_for_ht = true, /* use rts/cts protection */ 1710 .use_rts_for_ht = true, /* use rts/cts protection */
1722 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1711 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1712 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1723}; 1713};
1724 1714
1725struct iwl_cfg iwl5150_abg_cfg = { 1715struct iwl_cfg iwl5150_abg_cfg = {
@@ -1742,6 +1732,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
1742 .use_bsm = false, 1732 .use_bsm = false,
1743 .led_compensation = 51, 1733 .led_compensation = 51,
1744 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1734 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1735 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1745}; 1736};
1746 1737
1747MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1738MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 90185777d98b..ddba39999997 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a5a0ed4817a4..a9f8551e0e40 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -108,7 +108,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
108 108
109 .auto_corr_max_ofdm = 145, 109 .auto_corr_max_ofdm = 145,
110 .auto_corr_max_ofdm_mrc = 232, 110 .auto_corr_max_ofdm_mrc = 232,
111 .auto_corr_max_ofdm_x1 = 145, 111 .auto_corr_max_ofdm_x1 = 110,
112 .auto_corr_max_ofdm_mrc_x1 = 232, 112 .auto_corr_max_ofdm_mrc_x1 = 232,
113 113
114 .auto_corr_min_cck = 125, 114 .auto_corr_min_cck = 125,
@@ -158,11 +158,25 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
158 /* Set initial sensitivity parameters */ 158 /* Set initial sensitivity parameters */
159 /* Set initial calibration set */ 159 /* Set initial calibration set */
160 priv->hw_params.sens = &iwl6000_sensitivity; 160 priv->hw_params.sens = &iwl6000_sensitivity;
161 priv->hw_params.calib_init_cfg = 161 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
162 case CSR_HW_REV_TYPE_6x50:
163 priv->hw_params.calib_init_cfg =
162 BIT(IWL_CALIB_XTAL) | 164 BIT(IWL_CALIB_XTAL) |
165 BIT(IWL_CALIB_DC) |
163 BIT(IWL_CALIB_LO) | 166 BIT(IWL_CALIB_LO) |
164 BIT(IWL_CALIB_TX_IQ) | 167 BIT(IWL_CALIB_TX_IQ) |
165 BIT(IWL_CALIB_BASE_BAND); 168 BIT(IWL_CALIB_BASE_BAND);
169
170 break;
171 default:
172 priv->hw_params.calib_init_cfg =
173 BIT(IWL_CALIB_XTAL) |
174 BIT(IWL_CALIB_LO) |
175 BIT(IWL_CALIB_TX_IQ) |
176 BIT(IWL_CALIB_BASE_BAND);
177 break;
178 }
179
166 return 0; 180 return 0;
167} 181}
168 182
@@ -216,6 +230,7 @@ static struct iwl_lib_ops iwl6000_lib = {
216 .dump_nic_event_log = iwl_dump_nic_event_log, 230 .dump_nic_event_log = iwl_dump_nic_event_log,
217 .dump_nic_error_log = iwl_dump_nic_error_log, 231 .dump_nic_error_log = iwl_dump_nic_error_log,
218 .dump_csr = iwl_dump_csr, 232 .dump_csr = iwl_dump_csr,
233 .dump_fh = iwl_dump_fh,
219 .init_alive_start = iwl5000_init_alive_start, 234 .init_alive_start = iwl5000_init_alive_start,
220 .alive_notify = iwl5000_alive_notify, 235 .alive_notify = iwl5000_alive_notify,
221 .send_tx_power = iwl5000_send_tx_power, 236 .send_tx_power = iwl5000_send_tx_power,
@@ -251,6 +266,7 @@ static struct iwl_lib_ops iwl6000_lib = {
251 .temperature = iwl5000_temperature, 266 .temperature = iwl5000_temperature,
252 .set_ct_kill = iwl6000_set_ct_threshold, 267 .set_ct_kill = iwl6000_set_ct_threshold,
253 }, 268 },
269 .add_bcast_station = iwl_add_bcast_station,
254}; 270};
255 271
256static const struct iwl_ops iwl6000_ops = { 272static const struct iwl_ops iwl6000_ops = {
@@ -307,6 +323,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
307 .supports_idle = true, 323 .supports_idle = true,
308 .adv_thermal_throttle = true, 324 .adv_thermal_throttle = true,
309 .support_ct_kill_exit = true, 325 .support_ct_kill_exit = true,
326 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
310}; 327};
311 328
312struct iwl_cfg iwl6000i_2abg_cfg = { 329struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -336,6 +353,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
336 .supports_idle = true, 353 .supports_idle = true,
337 .adv_thermal_throttle = true, 354 .adv_thermal_throttle = true,
338 .support_ct_kill_exit = true, 355 .support_ct_kill_exit = true,
356 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
339}; 357};
340 358
341struct iwl_cfg iwl6000i_2bg_cfg = { 359struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -365,6 +383,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
365 .supports_idle = true, 383 .supports_idle = true,
366 .adv_thermal_throttle = true, 384 .adv_thermal_throttle = true,
367 .support_ct_kill_exit = true, 385 .support_ct_kill_exit = true,
386 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
368}; 387};
369 388
370struct iwl_cfg iwl6050_2agn_cfg = { 389struct iwl_cfg iwl6050_2agn_cfg = {
@@ -395,6 +414,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
395 .supports_idle = true, 414 .supports_idle = true,
396 .adv_thermal_throttle = true, 415 .adv_thermal_throttle = true,
397 .support_ct_kill_exit = true, 416 .support_ct_kill_exit = true,
417 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
398}; 418};
399 419
400struct iwl_cfg iwl6050_2abg_cfg = { 420struct iwl_cfg iwl6050_2abg_cfg = {
@@ -424,6 +444,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
424 .supports_idle = true, 444 .supports_idle = true,
425 .adv_thermal_throttle = true, 445 .adv_thermal_throttle = true,
426 .support_ct_kill_exit = true, 446 .support_ct_kill_exit = true,
447 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
427}; 448};
428 449
429struct iwl_cfg iwl6000_3agn_cfg = { 450struct iwl_cfg iwl6000_3agn_cfg = {
@@ -454,6 +475,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
454 .supports_idle = true, 475 .supports_idle = true,
455 .adv_thermal_throttle = true, 476 .adv_thermal_throttle = true,
456 .support_ct_kill_exit = true, 477 .support_ct_kill_exit = true,
478 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
457}; 479};
458 480
459MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 481MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
index 3bccba20f6da..1a24946bc203 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
index ab55f92a161d..a594e4fdc6b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index b93e49158196..6aebcedaca8d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index affc0c5a2f2c..e71923961e69 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -191,7 +191,7 @@ enum {
191 IWL_RATE_2M_MASK) 191 IWL_RATE_2M_MASK)
192 192
193#define IWL_CCK_RATES_MASK \ 193#define IWL_CCK_RATES_MASK \
194 (IWL_BASIC_RATES_MASK | \ 194 (IWL_CCK_BASIC_RATES_MASK | \
195 IWL_RATE_5M_MASK | \ 195 IWL_RATE_5M_MASK | \
196 IWL_RATE_11M_MASK) 196 IWL_RATE_11M_MASK)
197 197
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 344e99de4cab..d0268280d679 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -73,13 +73,7 @@
73#define VD 73#define VD
74#endif 74#endif
75 75
76#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT 76#define DRV_VERSION IWLWIFI_VERSION VD
77#define VS "s"
78#else
79#define VS
80#endif
81
82#define DRV_VERSION IWLWIFI_VERSION VD VS
83 77
84 78
85MODULE_DESCRIPTION(DRV_DESCRIPTION); 79MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -203,7 +197,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
203 priv->start_calib = 0; 197 priv->start_calib = 0;
204 198
205 /* Add the broadcast address so we can send broadcast frames */ 199 /* Add the broadcast address so we can send broadcast frames */
206 iwl_add_bcast_station(priv); 200 priv->cfg->ops->lib->add_bcast_station(priv);
201
207 202
208 /* If we have set the ASSOC_MSK and we are in BSS mode then 203 /* If we have set the ASSOC_MSK and we are in BSS mode then
209 * add the IWL_AP_ID to the station rate table */ 204 * add the IWL_AP_ID to the station rate table */
@@ -704,7 +699,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
704 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 699 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
705} 700}
706 701
707void iwl_continuous_event_trace(struct iwl_priv *priv) 702static void iwl_continuous_event_trace(struct iwl_priv *priv)
708{ 703{
709 u32 capacity; /* event log capacity in # entries */ 704 u32 capacity; /* event log capacity in # entries */
710 u32 base; /* SRAM byte address of event log header */ 705 u32 base; /* SRAM byte address of event log header */
@@ -888,6 +883,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
888 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 883 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
889 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 884 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
890 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 885 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
886 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
887 iwl_rx_spectrum_measure_notif;
891 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 888 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
892 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 889 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
893 iwl_rx_pm_debug_statistics_notif; 890 iwl_rx_pm_debug_statistics_notif;
@@ -901,7 +898,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
901 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; 898 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
902 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 899 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
903 900
904 iwl_setup_spectrum_handlers(priv);
905 iwl_setup_rx_scan_handlers(priv); 901 iwl_setup_rx_scan_handlers(priv);
906 902
907 /* status change handler */ 903 /* status change handler */
@@ -1761,7 +1757,7 @@ static const char *desc_lookup_text[] = {
1761 "DEBUG_1", 1757 "DEBUG_1",
1762 "DEBUG_2", 1758 "DEBUG_2",
1763 "DEBUG_3", 1759 "DEBUG_3",
1764 "UNKNOWN" 1760 "ADVANCED SYSASSERT"
1765}; 1761};
1766 1762
1767static const char *desc_lookup(int i) 1763static const char *desc_lookup(int i)
@@ -1965,7 +1961,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1965 IWL_ERR(priv, 1961 IWL_ERR(priv,
1966 "Invalid event log pointer 0x%08X for %s uCode\n", 1962 "Invalid event log pointer 0x%08X for %s uCode\n",
1967 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); 1963 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1968 return pos; 1964 return -EINVAL;
1969 } 1965 }
1970 1966
1971 /* event log header */ 1967 /* event log header */
@@ -2013,7 +2009,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2013 bufsz = size * 48; 2009 bufsz = size * 48;
2014 *buf = kmalloc(bufsz, GFP_KERNEL); 2010 *buf = kmalloc(bufsz, GFP_KERNEL);
2015 if (!*buf) 2011 if (!*buf)
2016 return pos; 2012 return -ENOMEM;
2017 } 2013 }
2018 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 2014 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
2019 /* 2015 /*
@@ -2443,18 +2439,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2443 return; 2439 return;
2444} 2440}
2445 2441
2446static void iwl_bg_up(struct work_struct *data)
2447{
2448 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
2449
2450 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2451 return;
2452
2453 mutex_lock(&priv->mutex);
2454 __iwl_up(priv);
2455 mutex_unlock(&priv->mutex);
2456}
2457
2458static void iwl_bg_restart(struct work_struct *data) 2442static void iwl_bg_restart(struct work_struct *data)
2459{ 2443{
2460 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 2444 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2471,7 +2455,13 @@ static void iwl_bg_restart(struct work_struct *data)
2471 ieee80211_restart_hw(priv->hw); 2455 ieee80211_restart_hw(priv->hw);
2472 } else { 2456 } else {
2473 iwl_down(priv); 2457 iwl_down(priv);
2474 queue_work(priv->workqueue, &priv->up); 2458
2459 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2460 return;
2461
2462 mutex_lock(&priv->mutex);
2463 __iwl_up(priv);
2464 mutex_unlock(&priv->mutex);
2475 } 2465 }
2476} 2466}
2477 2467
@@ -2607,7 +2597,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2607 * Not a mac80211 entry point function, but it fits in with all the 2597 * Not a mac80211 entry point function, but it fits in with all the
2608 * other mac80211 functions grouped here. 2598 * other mac80211 functions grouped here.
2609 */ 2599 */
2610static int iwl_setup_mac(struct iwl_priv *priv) 2600static int iwl_mac_setup_register(struct iwl_priv *priv)
2611{ 2601{
2612 int ret; 2602 int ret;
2613 struct ieee80211_hw *hw = priv->hw; 2603 struct ieee80211_hw *hw = priv->hw;
@@ -2839,14 +2829,18 @@ void iwl_config_ap(struct iwl_priv *priv)
2839} 2829}
2840 2830
2841static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, 2831static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
2842 struct ieee80211_key_conf *keyconf, const u8 *addr, 2832 struct ieee80211_vif *vif,
2843 u32 iv32, u16 *phase1key) 2833 struct ieee80211_key_conf *keyconf,
2834 struct ieee80211_sta *sta,
2835 u32 iv32, u16 *phase1key)
2844{ 2836{
2845 2837
2846 struct iwl_priv *priv = hw->priv; 2838 struct iwl_priv *priv = hw->priv;
2847 IWL_DEBUG_MAC80211(priv, "enter\n"); 2839 IWL_DEBUG_MAC80211(priv, "enter\n");
2848 2840
2849 iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key); 2841 iwl_update_tkip_key(priv, keyconf,
2842 sta ? sta->addr : iwl_bcast_addr,
2843 iv32, phase1key);
2850 2844
2851 IWL_DEBUG_MAC80211(priv, "leave\n"); 2845 IWL_DEBUG_MAC80211(priv, "leave\n");
2852} 2846}
@@ -3007,6 +3001,8 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3007 break; 3001 break;
3008 case STA_NOTIFY_AWAKE: 3002 case STA_NOTIFY_AWAKE:
3009 WARN_ON(!sta_priv->client); 3003 WARN_ON(!sta_priv->client);
3004 if (!sta_priv->asleep)
3005 break;
3010 sta_priv->asleep = false; 3006 sta_priv->asleep = false;
3011 sta_id = iwl_find_station(priv, sta->addr); 3007 sta_id = iwl_find_station(priv, sta->addr);
3012 if (sta_id != IWL_INVALID_STATION) 3008 if (sta_id != IWL_INVALID_STATION)
@@ -3283,7 +3279,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3283 3279
3284 init_waitqueue_head(&priv->wait_command_queue); 3280 init_waitqueue_head(&priv->wait_command_queue);
3285 3281
3286 INIT_WORK(&priv->up, iwl_bg_up);
3287 INIT_WORK(&priv->restart, iwl_bg_restart); 3282 INIT_WORK(&priv->restart, iwl_bg_restart);
3288 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3283 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3289 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3284 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
@@ -3368,6 +3363,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3368 3363
3369 priv->iw_mode = NL80211_IFTYPE_STATION; 3364 priv->iw_mode = NL80211_IFTYPE_STATION;
3370 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 3365 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3366 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3371 3367
3372 /* Choose which receivers/antennas to use */ 3368 /* Choose which receivers/antennas to use */
3373 if (priv->cfg->ops->hcmd->set_rxon_chain) 3369 if (priv->cfg->ops->hcmd->set_rxon_chain)
@@ -3619,9 +3615,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3619 iwl_setup_deferred_work(priv); 3615 iwl_setup_deferred_work(priv);
3620 iwl_setup_rx_handlers(priv); 3616 iwl_setup_rx_handlers(priv);
3621 3617
3622 /********************************** 3618 /*********************************************
3623 * 8. Setup and register mac80211 3619 * 8. Enable interrupts and read RFKILL state
3624 **********************************/ 3620 *********************************************/
3625 3621
3626 /* enable interrupts if needed: hw bug w/a */ 3622 /* enable interrupts if needed: hw bug w/a */
3627 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); 3623 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
@@ -3632,14 +3628,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3632 3628
3633 iwl_enable_interrupts(priv); 3629 iwl_enable_interrupts(priv);
3634 3630
3635 err = iwl_setup_mac(priv);
3636 if (err)
3637 goto out_remove_sysfs;
3638
3639 err = iwl_dbgfs_register(priv, DRV_NAME);
3640 if (err)
3641 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3642
3643 /* If platform's RF_KILL switch is NOT set to KILL */ 3631 /* If platform's RF_KILL switch is NOT set to KILL */
3644 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) 3632 if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
3645 clear_bit(STATUS_RF_KILL_HW, &priv->status); 3633 clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -3651,6 +3639,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3651 3639
3652 iwl_power_initialize(priv); 3640 iwl_power_initialize(priv);
3653 iwl_tt_initialize(priv); 3641 iwl_tt_initialize(priv);
3642
3643 /**************************************************
3644 * 9. Setup and register with mac80211 and debugfs
3645 **************************************************/
3646 err = iwl_mac_setup_register(priv);
3647 if (err)
3648 goto out_remove_sysfs;
3649
3650 err = iwl_dbgfs_register(priv, DRV_NAME);
3651 if (err)
3652 IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
3653
3654 return 0; 3654 return 0;
3655 3655
3656 out_remove_sysfs: 3656 out_remove_sysfs:
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index dc61906290e8..845831ac053e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index b6cef989a796..2b7b1df83ba0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 3320cce3d57b..c2f31eb26bef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -2247,10 +2247,22 @@ struct iwl_link_quality_cmd {
2247 __le32 reserved2; 2247 __le32 reserved2;
2248} __attribute__ ((packed)); 2248} __attribute__ ((packed));
2249 2249
2250/*
2251 * BT configuration enable flags:
2252 * bit 0 - 1: BT channel announcement enabled
2253 * 0: disable
2254 * bit 1 - 1: priority of BT device enabled
2255 * 0: disable
2256 * bit 2 - 1: BT 2 wire support enabled
2257 * 0: disable
2258 */
2259#define BT_COEX_DISABLE (0x0)
2260#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0)
2261#define BT_ENABLE_PRIORITY BIT(1)
2262#define BT_ENABLE_2_WIRE BIT(2)
2263
2250#define BT_COEX_DISABLE (0x0) 2264#define BT_COEX_DISABLE (0x0)
2251#define BT_COEX_MODE_2W (0x1) 2265#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY)
2252#define BT_COEX_MODE_3W (0x2)
2253#define BT_COEX_MODE_4W (0x3)
2254 2266
2255#define BT_LEAD_TIME_MIN (0x0) 2267#define BT_LEAD_TIME_MIN (0x0)
2256#define BT_LEAD_TIME_DEF (0x1E) 2268#define BT_LEAD_TIME_DEF (0x1E)
@@ -3095,7 +3107,12 @@ struct statistics_general {
3095 __le32 ttl_timestamp; 3107 __le32 ttl_timestamp;
3096 struct statistics_div div; 3108 struct statistics_div div;
3097 __le32 rx_enable_counter; 3109 __le32 rx_enable_counter;
3098 __le32 reserved1; 3110 /*
3111 * num_of_sos_states:
3112 * count the number of times we have to re-tune
3113 * in order to get out of bad PHY status
3114 */
3115 __le32 num_of_sos_states;
3099 __le32 reserved2; 3116 __le32 reserved2;
3100 __le32 reserved3; 3117 __le32 reserved3;
3101} __attribute__ ((packed)); 3118} __attribute__ ((packed));
@@ -3160,13 +3177,30 @@ struct iwl_notif_statistics {
3160 3177
3161/* 3178/*
3162 * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) 3179 * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
3180 *
3181 * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed
3182 * in regardless of how many missed beacons, which mean when driver receive the
3183 * notification, inside the command, it can find all the beacons information
3184 * which include number of total missed beacons, number of consecutive missed
3185 * beacons, number of beacons received and number of beacons expected to
3186 * receive.
3187 *
3188 * If uCode detected consecutive_missed_beacons > 5, it will reset the radio
3189 * in order to bring the radio/PHY back to working state; which has no relation
3190 * to when driver will perform sensitivity calibration.
3191 *
3192 * Driver should set it own missed_beacon_threshold to decide when to perform
3193 * sensitivity calibration based on number of consecutive missed beacons in
3194 * order to improve overall performance, especially in noisy environment.
3195 *
3163 */ 3196 */
3164/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, 3197
3165 * then this notification will be sent. */ 3198#define IWL_MISSED_BEACON_THRESHOLD_MIN (1)
3166#define CONSECUTIVE_MISSED_BCONS_TH 20 3199#define IWL_MISSED_BEACON_THRESHOLD_DEF (5)
3200#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF
3167 3201
3168struct iwl_missed_beacon_notif { 3202struct iwl_missed_beacon_notif {
3169 __le32 consequtive_missed_beacons; 3203 __le32 consecutive_missed_beacons;
3170 __le32 total_missed_becons; 3204 __le32 total_missed_becons;
3171 __le32 num_expected_beacons; 3205 __le32 num_expected_beacons;
3172 __le32 num_recvd_beacons; 3206 __le32 num_recvd_beacons;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5b56307a3812..02bf17ecaf54 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of version 2 of the GNU General Public License as
@@ -47,6 +47,26 @@ MODULE_VERSION(IWLWIFI_VERSION);
47MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 47MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50/*
51 * set bt_coex_active to true, uCode will do kill/defer
52 * every time the priority line is asserted (BT is sending signals on the
53 * priority line in the PCIx).
54 * set bt_coex_active to false, uCode will ignore the BT activity and
55 * perform the normal operation
56 *
57 * User might experience transmit issue on some platform due to WiFi/BT
58 * co-exist problem. The possible behaviors are:
59 * Able to scan and finding all the available AP
60 * Not able to associate with any AP
61 * On those platforms, WiFi communication can be restored by set
62 * "bt_coex_active" module parameter to "false"
63 *
64 * default: bt_coex_active = true (BT_COEX_ENABLE)
65 */
66static bool bt_coex_active = true;
67module_param(bt_coex_active, bool, S_IRUGO);
68MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n");
69
50static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { 70static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
51 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 71 {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
52 0, COEX_UNASSOC_IDLE_FLAGS}, 72 0, COEX_UNASSOC_IDLE_FLAGS},
@@ -257,8 +277,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
257 spin_lock_irqsave(&priv->lock, flags); 277 spin_lock_irqsave(&priv->lock, flags);
258 priv->cfg->ops->lib->apm_ops.init(priv); 278 priv->cfg->ops->lib->apm_ops.init(priv);
259 279
260 /* Set interrupt coalescing timer to 512 usecs */ 280 /* Set interrupt coalescing calibration timer to default (512 usecs) */
261 iwl_write8(priv, CSR_INT_COALESCING, 512 / 32); 281 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
262 282
263 spin_unlock_irqrestore(&priv->lock, flags); 283 spin_unlock_irqrestore(&priv->lock, flags);
264 284
@@ -1353,6 +1373,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1353 priv->cfg->ops->lib->dump_nic_error_log(priv); 1373 priv->cfg->ops->lib->dump_nic_error_log(priv);
1354 if (priv->cfg->ops->lib->dump_csr) 1374 if (priv->cfg->ops->lib->dump_csr)
1355 priv->cfg->ops->lib->dump_csr(priv); 1375 priv->cfg->ops->lib->dump_csr(priv);
1376 if (priv->cfg->ops->lib->dump_fh)
1377 priv->cfg->ops->lib->dump_fh(priv, NULL, false);
1356 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); 1378 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1357#ifdef CONFIG_IWLWIFI_DEBUG 1379#ifdef CONFIG_IWLWIFI_DEBUG
1358 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1380 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
@@ -1803,6 +1825,16 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
1803 if (val == 0xffffffff) 1825 if (val == 0xffffffff)
1804 val = 0; 1826 val = 0;
1805 1827
1828 /*
1829 * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
1830 * (bit 15 before shifting it to 31) to clear when using interrupt
1831 * coalescing. fortunately, bits 18 and 19 stay set when this happens
1832 * so we use them to decide on the real state of the Rx bit.
1833 * In order words, bit 15 is set if bit 18 or bit 19 are set.
1834 */
1835 if (val & 0xC0000)
1836 val |= 0x8000;
1837
1806 inta = (0xff & val) | ((0xff00 & val) << 16); 1838 inta = (0xff & val) | ((0xff00 & val) << 16);
1807 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", 1839 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
1808 inta, inta_mask, val); 1840 inta, inta_mask, val);
@@ -1965,13 +1997,20 @@ EXPORT_SYMBOL(iwl_isr_legacy);
1965int iwl_send_bt_config(struct iwl_priv *priv) 1997int iwl_send_bt_config(struct iwl_priv *priv)
1966{ 1998{
1967 struct iwl_bt_cmd bt_cmd = { 1999 struct iwl_bt_cmd bt_cmd = {
1968 .flags = BT_COEX_MODE_4W,
1969 .lead_time = BT_LEAD_TIME_DEF, 2000 .lead_time = BT_LEAD_TIME_DEF,
1970 .max_kill = BT_MAX_KILL_DEF, 2001 .max_kill = BT_MAX_KILL_DEF,
1971 .kill_ack_mask = 0, 2002 .kill_ack_mask = 0,
1972 .kill_cts_mask = 0, 2003 .kill_cts_mask = 0,
1973 }; 2004 };
1974 2005
2006 if (!bt_coex_active)
2007 bt_cmd.flags = BT_COEX_DISABLE;
2008 else
2009 bt_cmd.flags = BT_COEX_ENABLE;
2010
2011 IWL_DEBUG_INFO(priv, "BT coex %s\n",
2012 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
2013
1975 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, 2014 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
1976 sizeof(struct iwl_bt_cmd), &bt_cmd); 2015 sizeof(struct iwl_bt_cmd), &bt_cmd);
1977} 2016}
@@ -2592,23 +2631,21 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2592 struct ieee80211_vif *vif) 2631 struct ieee80211_vif *vif)
2593{ 2632{
2594 struct iwl_priv *priv = hw->priv; 2633 struct iwl_priv *priv = hw->priv;
2595 unsigned long flags; 2634 int err = 0;
2596 2635
2597 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type); 2636 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
2598 2637
2638 mutex_lock(&priv->mutex);
2639
2599 if (priv->vif) { 2640 if (priv->vif) {
2600 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2641 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2601 return -EOPNOTSUPP; 2642 err = -EOPNOTSUPP;
2643 goto out;
2602 } 2644 }
2603 2645
2604 spin_lock_irqsave(&priv->lock, flags);
2605 priv->vif = vif; 2646 priv->vif = vif;
2606 priv->iw_mode = vif->type; 2647 priv->iw_mode = vif->type;
2607 2648
2608 spin_unlock_irqrestore(&priv->lock, flags);
2609
2610 mutex_lock(&priv->mutex);
2611
2612 if (vif->addr) { 2649 if (vif->addr) {
2613 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); 2650 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2614 memcpy(priv->mac_addr, vif->addr, ETH_ALEN); 2651 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
@@ -2618,10 +2655,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2618 /* we are not ready, will run again when ready */ 2655 /* we are not ready, will run again when ready */
2619 set_bit(STATUS_MODE_PENDING, &priv->status); 2656 set_bit(STATUS_MODE_PENDING, &priv->status);
2620 2657
2658 out:
2621 mutex_unlock(&priv->mutex); 2659 mutex_unlock(&priv->mutex);
2622 2660
2623 IWL_DEBUG_MAC80211(priv, "leave\n"); 2661 IWL_DEBUG_MAC80211(priv, "leave\n");
2624 return 0; 2662 return err;
2625} 2663}
2626EXPORT_SYMBOL(iwl_mac_add_interface); 2664EXPORT_SYMBOL(iwl_mac_add_interface);
2627 2665
@@ -3268,6 +3306,93 @@ void iwl_dump_csr(struct iwl_priv *priv)
3268} 3306}
3269EXPORT_SYMBOL(iwl_dump_csr); 3307EXPORT_SYMBOL(iwl_dump_csr);
3270 3308
3309const static char *get_fh_string(int cmd)
3310{
3311 switch (cmd) {
3312 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
3313 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
3314 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
3315 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
3316 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
3317 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
3318 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
3319 IWL_CMD(FH_TSSR_TX_STATUS_REG);
3320 IWL_CMD(FH_TSSR_TX_ERROR_REG);
3321 default:
3322 return "UNKNOWN";
3323
3324 }
3325}
3326
3327int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
3328{
3329 int i;
3330#ifdef CONFIG_IWLWIFI_DEBUG
3331 int pos = 0;
3332 size_t bufsz = 0;
3333#endif
3334 u32 fh_tbl[] = {
3335 FH_RSCSR_CHNL0_STTS_WPTR_REG,
3336 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
3337 FH_RSCSR_CHNL0_WPTR,
3338 FH_MEM_RCSR_CHNL0_CONFIG_REG,
3339 FH_MEM_RSSR_SHARED_CTRL_REG,
3340 FH_MEM_RSSR_RX_STATUS_REG,
3341 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
3342 FH_TSSR_TX_STATUS_REG,
3343 FH_TSSR_TX_ERROR_REG
3344 };
3345#ifdef CONFIG_IWLWIFI_DEBUG
3346 if (display) {
3347 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
3348 *buf = kmalloc(bufsz, GFP_KERNEL);
3349 if (!*buf)
3350 return -ENOMEM;
3351 pos += scnprintf(*buf + pos, bufsz - pos,
3352 "FH register values:\n");
3353 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3354 pos += scnprintf(*buf + pos, bufsz - pos,
3355 " %34s: 0X%08x\n",
3356 get_fh_string(fh_tbl[i]),
3357 iwl_read_direct32(priv, fh_tbl[i]));
3358 }
3359 return pos;
3360 }
3361#endif
3362 IWL_ERR(priv, "FH register values:\n");
3363 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
3364 IWL_ERR(priv, " %34s: 0X%08x\n",
3365 get_fh_string(fh_tbl[i]),
3366 iwl_read_direct32(priv, fh_tbl[i]));
3367 }
3368 return 0;
3369}
3370EXPORT_SYMBOL(iwl_dump_fh);
3371
3372void iwl_force_rf_reset(struct iwl_priv *priv)
3373{
3374 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3375 return;
3376
3377 if (!iwl_is_associated(priv)) {
3378 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
3379 return;
3380 }
3381 /*
3382 * There is no easy and better way to force reset the radio,
3383 * the only known method is switching channel which will force to
3384 * reset and tune the radio.
3385 * Use internal short scan (single channel) operation to should
3386 * achieve this objective.
3387 * Driver should reset the radio when number of consecutive missed
3388 * beacon, or any other uCode error condition detected.
3389 */
3390 IWL_DEBUG_INFO(priv, "perform radio reset.\n");
3391 iwl_internal_short_hw_scan(priv);
3392 return;
3393}
3394EXPORT_SYMBOL(iwl_force_rf_reset);
3395
3271#ifdef CONFIG_PM 3396#ifdef CONFIG_PM
3272 3397
3273int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 3398int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 8deb83bfe182..ec1fe1d7cc9a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ struct iwl_cmd;
71 71
72 72
73#define IWLWIFI_VERSION "in-tree:" 73#define IWLWIFI_VERSION "in-tree:"
74#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" 74#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
75#define DRV_AUTHOR "<ilw@linux.intel.com>" 75#define DRV_AUTHOR "<ilw@linux.intel.com>"
76 76
77#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 77#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -171,6 +171,7 @@ struct iwl_lib_ops {
171 bool full_log, char **buf, bool display); 171 bool full_log, char **buf, bool display);
172 void (*dump_nic_error_log)(struct iwl_priv *priv); 172 void (*dump_nic_error_log)(struct iwl_priv *priv);
173 void (*dump_csr)(struct iwl_priv *priv); 173 void (*dump_csr)(struct iwl_priv *priv);
174 int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 175 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
175 /* power management */ 176 /* power management */
176 struct iwl_apm_ops apm_ops; 177 struct iwl_apm_ops apm_ops;
@@ -187,6 +188,8 @@ struct iwl_lib_ops {
187 188
188 /* temperature */ 189 /* temperature */
189 struct iwl_temp_ops temp_ops; 190 struct iwl_temp_ops temp_ops;
191 /* station management */
192 void (*add_bcast_station)(struct iwl_priv *priv);
190}; 193};
191 194
192struct iwl_led_ops { 195struct iwl_led_ops {
@@ -231,6 +234,8 @@ struct iwl_mod_params {
231 * @adv_thermal_throttle: support advance thermal throttle 234 * @adv_thermal_throttle: support advance thermal throttle
232 * @support_ct_kill_exit: support ct kill exit condition 235 * @support_ct_kill_exit: support ct kill exit condition
233 * @support_wimax_coexist: support wimax/wifi co-exist 236 * @support_wimax_coexist: support wimax/wifi co-exist
237 * @plcp_delta_threshold: plcp error rate threshold used to trigger
238 * radio tuning when there is a high receiving plcp error rate
234 * 239 *
235 * We enable the driver to be backward compatible wrt API version. The 240 * We enable the driver to be backward compatible wrt API version. The
236 * driver specifies which APIs it supports (with @ucode_api_max being the 241 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -287,6 +292,7 @@ struct iwl_cfg {
287 bool adv_thermal_throttle; 292 bool adv_thermal_throttle;
288 bool support_ct_kill_exit; 293 bool support_ct_kill_exit;
289 const bool support_wimax_coexist; 294 const bool support_wimax_coexist;
295 u8 plcp_delta_threshold;
290}; 296};
291 297
292/*************************** 298/***************************
@@ -423,6 +429,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
423/* Handlers */ 429/* Handlers */
424void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, 430void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
425 struct iwl_rx_mem_buffer *rxb); 431 struct iwl_rx_mem_buffer *rxb);
432void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
433 struct iwl_rx_mem_buffer *rxb);
426void iwl_rx_statistics(struct iwl_priv *priv, 434void iwl_rx_statistics(struct iwl_priv *priv,
427 struct iwl_rx_mem_buffer *rxb); 435 struct iwl_rx_mem_buffer *rxb);
428void iwl_reply_statistics(struct iwl_priv *priv, 436void iwl_reply_statistics(struct iwl_priv *priv,
@@ -493,6 +501,8 @@ void iwl_init_scan_params(struct iwl_priv *priv);
493int iwl_scan_cancel(struct iwl_priv *priv); 501int iwl_scan_cancel(struct iwl_priv *priv);
494int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); 502int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
495int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); 503int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
504int iwl_internal_short_hw_scan(struct iwl_priv *priv);
505void iwl_force_rf_reset(struct iwl_priv *priv);
496u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 506u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
497 const u8 *ie, int ie_len, int left); 507 const u8 *ie, int ie_len, int left);
498void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 508void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
@@ -523,14 +533,6 @@ int iwl_send_calib_results(struct iwl_priv *priv);
523int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); 533int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
524void iwl_calib_free_results(struct iwl_priv *priv); 534void iwl_calib_free_results(struct iwl_priv *priv);
525 535
526/*******************************************************************************
527 * Spectrum Measureemtns in iwl-spectrum.c
528 ******************************************************************************/
529#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
530void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
531#else
532static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
533#endif
534/***************************************************** 536/*****************************************************
535 * S e n d i n g H o s t C o m m a n d s * 537 * S e n d i n g H o s t C o m m a n d s *
536 *****************************************************/ 538 *****************************************************/
@@ -582,6 +584,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv);
582int iwl_dump_nic_event_log(struct iwl_priv *priv, 584int iwl_dump_nic_event_log(struct iwl_priv *priv,
583 bool full_log, char **buf, bool display); 585 bool full_log, char **buf, bool display);
584void iwl_dump_csr(struct iwl_priv *priv); 586void iwl_dump_csr(struct iwl_priv *priv);
587int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
585#ifdef CONFIG_IWLWIFI_DEBUG 588#ifdef CONFIG_IWLWIFI_DEBUG
586void iwl_print_rx_config_cmd(struct iwl_priv *priv); 589void iwl_print_rx_config_cmd(struct iwl_priv *priv);
587#else 590#else
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 1ec8cb4d5eae..1e00720bf8b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 58e0462cafa3..1c7b53d511c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
@@ -67,59 +67,6 @@ do { \
67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ 67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
68} while (0) 68} while (0)
69 69
70#ifdef CONFIG_IWLWIFI_DEBUGFS
71struct iwl_debugfs {
72 const char *name;
73 struct dentry *dir_drv;
74 struct dentry *dir_data;
75 struct dentry *dir_debug;
76 struct dentry *dir_rf;
77 struct dir_data_files {
78 struct dentry *file_sram;
79 struct dentry *file_nvm;
80 struct dentry *file_stations;
81 struct dentry *file_log_event;
82 struct dentry *file_channels;
83 struct dentry *file_status;
84 struct dentry *file_interrupt;
85 struct dentry *file_qos;
86 struct dentry *file_thermal_throttling;
87 struct dentry *file_led;
88 struct dentry *file_disable_ht40;
89 struct dentry *file_sleep_level_override;
90 struct dentry *file_current_sleep_command;
91 } dbgfs_data_files;
92 struct dir_rf_files {
93 struct dentry *file_disable_sensitivity;
94 struct dentry *file_disable_chain_noise;
95 struct dentry *file_disable_tx_power;
96 } dbgfs_rf_files;
97 struct dir_debug_files {
98 struct dentry *file_rx_statistics;
99 struct dentry *file_tx_statistics;
100 struct dentry *file_traffic_log;
101 struct dentry *file_rx_queue;
102 struct dentry *file_tx_queue;
103 struct dentry *file_ucode_rx_stats;
104 struct dentry *file_ucode_tx_stats;
105 struct dentry *file_ucode_general_stats;
106 struct dentry *file_sensitivity;
107 struct dentry *file_chain_noise;
108 struct dentry *file_tx_power;
109 struct dentry *file_power_save_status;
110 struct dentry *file_clear_ucode_statistics;
111 struct dentry *file_clear_traffic_statistics;
112 struct dentry *file_csr;
113 struct dentry *file_ucode_tracing;
114 } dbgfs_debug_files;
115 u32 sram_offset;
116 u32 sram_len;
117};
118
119int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
120void iwl_dbgfs_unregister(struct iwl_priv *priv);
121#endif
122
123#else 70#else
124#define IWL_DEBUG(__priv, level, fmt, args...) 71#define IWL_DEBUG(__priv, level, fmt, args...)
125#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) 72#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
@@ -128,9 +75,10 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
128{} 75{}
129#endif /* CONFIG_IWLWIFI_DEBUG */ 76#endif /* CONFIG_IWLWIFI_DEBUG */
130 77
131 78#ifdef CONFIG_IWLWIFI_DEBUGFS
132 79int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
133#ifndef CONFIG_IWLWIFI_DEBUGFS 80void iwl_dbgfs_unregister(struct iwl_priv *priv);
81#else
134static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 82static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
135{ 83{
136 return 0; 84 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 4a2ac9311ba8..d134301b553c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of version 2 of the GNU General Public License as
@@ -41,43 +41,28 @@
41#include "iwl-calib.h" 41#include "iwl-calib.h"
42 42
43/* create and remove of files */ 43/* create and remove of files */
44#define DEBUGFS_ADD_DIR(name, parent) do { \ 44#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
45 dbgfs->dir_##name = debugfs_create_dir(#name, parent); \ 45 if (!debugfs_create_file(#name, mode, parent, priv, \
46 if (!(dbgfs->dir_##name)) \ 46 &iwl_dbgfs_##name##_ops)) \
47 goto err; \ 47 goto err; \
48} while (0) 48} while (0)
49 49
50#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 50#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
51 dbgfs->dbgfs_##parent##_files.file_##name = \ 51 struct dentry *__tmp; \
52 debugfs_create_file(#name, mode, \ 52 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
53 dbgfs->dir_##parent, priv, \ 53 parent, ptr); \
54 &iwl_dbgfs_##name##_ops); \ 54 if (IS_ERR(__tmp) || !__tmp) \
55 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 55 goto err; \
56 goto err; \
57} while (0) 56} while (0)
58 57
59#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 58#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
60 dbgfs->dbgfs_##parent##_files.file_##name = \ 59 struct dentry *__tmp; \
61 debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 60 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
62 dbgfs->dir_##parent, ptr); \ 61 parent, ptr); \
63 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 62 if (IS_ERR(__tmp) || !__tmp) \
64 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 63 goto err; \
65 goto err; \
66} while (0) 64} while (0)
67 65
68#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
69 dbgfs->dbgfs_##parent##_files.file_##name = \
70 debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \
71 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
72 || !dbgfs->dbgfs_##parent##_files.file_##name) \
73 goto err; \
74} while (0)
75
76#define DEBUGFS_REMOVE(name) do { \
77 debugfs_remove(name); \
78 name = NULL; \
79} while (0);
80
81/* file operation */ 66/* file operation */
82#define DEBUGFS_READ_FUNC(name) \ 67#define DEBUGFS_READ_FUNC(name) \
83static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 68static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
@@ -236,24 +221,24 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
236 size_t bufsz; 221 size_t bufsz;
237 222
238 /* default is to dump the entire data segment */ 223 /* default is to dump the entire data segment */
239 if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) { 224 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
240 priv->dbgfs->sram_offset = 0x800000; 225 priv->dbgfs_sram_offset = 0x800000;
241 if (priv->ucode_type == UCODE_INIT) 226 if (priv->ucode_type == UCODE_INIT)
242 priv->dbgfs->sram_len = priv->ucode_init_data.len; 227 priv->dbgfs_sram_len = priv->ucode_init_data.len;
243 else 228 else
244 priv->dbgfs->sram_len = priv->ucode_data.len; 229 priv->dbgfs_sram_len = priv->ucode_data.len;
245 } 230 }
246 bufsz = 30 + priv->dbgfs->sram_len * sizeof(char) * 10; 231 bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10;
247 buf = kmalloc(bufsz, GFP_KERNEL); 232 buf = kmalloc(bufsz, GFP_KERNEL);
248 if (!buf) 233 if (!buf)
249 return -ENOMEM; 234 return -ENOMEM;
250 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 235 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
251 priv->dbgfs->sram_len); 236 priv->dbgfs_sram_len);
252 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 237 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
253 priv->dbgfs->sram_offset); 238 priv->dbgfs_sram_offset);
254 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 239 for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
255 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 240 val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
256 priv->dbgfs->sram_len - i); 241 priv->dbgfs_sram_len - i);
257 if (i < 4) { 242 if (i < 4) {
258 switch (i) { 243 switch (i) {
259 case 1: 244 case 1:
@@ -293,11 +278,11 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
293 return -EFAULT; 278 return -EFAULT;
294 279
295 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 280 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
296 priv->dbgfs->sram_offset = offset; 281 priv->dbgfs_sram_offset = offset;
297 priv->dbgfs->sram_len = len; 282 priv->dbgfs_sram_len = len;
298 } else { 283 } else {
299 priv->dbgfs->sram_offset = 0; 284 priv->dbgfs_sram_offset = 0;
300 priv->dbgfs->sram_len = 0; 285 priv->dbgfs_sram_len = 0;
301 } 286 }
302 287
303 return count; 288 return count;
@@ -429,8 +414,9 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file,
429 int pos = 0; 414 int pos = 0;
430 ssize_t ret = -ENOMEM; 415 ssize_t ret = -ENOMEM;
431 416
432 pos = priv->cfg->ops->lib->dump_nic_event_log(priv, true, &buf, true); 417 ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
433 if (pos && buf) { 418 priv, true, &buf, true);
419 if (buf) {
434 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 420 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
435 kfree(buf); 421 kfree(buf);
436 } 422 }
@@ -829,7 +815,9 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
829 815
830 priv->power_data.debug_sleep_level_override = value; 816 priv->power_data.debug_sleep_level_override = value;
831 817
818 mutex_lock(&priv->mutex);
832 iwl_power_update_mode(priv, true); 819 iwl_power_update_mode(priv, true);
820 mutex_unlock(&priv->mutex);
833 821
834 return count; 822 return count;
835} 823}
@@ -1081,6 +1069,12 @@ static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1081 return p; 1069 return p;
1082} 1070}
1083 1071
1072static const char ucode_stats_header[] =
1073 "%-32s current acumulative delta max\n";
1074static const char ucode_stats_short_format[] =
1075 " %-30s %10u\n";
1076static const char ucode_stats_format[] =
1077 " %-30s %10u %10u %10u %10u\n";
1084 1078
1085static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1079static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1086 char __user *user_buf, 1080 char __user *user_buf,
@@ -1089,28 +1083,19 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1089 struct iwl_priv *priv = file->private_data; 1083 struct iwl_priv *priv = file->private_data;
1090 int pos = 0; 1084 int pos = 0;
1091 char *buf; 1085 char *buf;
1092 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1086 int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1093 sizeof(struct statistics_rx_non_phy) * 20 + 1087 sizeof(struct statistics_rx_non_phy) * 40 +
1094 sizeof(struct statistics_rx_ht_phy) * 20 + 400; 1088 sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1095 ssize_t ret; 1089 ssize_t ret;
1096 struct statistics_rx_phy *ofdm, *accum_ofdm; 1090 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1097 struct statistics_rx_phy *cck, *accum_cck; 1091 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1098 struct statistics_rx_non_phy *general, *accum_general; 1092 struct statistics_rx_non_phy *general, *accum_general;
1099 struct statistics_rx_ht_phy *ht, *accum_ht; 1093 struct statistics_rx_non_phy *delta_general, *max_general;
1094 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1100 1095
1101 if (!iwl_is_alive(priv)) 1096 if (!iwl_is_alive(priv))
1102 return -EAGAIN; 1097 return -EAGAIN;
1103 1098
1104 /* make request to uCode to retrieve statistics information */
1105 mutex_lock(&priv->mutex);
1106 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1107 mutex_unlock(&priv->mutex);
1108
1109 if (ret) {
1110 IWL_ERR(priv,
1111 "Error sending statistics request: %zd\n", ret);
1112 return -EAGAIN;
1113 }
1114 buf = kzalloc(bufsz, GFP_KERNEL); 1099 buf = kzalloc(bufsz, GFP_KERNEL);
1115 if (!buf) { 1100 if (!buf) {
1116 IWL_ERR(priv, "Can not allocate Buffer\n"); 1101 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1129,267 +1114,401 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1129 accum_cck = &priv->accum_statistics.rx.cck; 1114 accum_cck = &priv->accum_statistics.rx.cck;
1130 accum_general = &priv->accum_statistics.rx.general; 1115 accum_general = &priv->accum_statistics.rx.general;
1131 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 1116 accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1117 delta_ofdm = &priv->delta_statistics.rx.ofdm;
1118 delta_cck = &priv->delta_statistics.rx.cck;
1119 delta_general = &priv->delta_statistics.rx.general;
1120 delta_ht = &priv->delta_statistics.rx.ofdm_ht;
1121 max_ofdm = &priv->max_delta.rx.ofdm;
1122 max_cck = &priv->max_delta.rx.cck;
1123 max_general = &priv->max_delta.rx.general;
1124 max_ht = &priv->max_delta.rx.ofdm_ht;
1125
1132 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1126 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1133 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); 1127 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1134 pos += scnprintf(buf + pos, bufsz - pos, 1128 "Statistics_Rx - OFDM:");
1135 "\t\t\tcurrent\t\t\taccumulative\n"); 1129 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1136 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1130 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
1137 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); 1131 accum_ofdm->ina_cnt,
1138 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1132 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1139 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); 1133 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1140 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1134 "fina_cnt:",
1141 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); 1135 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1142 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1136 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1143 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); 1137 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1144 pos += scnprintf(buf + pos, bufsz - pos, 1138 "plcp_err:",
1145 "overrun_err:\t\t%u\t\t\t%u\n", 1139 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1140 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1141 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1142 "crc32_err:",
1143 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1144 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1145 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1146 "overrun_err:",
1146 le32_to_cpu(ofdm->overrun_err), 1147 le32_to_cpu(ofdm->overrun_err),
1147 accum_ofdm->overrun_err); 1148 accum_ofdm->overrun_err,
1148 pos += scnprintf(buf + pos, bufsz - pos, 1149 delta_ofdm->overrun_err, max_ofdm->overrun_err);
1149 "early_overrun_err:\t%u\t\t\t%u\n", 1150 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1151 "early_overrun_err:",
1150 le32_to_cpu(ofdm->early_overrun_err), 1152 le32_to_cpu(ofdm->early_overrun_err),
1151 accum_ofdm->early_overrun_err); 1153 accum_ofdm->early_overrun_err,
1152 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1154 delta_ofdm->early_overrun_err,
1155 max_ofdm->early_overrun_err);
1156 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1157 "crc32_good:",
1153 le32_to_cpu(ofdm->crc32_good), 1158 le32_to_cpu(ofdm->crc32_good),
1154 accum_ofdm->crc32_good); 1159 accum_ofdm->crc32_good,
1155 pos += scnprintf(buf + pos, bufsz - pos, 1160 delta_ofdm->crc32_good, max_ofdm->crc32_good);
1156 "false_alarm_cnt:\t%u\t\t\t%u\n", 1161 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1162 "false_alarm_cnt:",
1157 le32_to_cpu(ofdm->false_alarm_cnt), 1163 le32_to_cpu(ofdm->false_alarm_cnt),
1158 accum_ofdm->false_alarm_cnt); 1164 accum_ofdm->false_alarm_cnt,
1159 pos += scnprintf(buf + pos, bufsz - pos, 1165 delta_ofdm->false_alarm_cnt,
1160 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1166 max_ofdm->false_alarm_cnt);
1167 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1168 "fina_sync_err_cnt:",
1161 le32_to_cpu(ofdm->fina_sync_err_cnt), 1169 le32_to_cpu(ofdm->fina_sync_err_cnt),
1162 accum_ofdm->fina_sync_err_cnt); 1170 accum_ofdm->fina_sync_err_cnt,
1163 pos += scnprintf(buf + pos, bufsz - pos, 1171 delta_ofdm->fina_sync_err_cnt,
1164 "sfd_timeout:\t\t%u\t\t\t%u\n", 1172 max_ofdm->fina_sync_err_cnt);
1173 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1174 "sfd_timeout:",
1165 le32_to_cpu(ofdm->sfd_timeout), 1175 le32_to_cpu(ofdm->sfd_timeout),
1166 accum_ofdm->sfd_timeout); 1176 accum_ofdm->sfd_timeout,
1167 pos += scnprintf(buf + pos, bufsz - pos, 1177 delta_ofdm->sfd_timeout,
1168 "fina_timeout:\t\t%u\t\t\t%u\n", 1178 max_ofdm->sfd_timeout);
1179 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1180 "fina_timeout:",
1169 le32_to_cpu(ofdm->fina_timeout), 1181 le32_to_cpu(ofdm->fina_timeout),
1170 accum_ofdm->fina_timeout); 1182 accum_ofdm->fina_timeout,
1171 pos += scnprintf(buf + pos, bufsz - pos, 1183 delta_ofdm->fina_timeout,
1172 "unresponded_rts:\t%u\t\t\t%u\n", 1184 max_ofdm->fina_timeout);
1185 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1186 "unresponded_rts:",
1173 le32_to_cpu(ofdm->unresponded_rts), 1187 le32_to_cpu(ofdm->unresponded_rts),
1174 accum_ofdm->unresponded_rts); 1188 accum_ofdm->unresponded_rts,
1175 pos += scnprintf(buf + pos, bufsz - pos, 1189 delta_ofdm->unresponded_rts,
1176 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1190 max_ofdm->unresponded_rts);
1191 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1192 "rxe_frame_lmt_ovrun:",
1177 le32_to_cpu(ofdm->rxe_frame_limit_overrun), 1193 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1178 accum_ofdm->rxe_frame_limit_overrun); 1194 accum_ofdm->rxe_frame_limit_overrun,
1179 pos += scnprintf(buf + pos, bufsz - pos, 1195 delta_ofdm->rxe_frame_limit_overrun,
1180 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1196 max_ofdm->rxe_frame_limit_overrun);
1197 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1198 "sent_ack_cnt:",
1181 le32_to_cpu(ofdm->sent_ack_cnt), 1199 le32_to_cpu(ofdm->sent_ack_cnt),
1182 accum_ofdm->sent_ack_cnt); 1200 accum_ofdm->sent_ack_cnt,
1183 pos += scnprintf(buf + pos, bufsz - pos, 1201 delta_ofdm->sent_ack_cnt,
1184 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1202 max_ofdm->sent_ack_cnt);
1203 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1204 "sent_cts_cnt:",
1185 le32_to_cpu(ofdm->sent_cts_cnt), 1205 le32_to_cpu(ofdm->sent_cts_cnt),
1186 accum_ofdm->sent_cts_cnt); 1206 accum_ofdm->sent_cts_cnt,
1187 pos += scnprintf(buf + pos, bufsz - pos, 1207 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1188 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1208 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1209 "sent_ba_rsp_cnt:",
1189 le32_to_cpu(ofdm->sent_ba_rsp_cnt), 1210 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1190 accum_ofdm->sent_ba_rsp_cnt); 1211 accum_ofdm->sent_ba_rsp_cnt,
1191 pos += scnprintf(buf + pos, bufsz - pos, 1212 delta_ofdm->sent_ba_rsp_cnt,
1192 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1213 max_ofdm->sent_ba_rsp_cnt);
1214 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1215 "dsp_self_kill:",
1193 le32_to_cpu(ofdm->dsp_self_kill), 1216 le32_to_cpu(ofdm->dsp_self_kill),
1194 accum_ofdm->dsp_self_kill); 1217 accum_ofdm->dsp_self_kill,
1195 pos += scnprintf(buf + pos, bufsz - pos, 1218 delta_ofdm->dsp_self_kill,
1196 "mh_format_err:\t\t%u\t\t\t%u\n", 1219 max_ofdm->dsp_self_kill);
1220 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1221 "mh_format_err:",
1197 le32_to_cpu(ofdm->mh_format_err), 1222 le32_to_cpu(ofdm->mh_format_err),
1198 accum_ofdm->mh_format_err); 1223 accum_ofdm->mh_format_err,
1199 pos += scnprintf(buf + pos, bufsz - pos, 1224 delta_ofdm->mh_format_err,
1200 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1225 max_ofdm->mh_format_err);
1226 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1227 "re_acq_main_rssi_sum:",
1201 le32_to_cpu(ofdm->re_acq_main_rssi_sum), 1228 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1202 accum_ofdm->re_acq_main_rssi_sum); 1229 accum_ofdm->re_acq_main_rssi_sum,
1203 1230 delta_ofdm->re_acq_main_rssi_sum,
1204 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); 1231 max_ofdm->re_acq_main_rssi_sum);
1205 pos += scnprintf(buf + pos, bufsz - pos, 1232
1206 "\t\t\tcurrent\t\t\taccumulative\n"); 1233 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1207 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1234 "Statistics_Rx - CCK:");
1208 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); 1235 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1209 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1236 "ina_cnt:",
1210 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); 1237 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1211 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1238 delta_cck->ina_cnt, max_cck->ina_cnt);
1212 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); 1239 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1213 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1240 "fina_cnt:",
1214 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); 1241 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1215 pos += scnprintf(buf + pos, bufsz - pos, 1242 delta_cck->fina_cnt, max_cck->fina_cnt);
1216 "overrun_err:\t\t%u\t\t\t%u\n", 1243 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1244 "plcp_err:",
1245 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1246 delta_cck->plcp_err, max_cck->plcp_err);
1247 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1248 "crc32_err:",
1249 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1250 delta_cck->crc32_err, max_cck->crc32_err);
1251 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1252 "overrun_err:",
1217 le32_to_cpu(cck->overrun_err), 1253 le32_to_cpu(cck->overrun_err),
1218 accum_cck->overrun_err); 1254 accum_cck->overrun_err,
1219 pos += scnprintf(buf + pos, bufsz - pos, 1255 delta_cck->overrun_err, max_cck->overrun_err);
1220 "early_overrun_err:\t%u\t\t\t%u\n", 1256 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1257 "early_overrun_err:",
1221 le32_to_cpu(cck->early_overrun_err), 1258 le32_to_cpu(cck->early_overrun_err),
1222 accum_cck->early_overrun_err); 1259 accum_cck->early_overrun_err,
1223 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1260 delta_cck->early_overrun_err,
1224 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); 1261 max_cck->early_overrun_err);
1225 pos += scnprintf(buf + pos, bufsz - pos, 1262 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1226 "false_alarm_cnt:\t%u\t\t\t%u\n", 1263 "crc32_good:",
1264 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1265 delta_cck->crc32_good,
1266 max_cck->crc32_good);
1267 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1268 "false_alarm_cnt:",
1227 le32_to_cpu(cck->false_alarm_cnt), 1269 le32_to_cpu(cck->false_alarm_cnt),
1228 accum_cck->false_alarm_cnt); 1270 accum_cck->false_alarm_cnt,
1229 pos += scnprintf(buf + pos, bufsz - pos, 1271 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1230 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1272 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1273 "fina_sync_err_cnt:",
1231 le32_to_cpu(cck->fina_sync_err_cnt), 1274 le32_to_cpu(cck->fina_sync_err_cnt),
1232 accum_cck->fina_sync_err_cnt); 1275 accum_cck->fina_sync_err_cnt,
1233 pos += scnprintf(buf + pos, bufsz - pos, 1276 delta_cck->fina_sync_err_cnt,
1234 "sfd_timeout:\t\t%u\t\t\t%u\n", 1277 max_cck->fina_sync_err_cnt);
1278 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1279 "sfd_timeout:",
1235 le32_to_cpu(cck->sfd_timeout), 1280 le32_to_cpu(cck->sfd_timeout),
1236 accum_cck->sfd_timeout); 1281 accum_cck->sfd_timeout,
1237 pos += scnprintf(buf + pos, bufsz - pos, 1282 delta_cck->sfd_timeout, max_cck->sfd_timeout);
1238 "fina_timeout:\t\t%u\t\t\t%u\n", 1283 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1284 "fina_timeout:",
1239 le32_to_cpu(cck->fina_timeout), 1285 le32_to_cpu(cck->fina_timeout),
1240 accum_cck->fina_timeout); 1286 accum_cck->fina_timeout,
1241 pos += scnprintf(buf + pos, bufsz - pos, 1287 delta_cck->fina_timeout, max_cck->fina_timeout);
1242 "unresponded_rts:\t%u\t\t\t%u\n", 1288 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1289 "unresponded_rts:",
1243 le32_to_cpu(cck->unresponded_rts), 1290 le32_to_cpu(cck->unresponded_rts),
1244 accum_cck->unresponded_rts); 1291 accum_cck->unresponded_rts,
1245 pos += scnprintf(buf + pos, bufsz - pos, 1292 delta_cck->unresponded_rts,
1246 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1293 max_cck->unresponded_rts);
1294 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1295 "rxe_frame_lmt_ovrun:",
1247 le32_to_cpu(cck->rxe_frame_limit_overrun), 1296 le32_to_cpu(cck->rxe_frame_limit_overrun),
1248 accum_cck->rxe_frame_limit_overrun); 1297 accum_cck->rxe_frame_limit_overrun,
1249 pos += scnprintf(buf + pos, bufsz - pos, 1298 delta_cck->rxe_frame_limit_overrun,
1250 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1299 max_cck->rxe_frame_limit_overrun);
1300 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1301 "sent_ack_cnt:",
1251 le32_to_cpu(cck->sent_ack_cnt), 1302 le32_to_cpu(cck->sent_ack_cnt),
1252 accum_cck->sent_ack_cnt); 1303 accum_cck->sent_ack_cnt,
1253 pos += scnprintf(buf + pos, bufsz - pos, 1304 delta_cck->sent_ack_cnt,
1254 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1305 max_cck->sent_ack_cnt);
1306 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1307 "sent_cts_cnt:",
1255 le32_to_cpu(cck->sent_cts_cnt), 1308 le32_to_cpu(cck->sent_cts_cnt),
1256 accum_cck->sent_cts_cnt); 1309 accum_cck->sent_cts_cnt,
1257 pos += scnprintf(buf + pos, bufsz - pos, 1310 delta_cck->sent_cts_cnt,
1258 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1311 max_cck->sent_cts_cnt);
1312 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1313 "sent_ba_rsp_cnt:",
1259 le32_to_cpu(cck->sent_ba_rsp_cnt), 1314 le32_to_cpu(cck->sent_ba_rsp_cnt),
1260 accum_cck->sent_ba_rsp_cnt); 1315 accum_cck->sent_ba_rsp_cnt,
1261 pos += scnprintf(buf + pos, bufsz - pos, 1316 delta_cck->sent_ba_rsp_cnt,
1262 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1317 max_cck->sent_ba_rsp_cnt);
1318 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1319 "dsp_self_kill:",
1263 le32_to_cpu(cck->dsp_self_kill), 1320 le32_to_cpu(cck->dsp_self_kill),
1264 accum_cck->dsp_self_kill); 1321 accum_cck->dsp_self_kill,
1265 pos += scnprintf(buf + pos, bufsz - pos, 1322 delta_cck->dsp_self_kill,
1266 "mh_format_err:\t\t%u\t\t\t%u\n", 1323 max_cck->dsp_self_kill);
1324 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1325 "mh_format_err:",
1267 le32_to_cpu(cck->mh_format_err), 1326 le32_to_cpu(cck->mh_format_err),
1268 accum_cck->mh_format_err); 1327 accum_cck->mh_format_err,
1269 pos += scnprintf(buf + pos, bufsz - pos, 1328 delta_cck->mh_format_err, max_cck->mh_format_err);
1270 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1329 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1330 "re_acq_main_rssi_sum:",
1271 le32_to_cpu(cck->re_acq_main_rssi_sum), 1331 le32_to_cpu(cck->re_acq_main_rssi_sum),
1272 accum_cck->re_acq_main_rssi_sum); 1332 accum_cck->re_acq_main_rssi_sum,
1273 1333 delta_cck->re_acq_main_rssi_sum,
1274 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); 1334 max_cck->re_acq_main_rssi_sum);
1275 pos += scnprintf(buf + pos, bufsz - pos, 1335
1276 "\t\t\tcurrent\t\t\taccumulative\n"); 1336 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1277 pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", 1337 "Statistics_Rx - GENERAL:");
1338 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1339 "bogus_cts:",
1278 le32_to_cpu(general->bogus_cts), 1340 le32_to_cpu(general->bogus_cts),
1279 accum_general->bogus_cts); 1341 accum_general->bogus_cts,
1280 pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", 1342 delta_general->bogus_cts, max_general->bogus_cts);
1343 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1344 "bogus_ack:",
1281 le32_to_cpu(general->bogus_ack), 1345 le32_to_cpu(general->bogus_ack),
1282 accum_general->bogus_ack); 1346 accum_general->bogus_ack,
1283 pos += scnprintf(buf + pos, bufsz - pos, 1347 delta_general->bogus_ack, max_general->bogus_ack);
1284 "non_bssid_frames:\t%u\t\t\t%u\n", 1348 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1349 "non_bssid_frames:",
1285 le32_to_cpu(general->non_bssid_frames), 1350 le32_to_cpu(general->non_bssid_frames),
1286 accum_general->non_bssid_frames); 1351 accum_general->non_bssid_frames,
1287 pos += scnprintf(buf + pos, bufsz - pos, 1352 delta_general->non_bssid_frames,
1288 "filtered_frames:\t%u\t\t\t%u\n", 1353 max_general->non_bssid_frames);
1354 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1355 "filtered_frames:",
1289 le32_to_cpu(general->filtered_frames), 1356 le32_to_cpu(general->filtered_frames),
1290 accum_general->filtered_frames); 1357 accum_general->filtered_frames,
1291 pos += scnprintf(buf + pos, bufsz - pos, 1358 delta_general->filtered_frames,
1292 "non_channel_beacons:\t%u\t\t\t%u\n", 1359 max_general->filtered_frames);
1360 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1361 "non_channel_beacons:",
1293 le32_to_cpu(general->non_channel_beacons), 1362 le32_to_cpu(general->non_channel_beacons),
1294 accum_general->non_channel_beacons); 1363 accum_general->non_channel_beacons,
1295 pos += scnprintf(buf + pos, bufsz - pos, 1364 delta_general->non_channel_beacons,
1296 "channel_beacons:\t%u\t\t\t%u\n", 1365 max_general->non_channel_beacons);
1366 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1367 "channel_beacons:",
1297 le32_to_cpu(general->channel_beacons), 1368 le32_to_cpu(general->channel_beacons),
1298 accum_general->channel_beacons); 1369 accum_general->channel_beacons,
1299 pos += scnprintf(buf + pos, bufsz - pos, 1370 delta_general->channel_beacons,
1300 "num_missed_bcon:\t%u\t\t\t%u\n", 1371 max_general->channel_beacons);
1372 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1373 "num_missed_bcon:",
1301 le32_to_cpu(general->num_missed_bcon), 1374 le32_to_cpu(general->num_missed_bcon),
1302 accum_general->num_missed_bcon); 1375 accum_general->num_missed_bcon,
1303 pos += scnprintf(buf + pos, bufsz - pos, 1376 delta_general->num_missed_bcon,
1304 "adc_rx_saturation_time:\t%u\t\t\t%u\n", 1377 max_general->num_missed_bcon);
1378 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1379 "adc_rx_saturation_time:",
1305 le32_to_cpu(general->adc_rx_saturation_time), 1380 le32_to_cpu(general->adc_rx_saturation_time),
1306 accum_general->adc_rx_saturation_time); 1381 accum_general->adc_rx_saturation_time,
1307 pos += scnprintf(buf + pos, bufsz - pos, 1382 delta_general->adc_rx_saturation_time,
1308 "ina_detect_search_tm:\t%u\t\t\t%u\n", 1383 max_general->adc_rx_saturation_time);
1384 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1385 "ina_detect_search_tm:",
1309 le32_to_cpu(general->ina_detection_search_time), 1386 le32_to_cpu(general->ina_detection_search_time),
1310 accum_general->ina_detection_search_time); 1387 accum_general->ina_detection_search_time,
1311 pos += scnprintf(buf + pos, bufsz - pos, 1388 delta_general->ina_detection_search_time,
1312 "beacon_silence_rssi_a:\t%u\t\t\t%u\n", 1389 max_general->ina_detection_search_time);
1390 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1391 "beacon_silence_rssi_a:",
1313 le32_to_cpu(general->beacon_silence_rssi_a), 1392 le32_to_cpu(general->beacon_silence_rssi_a),
1314 accum_general->beacon_silence_rssi_a); 1393 accum_general->beacon_silence_rssi_a,
1315 pos += scnprintf(buf + pos, bufsz - pos, 1394 delta_general->beacon_silence_rssi_a,
1316 "beacon_silence_rssi_b:\t%u\t\t\t%u\n", 1395 max_general->beacon_silence_rssi_a);
1396 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1397 "beacon_silence_rssi_b:",
1317 le32_to_cpu(general->beacon_silence_rssi_b), 1398 le32_to_cpu(general->beacon_silence_rssi_b),
1318 accum_general->beacon_silence_rssi_b); 1399 accum_general->beacon_silence_rssi_b,
1319 pos += scnprintf(buf + pos, bufsz - pos, 1400 delta_general->beacon_silence_rssi_b,
1320 "beacon_silence_rssi_c:\t%u\t\t\t%u\n", 1401 max_general->beacon_silence_rssi_b);
1402 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1403 "beacon_silence_rssi_c:",
1321 le32_to_cpu(general->beacon_silence_rssi_c), 1404 le32_to_cpu(general->beacon_silence_rssi_c),
1322 accum_general->beacon_silence_rssi_c); 1405 accum_general->beacon_silence_rssi_c,
1323 pos += scnprintf(buf + pos, bufsz - pos, 1406 delta_general->beacon_silence_rssi_c,
1324 "interference_data_flag:\t%u\t\t\t%u\n", 1407 max_general->beacon_silence_rssi_c);
1408 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1409 "interference_data_flag:",
1325 le32_to_cpu(general->interference_data_flag), 1410 le32_to_cpu(general->interference_data_flag),
1326 accum_general->interference_data_flag); 1411 accum_general->interference_data_flag,
1327 pos += scnprintf(buf + pos, bufsz - pos, 1412 delta_general->interference_data_flag,
1328 "channel_load:\t\t%u\t\t\t%u\n", 1413 max_general->interference_data_flag);
1414 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1415 "channel_load:",
1329 le32_to_cpu(general->channel_load), 1416 le32_to_cpu(general->channel_load),
1330 accum_general->channel_load); 1417 accum_general->channel_load,
1331 pos += scnprintf(buf + pos, bufsz - pos, 1418 delta_general->channel_load,
1332 "dsp_false_alarms:\t%u\t\t\t%u\n", 1419 max_general->channel_load);
1420 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1421 "dsp_false_alarms:",
1333 le32_to_cpu(general->dsp_false_alarms), 1422 le32_to_cpu(general->dsp_false_alarms),
1334 accum_general->dsp_false_alarms); 1423 accum_general->dsp_false_alarms,
1335 pos += scnprintf(buf + pos, bufsz - pos, 1424 delta_general->dsp_false_alarms,
1336 "beacon_rssi_a:\t\t%u\t\t\t%u\n", 1425 max_general->dsp_false_alarms);
1426 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1427 "beacon_rssi_a:",
1337 le32_to_cpu(general->beacon_rssi_a), 1428 le32_to_cpu(general->beacon_rssi_a),
1338 accum_general->beacon_rssi_a); 1429 accum_general->beacon_rssi_a,
1339 pos += scnprintf(buf + pos, bufsz - pos, 1430 delta_general->beacon_rssi_a,
1340 "beacon_rssi_b:\t\t%u\t\t\t%u\n", 1431 max_general->beacon_rssi_a);
1432 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1433 "beacon_rssi_b:",
1341 le32_to_cpu(general->beacon_rssi_b), 1434 le32_to_cpu(general->beacon_rssi_b),
1342 accum_general->beacon_rssi_b); 1435 accum_general->beacon_rssi_b,
1343 pos += scnprintf(buf + pos, bufsz - pos, 1436 delta_general->beacon_rssi_b,
1344 "beacon_rssi_c:\t\t%u\t\t\t%u\n", 1437 max_general->beacon_rssi_b);
1438 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 "beacon_rssi_c:",
1345 le32_to_cpu(general->beacon_rssi_c), 1440 le32_to_cpu(general->beacon_rssi_c),
1346 accum_general->beacon_rssi_c); 1441 accum_general->beacon_rssi_c,
1347 pos += scnprintf(buf + pos, bufsz - pos, 1442 delta_general->beacon_rssi_c,
1348 "beacon_energy_a:\t%u\t\t\t%u\n", 1443 max_general->beacon_rssi_c);
1444 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1445 "beacon_energy_a:",
1349 le32_to_cpu(general->beacon_energy_a), 1446 le32_to_cpu(general->beacon_energy_a),
1350 accum_general->beacon_energy_a); 1447 accum_general->beacon_energy_a,
1351 pos += scnprintf(buf + pos, bufsz - pos, 1448 delta_general->beacon_energy_a,
1352 "beacon_energy_b:\t%u\t\t\t%u\n", 1449 max_general->beacon_energy_a);
1450 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1451 "beacon_energy_b:",
1353 le32_to_cpu(general->beacon_energy_b), 1452 le32_to_cpu(general->beacon_energy_b),
1354 accum_general->beacon_energy_b); 1453 accum_general->beacon_energy_b,
1355 pos += scnprintf(buf + pos, bufsz - pos, 1454 delta_general->beacon_energy_b,
1356 "beacon_energy_c:\t%u\t\t\t%u\n", 1455 max_general->beacon_energy_b);
1456 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1457 "beacon_energy_c:",
1357 le32_to_cpu(general->beacon_energy_c), 1458 le32_to_cpu(general->beacon_energy_c),
1358 accum_general->beacon_energy_c); 1459 accum_general->beacon_energy_c,
1460 delta_general->beacon_energy_c,
1461 max_general->beacon_energy_c);
1359 1462
1360 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); 1463 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1361 pos += scnprintf(buf + pos, bufsz - pos, 1464 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1362 "\t\t\tcurrent\t\t\taccumulative\n"); 1465 "Statistics_Rx - OFDM_HT:");
1363 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1466 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1364 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); 1467 "plcp_err:",
1365 pos += scnprintf(buf + pos, bufsz - pos, 1468 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1366 "overrun_err:\t\t%u\t\t\t%u\n", 1469 delta_ht->plcp_err, max_ht->plcp_err);
1367 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); 1470 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1368 pos += scnprintf(buf + pos, bufsz - pos, 1471 "overrun_err:",
1369 "early_overrun_err:\t%u\t\t\t%u\n", 1472 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1473 delta_ht->overrun_err, max_ht->overrun_err);
1474 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1475 "early_overrun_err:",
1370 le32_to_cpu(ht->early_overrun_err), 1476 le32_to_cpu(ht->early_overrun_err),
1371 accum_ht->early_overrun_err); 1477 accum_ht->early_overrun_err,
1372 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1478 delta_ht->early_overrun_err,
1373 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); 1479 max_ht->early_overrun_err);
1374 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1480 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1375 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); 1481 "crc32_good:",
1376 pos += scnprintf(buf + pos, bufsz - pos, 1482 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1377 "mh_format_err:\t\t%u\t\t\t%u\n", 1483 delta_ht->crc32_good, max_ht->crc32_good);
1484 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1485 "crc32_err:",
1486 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1487 delta_ht->crc32_err, max_ht->crc32_err);
1488 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1489 "mh_format_err:",
1378 le32_to_cpu(ht->mh_format_err), 1490 le32_to_cpu(ht->mh_format_err),
1379 accum_ht->mh_format_err); 1491 accum_ht->mh_format_err,
1380 pos += scnprintf(buf + pos, bufsz - pos, 1492 delta_ht->mh_format_err, max_ht->mh_format_err);
1381 "agg_crc32_good:\t\t%u\t\t\t%u\n", 1493 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1494 "agg_crc32_good:",
1382 le32_to_cpu(ht->agg_crc32_good), 1495 le32_to_cpu(ht->agg_crc32_good),
1383 accum_ht->agg_crc32_good); 1496 accum_ht->agg_crc32_good,
1384 pos += scnprintf(buf + pos, bufsz - pos, 1497 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1385 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", 1498 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1499 "agg_mpdu_cnt:",
1386 le32_to_cpu(ht->agg_mpdu_cnt), 1500 le32_to_cpu(ht->agg_mpdu_cnt),
1387 accum_ht->agg_mpdu_cnt); 1501 accum_ht->agg_mpdu_cnt,
1388 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1502 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1389 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1503 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1390 pos += scnprintf(buf + pos, bufsz - pos, "unsupport_mcs:\t\t%u\t\t\t%u\n", 1504 "agg_cnt:",
1505 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1506 delta_ht->agg_cnt, max_ht->agg_cnt);
1507 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1508 "unsupport_mcs:",
1391 le32_to_cpu(ht->unsupport_mcs), 1509 le32_to_cpu(ht->unsupport_mcs),
1392 accum_ht->unsupport_mcs); 1510 accum_ht->unsupport_mcs,
1511 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1393 1512
1394 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1513 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1395 kfree(buf); 1514 kfree(buf);
@@ -1403,23 +1522,13 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1403 struct iwl_priv *priv = file->private_data; 1522 struct iwl_priv *priv = file->private_data;
1404 int pos = 0; 1523 int pos = 0;
1405 char *buf; 1524 char *buf;
1406 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1525 int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1407 ssize_t ret; 1526 ssize_t ret;
1408 struct statistics_tx *tx, *accum_tx; 1527 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1409 1528
1410 if (!iwl_is_alive(priv)) 1529 if (!iwl_is_alive(priv))
1411 return -EAGAIN; 1530 return -EAGAIN;
1412 1531
1413 /* make request to uCode to retrieve statistics information */
1414 mutex_lock(&priv->mutex);
1415 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1416 mutex_unlock(&priv->mutex);
1417
1418 if (ret) {
1419 IWL_ERR(priv,
1420 "Error sending statistics request: %zd\n", ret);
1421 return -EAGAIN;
1422 }
1423 buf = kzalloc(bufsz, GFP_KERNEL); 1532 buf = kzalloc(bufsz, GFP_KERNEL);
1424 if (!buf) { 1533 if (!buf) {
1425 IWL_ERR(priv, "Can not allocate Buffer\n"); 1534 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1432,106 +1541,148 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1432 */ 1541 */
1433 tx = &priv->statistics.tx; 1542 tx = &priv->statistics.tx;
1434 accum_tx = &priv->accum_statistics.tx; 1543 accum_tx = &priv->accum_statistics.tx;
1544 delta_tx = &priv->delta_statistics.tx;
1545 max_tx = &priv->max_delta.tx;
1435 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1546 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1436 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); 1547 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1437 pos += scnprintf(buf + pos, bufsz - pos, 1548 "Statistics_Tx:");
1438 "\t\t\tcurrent\t\t\taccumulative\n"); 1549 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439 pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", 1550 "preamble:",
1440 le32_to_cpu(tx->preamble_cnt), 1551 le32_to_cpu(tx->preamble_cnt),
1441 accum_tx->preamble_cnt); 1552 accum_tx->preamble_cnt,
1442 pos += scnprintf(buf + pos, bufsz - pos, 1553 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1443 "rx_detected_cnt:\t\t%u\t\t\t%u\n", 1554 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1555 "rx_detected_cnt:",
1444 le32_to_cpu(tx->rx_detected_cnt), 1556 le32_to_cpu(tx->rx_detected_cnt),
1445 accum_tx->rx_detected_cnt); 1557 accum_tx->rx_detected_cnt,
1446 pos += scnprintf(buf + pos, bufsz - pos, 1558 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1447 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", 1559 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1560 "bt_prio_defer_cnt:",
1448 le32_to_cpu(tx->bt_prio_defer_cnt), 1561 le32_to_cpu(tx->bt_prio_defer_cnt),
1449 accum_tx->bt_prio_defer_cnt); 1562 accum_tx->bt_prio_defer_cnt,
1450 pos += scnprintf(buf + pos, bufsz - pos, 1563 delta_tx->bt_prio_defer_cnt,
1451 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", 1564 max_tx->bt_prio_defer_cnt);
1565 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1566 "bt_prio_kill_cnt:",
1452 le32_to_cpu(tx->bt_prio_kill_cnt), 1567 le32_to_cpu(tx->bt_prio_kill_cnt),
1453 accum_tx->bt_prio_kill_cnt); 1568 accum_tx->bt_prio_kill_cnt,
1454 pos += scnprintf(buf + pos, bufsz - pos, 1569 delta_tx->bt_prio_kill_cnt,
1455 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", 1570 max_tx->bt_prio_kill_cnt);
1571 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1572 "few_bytes_cnt:",
1456 le32_to_cpu(tx->few_bytes_cnt), 1573 le32_to_cpu(tx->few_bytes_cnt),
1457 accum_tx->few_bytes_cnt); 1574 accum_tx->few_bytes_cnt,
1458 pos += scnprintf(buf + pos, bufsz - pos, 1575 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1459 "cts_timeout:\t\t\t%u\t\t\t%u\n", 1576 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1460 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); 1577 "cts_timeout:",
1461 pos += scnprintf(buf + pos, bufsz - pos, 1578 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1462 "ack_timeout:\t\t\t%u\t\t\t%u\n", 1579 delta_tx->cts_timeout, max_tx->cts_timeout);
1580 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1581 "ack_timeout:",
1463 le32_to_cpu(tx->ack_timeout), 1582 le32_to_cpu(tx->ack_timeout),
1464 accum_tx->ack_timeout); 1583 accum_tx->ack_timeout,
1465 pos += scnprintf(buf + pos, bufsz - pos, 1584 delta_tx->ack_timeout, max_tx->ack_timeout);
1466 "expected_ack_cnt:\t\t%u\t\t\t%u\n", 1585 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1586 "expected_ack_cnt:",
1467 le32_to_cpu(tx->expected_ack_cnt), 1587 le32_to_cpu(tx->expected_ack_cnt),
1468 accum_tx->expected_ack_cnt); 1588 accum_tx->expected_ack_cnt,
1469 pos += scnprintf(buf + pos, bufsz - pos, 1589 delta_tx->expected_ack_cnt,
1470 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", 1590 max_tx->expected_ack_cnt);
1591 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1592 "actual_ack_cnt:",
1471 le32_to_cpu(tx->actual_ack_cnt), 1593 le32_to_cpu(tx->actual_ack_cnt),
1472 accum_tx->actual_ack_cnt); 1594 accum_tx->actual_ack_cnt,
1473 pos += scnprintf(buf + pos, bufsz - pos, 1595 delta_tx->actual_ack_cnt,
1474 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", 1596 max_tx->actual_ack_cnt);
1597 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1598 "dump_msdu_cnt:",
1475 le32_to_cpu(tx->dump_msdu_cnt), 1599 le32_to_cpu(tx->dump_msdu_cnt),
1476 accum_tx->dump_msdu_cnt); 1600 accum_tx->dump_msdu_cnt,
1477 pos += scnprintf(buf + pos, bufsz - pos, 1601 delta_tx->dump_msdu_cnt,
1478 "abort_nxt_frame_mismatch:" 1602 max_tx->dump_msdu_cnt);
1479 "\t%u\t\t\t%u\n", 1603 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1604 "abort_nxt_frame_mismatch:",
1480 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 1605 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1481 accum_tx->burst_abort_next_frame_mismatch_cnt); 1606 accum_tx->burst_abort_next_frame_mismatch_cnt,
1482 pos += scnprintf(buf + pos, bufsz - pos, 1607 delta_tx->burst_abort_next_frame_mismatch_cnt,
1483 "abort_missing_nxt_frame:" 1608 max_tx->burst_abort_next_frame_mismatch_cnt);
1484 "\t%u\t\t\t%u\n", 1609 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1610 "abort_missing_nxt_frame:",
1485 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 1611 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1486 accum_tx->burst_abort_missing_next_frame_cnt); 1612 accum_tx->burst_abort_missing_next_frame_cnt,
1487 pos += scnprintf(buf + pos, bufsz - pos, 1613 delta_tx->burst_abort_missing_next_frame_cnt,
1488 "cts_timeout_collision:\t\t%u\t\t\t%u\n", 1614 max_tx->burst_abort_missing_next_frame_cnt);
1615 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1616 "cts_timeout_collision:",
1489 le32_to_cpu(tx->cts_timeout_collision), 1617 le32_to_cpu(tx->cts_timeout_collision),
1490 accum_tx->cts_timeout_collision); 1618 accum_tx->cts_timeout_collision,
1491 pos += scnprintf(buf + pos, bufsz - pos, 1619 delta_tx->cts_timeout_collision,
1492 "ack_ba_timeout_collision:\t%u\t\t\t%u\n", 1620 max_tx->cts_timeout_collision);
1621 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1622 "ack_ba_timeout_collision:",
1493 le32_to_cpu(tx->ack_or_ba_timeout_collision), 1623 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1494 accum_tx->ack_or_ba_timeout_collision); 1624 accum_tx->ack_or_ba_timeout_collision,
1495 pos += scnprintf(buf + pos, bufsz - pos, 1625 delta_tx->ack_or_ba_timeout_collision,
1496 "agg ba_timeout:\t\t\t%u\t\t\t%u\n", 1626 max_tx->ack_or_ba_timeout_collision);
1627 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1628 "agg ba_timeout:",
1497 le32_to_cpu(tx->agg.ba_timeout), 1629 le32_to_cpu(tx->agg.ba_timeout),
1498 accum_tx->agg.ba_timeout); 1630 accum_tx->agg.ba_timeout,
1499 pos += scnprintf(buf + pos, bufsz - pos, 1631 delta_tx->agg.ba_timeout,
1500 "agg ba_resched_frames:\t\t%u\t\t\t%u\n", 1632 max_tx->agg.ba_timeout);
1633 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1634 "agg ba_resched_frames:",
1501 le32_to_cpu(tx->agg.ba_reschedule_frames), 1635 le32_to_cpu(tx->agg.ba_reschedule_frames),
1502 accum_tx->agg.ba_reschedule_frames); 1636 accum_tx->agg.ba_reschedule_frames,
1503 pos += scnprintf(buf + pos, bufsz - pos, 1637 delta_tx->agg.ba_reschedule_frames,
1504 "agg scd_query_agg_frame:\t%u\t\t\t%u\n", 1638 max_tx->agg.ba_reschedule_frames);
1639 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1640 "agg scd_query_agg_frame:",
1505 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 1641 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1506 accum_tx->agg.scd_query_agg_frame_cnt); 1642 accum_tx->agg.scd_query_agg_frame_cnt,
1507 pos += scnprintf(buf + pos, bufsz - pos, 1643 delta_tx->agg.scd_query_agg_frame_cnt,
1508 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", 1644 max_tx->agg.scd_query_agg_frame_cnt);
1645 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1646 "agg scd_query_no_agg:",
1509 le32_to_cpu(tx->agg.scd_query_no_agg), 1647 le32_to_cpu(tx->agg.scd_query_no_agg),
1510 accum_tx->agg.scd_query_no_agg); 1648 accum_tx->agg.scd_query_no_agg,
1511 pos += scnprintf(buf + pos, bufsz - pos, 1649 delta_tx->agg.scd_query_no_agg,
1512 "agg scd_query_agg:\t\t%u\t\t\t%u\n", 1650 max_tx->agg.scd_query_no_agg);
1651 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1652 "agg scd_query_agg:",
1513 le32_to_cpu(tx->agg.scd_query_agg), 1653 le32_to_cpu(tx->agg.scd_query_agg),
1514 accum_tx->agg.scd_query_agg); 1654 accum_tx->agg.scd_query_agg,
1515 pos += scnprintf(buf + pos, bufsz - pos, 1655 delta_tx->agg.scd_query_agg,
1516 "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", 1656 max_tx->agg.scd_query_agg);
1657 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1658 "agg scd_query_mismatch:",
1517 le32_to_cpu(tx->agg.scd_query_mismatch), 1659 le32_to_cpu(tx->agg.scd_query_mismatch),
1518 accum_tx->agg.scd_query_mismatch); 1660 accum_tx->agg.scd_query_mismatch,
1519 pos += scnprintf(buf + pos, bufsz - pos, 1661 delta_tx->agg.scd_query_mismatch,
1520 "agg frame_not_ready:\t\t%u\t\t\t%u\n", 1662 max_tx->agg.scd_query_mismatch);
1663 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1664 "agg frame_not_ready:",
1521 le32_to_cpu(tx->agg.frame_not_ready), 1665 le32_to_cpu(tx->agg.frame_not_ready),
1522 accum_tx->agg.frame_not_ready); 1666 accum_tx->agg.frame_not_ready,
1523 pos += scnprintf(buf + pos, bufsz - pos, 1667 delta_tx->agg.frame_not_ready,
1524 "agg underrun:\t\t\t%u\t\t\t%u\n", 1668 max_tx->agg.frame_not_ready);
1669 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1670 "agg underrun:",
1525 le32_to_cpu(tx->agg.underrun), 1671 le32_to_cpu(tx->agg.underrun),
1526 accum_tx->agg.underrun); 1672 accum_tx->agg.underrun,
1527 pos += scnprintf(buf + pos, bufsz - pos, 1673 delta_tx->agg.underrun, max_tx->agg.underrun);
1528 "agg bt_prio_kill:\t\t%u\t\t\t%u\n", 1674 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1675 "agg bt_prio_kill:",
1529 le32_to_cpu(tx->agg.bt_prio_kill), 1676 le32_to_cpu(tx->agg.bt_prio_kill),
1530 accum_tx->agg.bt_prio_kill); 1677 accum_tx->agg.bt_prio_kill,
1531 pos += scnprintf(buf + pos, bufsz - pos, 1678 delta_tx->agg.bt_prio_kill,
1532 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", 1679 max_tx->agg.bt_prio_kill);
1680 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1681 "agg rx_ba_rsp_cnt:",
1533 le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 1682 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1534 accum_tx->agg.rx_ba_rsp_cnt); 1683 accum_tx->agg.rx_ba_rsp_cnt,
1684 delta_tx->agg.rx_ba_rsp_cnt,
1685 max_tx->agg.rx_ba_rsp_cnt);
1535 1686
1536 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1687 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1537 kfree(buf); 1688 kfree(buf);
@@ -1545,25 +1696,16 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1545 struct iwl_priv *priv = file->private_data; 1696 struct iwl_priv *priv = file->private_data;
1546 int pos = 0; 1697 int pos = 0;
1547 char *buf; 1698 char *buf;
1548 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1699 int bufsz = sizeof(struct statistics_general) * 10 + 300;
1549 ssize_t ret; 1700 ssize_t ret;
1550 struct statistics_general *general, *accum_general; 1701 struct statistics_general *general, *accum_general;
1551 struct statistics_dbg *dbg, *accum_dbg; 1702 struct statistics_general *delta_general, *max_general;
1552 struct statistics_div *div, *accum_div; 1703 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1704 struct statistics_div *div, *accum_div, *delta_div, *max_div;
1553 1705
1554 if (!iwl_is_alive(priv)) 1706 if (!iwl_is_alive(priv))
1555 return -EAGAIN; 1707 return -EAGAIN;
1556 1708
1557 /* make request to uCode to retrieve statistics information */
1558 mutex_lock(&priv->mutex);
1559 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1560 mutex_unlock(&priv->mutex);
1561
1562 if (ret) {
1563 IWL_ERR(priv,
1564 "Error sending statistics request: %zd\n", ret);
1565 return -EAGAIN;
1566 }
1567 buf = kzalloc(bufsz, GFP_KERNEL); 1709 buf = kzalloc(bufsz, GFP_KERNEL);
1568 if (!buf) { 1710 if (!buf) {
1569 IWL_ERR(priv, "Can not allocate Buffer\n"); 1711 IWL_ERR(priv, "Can not allocate Buffer\n");
@@ -1578,52 +1720,78 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1578 dbg = &priv->statistics.general.dbg; 1720 dbg = &priv->statistics.general.dbg;
1579 div = &priv->statistics.general.div; 1721 div = &priv->statistics.general.div;
1580 accum_general = &priv->accum_statistics.general; 1722 accum_general = &priv->accum_statistics.general;
1723 delta_general = &priv->delta_statistics.general;
1724 max_general = &priv->max_delta.general;
1581 accum_dbg = &priv->accum_statistics.general.dbg; 1725 accum_dbg = &priv->accum_statistics.general.dbg;
1726 delta_dbg = &priv->delta_statistics.general.dbg;
1727 max_dbg = &priv->max_delta.general.dbg;
1582 accum_div = &priv->accum_statistics.general.div; 1728 accum_div = &priv->accum_statistics.general.div;
1729 delta_div = &priv->delta_statistics.general.div;
1730 max_div = &priv->max_delta.general.div;
1583 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1731 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1584 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); 1732 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1585 pos += scnprintf(buf + pos, bufsz - pos, 1733 "Statistics_General:");
1586 "\t\t\tcurrent\t\t\taccumulative\n"); 1734 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1587 pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", 1735 "temperature:",
1588 le32_to_cpu(general->temperature)); 1736 le32_to_cpu(general->temperature));
1589 pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", 1737 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1738 "temperature_m:",
1590 le32_to_cpu(general->temperature_m)); 1739 le32_to_cpu(general->temperature_m));
1591 pos += scnprintf(buf + pos, bufsz - pos, 1740 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1592 "burst_check:\t\t\t%u\t\t\t%u\n", 1741 "burst_check:",
1593 le32_to_cpu(dbg->burst_check), 1742 le32_to_cpu(dbg->burst_check),
1594 accum_dbg->burst_check); 1743 accum_dbg->burst_check,
1595 pos += scnprintf(buf + pos, bufsz - pos, 1744 delta_dbg->burst_check, max_dbg->burst_check);
1596 "burst_count:\t\t\t%u\t\t\t%u\n", 1745 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1746 "burst_count:",
1597 le32_to_cpu(dbg->burst_count), 1747 le32_to_cpu(dbg->burst_count),
1598 accum_dbg->burst_count); 1748 accum_dbg->burst_count,
1599 pos += scnprintf(buf + pos, bufsz - pos, 1749 delta_dbg->burst_count, max_dbg->burst_count);
1600 "sleep_time:\t\t\t%u\t\t\t%u\n", 1750 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1751 "sleep_time:",
1601 le32_to_cpu(general->sleep_time), 1752 le32_to_cpu(general->sleep_time),
1602 accum_general->sleep_time); 1753 accum_general->sleep_time,
1603 pos += scnprintf(buf + pos, bufsz - pos, 1754 delta_general->sleep_time, max_general->sleep_time);
1604 "slots_out:\t\t\t%u\t\t\t%u\n", 1755 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1756 "slots_out:",
1605 le32_to_cpu(general->slots_out), 1757 le32_to_cpu(general->slots_out),
1606 accum_general->slots_out); 1758 accum_general->slots_out,
1607 pos += scnprintf(buf + pos, bufsz - pos, 1759 delta_general->slots_out, max_general->slots_out);
1608 "slots_idle:\t\t\t%u\t\t\t%u\n", 1760 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1761 "slots_idle:",
1609 le32_to_cpu(general->slots_idle), 1762 le32_to_cpu(general->slots_idle),
1610 accum_general->slots_idle); 1763 accum_general->slots_idle,
1764 delta_general->slots_idle, max_general->slots_idle);
1611 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", 1765 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1612 le32_to_cpu(general->ttl_timestamp)); 1766 le32_to_cpu(general->ttl_timestamp));
1613 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", 1767 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1614 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); 1768 "tx_on_a:",
1615 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", 1769 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1616 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); 1770 delta_div->tx_on_a, max_div->tx_on_a);
1617 pos += scnprintf(buf + pos, bufsz - pos, 1771 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1618 "exec_time:\t\t\t%u\t\t\t%u\n", 1772 "tx_on_b:",
1619 le32_to_cpu(div->exec_time), accum_div->exec_time); 1773 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1620 pos += scnprintf(buf + pos, bufsz - pos, 1774 delta_div->tx_on_b, max_div->tx_on_b);
1621 "probe_time:\t\t\t%u\t\t\t%u\n", 1775 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1622 le32_to_cpu(div->probe_time), accum_div->probe_time); 1776 "exec_time:",
1623 pos += scnprintf(buf + pos, bufsz - pos, 1777 le32_to_cpu(div->exec_time), accum_div->exec_time,
1624 "rx_enable_counter:\t\t%u\t\t\t%u\n", 1778 delta_div->exec_time, max_div->exec_time);
1779 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1780 "probe_time:",
1781 le32_to_cpu(div->probe_time), accum_div->probe_time,
1782 delta_div->probe_time, max_div->probe_time);
1783 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1784 "rx_enable_counter:",
1625 le32_to_cpu(general->rx_enable_counter), 1785 le32_to_cpu(general->rx_enable_counter),
1626 accum_general->rx_enable_counter); 1786 accum_general->rx_enable_counter,
1787 delta_general->rx_enable_counter,
1788 max_general->rx_enable_counter);
1789 pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1790 "num_of_sos_states:",
1791 le32_to_cpu(general->num_of_sos_states),
1792 accum_general->num_of_sos_states,
1793 delta_general->num_of_sos_states,
1794 max_general->num_of_sos_states);
1627 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1795 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1628 kfree(buf); 1796 kfree(buf);
1629 return ret; 1797 return ret;
@@ -1775,23 +1943,12 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1775 struct iwl_priv *priv = file->private_data; 1943 struct iwl_priv *priv = file->private_data;
1776 char buf[128]; 1944 char buf[128];
1777 int pos = 0; 1945 int pos = 0;
1778 ssize_t ret;
1779 const size_t bufsz = sizeof(buf); 1946 const size_t bufsz = sizeof(buf);
1780 struct statistics_tx *tx; 1947 struct statistics_tx *tx;
1781 1948
1782 if (!iwl_is_alive(priv)) 1949 if (!iwl_is_alive(priv))
1783 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 1950 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1784 else { 1951 else {
1785 /* make request to uCode to retrieve statistics information */
1786 mutex_lock(&priv->mutex);
1787 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1788 mutex_unlock(&priv->mutex);
1789
1790 if (ret) {
1791 IWL_ERR(priv, "Error sending statistics request: %zd\n",
1792 ret);
1793 return -EAGAIN;
1794 }
1795 tx = &priv->statistics.tx; 1952 tx = &priv->statistics.tx;
1796 if (tx->tx_power.ant_a || 1953 if (tx->tx_power.ant_a ||
1797 tx->tx_power.ant_b || 1954 tx->tx_power.ant_b ||
@@ -1940,6 +2097,132 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1940 return count; 2097 return count;
1941} 2098}
1942 2099
2100static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2101 char __user *user_buf,
2102 size_t count, loff_t *ppos)
2103{
2104 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2105 char *buf;
2106 int pos = 0;
2107 ssize_t ret = -EFAULT;
2108
2109 if (priv->cfg->ops->lib->dump_fh) {
2110 ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
2111 if (buf) {
2112 ret = simple_read_from_buffer(user_buf,
2113 count, ppos, buf, pos);
2114 kfree(buf);
2115 }
2116 }
2117
2118 return ret;
2119}
2120
2121static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2122 char __user *user_buf,
2123 size_t count, loff_t *ppos) {
2124
2125 struct iwl_priv *priv = file->private_data;
2126 int pos = 0;
2127 char buf[12];
2128 const size_t bufsz = sizeof(buf);
2129 ssize_t ret;
2130
2131 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2132 priv->missed_beacon_threshold);
2133
2134 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2135 return ret;
2136}
2137
2138static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2139 const char __user *user_buf,
2140 size_t count, loff_t *ppos)
2141{
2142 struct iwl_priv *priv = file->private_data;
2143 char buf[8];
2144 int buf_size;
2145 int missed;
2146
2147 memset(buf, 0, sizeof(buf));
2148 buf_size = min(count, sizeof(buf) - 1);
2149 if (copy_from_user(buf, user_buf, buf_size))
2150 return -EFAULT;
2151 if (sscanf(buf, "%d", &missed) != 1)
2152 return -EINVAL;
2153
2154 if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2155 missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2156 priv->missed_beacon_threshold =
2157 IWL_MISSED_BEACON_THRESHOLD_DEF;
2158 else
2159 priv->missed_beacon_threshold = missed;
2160
2161 return count;
2162}
2163
2164static ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2165 const char __user *user_buf,
2166 size_t count, loff_t *ppos)
2167{
2168 struct iwl_priv *priv = file->private_data;
2169 char buf[8];
2170 int buf_size;
2171 int scan;
2172
2173 memset(buf, 0, sizeof(buf));
2174 buf_size = min(count, sizeof(buf) - 1);
2175 if (copy_from_user(buf, user_buf, buf_size))
2176 return -EFAULT;
2177 if (sscanf(buf, "%d", &scan) != 1)
2178 return -EINVAL;
2179
2180 iwl_internal_short_hw_scan(priv);
2181
2182 return count;
2183}
2184
2185static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2186 char __user *user_buf,
2187 size_t count, loff_t *ppos) {
2188
2189 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2190 int pos = 0;
2191 char buf[12];
2192 const size_t bufsz = sizeof(buf);
2193 ssize_t ret;
2194
2195 pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2196 priv->cfg->plcp_delta_threshold);
2197
2198 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2199 return ret;
2200}
2201
2202static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2203 const char __user *user_buf,
2204 size_t count, loff_t *ppos) {
2205
2206 struct iwl_priv *priv = file->private_data;
2207 char buf[8];
2208 int buf_size;
2209 int plcp;
2210
2211 memset(buf, 0, sizeof(buf));
2212 buf_size = min(count, sizeof(buf) - 1);
2213 if (copy_from_user(buf, user_buf, buf_size))
2214 return -EFAULT;
2215 if (sscanf(buf, "%d", &plcp) != 1)
2216 return -EINVAL;
2217 if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
2218 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
2219 priv->cfg->plcp_delta_threshold =
2220 IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
2221 else
2222 priv->cfg->plcp_delta_threshold = plcp;
2223 return count;
2224}
2225
1943DEBUGFS_READ_FILE_OPS(rx_statistics); 2226DEBUGFS_READ_FILE_OPS(rx_statistics);
1944DEBUGFS_READ_FILE_OPS(tx_statistics); 2227DEBUGFS_READ_FILE_OPS(tx_statistics);
1945DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2228DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1956,6 +2239,10 @@ DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1956DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 2239DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1957DEBUGFS_WRITE_FILE_OPS(csr); 2240DEBUGFS_WRITE_FILE_OPS(csr);
1958DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 2241DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2242DEBUGFS_READ_FILE_OPS(fh_reg);
2243DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2244DEBUGFS_WRITE_FILE_OPS(internal_scan);
2245DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
1959 2246
1960/* 2247/*
1961 * Create the debugfs files and directories 2248 * Create the debugfs files and directories
@@ -1963,71 +2250,73 @@ DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
1963 */ 2250 */
1964int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 2251int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1965{ 2252{
1966 struct iwl_debugfs *dbgfs;
1967 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 2253 struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1968 int ret = 0; 2254 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1969 2255
1970 dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 2256 dir_drv = debugfs_create_dir(name, phyd);
1971 if (!dbgfs) { 2257 if (!dir_drv)
1972 ret = -ENOMEM; 2258 return -ENOMEM;
1973 goto err;
1974 }
1975 2259
1976 priv->dbgfs = dbgfs; 2260 priv->debugfs_dir = dir_drv;
1977 dbgfs->name = name; 2261
1978 dbgfs->dir_drv = debugfs_create_dir(name, phyd); 2262 dir_data = debugfs_create_dir("data", dir_drv);
1979 if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 2263 if (!dir_data)
1980 ret = -ENOENT; 2264 goto err;
2265 dir_rf = debugfs_create_dir("rf", dir_drv);
2266 if (!dir_rf)
2267 goto err;
2268 dir_debug = debugfs_create_dir("debug", dir_drv);
2269 if (!dir_debug)
1981 goto err; 2270 goto err;
1982 }
1983 2271
1984 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 2272 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1985 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 2273 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1986 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 2274 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
1987 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); 2275 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1988 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); 2276 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1989 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR | S_IRUSR); 2277 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1990 DEBUGFS_ADD_FILE(stations, data, S_IRUSR); 2278 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1991 DEBUGFS_ADD_FILE(channels, data, S_IRUSR); 2279 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1992 DEBUGFS_ADD_FILE(status, data, S_IRUSR); 2280 DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1993 DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR); 2281 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
1994 DEBUGFS_ADD_FILE(qos, data, S_IRUSR); 2282 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1995 DEBUGFS_ADD_FILE(led, data, S_IRUSR); 2283 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
1996 DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR); 2284 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1997 DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR); 2285 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
1998 DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR); 2286 DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
1999 DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR); 2287 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
2000 DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR); 2288 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
2001 DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR); 2289 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
2002 DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR); 2290 DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
2003 DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR); 2291 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
2004 DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR); 2292 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
2005 DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR); 2293 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
2006 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); 2294 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
2007 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); 2295 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
2008 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); 2296 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2009 DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); 2297 DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
2298 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2010 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2299 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
2011 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2300 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
2012 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2301 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
2013 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 2302 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
2014 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 2303 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
2015 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 2304 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2016 DEBUGFS_ADD_FILE(ucode_tracing, debug, S_IWUSR | S_IRUSR); 2305 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
2017 } 2306 }
2018 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 2307 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
2019 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 2308 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2020 &priv->disable_chain_noise_cal); 2309 &priv->disable_chain_noise_cal);
2021 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 2310 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
2022 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 2311 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
2023 DEBUGFS_ADD_BOOL(disable_tx_power, rf, 2312 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
2024 &priv->disable_tx_power_cal); 2313 &priv->disable_tx_power_cal);
2025 return 0; 2314 return 0;
2026 2315
2027err: 2316err:
2028 IWL_ERR(priv, "Can't open the debugfs directory\n"); 2317 IWL_ERR(priv, "Can't create the debugfs directory\n");
2029 iwl_dbgfs_unregister(priv); 2318 iwl_dbgfs_unregister(priv);
2030 return ret; 2319 return -ENOMEM;
2031} 2320}
2032EXPORT_SYMBOL(iwl_dbgfs_register); 2321EXPORT_SYMBOL(iwl_dbgfs_register);
2033 2322
@@ -2037,59 +2326,11 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
2037 */ 2326 */
2038void iwl_dbgfs_unregister(struct iwl_priv *priv) 2327void iwl_dbgfs_unregister(struct iwl_priv *priv)
2039{ 2328{
2040 if (!priv->dbgfs) 2329 if (!priv->debugfs_dir)
2041 return; 2330 return;
2042 2331
2043 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override); 2332 debugfs_remove_recursive(priv->debugfs_dir);
2044 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command); 2333 priv->debugfs_dir = NULL;
2045 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
2046 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
2047 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
2048 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
2049 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
2050 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
2051 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
2052 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
2053 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
2054 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
2055 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
2056 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
2057 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
2058 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
2059 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
2060 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
2061 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
2062 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
2063 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
2064 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2065 file_clear_ucode_statistics);
2066 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2067 file_clear_traffic_statistics);
2068 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr);
2069 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
2070 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2071 file_ucode_rx_stats);
2072 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2073 file_ucode_tx_stats);
2074 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2075 file_ucode_general_stats);
2076 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2077 file_sensitivity);
2078 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2079 file_chain_noise);
2080 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2081 file_ucode_tracing);
2082 }
2083 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
2084 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
2085 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
2086 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
2087 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
2088 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
2089 DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
2090 DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
2091 kfree(priv->dbgfs);
2092 priv->dbgfs = NULL;
2093} 2334}
2094EXPORT_SYMBOL(iwl_dbgfs_unregister); 2335EXPORT_SYMBOL(iwl_dbgfs_unregister);
2095 2336
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 70f0e79c8e4a..55dc5a866542 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -1011,6 +1011,30 @@ struct iwl_event_log {
1011 int wraps_more_count; 1011 int wraps_more_count;
1012}; 1012};
1013 1013
1014/*
1015 * host interrupt timeout value
1016 * used with setting interrupt coalescing timer
1017 * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
1018 *
1019 * default interrupt coalescing timer is 64 x 32 = 2048 usecs
1020 * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
1021 */
1022#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
1023#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
1024#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
1025#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
1026#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
1027#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
1028
1029/*
1030 * This is the threshold value of plcp error rate per 100mSecs. It is
1031 * used to set and check for the validity of plcp_delta.
1032 */
1033#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0)
1034#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)
1035#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)
1036#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
1037
1014struct iwl_priv { 1038struct iwl_priv {
1015 1039
1016 /* ieee device used by generic ieee processing code */ 1040 /* ieee device used by generic ieee processing code */
@@ -1031,13 +1055,16 @@ struct iwl_priv {
1031 1055
1032 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 1056 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
1033 1057
1034#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
1035 /* spectrum measurement report caching */ 1058 /* spectrum measurement report caching */
1036 struct iwl_spectrum_notification measure_report; 1059 struct iwl_spectrum_notification measure_report;
1037 u8 measurement_status; 1060 u8 measurement_status;
1038#endif 1061
1039 /* ucode beacon time */ 1062 /* ucode beacon time */
1040 u32 ucode_beacon_time; 1063 u32 ucode_beacon_time;
1064 int missed_beacon_threshold;
1065
1066 /* storing the jiffies when the plcp error rate is received */
1067 unsigned long plcp_jiffies;
1041 1068
1042 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1069 /* we allocate array of iwl4965_channel_info for NIC's valid channels.
1043 * Access via channel # using indirect index array */ 1070 * Access via channel # using indirect index array */
@@ -1056,14 +1083,15 @@ struct iwl_priv {
1056 struct iwl_calib_result calib_results[IWL_CALIB_MAX]; 1083 struct iwl_calib_result calib_results[IWL_CALIB_MAX];
1057 1084
1058 /* Scan related variables */ 1085 /* Scan related variables */
1059 unsigned long last_scan_jiffies;
1060 unsigned long next_scan_jiffies; 1086 unsigned long next_scan_jiffies;
1061 unsigned long scan_start; 1087 unsigned long scan_start;
1062 unsigned long scan_pass_start; 1088 unsigned long scan_pass_start;
1063 unsigned long scan_start_tsf; 1089 unsigned long scan_start_tsf;
1090 unsigned long last_internal_scan_jiffies;
1064 void *scan; 1091 void *scan;
1065 int scan_bands; 1092 int scan_bands;
1066 struct cfg80211_scan_request *scan_request; 1093 struct cfg80211_scan_request *scan_request;
1094 bool is_internal_short_scan;
1067 u8 scan_tx_ant[IEEE80211_NUM_BANDS]; 1095 u8 scan_tx_ant[IEEE80211_NUM_BANDS];
1068 u8 mgmt_tx_ant; 1096 u8 mgmt_tx_ant;
1069 1097
@@ -1162,6 +1190,8 @@ struct iwl_priv {
1162 struct iwl_notif_statistics statistics; 1190 struct iwl_notif_statistics statistics;
1163#ifdef CONFIG_IWLWIFI_DEBUG 1191#ifdef CONFIG_IWLWIFI_DEBUG
1164 struct iwl_notif_statistics accum_statistics; 1192 struct iwl_notif_statistics accum_statistics;
1193 struct iwl_notif_statistics delta_statistics;
1194 struct iwl_notif_statistics max_delta;
1165#endif 1195#endif
1166 1196
1167 /* context information */ 1197 /* context information */
@@ -1234,15 +1264,10 @@ struct iwl_priv {
1234 1264
1235 struct workqueue_struct *workqueue; 1265 struct workqueue_struct *workqueue;
1236 1266
1237 struct work_struct up;
1238 struct work_struct restart; 1267 struct work_struct restart;
1239 struct work_struct calibrated_work;
1240 struct work_struct scan_completed; 1268 struct work_struct scan_completed;
1241 struct work_struct rx_replenish; 1269 struct work_struct rx_replenish;
1242 struct work_struct abort_scan; 1270 struct work_struct abort_scan;
1243 struct work_struct update_link_led;
1244 struct work_struct auth_work;
1245 struct work_struct report_work;
1246 struct work_struct request_scan; 1271 struct work_struct request_scan;
1247 struct work_struct beacon_update; 1272 struct work_struct beacon_update;
1248 struct work_struct tt_work; 1273 struct work_struct tt_work;
@@ -1278,7 +1303,8 @@ struct iwl_priv {
1278 u16 rx_traffic_idx; 1303 u16 rx_traffic_idx;
1279 u8 *tx_traffic; 1304 u8 *tx_traffic;
1280 u8 *rx_traffic; 1305 u8 *rx_traffic;
1281 struct iwl_debugfs *dbgfs; 1306 struct dentry *debugfs_dir;
1307 u32 dbgfs_sram_offset, dbgfs_sram_len;
1282#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1308#endif /* CONFIG_IWLWIFI_DEBUGFS */
1283#endif /* CONFIG_IWLWIFI_DEBUG */ 1309#endif /* CONFIG_IWLWIFI_DEBUG */
1284 1310
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 4a30969689ff..fd37152abae3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 0cd9c02ee044..4e1ba824dc50 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 65fa8a69fd5a..113c3669b9ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -379,6 +379,25 @@
379 379
380#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010) 380#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010)
381 381
382/**
383 * Bit fields for TSSR(Tx Shared Status & Control) error status register:
384 * 31: Indicates an address error when accessed to internal memory
385 * uCode/driver must write "1" in order to clear this flag
386 * 30: Indicates that Host did not send the expected number of dwords to FH
387 * uCode/driver must write "1" in order to clear this flag
388 * 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA
389 * command was received from the scheduler while the TRB was already full
390 * with previous command
391 * uCode/driver must write "1" in order to clear this flag
392 * 7-0: Each status bit indicates a channel's TxCredit error. When an error
393 * bit is set, it indicates that the FH has received a full indication
394 * from the RTC TxFIFO and the current value of the TxCredit counter was
395 * not equal to zero. This mean that the credit mechanism was not
396 * synchronized to the TxFIFO status
397 * uCode/driver must write "1" in order to clear this flag
398 */
399#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018)
400
382#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24) 401#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
383#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16) 402#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
384 403
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 87d684efe110..86783c27d97c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index bd0b12efb5c7..45af5bbc1c56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index e552d4c4bdbe..c719baf2585a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project. 5 * Portions of this file are derived from the ipw3945 project.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 46c7a95b88f0..a6f9c918aabc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index f47f053f02ea..49a70baa3fb6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 8ccc0bb1d9ed..1a1a9f081cc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -303,13 +303,12 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
303 sizeof(struct iwl_powertable_cmd), cmd); 303 sizeof(struct iwl_powertable_cmd), cmd);
304} 304}
305 305
306 306/* priv->mutex must be held */
307int iwl_power_update_mode(struct iwl_priv *priv, bool force) 307int iwl_power_update_mode(struct iwl_priv *priv, bool force)
308{ 308{
309 int ret = 0; 309 int ret = 0;
310 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 310 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
311 bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) && 311 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
312 (priv->hw->conf.flags & IEEE80211_CONF_PS);
313 bool update_chains; 312 bool update_chains;
314 struct iwl_powertable_cmd cmd; 313 struct iwl_powertable_cmd cmd;
315 int dtimper; 314 int dtimper;
@@ -319,7 +318,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
319 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; 318 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
320 319
321 if (priv->vif) 320 if (priv->vif)
322 dtimper = priv->vif->bss_conf.dtim_period; 321 dtimper = priv->hw->conf.ps_dtim_period;
323 else 322 else
324 dtimper = 1; 323 dtimper = 1;
325 324
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 310c32e8f698..5db91c10dcc8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 6d95832db06d..d2d2a9174900 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
9 * 9 *
10 * 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
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. 33 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 6f36b6e79f5e..5df66382d922 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -473,8 +473,8 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
473 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| 473 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); 474 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
475 475
476 /* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */ 476 /* Set interrupt coalescing timer to default (2048 usecs) */
477 iwl_write8(priv, CSR_INT_COALESCING, 0x40); 477 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
478 478
479 return 0; 479 return 0;
480} 480}
@@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
499 struct iwl_missed_beacon_notif *missed_beacon; 499 struct iwl_missed_beacon_notif *missed_beacon;
500 500
501 missed_beacon = &pkt->u.missed_beacon; 501 missed_beacon = &pkt->u.missed_beacon;
502 if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { 502 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
503 priv->missed_beacon_threshold) {
503 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", 504 IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
504 le32_to_cpu(missed_beacon->consequtive_missed_beacons), 505 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
505 le32_to_cpu(missed_beacon->total_missed_becons), 506 le32_to_cpu(missed_beacon->total_missed_becons),
506 le32_to_cpu(missed_beacon->num_recvd_beacons), 507 le32_to_cpu(missed_beacon->num_recvd_beacons),
507 le32_to_cpu(missed_beacon->num_expected_beacons)); 508 le32_to_cpu(missed_beacon->num_expected_beacons));
@@ -511,6 +512,24 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
511} 512}
512EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); 513EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
513 514
515void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
516 struct iwl_rx_mem_buffer *rxb)
517{
518 struct iwl_rx_packet *pkt = rxb_addr(rxb);
519 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
520
521 if (!report->state) {
522 IWL_DEBUG_11H(priv,
523 "Spectrum Measure Notification: Start\n");
524 return;
525 }
526
527 memcpy(&priv->measure_report, report, sizeof(*report));
528 priv->measurement_status |= MEASUREMENT_READY;
529}
530EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
531
532
514 533
515/* Calculate noise level, based on measurements during network silence just 534/* Calculate noise level, based on measurements during network silence just
516 * before arriving beacon. This measurement can be done only if we know 535 * before arriving beacon. This measurement can be done only if we know
@@ -564,15 +583,24 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
564 int i; 583 int i;
565 __le32 *prev_stats; 584 __le32 *prev_stats;
566 u32 *accum_stats; 585 u32 *accum_stats;
586 u32 *delta, *max_delta;
567 587
568 prev_stats = (__le32 *)&priv->statistics; 588 prev_stats = (__le32 *)&priv->statistics;
569 accum_stats = (u32 *)&priv->accum_statistics; 589 accum_stats = (u32 *)&priv->accum_statistics;
590 delta = (u32 *)&priv->delta_statistics;
591 max_delta = (u32 *)&priv->max_delta;
570 592
571 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 593 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
572 i += sizeof(__le32), stats++, prev_stats++, accum_stats++) 594 i += sizeof(__le32), stats++, prev_stats++, delta++,
573 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) 595 max_delta++, accum_stats++) {
574 *accum_stats += (le32_to_cpu(*stats) - 596 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
597 *delta = (le32_to_cpu(*stats) -
575 le32_to_cpu(*prev_stats)); 598 le32_to_cpu(*prev_stats));
599 *accum_stats += *delta;
600 if (*delta > *max_delta)
601 *max_delta = *delta;
602 }
603 }
576 604
577 /* reset accumulative statistics for "no-counter" type statistics */ 605 /* reset accumulative statistics for "no-counter" type statistics */
578 priv->accum_statistics.general.temperature = 606 priv->accum_statistics.general.temperature =
@@ -592,11 +620,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
592 620
593#define REG_RECALIB_PERIOD (60) 621#define REG_RECALIB_PERIOD (60)
594 622
623#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
595void iwl_rx_statistics(struct iwl_priv *priv, 624void iwl_rx_statistics(struct iwl_priv *priv,
596 struct iwl_rx_mem_buffer *rxb) 625 struct iwl_rx_mem_buffer *rxb)
597{ 626{
598 int change; 627 int change;
599 struct iwl_rx_packet *pkt = rxb_addr(rxb); 628 struct iwl_rx_packet *pkt = rxb_addr(rxb);
629 int combined_plcp_delta;
630 unsigned int plcp_msec;
631 unsigned long plcp_received_jiffies;
600 632
601 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 633 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
602 (int)sizeof(priv->statistics), 634 (int)sizeof(priv->statistics),
@@ -611,6 +643,56 @@ void iwl_rx_statistics(struct iwl_priv *priv,
611#ifdef CONFIG_IWLWIFI_DEBUG 643#ifdef CONFIG_IWLWIFI_DEBUG
612 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 644 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
613#endif 645#endif
646 /*
647 * check for plcp_err and trigger radio reset if it exceeds
648 * the plcp error threshold plcp_delta.
649 */
650 plcp_received_jiffies = jiffies;
651 plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
652 (long) priv->plcp_jiffies);
653 priv->plcp_jiffies = plcp_received_jiffies;
654 /*
655 * check to make sure plcp_msec is not 0 to prevent division
656 * by zero.
657 */
658 if (plcp_msec) {
659 combined_plcp_delta =
660 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
661 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) +
662 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
663 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
664
665 if ((combined_plcp_delta > 0) &&
666 ((combined_plcp_delta * 100) / plcp_msec) >
667 priv->cfg->plcp_delta_threshold) {
668 /*
669 * if plcp_err exceed the threshold, the following
670 * data is printed in csv format:
671 * Text: plcp_err exceeded %d,
672 * Received ofdm.plcp_err,
673 * Current ofdm.plcp_err,
674 * Received ofdm_ht.plcp_err,
675 * Current ofdm_ht.plcp_err,
676 * combined_plcp_delta,
677 * plcp_msec
678 */
679 IWL_DEBUG_RADIO(priv, PLCP_MSG,
680 priv->cfg->plcp_delta_threshold,
681 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
682 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
683 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
684 le32_to_cpu(
685 priv->statistics.rx.ofdm_ht.plcp_err),
686 combined_plcp_delta, plcp_msec);
687
688 /*
689 * Reset the RF radio due to the high plcp
690 * error rate
691 */
692 iwl_force_rf_reset(priv);
693 }
694 }
695
614 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 696 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
615 697
616 set_bit(STATUS_STATISTICS, &priv->status); 698 set_bit(STATUS_STATISTICS, &priv->status);
@@ -638,11 +720,13 @@ void iwl_reply_statistics(struct iwl_priv *priv,
638 struct iwl_rx_packet *pkt = rxb_addr(rxb); 720 struct iwl_rx_packet *pkt = rxb_addr(rxb);
639 721
640 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 722 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
641 memset(&priv->statistics, 0,
642 sizeof(struct iwl_notif_statistics));
643#ifdef CONFIG_IWLWIFI_DEBUG 723#ifdef CONFIG_IWLWIFI_DEBUG
644 memset(&priv->accum_statistics, 0, 724 memset(&priv->accum_statistics, 0,
645 sizeof(struct iwl_notif_statistics)); 725 sizeof(struct iwl_notif_statistics));
726 memset(&priv->delta_statistics, 0,
727 sizeof(struct iwl_notif_statistics));
728 memset(&priv->max_delta, 0,
729 sizeof(struct iwl_notif_statistics));
646#endif 730#endif
647 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 731 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
648 } 732 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index fa1c89ba6459..08faafae8497 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of version 2 of the GNU General Public License as
@@ -192,19 +192,17 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
192 IWL_DEBUG_SCAN(priv, "Scan ch.res: " 192 IWL_DEBUG_SCAN(priv, "Scan ch.res: "
193 "%d [802.11%s] " 193 "%d [802.11%s] "
194 "(TSF: 0x%08X:%08X) - %d " 194 "(TSF: 0x%08X:%08X) - %d "
195 "elapsed=%lu usec (%dms since last)\n", 195 "elapsed=%lu usec\n",
196 notif->channel, 196 notif->channel,
197 notif->band ? "bg" : "a", 197 notif->band ? "bg" : "a",
198 le32_to_cpu(notif->tsf_high), 198 le32_to_cpu(notif->tsf_high),
199 le32_to_cpu(notif->tsf_low), 199 le32_to_cpu(notif->tsf_low),
200 le32_to_cpu(notif->statistics[0]), 200 le32_to_cpu(notif->statistics[0]),
201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, 201 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
202 jiffies_to_msecs(elapsed_jiffies
203 (priv->last_scan_jiffies, jiffies)));
204#endif 202#endif
205 203
206 priv->last_scan_jiffies = jiffies; 204 if (!priv->is_internal_short_scan)
207 priv->next_scan_jiffies = 0; 205 priv->next_scan_jiffies = 0;
208} 206}
209 207
210/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ 208/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
@@ -250,8 +248,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
250 goto reschedule; 248 goto reschedule;
251 } 249 }
252 250
253 priv->last_scan_jiffies = jiffies; 251 if (!priv->is_internal_short_scan)
254 priv->next_scan_jiffies = 0; 252 priv->next_scan_jiffies = 0;
253 else
254 priv->last_internal_scan_jiffies = jiffies;
255
255 IWL_DEBUG_INFO(priv, "Setting scan to off\n"); 256 IWL_DEBUG_INFO(priv, "Setting scan to off\n");
256 257
257 clear_bit(STATUS_SCANNING, &priv->status); 258 clear_bit(STATUS_SCANNING, &priv->status);
@@ -314,6 +315,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
314} 315}
315EXPORT_SYMBOL(iwl_get_passive_dwell_time); 316EXPORT_SYMBOL(iwl_get_passive_dwell_time);
316 317
318static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
319 enum ieee80211_band band,
320 struct iwl_scan_channel *scan_ch)
321{
322 const struct ieee80211_supported_band *sband;
323 const struct iwl_channel_info *ch_info;
324 u16 passive_dwell = 0;
325 u16 active_dwell = 0;
326 int i, added = 0;
327 u16 channel = 0;
328
329 sband = iwl_get_hw_mode(priv, band);
330 if (!sband) {
331 IWL_ERR(priv, "invalid band\n");
332 return added;
333 }
334
335 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
336 passive_dwell = iwl_get_passive_dwell_time(priv, band);
337
338 if (passive_dwell <= active_dwell)
339 passive_dwell = active_dwell + 1;
340
341 /* only scan single channel, good enough to reset the RF */
342 /* pick the first valid not in-use channel */
343 if (band == IEEE80211_BAND_5GHZ) {
344 for (i = 14; i < priv->channel_count; i++) {
345 if (priv->channel_info[i].channel !=
346 le16_to_cpu(priv->staging_rxon.channel)) {
347 channel = priv->channel_info[i].channel;
348 ch_info = iwl_get_channel_info(priv,
349 band, channel);
350 if (is_channel_valid(ch_info))
351 break;
352 }
353 }
354 } else {
355 for (i = 0; i < 14; i++) {
356 if (priv->channel_info[i].channel !=
357 le16_to_cpu(priv->staging_rxon.channel)) {
358 channel =
359 priv->channel_info[i].channel;
360 ch_info = iwl_get_channel_info(priv,
361 band, channel);
362 if (is_channel_valid(ch_info))
363 break;
364 }
365 }
366 }
367 if (channel) {
368 scan_ch->channel = cpu_to_le16(channel);
369 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
370 scan_ch->active_dwell = cpu_to_le16(active_dwell);
371 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
372 /* Set txpower levels to defaults */
373 scan_ch->dsp_atten = 110;
374 if (band == IEEE80211_BAND_5GHZ)
375 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
376 else
377 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
378 added++;
379 } else
380 IWL_ERR(priv, "no valid channel found\n");
381 return added;
382}
383
317static int iwl_get_channels_for_scan(struct iwl_priv *priv, 384static int iwl_get_channels_for_scan(struct iwl_priv *priv,
318 enum ieee80211_band band, 385 enum ieee80211_band band,
319 u8 is_active, u8 n_probes, 386 u8 is_active, u8 n_probes,
@@ -421,6 +488,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
421 488
422 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 489 IWL_DEBUG_INFO(priv, "Starting scan...\n");
423 set_bit(STATUS_SCANNING, &priv->status); 490 set_bit(STATUS_SCANNING, &priv->status);
491 priv->is_internal_short_scan = false;
424 priv->scan_start = jiffies; 492 priv->scan_start = jiffies;
425 priv->scan_pass_start = priv->scan_start; 493 priv->scan_pass_start = priv->scan_start;
426 494
@@ -461,15 +529,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
461 goto out_unlock; 529 goto out_unlock;
462 } 530 }
463 531
464 /* if we just finished scan ask for delay */
465 if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
466 time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
467 IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
468 queue_work(priv->workqueue, &priv->scan_completed);
469 ret = 0;
470 goto out_unlock;
471 }
472
473 priv->scan_bands = 0; 532 priv->scan_bands = 0;
474 for (i = 0; i < req->n_channels; i++) 533 for (i = 0; i < req->n_channels; i++)
475 priv->scan_bands |= BIT(req->channels[i]->band); 534 priv->scan_bands |= BIT(req->channels[i]->band);
@@ -488,6 +547,54 @@ out_unlock:
488} 547}
489EXPORT_SYMBOL(iwl_mac_hw_scan); 548EXPORT_SYMBOL(iwl_mac_hw_scan);
490 549
550/*
551 * internal short scan, this function should only been called while associated.
552 * It will reset and tune the radio to prevent possible RF related problem
553 */
554#define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1)
555
556int iwl_internal_short_hw_scan(struct iwl_priv *priv)
557{
558 int ret = 0;
559
560 if (!iwl_is_ready_rf(priv)) {
561 ret = -EIO;
562 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
563 goto out;
564 }
565 if (test_bit(STATUS_SCANNING, &priv->status)) {
566 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
567 ret = -EAGAIN;
568 goto out;
569 }
570 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
571 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
572 ret = -EAGAIN;
573 goto out;
574 }
575 if (priv->last_internal_scan_jiffies &&
576 time_after(priv->last_internal_scan_jiffies +
577 IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) {
578 IWL_DEBUG_SCAN(priv, "internal scan rejected\n");
579 goto out;
580 }
581
582 priv->scan_bands = 0;
583 if (priv->band == IEEE80211_BAND_5GHZ)
584 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
585 else
586 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
587
588 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
589 set_bit(STATUS_SCANNING, &priv->status);
590 priv->is_internal_short_scan = true;
591 queue_work(priv->workqueue, &priv->request_scan);
592
593out:
594 return ret;
595}
596EXPORT_SYMBOL(iwl_internal_short_hw_scan);
597
491#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) 598#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
492 599
493void iwl_bg_scan_check(struct work_struct *data) 600void iwl_bg_scan_check(struct work_struct *data)
@@ -551,7 +658,8 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
551 if (WARN_ON(left < ie_len)) 658 if (WARN_ON(left < ie_len))
552 return len; 659 return len;
553 660
554 memcpy(pos, ies, ie_len); 661 if (ies)
662 memcpy(pos, ies, ie_len);
555 len += ie_len; 663 len += ie_len;
556 left -= ie_len; 664 left -= ie_len;
557 665
@@ -654,7 +762,6 @@ static void iwl_bg_request_scan(struct work_struct *data)
654 unsigned long flags; 762 unsigned long flags;
655 763
656 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 764 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
657
658 spin_lock_irqsave(&priv->lock, flags); 765 spin_lock_irqsave(&priv->lock, flags);
659 interval = priv->beacon_int; 766 interval = priv->beacon_int;
660 spin_unlock_irqrestore(&priv->lock, flags); 767 spin_unlock_irqrestore(&priv->lock, flags);
@@ -672,7 +779,9 @@ static void iwl_bg_request_scan(struct work_struct *data)
672 scan_suspend_time, interval); 779 scan_suspend_time, interval);
673 } 780 }
674 781
675 if (priv->scan_request->n_ssids) { 782 if (priv->is_internal_short_scan) {
783 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
784 } else if (priv->scan_request->n_ssids) {
676 int i, p = 0; 785 int i, p = 0;
677 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); 786 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
678 for (i = 0; i < priv->scan_request->n_ssids; i++) { 787 for (i = 0; i < priv->scan_request->n_ssids; i++) {
@@ -753,24 +862,38 @@ static void iwl_bg_request_scan(struct work_struct *data)
753 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; 862 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
754 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 863 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
755 scan->rx_chain = cpu_to_le16(rx_chain); 864 scan->rx_chain = cpu_to_le16(rx_chain);
756 cmd_len = iwl_fill_probe_req(priv, 865 if (!priv->is_internal_short_scan) {
757 (struct ieee80211_mgmt *)scan->data, 866 cmd_len = iwl_fill_probe_req(priv,
758 priv->scan_request->ie, 867 (struct ieee80211_mgmt *)scan->data,
759 priv->scan_request->ie_len, 868 priv->scan_request->ie,
760 IWL_MAX_SCAN_SIZE - sizeof(*scan)); 869 priv->scan_request->ie_len,
870 IWL_MAX_SCAN_SIZE - sizeof(*scan));
871 } else {
872 cmd_len = iwl_fill_probe_req(priv,
873 (struct ieee80211_mgmt *)scan->data,
874 NULL, 0,
875 IWL_MAX_SCAN_SIZE - sizeof(*scan));
761 876
877 }
762 scan->tx_cmd.len = cpu_to_le16(cmd_len); 878 scan->tx_cmd.len = cpu_to_le16(cmd_len);
763
764 if (iwl_is_monitor_mode(priv)) 879 if (iwl_is_monitor_mode(priv))
765 scan->filter_flags = RXON_FILTER_PROMISC_MSK; 880 scan->filter_flags = RXON_FILTER_PROMISC_MSK;
766 881
767 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | 882 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
768 RXON_FILTER_BCON_AWARE_MSK); 883 RXON_FILTER_BCON_AWARE_MSK);
769 884
770 scan->channel_count = 885 if (priv->is_internal_short_scan) {
771 iwl_get_channels_for_scan(priv, band, is_active, n_probes, 886 scan->channel_count =
772 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 887 iwl_get_single_channel_for_scan(priv, band,
773 888 (void *)&scan->data[le16_to_cpu(
889 scan->tx_cmd.len)]);
890 } else {
891 scan->channel_count =
892 iwl_get_channels_for_scan(priv, band,
893 is_active, n_probes,
894 (void *)&scan->data[le16_to_cpu(
895 scan->tx_cmd.len)]);
896 }
774 if (scan->channel_count == 0) { 897 if (scan->channel_count == 0) {
775 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 898 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
776 goto done; 899 goto done;
@@ -831,7 +954,12 @@ void iwl_bg_scan_completed(struct work_struct *work)
831 954
832 cancel_delayed_work(&priv->scan_check); 955 cancel_delayed_work(&priv->scan_check);
833 956
834 ieee80211_scan_completed(priv->hw, false); 957 if (!priv->is_internal_short_scan)
958 ieee80211_scan_completed(priv->hw, false);
959 else {
960 priv->is_internal_short_scan = false;
961 IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
962 }
835 963
836 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 964 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
837 return; 965 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
deleted file mode 100644
index 1ea5cd345fe8..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/wireless.h>
38
39#include <net/mac80211.h>
40
41#include "iwl-eeprom.h"
42#include "iwl-dev.h"
43#include "iwl-core.h"
44#include "iwl-io.h"
45#include "iwl-spectrum.h"
46
47#define BEACON_TIME_MASK_LOW 0x00FFFFFF
48#define BEACON_TIME_MASK_HIGH 0xFF000000
49#define TIME_UNIT 1024
50
51/*
52 * extended beacon time format
53 * time in usec will be changed into a 32-bit value in 8:24 format
54 * the high 1 byte is the beacon counts
55 * the lower 3 bytes is the time in usec within one beacon interval
56 */
57
58/* TOOD: was used in sysfs debug interface need to add to mac */
59#if 0
60static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
61{
62 u32 quot;
63 u32 rem;
64 u32 interval = beacon_interval * 1024;
65
66 if (!interval || !usec)
67 return 0;
68
69 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
70 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
71
72 return (quot << 24) + rem;
73}
74
75/* base is usually what we get from ucode with each received frame,
76 * the same as HW timer counter counting down
77 */
78
79static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
80{
81 u32 base_low = base & BEACON_TIME_MASK_LOW;
82 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
83 u32 interval = beacon_interval * TIME_UNIT;
84 u32 res = (base & BEACON_TIME_MASK_HIGH) +
85 (addon & BEACON_TIME_MASK_HIGH);
86
87 if (base_low > addon_low)
88 res += base_low - addon_low;
89 else if (base_low < addon_low) {
90 res += interval + base_low - addon_low;
91 res += (1 << 24);
92 } else
93 res += (1 << 24);
94
95 return cpu_to_le32(res);
96}
97static int iwl_get_measurement(struct iwl_priv *priv,
98 struct ieee80211_measurement_params *params,
99 u8 type)
100{
101 struct iwl4965_spectrum_cmd spectrum;
102 struct iwl_rx_packet *res;
103 struct iwl_host_cmd cmd = {
104 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
105 .data = (void *)&spectrum,
106 .meta.flags = CMD_WANT_SKB,
107 };
108 u32 add_time = le64_to_cpu(params->start_time);
109 int rc;
110 int spectrum_resp_status;
111 int duration = le16_to_cpu(params->duration);
112
113 if (iwl_is_associated(priv))
114 add_time =
115 iwl_usecs_to_beacons(
116 le64_to_cpu(params->start_time) - priv->last_tsf,
117 le16_to_cpu(priv->rxon_timing.beacon_interval));
118
119 memset(&spectrum, 0, sizeof(spectrum));
120
121 spectrum.channel_count = cpu_to_le16(1);
122 spectrum.flags =
123 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
124 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
125 cmd.len = sizeof(spectrum);
126 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
127
128 if (iwl_is_associated(priv))
129 spectrum.start_time =
130 iwl_add_beacon_time(priv->last_beacon_time,
131 add_time,
132 le16_to_cpu(priv->rxon_timing.beacon_interval));
133 else
134 spectrum.start_time = 0;
135
136 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
137 spectrum.channels[0].channel = params->channel;
138 spectrum.channels[0].type = type;
139 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
140 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
141 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
142
143 rc = iwl_send_cmd_sync(priv, &cmd);
144 if (rc)
145 return rc;
146
147 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
148 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
149 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
150 rc = -EIO;
151 }
152
153 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
154 switch (spectrum_resp_status) {
155 case 0: /* Command will be handled */
156 if (res->u.spectrum.id != 0xff) {
157 IWL_DEBUG_INFO(priv,
158 "Replaced existing measurement: %d\n",
159 res->u.spectrum.id);
160 priv->measurement_status &= ~MEASUREMENT_READY;
161 }
162 priv->measurement_status |= MEASUREMENT_ACTIVE;
163 rc = 0;
164 break;
165
166 case 1: /* Command will not be handled */
167 rc = -EAGAIN;
168 break;
169 }
170
171 dev_kfree_skb_any(cmd.meta.u.skb);
172
173 return rc;
174}
175#endif
176
177static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
178 struct iwl_rx_mem_buffer *rxb)
179{
180 struct iwl_rx_packet *pkt = rxb_addr(rxb);
181 struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
182
183 if (!report->state) {
184 IWL_DEBUG_11H(priv,
185 "Spectrum Measure Notification: Start\n");
186 return;
187 }
188
189 memcpy(&priv->measure_report, report, sizeof(*report));
190 priv->measurement_status |= MEASUREMENT_READY;
191}
192
193void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
194{
195 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
196 iwl_rx_spectrum_measure_notif;
197}
198EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index a77c1e619062..af6babee2891 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ieee80211 subsystem header files. 5 * Portions of this file are derived from the ieee80211 subsystem header files.
6 * 6 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 90fbdb25399e..4a6686fa6b36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -80,46 +80,103 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
80} 80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id); 81EXPORT_SYMBOL(iwl_get_ra_sta_id);
82 82
83/* priv->sta_lock must be held */
83static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 84static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
84{ 85{
85 unsigned long flags;
86
87 spin_lock_irqsave(&priv->sta_lock, flags);
88 86
89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) 87 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
90 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", 88 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
91 sta_id); 89 sta_id, priv->stations[sta_id].sta.sta.addr);
92
93 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
94 IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
95 priv->stations[sta_id].sta.sta.addr);
96 90
97 spin_unlock_irqrestore(&priv->sta_lock, flags); 91 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
92 IWL_DEBUG_ASSOC(priv,
93 "STA id %u addr %pM already present in uCode (according to driver)\n",
94 sta_id, priv->stations[sta_id].sta.sta.addr);
95 } else {
96 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
97 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
98 sta_id, priv->stations[sta_id].sta.sta.addr);
99 }
98} 100}
99 101
100static void iwl_add_sta_callback(struct iwl_priv *priv, 102static void iwl_process_add_sta_resp(struct iwl_priv *priv,
101 struct iwl_device_cmd *cmd, 103 struct iwl_addsta_cmd *addsta,
102 struct iwl_rx_packet *pkt) 104 struct iwl_rx_packet *pkt,
105 bool sync)
103{ 106{
104 struct iwl_addsta_cmd *addsta =
105 (struct iwl_addsta_cmd *)cmd->cmd.payload;
106 u8 sta_id = addsta->sta.sta_id; 107 u8 sta_id = addsta->sta.sta_id;
108 unsigned long flags;
107 109
108 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 110 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
109 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 111 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
110 pkt->hdr.flags); 112 pkt->hdr.flags);
111 return; 113 return;
112 } 114 }
113 115
116 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
117 sta_id);
118
119 spin_lock_irqsave(&priv->sta_lock, flags);
120
114 switch (pkt->u.add_sta.status) { 121 switch (pkt->u.add_sta.status) {
115 case ADD_STA_SUCCESS_MSK: 122 case ADD_STA_SUCCESS_MSK:
123 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
116 iwl_sta_ucode_activate(priv, sta_id); 124 iwl_sta_ucode_activate(priv, sta_id);
117 /* fall through */ 125 break;
126 case ADD_STA_NO_ROOM_IN_TABLE:
127 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
128 sta_id);
129 break;
130 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
131 IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
132 sta_id);
133 break;
134 case ADD_STA_MODIFY_NON_EXIST_STA:
135 IWL_ERR(priv, "Attempting to modify non-existing station %d \n",
136 sta_id);
137 break;
118 default: 138 default:
119 IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", 139 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
120 pkt->u.add_sta.status); 140 pkt->u.add_sta.status);
121 break; 141 break;
122 } 142 }
143
144 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
145 priv->stations[sta_id].sta.mode ==
146 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
147 sta_id, priv->stations[sta_id].sta.sta.addr);
148
149 /*
150 * XXX: The MAC address in the command buffer is often changed from
151 * the original sent to the device. That is, the MAC address
152 * written to the command buffer often is not the same MAC adress
153 * read from the command buffer when the command returns. This
154 * issue has not yet been resolved and this debugging is left to
155 * observe the problem.
156 */
157 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
158 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags);
169}
170
171static void iwl_add_sta_callback(struct iwl_priv *priv,
172 struct iwl_device_cmd *cmd,
173 struct iwl_rx_packet *pkt)
174{
175 struct iwl_addsta_cmd *addsta =
176 (struct iwl_addsta_cmd *)cmd->cmd.payload;
177
178 iwl_process_add_sta_resp(priv, addsta, pkt, false);
179
123} 180}
124 181
125int iwl_send_add_sta(struct iwl_priv *priv, 182int iwl_send_add_sta(struct iwl_priv *priv,
@@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *priv,
145 if (ret || (flags & CMD_ASYNC)) 202 if (ret || (flags & CMD_ASYNC))
146 return ret; 203 return ret;
147 204
148 pkt = (struct iwl_rx_packet *)cmd.reply_page;
149 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
150 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
151 pkt->hdr.flags);
152 ret = -EIO;
153 }
154
155 if (ret == 0) { 205 if (ret == 0) {
156 switch (pkt->u.add_sta.status) { 206 pkt = (struct iwl_rx_packet *)cmd.reply_page;
157 case ADD_STA_SUCCESS_MSK: 207 iwl_process_add_sta_resp(priv, sta, pkt, true);
158 iwl_sta_ucode_activate(priv, sta->sta.sta_id);
159 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
160 break;
161 default:
162 ret = -EIO;
163 IWL_WARN(priv, "REPLY_ADD_STA failed\n");
164 break;
165 }
166 } 208 }
167 iwl_free_pages(priv, cmd.reply_page); 209 iwl_free_pages(priv, cmd.reply_page);
168 210
@@ -1003,24 +1045,19 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1003 struct ieee80211_sta_ht_cap *cur_ht_config = NULL; 1045 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1004 u8 sta_id; 1046 u8 sta_id;
1005 1047
1006 /* Add station to device's station table */
1007
1008 /* 1048 /*
1009 * XXX: This check is definitely not correct, if we're an AP 1049 * Set HT capabilities. It is ok to set this struct even if not using
1010 * it'll always be false which is not what we want, but 1050 * HT config: the priv->current_ht_config.is_ht flag will just be false
1011 * it doesn't look like iwlagn is prepared to be an HT
1012 * AP anyway.
1013 */ 1051 */
1014 if (priv->current_ht_config.is_ht) { 1052 rcu_read_lock();
1015 rcu_read_lock(); 1053 sta = ieee80211_find_sta(priv->vif, addr);
1016 sta = ieee80211_find_sta(priv->vif, addr); 1054 if (sta) {
1017 if (sta) { 1055 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1018 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); 1056 cur_ht_config = &ht_config;
1019 cur_ht_config = &ht_config;
1020 }
1021 rcu_read_unlock();
1022 } 1057 }
1058 rcu_read_unlock();
1023 1059
1060 /* Add station to device's station table */
1024 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config); 1061 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1025 1062
1026 /* Set up default rate scaling table in device's station table */ 1063 /* Set up default rate scaling table in device's station table */
@@ -1085,6 +1122,7 @@ static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
1085 */ 1122 */
1086void iwl_add_bcast_station(struct iwl_priv *priv) 1123void iwl_add_bcast_station(struct iwl_priv *priv)
1087{ 1124{
1125 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1088 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1126 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1089 1127
1090 /* Set up default rate scaling table in device's station table */ 1128 /* Set up default rate scaling table in device's station table */
@@ -1093,6 +1131,16 @@ void iwl_add_bcast_station(struct iwl_priv *priv)
1093EXPORT_SYMBOL(iwl_add_bcast_station); 1131EXPORT_SYMBOL(iwl_add_bcast_station);
1094 1132
1095/** 1133/**
1134 * iwl3945_add_bcast_station - add broadcast station into station table.
1135 */
1136void iwl3945_add_bcast_station(struct iwl_priv *priv)
1137{
1138 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1139 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL);
1140}
1141EXPORT_SYMBOL(iwl3945_add_bcast_station);
1142
1143/**
1096 * iwl_get_sta_id - Find station's index within station table 1144 * iwl_get_sta_id - Find station's index within station table
1097 * 1145 *
1098 * If new IBSS station, create new entry in station table 1146 * If new IBSS station, create new entry in station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 8d052de2d405..2dc35fe28f56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -53,6 +53,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
53 53
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55void iwl_add_bcast_station(struct iwl_priv *priv); 55void iwl_add_bcast_station(struct iwl_priv *priv);
56void iwl3945_add_bcast_station(struct iwl_priv *priv);
56int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 57int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
57void iwl_clear_stations_table(struct iwl_priv *priv); 58void iwl_clear_stations_table(struct iwl_priv *priv);
58int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 59int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 87ce2bd292c7..d365d13e3291 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 10b0aa8024c4..119da54116de 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4 * 4 *
5 * Portions of this file are derived from the ipw3945 project, as well 5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files. 6 * as portions of the ieee80211 subsystem header files.
@@ -56,6 +56,7 @@
56#include "iwl-helpers.h" 56#include "iwl-helpers.h"
57#include "iwl-core.h" 57#include "iwl-core.h"
58#include "iwl-dev.h" 58#include "iwl-dev.h"
59#include "iwl-spectrum.h"
59 60
60/* 61/*
61 * module name, copyright, version, etc. 62 * module name, copyright, version, etc.
@@ -70,14 +71,13 @@
70#define VD 71#define VD
71#endif 72#endif
72 73
73#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT 74/*
74#define VS "s" 75 * add "s" to indicate spectrum measurement included.
75#else 76 * we add it here to be consistent with previous releases in which
76#define VS 77 * this was configurable.
77#endif 78 */
78 79#define DRV_VERSION IWLWIFI_VERSION VD "s"
79#define DRV_VERSION IWLWIFI_VERSION VD VS 80#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
80#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
81#define DRV_AUTHOR "<ilw@linux.intel.com>" 81#define DRV_AUTHOR "<ilw@linux.intel.com>"
82 82
83MODULE_DESCRIPTION(DRV_DESCRIPTION); 83MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -689,10 +689,6 @@ drop:
689 return -1; 689 return -1;
690} 690}
691 691
692#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
693
694#include "iwl-spectrum.h"
695
696#define BEACON_TIME_MASK_LOW 0x00FFFFFF 692#define BEACON_TIME_MASK_LOW 0x00FFFFFF
697#define BEACON_TIME_MASK_HIGH 0xFF000000 693#define BEACON_TIME_MASK_HIGH 0xFF000000
698#define TIME_UNIT 1024 694#define TIME_UNIT 1024
@@ -819,7 +815,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
819 815
820 return rc; 816 return rc;
821} 817}
822#endif
823 818
824static void iwl3945_rx_reply_alive(struct iwl_priv *priv, 819static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
825 struct iwl_rx_mem_buffer *rxb) 820 struct iwl_rx_mem_buffer *rxb)
@@ -962,6 +957,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
962 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; 957 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
963 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 958 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
964 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 959 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
960 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
961 iwl_rx_spectrum_measure_notif;
965 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 962 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
966 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 963 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
967 iwl_rx_pm_debug_statistics_notif; 964 iwl_rx_pm_debug_statistics_notif;
@@ -975,7 +972,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
975 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; 972 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
976 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; 973 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
977 974
978 iwl_setup_spectrum_handlers(priv);
979 iwl_setup_rx_scan_handlers(priv); 975 iwl_setup_rx_scan_handlers(priv);
980 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; 976 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
981 977
@@ -1644,7 +1640,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1644 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1640 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1645 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1641 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1646 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1642 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1647 return pos; 1643 return -EINVAL;
1648 } 1644 }
1649 1645
1650 /* event log header */ 1646 /* event log header */
@@ -1693,7 +1689,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1693 bufsz = size * 48; 1689 bufsz = size * 48;
1694 *buf = kmalloc(bufsz, GFP_KERNEL); 1690 *buf = kmalloc(bufsz, GFP_KERNEL);
1695 if (!*buf) 1691 if (!*buf)
1696 return pos; 1692 return -ENOMEM;
1697 } 1693 }
1698 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1694 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1699 /* if uCode has wrapped back to top of log, 1695 /* if uCode has wrapped back to top of log,
@@ -3037,18 +3033,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
3037 mutex_unlock(&priv->mutex); 3033 mutex_unlock(&priv->mutex);
3038} 3034}
3039 3035
3040static void iwl3945_bg_up(struct work_struct *data)
3041{
3042 struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
3043
3044 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3045 return;
3046
3047 mutex_lock(&priv->mutex);
3048 __iwl3945_up(priv);
3049 mutex_unlock(&priv->mutex);
3050}
3051
3052static void iwl3945_bg_restart(struct work_struct *data) 3036static void iwl3945_bg_restart(struct work_struct *data)
3053{ 3037{
3054 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); 3038 struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -3065,7 +3049,13 @@ static void iwl3945_bg_restart(struct work_struct *data)
3065 ieee80211_restart_hw(priv->hw); 3049 ieee80211_restart_hw(priv->hw);
3066 } else { 3050 } else {
3067 iwl3945_down(priv); 3051 iwl3945_down(priv);
3068 queue_work(priv->workqueue, &priv->up); 3052
3053 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3054 return;
3055
3056 mutex_lock(&priv->mutex);
3057 __iwl3945_up(priv);
3058 mutex_unlock(&priv->mutex);
3069 } 3059 }
3070} 3060}
3071 3061
@@ -3569,8 +3559,6 @@ static ssize_t store_filter_flags(struct device *d,
3569static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3559static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3570 store_filter_flags); 3560 store_filter_flags);
3571 3561
3572#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3573
3574static ssize_t show_measurement(struct device *d, 3562static ssize_t show_measurement(struct device *d,
3575 struct device_attribute *attr, char *buf) 3563 struct device_attribute *attr, char *buf)
3576{ 3564{
@@ -3640,7 +3628,6 @@ static ssize_t store_measurement(struct device *d,
3640 3628
3641static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, 3629static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3642 show_measurement, store_measurement); 3630 show_measurement, store_measurement);
3643#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
3644 3631
3645static ssize_t store_retry_rate(struct device *d, 3632static ssize_t store_retry_rate(struct device *d,
3646 struct device_attribute *attr, 3633 struct device_attribute *attr,
@@ -3789,7 +3776,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3789 3776
3790 init_waitqueue_head(&priv->wait_command_queue); 3777 init_waitqueue_head(&priv->wait_command_queue);
3791 3778
3792 INIT_WORK(&priv->up, iwl3945_bg_up);
3793 INIT_WORK(&priv->restart, iwl3945_bg_restart); 3779 INIT_WORK(&priv->restart, iwl3945_bg_restart);
3794 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); 3780 INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
3795 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); 3781 INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
@@ -3823,9 +3809,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
3823 &dev_attr_dump_errors.attr, 3809 &dev_attr_dump_errors.attr,
3824 &dev_attr_flags.attr, 3810 &dev_attr_flags.attr,
3825 &dev_attr_filter_flags.attr, 3811 &dev_attr_filter_flags.attr,
3826#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3827 &dev_attr_measurement.attr, 3812 &dev_attr_measurement.attr,
3828#endif
3829 &dev_attr_retry_rate.attr, 3813 &dev_attr_retry_rate.attr,
3830 &dev_attr_statistics.attr, 3814 &dev_attr_statistics.attr,
3831 &dev_attr_status.attr, 3815 &dev_attr_status.attr,
@@ -3881,6 +3865,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3881 priv->band = IEEE80211_BAND_2GHZ; 3865 priv->band = IEEE80211_BAND_2GHZ;
3882 3866
3883 priv->iw_mode = NL80211_IFTYPE_STATION; 3867 priv->iw_mode = NL80211_IFTYPE_STATION;
3868 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3884 3869
3885 iwl_reset_qos(priv); 3870 iwl_reset_qos(priv);
3886 3871
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 5e650f358415..f03d5e4e59c3 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -1160,11 +1160,11 @@ int lbs_adhoc_stop(struct lbs_private *priv)
1160static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, 1160static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
1161 struct bss_descriptor *match_bss) 1161 struct bss_descriptor *match_bss)
1162{ 1162{
1163 if (!secinfo->wep_enabled && !secinfo->WPAenabled 1163 if (!secinfo->wep_enabled &&
1164 && !secinfo->WPA2enabled 1164 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1165 && match_bss->wpa_ie[0] != WLAN_EID_GENERIC 1165 match_bss->wpa_ie[0] != WLAN_EID_GENERIC &&
1166 && match_bss->rsn_ie[0] != WLAN_EID_RSN 1166 match_bss->rsn_ie[0] != WLAN_EID_RSN &&
1167 && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1167 !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1168 return 1; 1168 return 1;
1169 else 1169 else
1170 return 0; 1170 return 0;
@@ -1173,9 +1173,9 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
1173static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, 1173static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
1174 struct bss_descriptor *match_bss) 1174 struct bss_descriptor *match_bss)
1175{ 1175{
1176 if (secinfo->wep_enabled && !secinfo->WPAenabled 1176 if (secinfo->wep_enabled &&
1177 && !secinfo->WPA2enabled 1177 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1178 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1178 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1179 return 1; 1179 return 1;
1180 else 1180 else
1181 return 0; 1181 return 0;
@@ -1184,8 +1184,8 @@ static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
1184static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, 1184static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
1185 struct bss_descriptor *match_bss) 1185 struct bss_descriptor *match_bss)
1186{ 1186{
1187 if (!secinfo->wep_enabled && secinfo->WPAenabled 1187 if (!secinfo->wep_enabled && secinfo->WPAenabled &&
1188 && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) 1188 (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
1189 /* privacy bit may NOT be set in some APs like LinkSys WRT54G 1189 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
1190 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ 1190 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
1191 ) 1191 )
@@ -1210,11 +1210,11 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
1210static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, 1210static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
1211 struct bss_descriptor *match_bss) 1211 struct bss_descriptor *match_bss)
1212{ 1212{
1213 if (!secinfo->wep_enabled && !secinfo->WPAenabled 1213 if (!secinfo->wep_enabled &&
1214 && !secinfo->WPA2enabled 1214 !secinfo->WPAenabled && !secinfo->WPA2enabled &&
1215 && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) 1215 (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) &&
1216 && (match_bss->rsn_ie[0] != WLAN_EID_RSN) 1216 (match_bss->rsn_ie[0] != WLAN_EID_RSN) &&
1217 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) 1217 (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
1218 return 1; 1218 return 1;
1219 else 1219 else
1220 return 0; 1220 return 0;
@@ -1525,8 +1525,8 @@ static int assoc_helper_associate(struct lbs_private *priv,
1525 /* If we're given and 'any' BSSID, try associating based on SSID */ 1525 /* If we're given and 'any' BSSID, try associating based on SSID */
1526 1526
1527 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1527 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1528 if (compare_ether_addr(bssid_any, assoc_req->bssid) 1528 if (compare_ether_addr(bssid_any, assoc_req->bssid) &&
1529 && compare_ether_addr(bssid_off, assoc_req->bssid)) { 1529 compare_ether_addr(bssid_off, assoc_req->bssid)) {
1530 ret = assoc_helper_bssid(priv, assoc_req); 1530 ret = assoc_helper_bssid(priv, assoc_req);
1531 done = 1; 1531 done = 1;
1532 } 1532 }
@@ -1612,11 +1612,9 @@ static int assoc_helper_channel(struct lbs_private *priv,
1612 goto restore_mesh; 1612 goto restore_mesh;
1613 } 1613 }
1614 1614
1615 if ( assoc_req->secinfo.wep_enabled 1615 if (assoc_req->secinfo.wep_enabled &&
1616 && (assoc_req->wep_keys[0].len 1616 (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
1617 || assoc_req->wep_keys[1].len 1617 assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) {
1618 || assoc_req->wep_keys[2].len
1619 || assoc_req->wep_keys[3].len)) {
1620 /* Make sure WEP keys are re-sent to firmware */ 1618 /* Make sure WEP keys are re-sent to firmware */
1621 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); 1619 set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
1622 } 1620 }
@@ -1983,14 +1981,14 @@ void lbs_association_worker(struct work_struct *work)
1983 assoc_req->secinfo.auth_mode); 1981 assoc_req->secinfo.auth_mode);
1984 1982
1985 /* If 'any' SSID was specified, find an SSID to associate with */ 1983 /* If 'any' SSID was specified, find an SSID to associate with */
1986 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) 1984 if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) &&
1987 && !assoc_req->ssid_len) 1985 !assoc_req->ssid_len)
1988 find_any_ssid = 1; 1986 find_any_ssid = 1;
1989 1987
1990 /* But don't use 'any' SSID if there's a valid locked BSSID to use */ 1988 /* But don't use 'any' SSID if there's a valid locked BSSID to use */
1991 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { 1989 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
1992 if (compare_ether_addr(assoc_req->bssid, bssid_any) 1990 if (compare_ether_addr(assoc_req->bssid, bssid_any) &&
1993 && compare_ether_addr(assoc_req->bssid, bssid_off)) 1991 compare_ether_addr(assoc_req->bssid, bssid_off))
1994 find_any_ssid = 0; 1992 find_any_ssid = 0;
1995 } 1993 }
1996 1994
@@ -2052,13 +2050,6 @@ void lbs_association_worker(struct work_struct *work)
2052 goto out; 2050 goto out;
2053 } 2051 }
2054 2052
2055 if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
2056 || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
2057 ret = assoc_helper_wep_keys(priv, assoc_req);
2058 if (ret)
2059 goto out;
2060 }
2061
2062 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { 2053 if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
2063 ret = assoc_helper_secinfo(priv, assoc_req); 2054 ret = assoc_helper_secinfo(priv, assoc_req);
2064 if (ret) 2055 if (ret)
@@ -2071,18 +2062,31 @@ void lbs_association_worker(struct work_struct *work)
2071 goto out; 2062 goto out;
2072 } 2063 }
2073 2064
2074 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) 2065 /*
2075 || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 2066 * v10 FW wants WPA keys to be set/cleared before WEP key operations,
2067 * otherwise it will fail to correctly associate to WEP networks.
2068 * Other firmware versions don't appear to care.
2069 */
2070 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) ||
2071 test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
2076 ret = assoc_helper_wpa_keys(priv, assoc_req); 2072 ret = assoc_helper_wpa_keys(priv, assoc_req);
2077 if (ret) 2073 if (ret)
2078 goto out; 2074 goto out;
2079 } 2075 }
2080 2076
2077 if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) ||
2078 test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
2079 ret = assoc_helper_wep_keys(priv, assoc_req);
2080 if (ret)
2081 goto out;
2082 }
2083
2084
2081 /* SSID/BSSID should be the _last_ config option set, because they 2085 /* SSID/BSSID should be the _last_ config option set, because they
2082 * trigger the association attempt. 2086 * trigger the association attempt.
2083 */ 2087 */
2084 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) 2088 if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) ||
2085 || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { 2089 test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
2086 int success = 1; 2090 int success = 1;
2087 2091
2088 ret = assoc_helper_associate(priv, assoc_req); 2092 ret = assoc_helper_associate(priv, assoc_req);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 84df3fcf37b3..0dbda8dfbd99 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -281,6 +281,8 @@ struct mac80211_hwsim_data {
281 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; 281 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
282 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 282 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
283 283
284 struct mac_address addresses[2];
285
284 struct ieee80211_channel *channel; 286 struct ieee80211_channel *channel;
285 unsigned long beacon_int; /* in jiffies unit */ 287 unsigned long beacon_int; /* in jiffies unit */
286 unsigned int rx_filter; 288 unsigned int rx_filter;
@@ -1154,7 +1156,11 @@ static int __init init_mac80211_hwsim(void)
1154 SET_IEEE80211_DEV(hw, data->dev); 1156 SET_IEEE80211_DEV(hw, data->dev);
1155 addr[3] = i >> 8; 1157 addr[3] = i >> 8;
1156 addr[4] = i; 1158 addr[4] = i;
1157 SET_IEEE80211_PERM_ADDR(hw, addr); 1159 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
1160 memcpy(data->addresses[1].addr, addr, ETH_ALEN);
1161 data->addresses[1].addr[0] |= 0x40;
1162 hw->wiphy->n_addresses = 2;
1163 hw->wiphy->addresses = data->addresses;
1158 1164
1159 hw->channel_change_time = 1; 1165 hw->channel_change_time = 1;
1160 hw->queues = 4; 1166 hw->queues = 4;
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 68546ca0ba37..f0f08f3919cc 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
3881 struct mwl8k_priv *priv = 3881 struct mwl8k_priv *priv =
3882 container_of(work, struct mwl8k_priv, finalize_join_worker); 3882 container_of(work, struct mwl8k_priv, finalize_join_worker);
3883 struct sk_buff *skb = priv->beacon_skb; 3883 struct sk_buff *skb = priv->beacon_skb;
3884 struct mwl8k_vif *mwl8k_vif; 3884 struct ieee80211_mgmt *mgmt = (void *)skb->data;
3885 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
3886 const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
3887 mgmt->u.beacon.variable, len);
3888 int dtim_period = 1;
3889
3890 if (tim && tim[1] >= 2)
3891 dtim_period = tim[3];
3885 3892
3886 mwl8k_vif = mwl8k_first_vif(priv); 3893 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
3887 if (mwl8k_vif != NULL)
3888 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len,
3889 mwl8k_vif->vif->bss_conf.dtim_period);
3890 3894
3891 dev_kfree_skb(skb); 3895 dev_kfree_skb(skb);
3892 priv->beacon_skb = NULL; 3896 priv->beacon_skb = NULL;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 57c646598062..ed4bdffdd63e 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
157 skb_tail_pointer(skb), 157 skb_tail_pointer(skb),
158 priv->common.rx_mtu + 32, 158 priv->common.rx_mtu + 32,
159 PCI_DMA_FROMDEVICE); 159 PCI_DMA_FROMDEVICE);
160
161 if (pci_dma_mapping_error(priv->pdev, mapping)) {
162 dev_kfree_skb_any(skb);
163 dev_err(&priv->pdev->dev,
164 "RX DMA Mapping error\n");
165 break;
166 }
167
160 desc->host_addr = cpu_to_le32(mapping); 168 desc->host_addr = cpu_to_le32(mapping);
161 desc->device_addr = 0; // FIXME: necessary? 169 desc->device_addr = 0; // FIXME: necessary?
162 desc->len = cpu_to_le16(priv->common.rx_mtu + 32); 170 desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
@@ -226,14 +234,14 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
226 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf); 234 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
227} 235}
228 236
229/* caller must hold priv->lock */
230static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, 237static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
231 int ring_index, struct p54p_desc *ring, u32 ring_limit, 238 int ring_index, struct p54p_desc *ring, u32 ring_limit,
232 void **tx_buf) 239 struct sk_buff **tx_buf)
233{ 240{
234 struct p54p_priv *priv = dev->priv; 241 struct p54p_priv *priv = dev->priv;
235 struct p54p_ring_control *ring_control = priv->ring_control; 242 struct p54p_ring_control *ring_control = priv->ring_control;
236 struct p54p_desc *desc; 243 struct p54p_desc *desc;
244 struct sk_buff *skb;
237 u32 idx, i; 245 u32 idx, i;
238 246
239 i = (*index) % ring_limit; 247 i = (*index) % ring_limit;
@@ -242,9 +250,8 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
242 250
243 while (i != idx) { 251 while (i != idx) {
244 desc = &ring[i]; 252 desc = &ring[i];
245 if (tx_buf[i]) 253
246 if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i])) 254 skb = tx_buf[i];
247 p54_free_skb(dev, tx_buf[i]);
248 tx_buf[i] = NULL; 255 tx_buf[i] = NULL;
249 256
250 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), 257 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
@@ -255,17 +262,28 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
255 desc->len = 0; 262 desc->len = 0;
256 desc->flags = 0; 263 desc->flags = 0;
257 264
265 if (skb && FREE_AFTER_TX(skb))
266 p54_free_skb(dev, skb);
267
258 i++; 268 i++;
259 i %= ring_limit; 269 i %= ring_limit;
260 } 270 }
261} 271}
262 272
263static void p54p_rx_tasklet(unsigned long dev_id) 273static void p54p_tasklet(unsigned long dev_id)
264{ 274{
265 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id; 275 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
266 struct p54p_priv *priv = dev->priv; 276 struct p54p_priv *priv = dev->priv;
267 struct p54p_ring_control *ring_control = priv->ring_control; 277 struct p54p_ring_control *ring_control = priv->ring_control;
268 278
279 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt,
280 ARRAY_SIZE(ring_control->tx_mgmt),
281 priv->tx_buf_mgmt);
282
283 p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data,
284 ARRAY_SIZE(ring_control->tx_data),
285 priv->tx_buf_data);
286
269 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, 287 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
270 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); 288 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
271 289
@@ -280,59 +298,49 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
280{ 298{
281 struct ieee80211_hw *dev = dev_id; 299 struct ieee80211_hw *dev = dev_id;
282 struct p54p_priv *priv = dev->priv; 300 struct p54p_priv *priv = dev->priv;
283 struct p54p_ring_control *ring_control = priv->ring_control;
284 __le32 reg; 301 __le32 reg;
285 302
286 spin_lock(&priv->lock);
287 reg = P54P_READ(int_ident); 303 reg = P54P_READ(int_ident);
288 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { 304 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
289 spin_unlock(&priv->lock); 305 goto out;
290 return IRQ_HANDLED;
291 } 306 }
292
293 P54P_WRITE(int_ack, reg); 307 P54P_WRITE(int_ack, reg);
294 308
295 reg &= P54P_READ(int_enable); 309 reg &= P54P_READ(int_enable);
296 310
297 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) { 311 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE))
298 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 312 tasklet_schedule(&priv->tasklet);
299 3, ring_control->tx_mgmt, 313 else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
300 ARRAY_SIZE(ring_control->tx_mgmt),
301 priv->tx_buf_mgmt);
302
303 p54p_check_tx_ring(dev, &priv->tx_idx_data,
304 1, ring_control->tx_data,
305 ARRAY_SIZE(ring_control->tx_data),
306 priv->tx_buf_data);
307
308 tasklet_schedule(&priv->rx_tasklet);
309
310 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
311 complete(&priv->boot_comp); 314 complete(&priv->boot_comp);
312 315
313 spin_unlock(&priv->lock); 316out:
314
315 return reg ? IRQ_HANDLED : IRQ_NONE; 317 return reg ? IRQ_HANDLED : IRQ_NONE;
316} 318}
317 319
318static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 320static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
319{ 321{
322 unsigned long flags;
320 struct p54p_priv *priv = dev->priv; 323 struct p54p_priv *priv = dev->priv;
321 struct p54p_ring_control *ring_control = priv->ring_control; 324 struct p54p_ring_control *ring_control = priv->ring_control;
322 unsigned long flags;
323 struct p54p_desc *desc; 325 struct p54p_desc *desc;
324 dma_addr_t mapping; 326 dma_addr_t mapping;
325 u32 device_idx, idx, i; 327 u32 device_idx, idx, i;
326 328
327 spin_lock_irqsave(&priv->lock, flags); 329 spin_lock_irqsave(&priv->lock, flags);
328
329 device_idx = le32_to_cpu(ring_control->device_idx[1]); 330 device_idx = le32_to_cpu(ring_control->device_idx[1]);
330 idx = le32_to_cpu(ring_control->host_idx[1]); 331 idx = le32_to_cpu(ring_control->host_idx[1]);
331 i = idx % ARRAY_SIZE(ring_control->tx_data); 332 i = idx % ARRAY_SIZE(ring_control->tx_data);
332 333
333 priv->tx_buf_data[i] = skb;
334 mapping = pci_map_single(priv->pdev, skb->data, skb->len, 334 mapping = pci_map_single(priv->pdev, skb->data, skb->len,
335 PCI_DMA_TODEVICE); 335 PCI_DMA_TODEVICE);
336 if (pci_dma_mapping_error(priv->pdev, mapping)) {
337 spin_unlock_irqrestore(&priv->lock, flags);
338 p54_free_skb(dev, skb);
339 dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
340 return ;
341 }
342 priv->tx_buf_data[i] = skb;
343
336 desc = &ring_control->tx_data[i]; 344 desc = &ring_control->tx_data[i];
337 desc->host_addr = cpu_to_le32(mapping); 345 desc->host_addr = cpu_to_le32(mapping);
338 desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; 346 desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
@@ -354,14 +362,14 @@ static void p54p_stop(struct ieee80211_hw *dev)
354 unsigned int i; 362 unsigned int i;
355 struct p54p_desc *desc; 363 struct p54p_desc *desc;
356 364
357 tasklet_kill(&priv->rx_tasklet);
358
359 P54P_WRITE(int_enable, cpu_to_le32(0)); 365 P54P_WRITE(int_enable, cpu_to_le32(0));
360 P54P_READ(int_enable); 366 P54P_READ(int_enable);
361 udelay(10); 367 udelay(10);
362 368
363 free_irq(priv->pdev->irq, dev); 369 free_irq(priv->pdev->irq, dev);
364 370
371 tasklet_kill(&priv->tasklet);
372
365 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); 373 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
366 374
367 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) { 375 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
@@ -545,7 +553,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
545 priv->common.tx = p54p_tx; 553 priv->common.tx = p54p_tx;
546 554
547 spin_lock_init(&priv->lock); 555 spin_lock_init(&priv->lock);
548 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); 556 tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);
549 557
550 err = request_firmware(&priv->firmware, "isl3886pci", 558 err = request_firmware(&priv->firmware, "isl3886pci",
551 &priv->pdev->dev); 559 &priv->pdev->dev);
diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h
index fbb683953fb2..2feead617a3b 100644
--- a/drivers/net/wireless/p54/p54pci.h
+++ b/drivers/net/wireless/p54/p54pci.h
@@ -92,7 +92,7 @@ struct p54p_priv {
92 struct p54_common common; 92 struct p54_common common;
93 struct pci_dev *pdev; 93 struct pci_dev *pdev;
94 struct p54p_csr __iomem *map; 94 struct p54p_csr __iomem *map;
95 struct tasklet_struct rx_tasklet; 95 struct tasklet_struct tasklet;
96 const struct firmware *firmware; 96 const struct firmware *firmware;
97 spinlock_t lock; 97 spinlock_t lock;
98 struct p54p_ring_control *ring_control; 98 struct p54p_ring_control *ring_control;
@@ -101,8 +101,8 @@ struct p54p_priv {
101 u32 rx_idx_mgmt, tx_idx_mgmt; 101 u32 rx_idx_mgmt, tx_idx_mgmt;
102 struct sk_buff *rx_buf_data[8]; 102 struct sk_buff *rx_buf_data[8];
103 struct sk_buff *rx_buf_mgmt[4]; 103 struct sk_buff *rx_buf_mgmt[4];
104 void *tx_buf_data[32]; 104 struct sk_buff *tx_buf_data[32];
105 void *tx_buf_mgmt[4]; 105 struct sk_buff *tx_buf_mgmt[4];
106 struct completion boot_comp; 106 struct completion boot_comp;
107}; 107};
108 108
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index b9192bfcc557..2b928ecf47bd 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -761,6 +761,14 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
761 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); 761 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
762} 762}
763 763
764static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
765{
766 struct rtl8180_priv *priv = dev->priv;
767
768 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
769 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
770}
771
764static const struct ieee80211_ops rtl8180_ops = { 772static const struct ieee80211_ops rtl8180_ops = {
765 .tx = rtl8180_tx, 773 .tx = rtl8180_tx,
766 .start = rtl8180_start, 774 .start = rtl8180_start,
@@ -771,6 +779,7 @@ static const struct ieee80211_ops rtl8180_ops = {
771 .bss_info_changed = rtl8180_bss_info_changed, 779 .bss_info_changed = rtl8180_bss_info_changed,
772 .prepare_multicast = rtl8180_prepare_multicast, 780 .prepare_multicast = rtl8180_prepare_multicast,
773 .configure_filter = rtl8180_configure_filter, 781 .configure_filter = rtl8180_configure_filter,
782 .get_tsf = rtl8180_get_tsf,
774}; 783};
775 784
776static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) 785static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index f336c63053c1..a05382557789 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1265,6 +1265,14 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
1265 return 0; 1265 return 0;
1266} 1266}
1267 1267
1268static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
1269{
1270 struct rtl8187_priv *priv = dev->priv;
1271
1272 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
1273 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
1274}
1275
1268static const struct ieee80211_ops rtl8187_ops = { 1276static const struct ieee80211_ops rtl8187_ops = {
1269 .tx = rtl8187_tx, 1277 .tx = rtl8187_tx,
1270 .start = rtl8187_start, 1278 .start = rtl8187_start,
@@ -1276,7 +1284,8 @@ static const struct ieee80211_ops rtl8187_ops = {
1276 .prepare_multicast = rtl8187_prepare_multicast, 1284 .prepare_multicast = rtl8187_prepare_multicast,
1277 .configure_filter = rtl8187_configure_filter, 1285 .configure_filter = rtl8187_configure_filter,
1278 .conf_tx = rtl8187_conf_tx, 1286 .conf_tx = rtl8187_conf_tx,
1279 .rfkill_poll = rtl8187_rfkill_poll 1287 .rfkill_poll = rtl8187_rfkill_poll,
1288 .get_tsf = rtl8187_get_tsf,
1280}; 1289};
1281 1290
1282static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) 1291static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 6301578d1565..37c61c19cae5 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -341,9 +341,6 @@ struct wl1251 {
341 /* Are we currently scanning */ 341 /* Are we currently scanning */
342 bool scanning; 342 bool scanning;
343 343
344 /* Our association ID */
345 u16 aid;
346
347 /* Default key (for WEP) */ 344 /* Default key (for WEP) */
348 u32 default_key; 345 u32 default_key;
349 346
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 595f0f94d16e..a717dde4822e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
617 617
618 wl->psm_requested = true; 618 wl->psm_requested = true;
619 619
620 wl->dtim_period = conf->ps_dtim_period;
621
622 ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
623 wl->dtim_period);
624
620 /* 625 /*
621 * We enter PSM only if we're already associated. 626 * mac80211 enables PSM only if we're already associated.
622 * If we're not, we'll enter it when joining an SSID,
623 * through the bss_info_changed() hook.
624 */ 627 */
625 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 628 ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
626 if (ret < 0) 629 if (ret < 0)
@@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
943 struct ieee80211_bss_conf *bss_conf, 946 struct ieee80211_bss_conf *bss_conf,
944 u32 changed) 947 u32 changed)
945{ 948{
946 enum wl1251_cmd_ps_mode mode;
947 struct wl1251 *wl = hw->priv; 949 struct wl1251 *wl = hw->priv;
948 struct sk_buff *beacon, *skb; 950 struct sk_buff *beacon, *skb;
949 int ret; 951 int ret;
@@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
984 if (changed & BSS_CHANGED_ASSOC) { 986 if (changed & BSS_CHANGED_ASSOC) {
985 if (bss_conf->assoc) { 987 if (bss_conf->assoc) {
986 wl->beacon_int = bss_conf->beacon_int; 988 wl->beacon_int = bss_conf->beacon_int;
987 wl->dtim_period = bss_conf->dtim_period;
988
989 ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
990 wl->dtim_period);
991 wl->aid = bss_conf->aid;
992 989
993 skb = ieee80211_pspoll_get(wl->hw, wl->vif); 990 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
994 if (!skb) 991 if (!skb)
@@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1001 if (ret < 0) 998 if (ret < 0)
1002 goto out_sleep; 999 goto out_sleep;
1003 1000
1004 ret = wl1251_acx_aid(wl, wl->aid); 1001 ret = wl1251_acx_aid(wl, bss_conf->aid);
1005 if (ret < 0) 1002 if (ret < 0)
1006 goto out_sleep; 1003 goto out_sleep;
1007
1008 /* If we want to go in PSM but we're not there yet */
1009 if (wl->psm_requested && !wl->psm) {
1010 mode = STATION_POWER_SAVE_MODE;
1011 ret = wl1251_ps_set_mode(wl, mode);
1012 if (ret < 0)
1013 goto out_sleep;
1014 }
1015 } else { 1004 } else {
1016 /* use defaults when not associated */ 1005 /* use defaults when not associated */
1017 wl->beacon_int = WL1251_DEFAULT_BEACON_INT; 1006 wl->beacon_int = WL1251_DEFAULT_BEACON_INT;