aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-05-29 14:50:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-05-29 14:50:45 -0400
commit531efffc3e3ff52d732c8fa6f32e084e9c447612 (patch)
tree79c301b2c8b5400a39c95e034764cf7a208a16a2 /drivers/net
parentbbf71a8f35cf52e97ba129401f82ccefd249c757 (diff)
parentb571a69745dc90aec3d0505a7ceac2702a93861b (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h138
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c10
-rw-r--r--drivers/net/wireless/b43/dma.c19
-rw-r--r--drivers/net/wireless/b43/dma.h4
-rw-r--r--drivers/net/wireless/b43/main.c43
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h21
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h57
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c107
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c20
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c14
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c45
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c427
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h93
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h260
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c42
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c244
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h197
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c212
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c75
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c183
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c509
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c48
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c31
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c50
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c32
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c8
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c3
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.c1
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c21
70 files changed, 2907 insertions, 546 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9b20d9ee2719..7f702fe3ecc2 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2369,6 +2369,9 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
2369 int i; 2369 int i;
2370 bool needreset = false; 2370 bool needreset = false;
2371 2371
2372 if (!test_bit(ATH_STAT_STARTED, ah->status))
2373 return;
2374
2372 mutex_lock(&ah->lock); 2375 mutex_lock(&ah->lock);
2373 2376
2374 for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) { 2377 for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
@@ -2676,6 +2679,7 @@ done:
2676 mmiowb(); 2679 mmiowb();
2677 mutex_unlock(&ah->lock); 2680 mutex_unlock(&ah->lock);
2678 2681
2682 set_bit(ATH_STAT_STARTED, ah->status);
2679 ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work, 2683 ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work,
2680 msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); 2684 msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
2681 2685
@@ -2737,6 +2741,7 @@ void ath5k_stop(struct ieee80211_hw *hw)
2737 2741
2738 ath5k_stop_tasklets(ah); 2742 ath5k_stop_tasklets(ah);
2739 2743
2744 clear_bit(ATH_STAT_STARTED, ah->status);
2740 cancel_delayed_work_sync(&ah->tx_complete_work); 2745 cancel_delayed_work_sync(&ah->tx_complete_work);
2741 2746
2742 if (!ath5k_modparam_no_hw_rfkill_switch) 2747 if (!ath5k_modparam_no_hw_rfkill_switch)
diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
index 0c2ac0c6dc89..e85a8b076c22 100644
--- a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
@@ -233,9 +233,9 @@ static const u32 ar9565_1p0_baseband_core[][2] = {
233 {0x00009d10, 0x01834061}, 233 {0x00009d10, 0x01834061},
234 {0x00009d14, 0x00c00400}, 234 {0x00009d14, 0x00c00400},
235 {0x00009d18, 0x00000000}, 235 {0x00009d18, 0x00000000},
236 {0x00009e08, 0x0078230c}, 236 {0x00009e08, 0x0038230c},
237 {0x00009e24, 0x990bb515}, 237 {0x00009e24, 0x9907b515},
238 {0x00009e28, 0x126f0000}, 238 {0x00009e28, 0x126f0600},
239 {0x00009e30, 0x06336f77}, 239 {0x00009e30, 0x06336f77},
240 {0x00009e34, 0x6af6532f}, 240 {0x00009e34, 0x6af6532f},
241 {0x00009e38, 0x0cc80c00}, 241 {0x00009e38, 0x0cc80c00},
@@ -337,7 +337,7 @@ static const u32 ar9565_1p0_baseband_core[][2] = {
337 337
338static const u32 ar9565_1p0_baseband_postamble[][5] = { 338static const u32 ar9565_1p0_baseband_postamble[][5] = {
339 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 339 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
340 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a800d}, 340 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8009},
341 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, 341 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
342 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, 342 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
343 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x09143c81}, 343 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x09143c81},
@@ -345,9 +345,9 @@ static const u32 ar9565_1p0_baseband_postamble[][5] = {
345 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, 345 {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
346 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, 346 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
347 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, 347 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
348 {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, 348 {0x00009e04, 0x00802020, 0x00802020, 0x00142020, 0x00142020},
349 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, 349 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
350 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, 350 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
351 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, 351 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
352 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 352 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
353 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 353 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
@@ -450,6 +450,8 @@ static const u32 ar9565_1p0_soc_postamble[][5] = {
450 450
451static const u32 ar9565_1p0_Common_rx_gain_table[][2] = { 451static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
452 /* Addr allmodes */ 452 /* Addr allmodes */
453 {0x00004050, 0x00300300},
454 {0x0000406c, 0x00100000},
453 {0x0000a000, 0x00010000}, 455 {0x0000a000, 0x00010000},
454 {0x0000a004, 0x00030002}, 456 {0x0000a004, 0x00030002},
455 {0x0000a008, 0x00050004}, 457 {0x0000a008, 0x00050004},
@@ -498,27 +500,27 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
498 {0x0000a0b4, 0x00000000}, 500 {0x0000a0b4, 0x00000000},
499 {0x0000a0b8, 0x00000000}, 501 {0x0000a0b8, 0x00000000},
500 {0x0000a0bc, 0x00000000}, 502 {0x0000a0bc, 0x00000000},
501 {0x0000a0c0, 0x001f0000}, 503 {0x0000a0c0, 0x00bf00a0},
502 {0x0000a0c4, 0x01000101}, 504 {0x0000a0c4, 0x11a011a1},
503 {0x0000a0c8, 0x011e011f}, 505 {0x0000a0c8, 0x11be11bf},
504 {0x0000a0cc, 0x011c011d}, 506 {0x0000a0cc, 0x11bc11bd},
505 {0x0000a0d0, 0x02030204}, 507 {0x0000a0d0, 0x22632264},
506 {0x0000a0d4, 0x02010202}, 508 {0x0000a0d4, 0x22612262},
507 {0x0000a0d8, 0x021f0200}, 509 {0x0000a0d8, 0x227f2260},
508 {0x0000a0dc, 0x0302021e}, 510 {0x0000a0dc, 0x4322227e},
509 {0x0000a0e0, 0x03000301}, 511 {0x0000a0e0, 0x43204321},
510 {0x0000a0e4, 0x031e031f}, 512 {0x0000a0e4, 0x433e433f},
511 {0x0000a0e8, 0x0402031d}, 513 {0x0000a0e8, 0x4462433d},
512 {0x0000a0ec, 0x04000401}, 514 {0x0000a0ec, 0x44604461},
513 {0x0000a0f0, 0x041e041f}, 515 {0x0000a0f0, 0x447e447f},
514 {0x0000a0f4, 0x0502041d}, 516 {0x0000a0f4, 0x5582447d},
515 {0x0000a0f8, 0x05000501}, 517 {0x0000a0f8, 0x55805581},
516 {0x0000a0fc, 0x051e051f}, 518 {0x0000a0fc, 0x559e559f},
517 {0x0000a100, 0x06010602}, 519 {0x0000a100, 0x66816682},
518 {0x0000a104, 0x061f0600}, 520 {0x0000a104, 0x669f6680},
519 {0x0000a108, 0x061d061e}, 521 {0x0000a108, 0x669d669e},
520 {0x0000a10c, 0x07020703}, 522 {0x0000a10c, 0x77627763},
521 {0x0000a110, 0x07000701}, 523 {0x0000a110, 0x77607761},
522 {0x0000a114, 0x00000000}, 524 {0x0000a114, 0x00000000},
523 {0x0000a118, 0x00000000}, 525 {0x0000a118, 0x00000000},
524 {0x0000a11c, 0x00000000}, 526 {0x0000a11c, 0x00000000},
@@ -530,27 +532,27 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = {
530 {0x0000a134, 0x00000000}, 532 {0x0000a134, 0x00000000},
531 {0x0000a138, 0x00000000}, 533 {0x0000a138, 0x00000000},
532 {0x0000a13c, 0x00000000}, 534 {0x0000a13c, 0x00000000},
533 {0x0000a140, 0x001f0000}, 535 {0x0000a140, 0x00bf00a0},
534 {0x0000a144, 0x01000101}, 536 {0x0000a144, 0x11a011a1},
535 {0x0000a148, 0x011e011f}, 537 {0x0000a148, 0x11be11bf},
536 {0x0000a14c, 0x011c011d}, 538 {0x0000a14c, 0x11bc11bd},
537 {0x0000a150, 0x02030204}, 539 {0x0000a150, 0x22632264},
538 {0x0000a154, 0x02010202}, 540 {0x0000a154, 0x22612262},
539 {0x0000a158, 0x021f0200}, 541 {0x0000a158, 0x227f2260},
540 {0x0000a15c, 0x0302021e}, 542 {0x0000a15c, 0x4322227e},
541 {0x0000a160, 0x03000301}, 543 {0x0000a160, 0x43204321},
542 {0x0000a164, 0x031e031f}, 544 {0x0000a164, 0x433e433f},
543 {0x0000a168, 0x0402031d}, 545 {0x0000a168, 0x4462433d},
544 {0x0000a16c, 0x04000401}, 546 {0x0000a16c, 0x44604461},
545 {0x0000a170, 0x041e041f}, 547 {0x0000a170, 0x447e447f},
546 {0x0000a174, 0x0502041d}, 548 {0x0000a174, 0x5582447d},
547 {0x0000a178, 0x05000501}, 549 {0x0000a178, 0x55805581},
548 {0x0000a17c, 0x051e051f}, 550 {0x0000a17c, 0x559e559f},
549 {0x0000a180, 0x06010602}, 551 {0x0000a180, 0x66816682},
550 {0x0000a184, 0x061f0600}, 552 {0x0000a184, 0x669f6680},
551 {0x0000a188, 0x061d061e}, 553 {0x0000a188, 0x669d669e},
552 {0x0000a18c, 0x07020703}, 554 {0x0000a18c, 0x77e677e7},
553 {0x0000a190, 0x07000701}, 555 {0x0000a190, 0x77e477e5},
554 {0x0000a194, 0x00000000}, 556 {0x0000a194, 0x00000000},
555 {0x0000a198, 0x00000000}, 557 {0x0000a198, 0x00000000},
556 {0x0000a19c, 0x00000000}, 558 {0x0000a19c, 0x00000000},
@@ -770,7 +772,7 @@ static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = {
770 772
771static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = { 773static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = {
772 /* Addr allmodes */ 774 /* Addr allmodes */
773 {0x00018c00, 0x18213ede}, 775 {0x00018c00, 0x18212ede},
774 {0x00018c04, 0x000801d8}, 776 {0x00018c04, 0x000801d8},
775 {0x00018c08, 0x0003780c}, 777 {0x00018c08, 0x0003780c},
776}; 778};
@@ -889,8 +891,8 @@ static const u32 ar9565_1p0_common_wo_xlna_rx_gain_table[][2] = {
889 {0x0000a180, 0x66816682}, 891 {0x0000a180, 0x66816682},
890 {0x0000a184, 0x669f6680}, 892 {0x0000a184, 0x669f6680},
891 {0x0000a188, 0x669d669e}, 893 {0x0000a188, 0x669d669e},
892 {0x0000a18c, 0x77627763}, 894 {0x0000a18c, 0x77e677e7},
893 {0x0000a190, 0x77607761}, 895 {0x0000a190, 0x77e477e5},
894 {0x0000a194, 0x00000000}, 896 {0x0000a194, 0x00000000},
895 {0x0000a198, 0x00000000}, 897 {0x0000a198, 0x00000000},
896 {0x0000a19c, 0x00000000}, 898 {0x0000a19c, 0x00000000},
@@ -1114,7 +1116,7 @@ static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = {
1114 {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, 1116 {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84},
1115 {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, 1117 {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000},
1116 {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, 1118 {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000},
1117 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 1119 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050df, 0x000050df},
1118 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 1120 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1119 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 1121 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1120 {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, 1122 {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004},
@@ -1140,13 +1142,13 @@ static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = {
1140 {0x0000a558, 0x69027f56, 0x69027f56, 0x53001ce5, 0x53001ce5}, 1142 {0x0000a558, 0x69027f56, 0x69027f56, 0x53001ce5, 0x53001ce5},
1141 {0x0000a55c, 0x6d029f56, 0x6d029f56, 0x57001ce9, 0x57001ce9}, 1143 {0x0000a55c, 0x6d029f56, 0x6d029f56, 0x57001ce9, 0x57001ce9},
1142 {0x0000a560, 0x73049f56, 0x73049f56, 0x5b001ceb, 0x5b001ceb}, 1144 {0x0000a560, 0x73049f56, 0x73049f56, 0x5b001ceb, 0x5b001ceb},
1143 {0x0000a564, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1145 {0x0000a564, 0x7804ff56, 0x7804ff56, 0x60001cf0, 0x60001cf0},
1144 {0x0000a568, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1146 {0x0000a568, 0x7804ff56, 0x7804ff56, 0x61001cf1, 0x61001cf1},
1145 {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1147 {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x62001cf2, 0x62001cf2},
1146 {0x0000a570, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1148 {0x0000a570, 0x7804ff56, 0x7804ff56, 0x63001cf3, 0x63001cf3},
1147 {0x0000a574, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1149 {0x0000a574, 0x7804ff56, 0x7804ff56, 0x64001cf4, 0x64001cf4},
1148 {0x0000a578, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1150 {0x0000a578, 0x7804ff56, 0x7804ff56, 0x66001ff6, 0x66001ff6},
1149 {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, 1151 {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x66001ff6, 0x66001ff6},
1150 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1152 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1151 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1153 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1152 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1154 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -1174,7 +1176,7 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = {
1174 {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, 1176 {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84},
1175 {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, 1177 {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000},
1176 {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, 1178 {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000},
1177 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 1179 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050df, 0x000050df},
1178 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 1180 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1179 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, 1181 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1180 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, 1182 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
@@ -1200,13 +1202,13 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = {
1200 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, 1202 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1201 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, 1203 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
1202 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, 1204 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
1203 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1205 {0x0000a564, 0x7504ff56, 0x7504ff56, 0x59001cf0, 0x59001cf0},
1204 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1206 {0x0000a568, 0x7504ff56, 0x7504ff56, 0x5a001cf1, 0x5a001cf1},
1205 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1207 {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x5b001cf2, 0x5b001cf2},
1206 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1208 {0x0000a570, 0x7504ff56, 0x7504ff56, 0x5c001cf3, 0x5c001cf3},
1207 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1209 {0x0000a574, 0x7504ff56, 0x7504ff56, 0x5d001cf4, 0x5d001cf4},
1208 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1210 {0x0000a578, 0x7504ff56, 0x7504ff56, 0x5f001ff6, 0x5f001ff6},
1209 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, 1211 {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x5f001ff6, 0x5f001ff6},
1210 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1212 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1211 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1213 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1212 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1214 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e6a30958e944..a1630d1ee3c9 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -226,13 +226,13 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
226 if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) 226 if (!test_bit(SC_OP_BEACONS, &sc->sc_flags))
227 goto work; 227 goto work;
228 228
229 ath9k_set_beacon(sc);
230
231 if (ah->opmode == NL80211_IFTYPE_STATION && 229 if (ah->opmode == NL80211_IFTYPE_STATION &&
232 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 230 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
233 spin_lock_irqsave(&sc->sc_pm_lock, flags); 231 spin_lock_irqsave(&sc->sc_pm_lock, flags);
234 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; 232 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
235 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 233 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
234 } else {
235 ath9k_set_beacon(sc);
236 } 236 }
237 work: 237 work:
238 ath_restart_work(sc); 238 ath_restart_work(sc);
@@ -1331,6 +1331,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
1331 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1331 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1332 struct ath_node *an = (struct ath_node *) sta->drv_priv; 1332 struct ath_node *an = (struct ath_node *) sta->drv_priv;
1333 struct ieee80211_key_conf ps_key = { }; 1333 struct ieee80211_key_conf ps_key = { };
1334 int key;
1334 1335
1335 ath_node_attach(sc, sta, vif); 1336 ath_node_attach(sc, sta, vif);
1336 1337
@@ -1338,7 +1339,9 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
1338 vif->type != NL80211_IFTYPE_AP_VLAN) 1339 vif->type != NL80211_IFTYPE_AP_VLAN)
1339 return 0; 1340 return 0;
1340 1341
1341 an->ps_key = ath_key_config(common, vif, sta, &ps_key); 1342 key = ath_key_config(common, vif, sta, &ps_key);
1343 if (key > 0)
1344 an->ps_key = key;
1342 1345
1343 return 0; 1346 return 0;
1344} 1347}
@@ -1355,6 +1358,7 @@ static void ath9k_del_ps_key(struct ath_softc *sc,
1355 return; 1358 return;
1356 1359
1357 ath_key_delete(common, &ps_key); 1360 ath_key_delete(common, &ps_key);
1361 an->ps_key = 0;
1358} 1362}
1359 1363
1360static int ath9k_sta_remove(struct ieee80211_hw *hw, 1364static int ath9k_sta_remove(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 523355b87659..f7c70b3a6ea9 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1728,6 +1728,25 @@ drop_recycle_buffer:
1728 sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); 1728 sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize);
1729} 1729}
1730 1730
1731void b43_dma_handle_rx_overflow(struct b43_dmaring *ring)
1732{
1733 int current_slot, previous_slot;
1734
1735 B43_WARN_ON(ring->tx);
1736
1737 /* Device has filled all buffers, drop all packets and let TCP
1738 * decrease speed.
1739 * Decrement RX index by one will let the device to see all slots
1740 * as free again
1741 */
1742 /*
1743 *TODO: How to increase rx_drop in mac80211?
1744 */
1745 current_slot = ring->ops->get_current_rxslot(ring);
1746 previous_slot = prev_slot(ring, current_slot);
1747 ring->ops->set_current_rxslot(ring, previous_slot);
1748}
1749
1731void b43_dma_rx(struct b43_dmaring *ring) 1750void b43_dma_rx(struct b43_dmaring *ring)
1732{ 1751{
1733 const struct b43_dma_ops *ops = ring->ops; 1752 const struct b43_dma_ops *ops = ring->ops;
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index 9fdd1983079c..df8c8cdcbdb5 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -9,7 +9,7 @@
9/* DMA-Interrupt reasons. */ 9/* DMA-Interrupt reasons. */
10#define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ 10#define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
11 | (1 << 14) | (1 << 15)) 11 | (1 << 14) | (1 << 15))
12#define B43_DMAIRQ_NONFATALMASK (1 << 13) 12#define B43_DMAIRQ_RDESC_UFLOW (1 << 13)
13#define B43_DMAIRQ_RX_DONE (1 << 16) 13#define B43_DMAIRQ_RX_DONE (1 << 16)
14 14
15/*** 32-bit DMA Engine. ***/ 15/*** 32-bit DMA Engine. ***/
@@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev,
295void b43_dma_handle_txstatus(struct b43_wldev *dev, 295void b43_dma_handle_txstatus(struct b43_wldev *dev,
296 const struct b43_txstatus *status); 296 const struct b43_txstatus *status);
297 297
298void b43_dma_handle_rx_overflow(struct b43_dmaring *ring);
299
298void b43_dma_rx(struct b43_dmaring *ring); 300void b43_dma_rx(struct b43_dmaring *ring);
299 301
300void b43_dma_direct_fifo_rx(struct b43_wldev *dev, 302void b43_dma_direct_fifo_rx(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index d377f77d30b5..6dd07e2ec595 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1902,30 +1902,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
1902 } 1902 }
1903 } 1903 }
1904 1904
1905 if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | 1905 if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) {
1906 B43_DMAIRQ_NONFATALMASK))) { 1906 b43err(dev->wl,
1907 if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { 1907 "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1908 b43err(dev->wl, "Fatal DMA error: " 1908 dma_reason[0], dma_reason[1],
1909 "0x%08X, 0x%08X, 0x%08X, " 1909 dma_reason[2], dma_reason[3],
1910 "0x%08X, 0x%08X, 0x%08X\n", 1910 dma_reason[4], dma_reason[5]);
1911 dma_reason[0], dma_reason[1], 1911 b43err(dev->wl, "This device does not support DMA "
1912 dma_reason[2], dma_reason[3],
1913 dma_reason[4], dma_reason[5]);
1914 b43err(dev->wl, "This device does not support DMA "
1915 "on your system. It will now be switched to PIO.\n"); 1912 "on your system. It will now be switched to PIO.\n");
1916 /* Fall back to PIO transfers if we get fatal DMA errors! */ 1913 /* Fall back to PIO transfers if we get fatal DMA errors! */
1917 dev->use_pio = true; 1914 dev->use_pio = true;
1918 b43_controller_restart(dev, "DMA error"); 1915 b43_controller_restart(dev, "DMA error");
1919 return; 1916 return;
1920 }
1921 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
1922 b43err(dev->wl, "DMA error: "
1923 "0x%08X, 0x%08X, 0x%08X, "
1924 "0x%08X, 0x%08X, 0x%08X\n",
1925 dma_reason[0], dma_reason[1],
1926 dma_reason[2], dma_reason[3],
1927 dma_reason[4], dma_reason[5]);
1928 }
1929 } 1917 }
1930 1918
1931 if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) 1919 if (unlikely(reason & B43_IRQ_UCODE_DEBUG))
@@ -1944,6 +1932,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
1944 handle_irq_noise(dev); 1932 handle_irq_noise(dev);
1945 1933
1946 /* Check the DMA reason registers for received data. */ 1934 /* Check the DMA reason registers for received data. */
1935 if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) {
1936 if (B43_DEBUG)
1937 b43warn(dev->wl, "RX descriptor underrun\n");
1938 b43_dma_handle_rx_overflow(dev->dma.rx_ring);
1939 }
1947 if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { 1940 if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
1948 if (b43_using_pio_transfers(dev)) 1941 if (b43_using_pio_transfers(dev))
1949 b43_pio_rx(dev->pio.rx_queue); 1942 b43_pio_rx(dev->pio.rx_queue);
@@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
2001 return IRQ_NONE; 1994 return IRQ_NONE;
2002 1995
2003 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) 1996 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
2004 & 0x0001DC00; 1997 & 0x0001FC00;
2005 dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) 1998 dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON)
2006 & 0x0000DC00; 1999 & 0x0000DC00;
2007 dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) 2000 dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON)
@@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev)
3130 b43_write32(dev, 0x018C, 0x02000000); 3123 b43_write32(dev, 0x018C, 0x02000000);
3131 } 3124 }
3132 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); 3125 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000);
3133 b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); 3126 b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00);
3134 b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); 3127 b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
3135 b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); 3128 b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
3136 b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); 3129 b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index b8f82e688c72..9a95045c97b6 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -5741,8 +5741,7 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
5741 hw->flags = 5741 hw->flags =
5742 IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | 5742 IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION |
5743 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT | 5743 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT |
5744 IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | 5744 IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
5745 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
5746 if (il->cfg->sku & IL_SKU_N) 5745 if (il->cfg->sku & IL_SKU_N)
5747 hw->flags |= 5746 hw->flags |=
5748 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 5747 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 48545ab00311..de2c9514bef6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -76,13 +76,16 @@
76#define IWL_INVALID_STATION 255 76#define IWL_INVALID_STATION 255
77 77
78/* device operations */ 78/* device operations */
79extern struct iwl_lib_ops iwl1000_lib; 79extern const struct iwl_dvm_cfg iwl_dvm_1000_cfg;
80extern struct iwl_lib_ops iwl2000_lib; 80extern const struct iwl_dvm_cfg iwl_dvm_2000_cfg;
81extern struct iwl_lib_ops iwl2030_lib; 81extern const struct iwl_dvm_cfg iwl_dvm_105_cfg;
82extern struct iwl_lib_ops iwl5000_lib; 82extern const struct iwl_dvm_cfg iwl_dvm_2030_cfg;
83extern struct iwl_lib_ops iwl5150_lib; 83extern const struct iwl_dvm_cfg iwl_dvm_5000_cfg;
84extern struct iwl_lib_ops iwl6000_lib; 84extern const struct iwl_dvm_cfg iwl_dvm_5150_cfg;
85extern struct iwl_lib_ops iwl6030_lib; 85extern const struct iwl_dvm_cfg iwl_dvm_6000_cfg;
86extern const struct iwl_dvm_cfg iwl_dvm_6005_cfg;
87extern const struct iwl_dvm_cfg iwl_dvm_6050_cfg;
88extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
86 89
87 90
88#define TIME_UNIT 1024 91#define TIME_UNIT 1024
@@ -291,8 +294,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena);
291 294
292static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) 295static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
293{ 296{
294 return priv->cfg->bt_params && 297 return priv->lib->bt_params &&
295 priv->cfg->bt_params->advanced_bt_coexist; 298 priv->lib->bt_params->advanced_bt_coexist;
296} 299}
297 300
298#ifdef CONFIG_IWLWIFI_DEBUG 301#ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index d6c4cf2ad7c5..1b0f0d502568 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -521,7 +521,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
521 521
522 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); 522 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
523 523
524 if (priv->cfg->base_params->hd_v2) { 524 if (priv->lib->hd_v2) {
525 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = 525 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
526 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; 526 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
527 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = 527 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
@@ -895,7 +895,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
895 continue; 895 continue;
896 } 896 }
897 897
898 delta_g = (priv->cfg->base_params->chain_noise_scale * 898 delta_g = (priv->lib->chain_noise_scale *
899 ((s32)average_noise[default_chain] - 899 ((s32)average_noise[default_chain] -
900 (s32)average_noise[i])) / 1500; 900 (s32)average_noise[i])) / 1500;
901 901
@@ -1051,8 +1051,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
1051 return; 1051 return;
1052 1052
1053 /* Analyze signal for disconnected antenna */ 1053 /* Analyze signal for disconnected antenna */
1054 if (priv->cfg->bt_params && 1054 if (priv->lib->bt_params &&
1055 priv->cfg->bt_params->advanced_bt_coexist) { 1055 priv->lib->bt_params->advanced_bt_coexist) {
1056 /* Disable disconnected antenna algorithm for advanced 1056 /* Disable disconnected antenna algorithm for advanced
1057 bt coex, assuming valid antennas are connected */ 1057 bt coex, assuming valid antennas are connected */
1058 data->active_chains = priv->nvm_data->valid_rx_ant; 1058 data->active_chains = priv->nvm_data->valid_rx_ant;
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 95ca026ecc9d..19f3ce7646ab 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -838,10 +838,6 @@ struct iwl_qosparam_cmd {
838#define STA_MODIFY_DELBA_TID_MSK 0x10 838#define STA_MODIFY_DELBA_TID_MSK 0x10
839#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 839#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20
840 840
841/* Receiver address (actually, Rx station's index into station table),
842 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
843#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
844
845/* agn */ 841/* agn */
846struct iwl_keyinfo { 842struct iwl_keyinfo {
847 __le16 key_flags; 843 __le16 key_flags;
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 71ea77576d22..f1b8df16dbba 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -568,16 +568,61 @@ struct iwl_hw_params {
568 const struct iwl_sensitivity_ranges *sens; 568 const struct iwl_sensitivity_ranges *sens;
569}; 569};
570 570
571struct iwl_lib_ops { 571/**
572 /* set hw dependent parameters */ 572 * struct iwl_dvm_bt_params - DVM specific BT (coex) parameters
573 * @advanced_bt_coexist: support advanced bt coexist
574 * @bt_init_traffic_load: specify initial bt traffic load
575 * @bt_prio_boost: default bt priority boost value
576 * @agg_time_limit: maximum number of uSec in aggregation
577 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
578 */
579struct iwl_dvm_bt_params {
580 bool advanced_bt_coexist;
581 u8 bt_init_traffic_load;
582 u32 bt_prio_boost;
583 u16 agg_time_limit;
584 bool bt_sco_disable;
585 bool bt_session_2;
586};
587
588/**
589 * struct iwl_dvm_cfg - DVM firmware specific device configuration
590 * @set_hw_params: set hardware parameters
591 * @set_channel_switch: send channel switch command
592 * @nic_config: apply device specific configuration
593 * @temperature: read temperature
594 * @adv_thermal_throttle: support advance thermal throttle
595 * @support_ct_kill_exit: support ct kill exit condition
596 * @plcp_delta_threshold: plcp error rate threshold used to trigger
597 * radio tuning when there is a high receiving plcp error rate
598 * @chain_noise_scale: default chain noise scale used for gain computation
599 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
600 * @no_idle_support: do not support idle mode
601 * @bt_params: pointer to BT parameters
602 * @need_temp_offset_calib: need to perform temperature offset calibration
603 * @no_xtal_calib: some devices do not need crystal calibration data,
604 * don't send it to those
605 * @temp_offset_v2: support v2 of temperature offset calibration
606 * @adv_pm: advanced power management
607 */
608struct iwl_dvm_cfg {
573 void (*set_hw_params)(struct iwl_priv *priv); 609 void (*set_hw_params)(struct iwl_priv *priv);
574 int (*set_channel_switch)(struct iwl_priv *priv, 610 int (*set_channel_switch)(struct iwl_priv *priv,
575 struct ieee80211_channel_switch *ch_switch); 611 struct ieee80211_channel_switch *ch_switch);
576 /* device specific configuration */
577 void (*nic_config)(struct iwl_priv *priv); 612 void (*nic_config)(struct iwl_priv *priv);
578
579 /* temperature */
580 void (*temperature)(struct iwl_priv *priv); 613 void (*temperature)(struct iwl_priv *priv);
614
615 const struct iwl_dvm_bt_params *bt_params;
616 s32 chain_noise_scale;
617 u8 plcp_delta_threshold;
618 bool adv_thermal_throttle;
619 bool support_ct_kill_exit;
620 bool hd_v2;
621 bool no_idle_support;
622 bool need_temp_offset_calib;
623 bool no_xtal_calib;
624 bool temp_offset_v2;
625 bool adv_pm;
581}; 626};
582 627
583struct iwl_wipan_noa_data { 628struct iwl_wipan_noa_data {
@@ -610,7 +655,7 @@ struct iwl_priv {
610 struct device *dev; /* for debug prints only */ 655 struct device *dev; /* for debug prints only */
611 const struct iwl_cfg *cfg; 656 const struct iwl_cfg *cfg;
612 const struct iwl_fw *fw; 657 const struct iwl_fw *fw;
613 const struct iwl_lib_ops *lib; 658 const struct iwl_dvm_cfg *lib;
614 unsigned long status; 659 unsigned long status;
615 660
616 spinlock_t sta_lock; 661 spinlock_t sta_lock;
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index c48907c8ab43..352c6cb7b4f1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -174,10 +174,13 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
174 priv->hw_params.sens = &iwl1000_sensitivity; 174 priv->hw_params.sens = &iwl1000_sensitivity;
175} 175}
176 176
177struct iwl_lib_ops iwl1000_lib = { 177const struct iwl_dvm_cfg iwl_dvm_1000_cfg = {
178 .set_hw_params = iwl1000_hw_set_hw_params, 178 .set_hw_params = iwl1000_hw_set_hw_params,
179 .nic_config = iwl1000_nic_config, 179 .nic_config = iwl1000_nic_config,
180 .temperature = iwlagn_temperature, 180 .temperature = iwlagn_temperature,
181 .support_ct_kill_exit = true,
182 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
183 .chain_noise_scale = 1000,
181}; 184};
182 185
183 186
@@ -232,16 +235,56 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
232 priv->hw_params.sens = &iwl2000_sensitivity; 235 priv->hw_params.sens = &iwl2000_sensitivity;
233} 236}
234 237
235struct iwl_lib_ops iwl2000_lib = { 238const struct iwl_dvm_cfg iwl_dvm_2000_cfg = {
236 .set_hw_params = iwl2000_hw_set_hw_params, 239 .set_hw_params = iwl2000_hw_set_hw_params,
237 .nic_config = iwl2000_nic_config, 240 .nic_config = iwl2000_nic_config,
238 .temperature = iwlagn_temperature, 241 .temperature = iwlagn_temperature,
242 .adv_thermal_throttle = true,
243 .support_ct_kill_exit = true,
244 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
245 .chain_noise_scale = 1000,
246 .hd_v2 = true,
247 .need_temp_offset_calib = true,
248 .temp_offset_v2 = true,
239}; 249};
240 250
241struct iwl_lib_ops iwl2030_lib = { 251const struct iwl_dvm_cfg iwl_dvm_105_cfg = {
242 .set_hw_params = iwl2000_hw_set_hw_params, 252 .set_hw_params = iwl2000_hw_set_hw_params,
243 .nic_config = iwl2000_nic_config, 253 .nic_config = iwl2000_nic_config,
244 .temperature = iwlagn_temperature, 254 .temperature = iwlagn_temperature,
255 .adv_thermal_throttle = true,
256 .support_ct_kill_exit = true,
257 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
258 .chain_noise_scale = 1000,
259 .hd_v2 = true,
260 .need_temp_offset_calib = true,
261 .temp_offset_v2 = true,
262 .adv_pm = true,
263};
264
265static const struct iwl_dvm_bt_params iwl2030_bt_params = {
266 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
267 .advanced_bt_coexist = true,
268 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
269 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
270 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
271 .bt_sco_disable = true,
272 .bt_session_2 = true,
273};
274
275const struct iwl_dvm_cfg iwl_dvm_2030_cfg = {
276 .set_hw_params = iwl2000_hw_set_hw_params,
277 .nic_config = iwl2000_nic_config,
278 .temperature = iwlagn_temperature,
279 .adv_thermal_throttle = true,
280 .support_ct_kill_exit = true,
281 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
282 .chain_noise_scale = 1000,
283 .hd_v2 = true,
284 .bt_params = &iwl2030_bt_params,
285 .need_temp_offset_calib = true,
286 .temp_offset_v2 = true,
287 .adv_pm = true,
245}; 288};
246 289
247/* 290/*
@@ -420,16 +463,23 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
420 return iwl_dvm_send_cmd(priv, &hcmd); 463 return iwl_dvm_send_cmd(priv, &hcmd);
421} 464}
422 465
423struct iwl_lib_ops iwl5000_lib = { 466const struct iwl_dvm_cfg iwl_dvm_5000_cfg = {
424 .set_hw_params = iwl5000_hw_set_hw_params, 467 .set_hw_params = iwl5000_hw_set_hw_params,
425 .set_channel_switch = iwl5000_hw_channel_switch, 468 .set_channel_switch = iwl5000_hw_channel_switch,
426 .temperature = iwlagn_temperature, 469 .temperature = iwlagn_temperature,
470 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
471 .chain_noise_scale = 1000,
472 .no_idle_support = true,
427}; 473};
428 474
429struct iwl_lib_ops iwl5150_lib = { 475const struct iwl_dvm_cfg iwl_dvm_5150_cfg = {
430 .set_hw_params = iwl5150_hw_set_hw_params, 476 .set_hw_params = iwl5150_hw_set_hw_params,
431 .set_channel_switch = iwl5000_hw_channel_switch, 477 .set_channel_switch = iwl5000_hw_channel_switch,
432 .temperature = iwl5150_temperature, 478 .temperature = iwl5150_temperature,
479 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
480 .chain_noise_scale = 1000,
481 .no_idle_support = true,
482 .no_xtal_calib = true,
433}; 483};
434 484
435 485
@@ -584,16 +634,59 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
584 return err; 634 return err;
585} 635}
586 636
587struct iwl_lib_ops iwl6000_lib = { 637const struct iwl_dvm_cfg iwl_dvm_6000_cfg = {
588 .set_hw_params = iwl6000_hw_set_hw_params, 638 .set_hw_params = iwl6000_hw_set_hw_params,
589 .set_channel_switch = iwl6000_hw_channel_switch, 639 .set_channel_switch = iwl6000_hw_channel_switch,
590 .nic_config = iwl6000_nic_config, 640 .nic_config = iwl6000_nic_config,
591 .temperature = iwlagn_temperature, 641 .temperature = iwlagn_temperature,
642 .adv_thermal_throttle = true,
643 .support_ct_kill_exit = true,
644 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
645 .chain_noise_scale = 1000,
646};
647
648const struct iwl_dvm_cfg iwl_dvm_6005_cfg = {
649 .set_hw_params = iwl6000_hw_set_hw_params,
650 .set_channel_switch = iwl6000_hw_channel_switch,
651 .nic_config = iwl6000_nic_config,
652 .temperature = iwlagn_temperature,
653 .adv_thermal_throttle = true,
654 .support_ct_kill_exit = true,
655 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
656 .chain_noise_scale = 1000,
657 .need_temp_offset_calib = true,
658};
659
660const struct iwl_dvm_cfg iwl_dvm_6050_cfg = {
661 .set_hw_params = iwl6000_hw_set_hw_params,
662 .set_channel_switch = iwl6000_hw_channel_switch,
663 .nic_config = iwl6000_nic_config,
664 .temperature = iwlagn_temperature,
665 .adv_thermal_throttle = true,
666 .support_ct_kill_exit = true,
667 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
668 .chain_noise_scale = 1500,
669};
670
671static const struct iwl_dvm_bt_params iwl6000_bt_params = {
672 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
673 .advanced_bt_coexist = true,
674 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
675 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
676 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
677 .bt_sco_disable = true,
592}; 678};
593 679
594struct iwl_lib_ops iwl6030_lib = { 680const struct iwl_dvm_cfg iwl_dvm_6030_cfg = {
595 .set_hw_params = iwl6000_hw_set_hw_params, 681 .set_hw_params = iwl6000_hw_set_hw_params,
596 .set_channel_switch = iwl6000_hw_channel_switch, 682 .set_channel_switch = iwl6000_hw_channel_switch,
597 .nic_config = iwl6000_nic_config, 683 .nic_config = iwl6000_nic_config,
598 .temperature = iwlagn_temperature, 684 .temperature = iwlagn_temperature,
685 .adv_thermal_throttle = true,
686 .support_ct_kill_exit = true,
687 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
688 .chain_noise_scale = 1000,
689 .bt_params = &iwl6000_bt_params,
690 .need_temp_offset_calib = true,
691 .adv_pm = true,
599}; 692};
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 54f553380aa8..9879550a0fea 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -254,23 +254,23 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
254 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != 254 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
255 sizeof(basic.bt3_lookup_table)); 255 sizeof(basic.bt3_lookup_table));
256 256
257 if (priv->cfg->bt_params) { 257 if (priv->lib->bt_params) {
258 /* 258 /*
259 * newer generation of devices (2000 series and newer) 259 * newer generation of devices (2000 series and newer)
260 * use the version 2 of the bt command 260 * use the version 2 of the bt command
261 * we need to make sure sending the host command 261 * we need to make sure sending the host command
262 * with correct data structure to avoid uCode assert 262 * with correct data structure to avoid uCode assert
263 */ 263 */
264 if (priv->cfg->bt_params->bt_session_2) { 264 if (priv->lib->bt_params->bt_session_2) {
265 bt_cmd_v2.prio_boost = cpu_to_le32( 265 bt_cmd_v2.prio_boost = cpu_to_le32(
266 priv->cfg->bt_params->bt_prio_boost); 266 priv->lib->bt_params->bt_prio_boost);
267 bt_cmd_v2.tx_prio_boost = 0; 267 bt_cmd_v2.tx_prio_boost = 0;
268 bt_cmd_v2.rx_prio_boost = 0; 268 bt_cmd_v2.rx_prio_boost = 0;
269 } else { 269 } else {
270 /* older version only has 8 bits */ 270 /* older version only has 8 bits */
271 WARN_ON(priv->cfg->bt_params->bt_prio_boost & ~0xFF); 271 WARN_ON(priv->lib->bt_params->bt_prio_boost & ~0xFF);
272 bt_cmd_v1.prio_boost = 272 bt_cmd_v1.prio_boost =
273 priv->cfg->bt_params->bt_prio_boost; 273 priv->lib->bt_params->bt_prio_boost;
274 bt_cmd_v1.tx_prio_boost = 0; 274 bt_cmd_v1.tx_prio_boost = 0;
275 bt_cmd_v1.rx_prio_boost = 0; 275 bt_cmd_v1.rx_prio_boost = 0;
276 } 276 }
@@ -330,7 +330,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
330 priv->bt_full_concurrent ? 330 priv->bt_full_concurrent ?
331 "full concurrency" : "3-wire"); 331 "full concurrency" : "3-wire");
332 332
333 if (priv->cfg->bt_params->bt_session_2) { 333 if (priv->lib->bt_params->bt_session_2) {
334 memcpy(&bt_cmd_v2.basic, &basic, 334 memcpy(&bt_cmd_v2.basic, &basic,
335 sizeof(basic)); 335 sizeof(basic));
336 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, 336 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
@@ -758,8 +758,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv)
758 */ 758 */
759static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) 759static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
760{ 760{
761 if (priv->cfg->bt_params && 761 if (priv->lib->bt_params &&
762 priv->cfg->bt_params->advanced_bt_coexist && 762 priv->lib->bt_params->advanced_bt_coexist &&
763 (priv->bt_full_concurrent || 763 (priv->bt_full_concurrent ||
764 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 764 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
765 /* 765 /*
@@ -830,8 +830,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
830 else 830 else
831 active_chains = priv->nvm_data->valid_rx_ant; 831 active_chains = priv->nvm_data->valid_rx_ant;
832 832
833 if (priv->cfg->bt_params && 833 if (priv->lib->bt_params &&
834 priv->cfg->bt_params->advanced_bt_coexist && 834 priv->lib->bt_params->advanced_bt_coexist &&
835 (priv->bt_full_concurrent || 835 (priv->bt_full_concurrent ||
836 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 836 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
837 /* 837 /*
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index cab23af0be9e..ac7ed3f809a0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -426,6 +426,10 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
426 if (ret) 426 if (ret)
427 goto error; 427 goto error;
428 428
429 /* let the ucode operate on its own */
430 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
431 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
432
429 iwl_trans_d3_suspend(priv->trans); 433 iwl_trans_d3_suspend(priv->trans);
430 434
431 goto out; 435 goto out;
@@ -509,6 +513,10 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
509 goto out_unlock; 513 goto out_unlock;
510 } 514 }
511 515
516 /* uCode is no longer operating by itself */
517 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
518 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
519
512 base = priv->device_pointers.error_event_table; 520 base = priv->device_pointers.error_event_table;
513 if (!iwlagn_hw_valid_rtc_data_addr(base)) { 521 if (!iwlagn_hw_valid_rtc_data_addr(base)) {
514 IWL_WARN(priv, "Invalid error table during resume!\n"); 522 IWL_WARN(priv, "Invalid error table during resume!\n");
@@ -1276,8 +1284,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1276 IWL_DEBUG_MAC80211(priv, "enter\n"); 1284 IWL_DEBUG_MAC80211(priv, "enter\n");
1277 mutex_lock(&priv->mutex); 1285 mutex_lock(&priv->mutex);
1278 1286
1279 if (priv->cfg->bt_params && 1287 if (priv->lib->bt_params &&
1280 priv->cfg->bt_params->advanced_bt_coexist) { 1288 priv->lib->bt_params->advanced_bt_coexist) {
1281 if (rssi_event == RSSI_EVENT_LOW) 1289 if (rssi_event == RSSI_EVENT_LOW)
1282 priv->bt_enable_pspoll = true; 1290 priv->bt_enable_pspoll = true;
1283 else if (rssi_event == RSSI_EVENT_HIGH) 1291 else if (rssi_event == RSSI_EVENT_HIGH)
@@ -1387,7 +1395,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
1387 return err; 1395 return err;
1388 } 1396 }
1389 1397
1390 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && 1398 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist &&
1391 vif->type == NL80211_IFTYPE_ADHOC) { 1399 vif->type == NL80211_IFTYPE_ADHOC) {
1392 /* 1400 /*
1393 * pretend to have high BT traffic as long as we 1401 * pretend to have high BT traffic as long as we
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 74d7572e7091..68f754659570 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -615,7 +615,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
615 615
616 priv->thermal_throttle.ct_kill_toggle = false; 616 priv->thermal_throttle.ct_kill_toggle = false;
617 617
618 if (priv->cfg->base_params->support_ct_kill_exit) { 618 if (priv->lib->support_ct_kill_exit) {
619 adv_cmd.critical_temperature_enter = 619 adv_cmd.critical_temperature_enter =
620 cpu_to_le32(priv->hw_params.ct_kill_threshold); 620 cpu_to_le32(priv->hw_params.ct_kill_threshold);
621 adv_cmd.critical_temperature_exit = 621 adv_cmd.critical_temperature_exit =
@@ -732,10 +732,10 @@ int iwl_alive_start(struct iwl_priv *priv)
732 } 732 }
733 733
734 /* download priority table before any calibration request */ 734 /* download priority table before any calibration request */
735 if (priv->cfg->bt_params && 735 if (priv->lib->bt_params &&
736 priv->cfg->bt_params->advanced_bt_coexist) { 736 priv->lib->bt_params->advanced_bt_coexist) {
737 /* Configure Bluetooth device coexistence support */ 737 /* Configure Bluetooth device coexistence support */
738 if (priv->cfg->bt_params->bt_sco_disable) 738 if (priv->lib->bt_params->bt_sco_disable)
739 priv->bt_enable_pspoll = false; 739 priv->bt_enable_pspoll = false;
740 else 740 else
741 priv->bt_enable_pspoll = true; 741 priv->bt_enable_pspoll = true;
@@ -873,9 +873,9 @@ void iwl_down(struct iwl_priv *priv)
873 priv->bt_status = 0; 873 priv->bt_status = 0;
874 priv->cur_rssi_ctx = NULL; 874 priv->cur_rssi_ctx = NULL;
875 priv->bt_is_sco = 0; 875 priv->bt_is_sco = 0;
876 if (priv->cfg->bt_params) 876 if (priv->lib->bt_params)
877 priv->bt_traffic_load = 877 priv->bt_traffic_load =
878 priv->cfg->bt_params->bt_init_traffic_load; 878 priv->lib->bt_params->bt_init_traffic_load;
879 else 879 else
880 priv->bt_traffic_load = 0; 880 priv->bt_traffic_load = 0;
881 priv->bt_full_concurrent = false; 881 priv->bt_full_concurrent = false;
@@ -1058,7 +1058,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1058 1058
1059 iwl_setup_scan_deferred_work(priv); 1059 iwl_setup_scan_deferred_work(priv);
1060 1060
1061 if (priv->cfg->bt_params) 1061 if (priv->lib->bt_params)
1062 iwlagn_bt_setup_deferred_work(priv); 1062 iwlagn_bt_setup_deferred_work(priv);
1063 1063
1064 init_timer(&priv->statistics_periodic); 1064 init_timer(&priv->statistics_periodic);
@@ -1072,7 +1072,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1072 1072
1073void iwl_cancel_deferred_work(struct iwl_priv *priv) 1073void iwl_cancel_deferred_work(struct iwl_priv *priv)
1074{ 1074{
1075 if (priv->cfg->bt_params) 1075 if (priv->lib->bt_params)
1076 iwlagn_bt_cancel_deferred_work(priv); 1076 iwlagn_bt_cancel_deferred_work(priv);
1077 1077
1078 cancel_work_sync(&priv->run_time_calib_work); 1078 cancel_work_sync(&priv->run_time_calib_work);
@@ -1098,8 +1098,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
1098 1098
1099 priv->band = IEEE80211_BAND_2GHZ; 1099 priv->band = IEEE80211_BAND_2GHZ;
1100 1100
1101 priv->plcp_delta_threshold = 1101 priv->plcp_delta_threshold = priv->lib->plcp_delta_threshold;
1102 priv->cfg->base_params->plcp_delta_threshold;
1103 1102
1104 priv->iw_mode = NL80211_IFTYPE_STATION; 1103 priv->iw_mode = NL80211_IFTYPE_STATION;
1105 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 1104 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
@@ -1116,8 +1115,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
1116 iwl_init_scan_params(priv); 1115 iwl_init_scan_params(priv);
1117 1116
1118 /* init bt coex */ 1117 /* init bt coex */
1119 if (priv->cfg->bt_params && 1118 if (priv->lib->bt_params &&
1120 priv->cfg->bt_params->advanced_bt_coexist) { 1119 priv->lib->bt_params->advanced_bt_coexist) {
1121 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 1120 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
1122 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 1121 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
1123 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 1122 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
@@ -1264,31 +1263,37 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1264 switch (priv->cfg->device_family) { 1263 switch (priv->cfg->device_family) {
1265 case IWL_DEVICE_FAMILY_1000: 1264 case IWL_DEVICE_FAMILY_1000:
1266 case IWL_DEVICE_FAMILY_100: 1265 case IWL_DEVICE_FAMILY_100:
1267 priv->lib = &iwl1000_lib; 1266 priv->lib = &iwl_dvm_1000_cfg;
1268 break; 1267 break;
1269 case IWL_DEVICE_FAMILY_2000: 1268 case IWL_DEVICE_FAMILY_2000:
1269 priv->lib = &iwl_dvm_2000_cfg;
1270 break;
1270 case IWL_DEVICE_FAMILY_105: 1271 case IWL_DEVICE_FAMILY_105:
1271 priv->lib = &iwl2000_lib; 1272 priv->lib = &iwl_dvm_105_cfg;
1272 break; 1273 break;
1273 case IWL_DEVICE_FAMILY_2030: 1274 case IWL_DEVICE_FAMILY_2030:
1274 case IWL_DEVICE_FAMILY_135: 1275 case IWL_DEVICE_FAMILY_135:
1275 priv->lib = &iwl2030_lib; 1276 priv->lib = &iwl_dvm_2030_cfg;
1276 break; 1277 break;
1277 case IWL_DEVICE_FAMILY_5000: 1278 case IWL_DEVICE_FAMILY_5000:
1278 priv->lib = &iwl5000_lib; 1279 priv->lib = &iwl_dvm_5000_cfg;
1279 break; 1280 break;
1280 case IWL_DEVICE_FAMILY_5150: 1281 case IWL_DEVICE_FAMILY_5150:
1281 priv->lib = &iwl5150_lib; 1282 priv->lib = &iwl_dvm_5150_cfg;
1282 break; 1283 break;
1283 case IWL_DEVICE_FAMILY_6000: 1284 case IWL_DEVICE_FAMILY_6000:
1284 case IWL_DEVICE_FAMILY_6005:
1285 case IWL_DEVICE_FAMILY_6000i: 1285 case IWL_DEVICE_FAMILY_6000i:
1286 priv->lib = &iwl_dvm_6000_cfg;
1287 break;
1288 case IWL_DEVICE_FAMILY_6005:
1289 priv->lib = &iwl_dvm_6005_cfg;
1290 break;
1286 case IWL_DEVICE_FAMILY_6050: 1291 case IWL_DEVICE_FAMILY_6050:
1287 case IWL_DEVICE_FAMILY_6150: 1292 case IWL_DEVICE_FAMILY_6150:
1288 priv->lib = &iwl6000_lib; 1293 priv->lib = &iwl_dvm_6050_cfg;
1289 break; 1294 break;
1290 case IWL_DEVICE_FAMILY_6030: 1295 case IWL_DEVICE_FAMILY_6030:
1291 priv->lib = &iwl6030_lib; 1296 priv->lib = &iwl_dvm_6030_cfg;
1292 break; 1297 break;
1293 default: 1298 default:
1294 break; 1299 break;
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index bd69018d07a9..77cb59712235 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -163,7 +163,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
163 u8 skip; 163 u8 skip;
164 u32 slp_itrvl; 164 u32 slp_itrvl;
165 165
166 if (priv->cfg->adv_pm) { 166 if (priv->lib->adv_pm) {
167 table = apm_range_2; 167 table = apm_range_2;
168 if (period <= IWL_DTIM_RANGE_1_MAX) 168 if (period <= IWL_DTIM_RANGE_1_MAX)
169 table = apm_range_1; 169 table = apm_range_1;
@@ -217,7 +217,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
217 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; 217 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
218 218
219 if (iwl_advanced_bt_coexist(priv)) { 219 if (iwl_advanced_bt_coexist(priv)) {
220 if (!priv->cfg->bt_params->bt_sco_disable) 220 if (!priv->lib->bt_params->bt_sco_disable)
221 cmd->flags |= IWL_POWER_BT_SCO_ENA; 221 cmd->flags |= IWL_POWER_BT_SCO_ENA;
222 else 222 else
223 cmd->flags &= ~IWL_POWER_BT_SCO_ENA; 223 cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
@@ -293,7 +293,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
293 293
294 if (priv->wowlan) 294 if (priv->wowlan)
295 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); 295 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
296 else if (!priv->cfg->base_params->no_idle_support && 296 else if (!priv->lib->no_idle_support &&
297 priv->hw->conf.flags & IEEE80211_CONF_IDLE) 297 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
298 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); 298 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
299 else if (iwl_tt_is_low_power_state(priv)) { 299 else if (iwl_tt_is_low_power_state(priv)) {
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 907bd6e50aad..94314a8e1029 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -1088,7 +1088,7 @@ done:
1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) 1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
1089 rs_program_fix_rate(priv, lq_sta); 1089 rs_program_fix_rate(priv, lq_sta);
1090#endif 1090#endif
1091 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) 1091 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)
1092 rs_bt_update_lq(priv, ctx, lq_sta); 1092 rs_bt_update_lq(priv, ctx, lq_sta);
1093} 1093}
1094 1094
@@ -3064,11 +3064,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
3064 * overwrite if needed, pass aggregation time limit 3064 * overwrite if needed, pass aggregation time limit
3065 * to uCode in uSec 3065 * to uCode in uSec
3066 */ 3066 */
3067 if (priv && priv->cfg->bt_params && 3067 if (priv && priv->lib->bt_params &&
3068 priv->cfg->bt_params->agg_time_limit && 3068 priv->lib->bt_params->agg_time_limit &&
3069 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) 3069 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
3070 lq_cmd->agg_params.agg_time_limit = 3070 lq_cmd->agg_params.agg_time_limit =
3071 cpu_to_le16(priv->cfg->bt_params->agg_time_limit); 3071 cpu_to_le16(priv->lib->bt_params->agg_time_limit);
3072} 3072}
3073 3073
3074static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 3074static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index a4eed2055fdb..2f3fd160ab44 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -1102,7 +1102,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1102 iwl_notification_wait_init(&priv->notif_wait); 1102 iwl_notification_wait_init(&priv->notif_wait);
1103 1103
1104 /* Set up BT Rx handlers */ 1104 /* Set up BT Rx handlers */
1105 if (priv->cfg->bt_params) 1105 if (priv->lib->bt_params)
1106 iwlagn_bt_rx_handler_setup(priv); 1106 iwlagn_bt_rx_handler_setup(priv);
1107} 1107}
1108 1108
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index d69b55866714..8c686a5b90ac 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -801,8 +801,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
801 * Internal scans are passive, so we can indiscriminately set 801 * Internal scans are passive, so we can indiscriminately set
802 * the BT ignore flag on 2.4 GHz since it applies to TX only. 802 * the BT ignore flag on 2.4 GHz since it applies to TX only.
803 */ 803 */
804 if (priv->cfg->bt_params && 804 if (priv->lib->bt_params &&
805 priv->cfg->bt_params->advanced_bt_coexist) 805 priv->lib->bt_params->advanced_bt_coexist)
806 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; 806 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
807 break; 807 break;
808 case IEEE80211_BAND_5GHZ: 808 case IEEE80211_BAND_5GHZ:
@@ -844,8 +844,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
844 band = priv->scan_band; 844 band = priv->scan_band;
845 845
846 if (band == IEEE80211_BAND_2GHZ && 846 if (band == IEEE80211_BAND_2GHZ &&
847 priv->cfg->bt_params && 847 priv->lib->bt_params &&
848 priv->cfg->bt_params->advanced_bt_coexist) { 848 priv->lib->bt_params->advanced_bt_coexist) {
849 /* transmit 2.4 GHz probes only on first antenna */ 849 /* transmit 2.4 GHz probes only on first antenna */
850 scan_tx_antennas = first_antenna(scan_tx_antennas); 850 scan_tx_antennas = first_antenna(scan_tx_antennas);
851 } 851 }
@@ -873,8 +873,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
873 873
874 rx_ant = first_antenna(active_chains); 874 rx_ant = first_antenna(active_chains);
875 } 875 }
876 if (priv->cfg->bt_params && 876 if (priv->lib->bt_params &&
877 priv->cfg->bt_params->advanced_bt_coexist && 877 priv->lib->bt_params->advanced_bt_coexist &&
878 priv->bt_full_concurrent) { 878 priv->bt_full_concurrent) {
879 /* operated as 1x1 in full concurrency mode */ 879 /* operated as 1x1 in full concurrency mode */
880 rx_ant = first_antenna(rx_ant); 880 rx_ant = first_antenna(rx_ant);
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index db183b44e038..c3c13ce96eb0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -735,7 +735,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
735 memcpy(&lq, priv->stations[i].lq, 735 memcpy(&lq, priv->stations[i].lq,
736 sizeof(struct iwl_link_quality_cmd)); 736 sizeof(struct iwl_link_quality_cmd));
737 737
738 if (!memcmp(&lq, &zero_lq, sizeof(lq))) 738 if (memcmp(&lq, &zero_lq, sizeof(lq)))
739 send_lq = true; 739 send_lq = true;
740 } 740 }
741 spin_unlock_bh(&priv->sta_lock); 741 spin_unlock_bh(&priv->sta_lock);
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index 03f9bc01c0cc..fbeee081ee2f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -627,7 +627,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
627 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); 627 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
628 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); 628 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
629 629
630 if (priv->cfg->base_params->adv_thermal_throttle) { 630 if (priv->lib->adv_thermal_throttle) {
631 IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); 631 IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
632 tt->restriction = kcalloc(IWL_TI_STATE_MAX, 632 tt->restriction = kcalloc(IWL_TI_STATE_MAX,
633 sizeof(struct iwl_tt_restriction), 633 sizeof(struct iwl_tt_restriction),
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index a900aaf47790..353a053b4eb1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -83,8 +83,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
83 else if (ieee80211_is_back_req(fc)) 83 else if (ieee80211_is_back_req(fc))
84 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; 84 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
85 else if (info->band == IEEE80211_BAND_2GHZ && 85 else if (info->band == IEEE80211_BAND_2GHZ &&
86 priv->cfg->bt_params && 86 priv->lib->bt_params &&
87 priv->cfg->bt_params->advanced_bt_coexist && 87 priv->lib->bt_params->advanced_bt_coexist &&
88 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || 88 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
89 ieee80211_is_reassoc_req(fc) || 89 ieee80211_is_reassoc_req(fc) ||
90 skb->protocol == cpu_to_be16(ETH_P_PAE))) 90 skb->protocol == cpu_to_be16(ETH_P_PAE)))
@@ -202,8 +202,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
202 rate_flags |= RATE_MCS_CCK_MSK; 202 rate_flags |= RATE_MCS_CCK_MSK;
203 203
204 /* Set up antennas */ 204 /* Set up antennas */
205 if (priv->cfg->bt_params && 205 if (priv->lib->bt_params &&
206 priv->cfg->bt_params->advanced_bt_coexist && 206 priv->lib->bt_params->advanced_bt_coexist &&
207 priv->bt_full_concurrent) { 207 priv->bt_full_concurrent) {
208 /* operated as 1x1 in full concurrency mode */ 208 /* operated as 1x1 in full concurrency mode */
209 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 209 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
@@ -986,8 +986,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
986 * notification again. 986 * notification again.
987 */ 987 */
988 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && 988 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
989 priv->cfg->bt_params && 989 priv->lib->bt_params &&
990 priv->cfg->bt_params->advanced_bt_coexist) { 990 priv->lib->bt_params->advanced_bt_coexist) {
991 IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); 991 IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n");
992 } 992 }
993 993
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 0a1cdc5e856b..86270b69cd02 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -132,8 +132,8 @@ int iwl_init_alive_start(struct iwl_priv *priv)
132{ 132{
133 int ret; 133 int ret;
134 134
135 if (priv->cfg->bt_params && 135 if (priv->lib->bt_params &&
136 priv->cfg->bt_params->advanced_bt_coexist) { 136 priv->lib->bt_params->advanced_bt_coexist) {
137 /* 137 /*
138 * Tell uCode we are ready to perform calibration 138 * Tell uCode we are ready to perform calibration
139 * need to perform this before any calibration 139 * need to perform this before any calibration
@@ -155,8 +155,8 @@ int iwl_init_alive_start(struct iwl_priv *priv)
155 * temperature offset calibration is only needed for runtime ucode, 155 * temperature offset calibration is only needed for runtime ucode,
156 * so prepare the value now. 156 * so prepare the value now.
157 */ 157 */
158 if (priv->cfg->need_temp_offset_calib) { 158 if (priv->lib->need_temp_offset_calib) {
159 if (priv->cfg->temp_offset_v2) 159 if (priv->lib->temp_offset_v2)
160 return iwl_set_temperature_offset_calib_v2(priv); 160 return iwl_set_temperature_offset_calib_v2(priv);
161 else 161 else
162 return iwl_set_temperature_offset_calib(priv); 162 return iwl_set_temperature_offset_calib(priv);
@@ -277,7 +277,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
277 if (ret) 277 if (ret)
278 return ret; 278 return ret;
279 279
280 if (!priv->cfg->no_xtal_calib) { 280 if (!priv->lib->no_xtal_calib) {
281 ret = iwl_set_Xtal_calib(priv); 281 ret = iwl_set_Xtal_calib(priv);
282 if (ret) 282 if (ret)
283 return ret; 283 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index c080ae3070b2..0d2afe098afc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -60,9 +60,6 @@ static const struct iwl_base_params iwl1000_base_params = {
60 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 60 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
61 .shadow_ram_support = false, 61 .shadow_ram_support = false,
62 .led_compensation = 51, 62 .led_compensation = 51,
63 .support_ct_kill_exit = true,
64 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
65 .chain_noise_scale = 1000,
66 .wd_timeout = IWL_WATCHDOG_DISABLED, 63 .wd_timeout = IWL_WATCHDOG_DISABLED,
67 .max_event_log_size = 128, 64 .max_event_log_size = 128,
68}; 65};
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index a6ddd2f9fba0..c727ec7c90a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -72,14 +72,9 @@ static const struct iwl_base_params iwl2000_base_params = {
72 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 72 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
73 .shadow_ram_support = true, 73 .shadow_ram_support = true,
74 .led_compensation = 51, 74 .led_compensation = 51,
75 .adv_thermal_throttle = true,
76 .support_ct_kill_exit = true,
77 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
78 .chain_noise_scale = 1000,
79 .wd_timeout = IWL_DEF_WD_TIMEOUT, 75 .wd_timeout = IWL_DEF_WD_TIMEOUT,
80 .max_event_log_size = 512, 76 .max_event_log_size = 512,
81 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 77 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
82 .hd_v2 = true,
83}; 78};
84 79
85 80
@@ -90,14 +85,9 @@ static const struct iwl_base_params iwl2030_base_params = {
90 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 85 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
91 .shadow_ram_support = true, 86 .shadow_ram_support = true,
92 .led_compensation = 57, 87 .led_compensation = 57,
93 .adv_thermal_throttle = true,
94 .support_ct_kill_exit = true,
95 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
96 .chain_noise_scale = 1000,
97 .wd_timeout = IWL_LONG_WD_TIMEOUT, 88 .wd_timeout = IWL_LONG_WD_TIMEOUT,
98 .max_event_log_size = 512, 89 .max_event_log_size = 512,
99 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 90 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
100 .hd_v2 = true,
101}; 91};
102 92
103static const struct iwl_ht_params iwl2000_ht_params = { 93static const struct iwl_ht_params iwl2000_ht_params = {
@@ -106,16 +96,6 @@ static const struct iwl_ht_params iwl2000_ht_params = {
106 .ht40_bands = BIT(IEEE80211_BAND_2GHZ), 96 .ht40_bands = BIT(IEEE80211_BAND_2GHZ),
107}; 97};
108 98
109static const struct iwl_bt_params iwl2030_bt_params = {
110 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
111 .advanced_bt_coexist = true,
112 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
113 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
114 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
115 .bt_sco_disable = true,
116 .bt_session_2 = true,
117};
118
119static const struct iwl_eeprom_params iwl20x0_eeprom_params = { 99static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
120 .regulatory_bands = { 100 .regulatory_bands = {
121 EEPROM_REG_BAND_1_CHANNELS, 101 EEPROM_REG_BAND_1_CHANNELS,
@@ -137,12 +117,10 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
137 .device_family = IWL_DEVICE_FAMILY_2000, \ 117 .device_family = IWL_DEVICE_FAMILY_2000, \
138 .max_inst_size = IWL60_RTC_INST_SIZE, \ 118 .max_inst_size = IWL60_RTC_INST_SIZE, \
139 .max_data_size = IWL60_RTC_DATA_SIZE, \ 119 .max_data_size = IWL60_RTC_DATA_SIZE, \
140 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 120 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
141 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 121 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
142 .base_params = &iwl2000_base_params, \ 122 .base_params = &iwl2000_base_params, \
143 .eeprom_params = &iwl20x0_eeprom_params, \ 123 .eeprom_params = &iwl20x0_eeprom_params, \
144 .need_temp_offset_calib = true, \
145 .temp_offset_v2 = true, \
146 .led_mode = IWL_LED_RF_STATE 124 .led_mode = IWL_LED_RF_STATE
147 125
148const struct iwl_cfg iwl2000_2bgn_cfg = { 126const struct iwl_cfg iwl2000_2bgn_cfg = {
@@ -168,12 +146,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
168 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 146 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
169 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 147 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
170 .base_params = &iwl2030_base_params, \ 148 .base_params = &iwl2030_base_params, \
171 .bt_params = &iwl2030_bt_params, \
172 .eeprom_params = &iwl20x0_eeprom_params, \ 149 .eeprom_params = &iwl20x0_eeprom_params, \
173 .need_temp_offset_calib = true, \ 150 .led_mode = IWL_LED_RF_STATE
174 .temp_offset_v2 = true, \
175 .led_mode = IWL_LED_RF_STATE, \
176 .adv_pm = true
177 151
178const struct iwl_cfg iwl2030_2bgn_cfg = { 152const struct iwl_cfg iwl2030_2bgn_cfg = {
179 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", 153 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
@@ -193,10 +167,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
193 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 167 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
194 .base_params = &iwl2000_base_params, \ 168 .base_params = &iwl2000_base_params, \
195 .eeprom_params = &iwl20x0_eeprom_params, \ 169 .eeprom_params = &iwl20x0_eeprom_params, \
196 .need_temp_offset_calib = true, \
197 .temp_offset_v2 = true, \
198 .led_mode = IWL_LED_RF_STATE, \ 170 .led_mode = IWL_LED_RF_STATE, \
199 .adv_pm = true, \
200 .rx_with_siso_diversity = true 171 .rx_with_siso_diversity = true
201 172
202const struct iwl_cfg iwl105_bgn_cfg = { 173const struct iwl_cfg iwl105_bgn_cfg = {
@@ -222,12 +193,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
222 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 193 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
223 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 194 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
224 .base_params = &iwl2030_base_params, \ 195 .base_params = &iwl2030_base_params, \
225 .bt_params = &iwl2030_bt_params, \
226 .eeprom_params = &iwl20x0_eeprom_params, \ 196 .eeprom_params = &iwl20x0_eeprom_params, \
227 .need_temp_offset_calib = true, \
228 .temp_offset_v2 = true, \
229 .led_mode = IWL_LED_RF_STATE, \ 197 .led_mode = IWL_LED_RF_STATE, \
230 .adv_pm = true, \
231 .rx_with_siso_diversity = true 198 .rx_with_siso_diversity = true
232 199
233const struct iwl_cfg iwl135_bgn_cfg = { 200const struct iwl_cfg iwl135_bgn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 403f3f224bf6..ecc01e1a61a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -59,11 +59,8 @@ static const struct iwl_base_params iwl5000_base_params = {
59 .num_of_queues = IWLAGN_NUM_QUEUES, 59 .num_of_queues = IWLAGN_NUM_QUEUES,
60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
61 .led_compensation = 51, 61 .led_compensation = 51,
62 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
63 .chain_noise_scale = 1000,
64 .wd_timeout = IWL_WATCHDOG_DISABLED, 62 .wd_timeout = IWL_WATCHDOG_DISABLED,
65 .max_event_log_size = 512, 63 .max_event_log_size = 512,
66 .no_idle_support = true,
67}; 64};
68 65
69static const struct iwl_ht_params iwl5000_ht_params = { 66static const struct iwl_ht_params iwl5000_ht_params = {
@@ -159,7 +156,6 @@ const struct iwl_cfg iwl5350_agn_cfg = {
159 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ 156 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
160 .base_params = &iwl5000_base_params, \ 157 .base_params = &iwl5000_base_params, \
161 .eeprom_params = &iwl5000_eeprom_params, \ 158 .eeprom_params = &iwl5000_eeprom_params, \
162 .no_xtal_calib = true, \
163 .led_mode = IWL_LED_BLINK, \ 159 .led_mode = IWL_LED_BLINK, \
164 .internal_wimax_coex = true 160 .internal_wimax_coex = true
165 161
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index b5ab8d1bcac0..30d45e2fc193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -82,10 +82,6 @@ static const struct iwl_base_params iwl6000_base_params = {
82 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 82 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
83 .shadow_ram_support = true, 83 .shadow_ram_support = true,
84 .led_compensation = 51, 84 .led_compensation = 51,
85 .adv_thermal_throttle = true,
86 .support_ct_kill_exit = true,
87 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
88 .chain_noise_scale = 1000,
89 .wd_timeout = IWL_DEF_WD_TIMEOUT, 85 .wd_timeout = IWL_DEF_WD_TIMEOUT,
90 .max_event_log_size = 512, 86 .max_event_log_size = 512,
91 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 87 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -98,10 +94,6 @@ static const struct iwl_base_params iwl6050_base_params = {
98 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 94 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
99 .shadow_ram_support = true, 95 .shadow_ram_support = true,
100 .led_compensation = 51, 96 .led_compensation = 51,
101 .adv_thermal_throttle = true,
102 .support_ct_kill_exit = true,
103 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
104 .chain_noise_scale = 1500,
105 .wd_timeout = IWL_DEF_WD_TIMEOUT, 97 .wd_timeout = IWL_DEF_WD_TIMEOUT,
106 .max_event_log_size = 1024, 98 .max_event_log_size = 1024,
107 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 99 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -114,10 +106,6 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
114 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 106 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
115 .shadow_ram_support = true, 107 .shadow_ram_support = true,
116 .led_compensation = 57, 108 .led_compensation = 57,
117 .adv_thermal_throttle = true,
118 .support_ct_kill_exit = true,
119 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
120 .chain_noise_scale = 1000,
121 .wd_timeout = IWL_LONG_WD_TIMEOUT, 109 .wd_timeout = IWL_LONG_WD_TIMEOUT,
122 .max_event_log_size = 512, 110 .max_event_log_size = 512,
123 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 111 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -129,15 +117,6 @@ static const struct iwl_ht_params iwl6000_ht_params = {
129 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 117 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
130}; 118};
131 119
132static const struct iwl_bt_params iwl6000_bt_params = {
133 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
134 .advanced_bt_coexist = true,
135 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
136 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
137 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
138 .bt_sco_disable = true,
139};
140
141static const struct iwl_eeprom_params iwl6000_eeprom_params = { 120static const struct iwl_eeprom_params iwl6000_eeprom_params = {
142 .regulatory_bands = { 121 .regulatory_bands = {
143 EEPROM_REG_BAND_1_CHANNELS, 122 EEPROM_REG_BAND_1_CHANNELS,
@@ -163,7 +142,6 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
163 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ 142 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
164 .base_params = &iwl6000_g2_base_params, \ 143 .base_params = &iwl6000_g2_base_params, \
165 .eeprom_params = &iwl6000_eeprom_params, \ 144 .eeprom_params = &iwl6000_eeprom_params, \
166 .need_temp_offset_calib = true, \
167 .led_mode = IWL_LED_RF_STATE 145 .led_mode = IWL_LED_RF_STATE
168 146
169const struct iwl_cfg iwl6005_2agn_cfg = { 147const struct iwl_cfg iwl6005_2agn_cfg = {
@@ -217,11 +195,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
217 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ 195 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
218 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 196 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
219 .base_params = &iwl6000_g2_base_params, \ 197 .base_params = &iwl6000_g2_base_params, \
220 .bt_params = &iwl6000_bt_params, \
221 .eeprom_params = &iwl6000_eeprom_params, \ 198 .eeprom_params = &iwl6000_eeprom_params, \
222 .need_temp_offset_calib = true, \ 199 .led_mode = IWL_LED_RF_STATE
223 .led_mode = IWL_LED_RF_STATE, \
224 .adv_pm = true \
225 200
226const struct iwl_cfg iwl6030_2agn_cfg = { 201const struct iwl_cfg iwl6030_2agn_cfg = {
227 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", 202 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
@@ -256,11 +231,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
256 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ 231 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
257 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 232 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
258 .base_params = &iwl6000_g2_base_params, \ 233 .base_params = &iwl6000_g2_base_params, \
259 .bt_params = &iwl6000_bt_params, \
260 .eeprom_params = &iwl6000_eeprom_params, \ 234 .eeprom_params = &iwl6000_eeprom_params, \
261 .need_temp_offset_calib = true, \ 235 .led_mode = IWL_LED_RF_STATE
262 .led_mode = IWL_LED_RF_STATE, \
263 .adv_pm = true
264 236
265const struct iwl_cfg iwl6035_2agn_cfg = { 237const struct iwl_cfg iwl6035_2agn_cfg = {
266 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", 238 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 50263e87fe15..d4f3b4864ab1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -96,13 +96,9 @@ static const struct iwl_base_params iwl7000_base_params = {
96 .pll_cfg_val = 0, 96 .pll_cfg_val = 0,
97 .shadow_ram_support = true, 97 .shadow_ram_support = true,
98 .led_compensation = 57, 98 .led_compensation = 57,
99 .adv_thermal_throttle = true,
100 .support_ct_kill_exit = true,
101 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
102 .chain_noise_scale = 1000,
103 .wd_timeout = IWL_LONG_WD_TIMEOUT, 99 .wd_timeout = IWL_LONG_WD_TIMEOUT,
104 .max_event_log_size = 512, 100 .max_event_log_size = 512,
105 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 101 .shadow_reg_enable = true,
106}; 102};
107 103
108static const struct iwl_ht_params iwl7000_ht_params = { 104static const struct iwl_ht_params iwl7000_ht_params = {
@@ -118,14 +114,11 @@ static const struct iwl_ht_params iwl7000_ht_params = {
118 .max_inst_size = IWL60_RTC_INST_SIZE, \ 114 .max_inst_size = IWL60_RTC_INST_SIZE, \
119 .max_data_size = IWL60_RTC_DATA_SIZE, \ 115 .max_data_size = IWL60_RTC_DATA_SIZE, \
120 .base_params = &iwl7000_base_params, \ 116 .base_params = &iwl7000_base_params, \
121 /* TODO: .bt_params? */ \ 117 .led_mode = IWL_LED_RF_STATE
122 .need_temp_offset_calib = true, \
123 .led_mode = IWL_LED_RF_STATE, \
124 .adv_pm = true \
125 118
126 119
127const struct iwl_cfg iwl7260_2ac_cfg = { 120const struct iwl_cfg iwl7260_2ac_cfg = {
128 .name = "Intel(R) Dual Band Wireless AC7260", 121 .name = "Intel(R) Dual Band Wireless AC 7260",
129 .fw_name_pre = IWL7260_FW_PRE, 122 .fw_name_pre = IWL7260_FW_PRE,
130 IWL_DEVICE_7000, 123 IWL_DEVICE_7000,
131 .ht_params = &iwl7000_ht_params, 124 .ht_params = &iwl7000_ht_params,
@@ -133,8 +126,44 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
133 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 126 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
134}; 127};
135 128
136const struct iwl_cfg iwl3160_ac_cfg = { 129const struct iwl_cfg iwl7260_2n_cfg = {
137 .name = "Intel(R) Dual Band Wireless AC3160", 130 .name = "Intel(R) Dual Band Wireless N 7260",
131 .fw_name_pre = IWL7260_FW_PRE,
132 IWL_DEVICE_7000,
133 .ht_params = &iwl7000_ht_params,
134 .nvm_ver = IWL7260_NVM_VERSION,
135 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
136};
137
138const struct iwl_cfg iwl7260_n_cfg = {
139 .name = "Intel(R) Wireless N 7260",
140 .fw_name_pre = IWL7260_FW_PRE,
141 IWL_DEVICE_7000,
142 .ht_params = &iwl7000_ht_params,
143 .nvm_ver = IWL7260_NVM_VERSION,
144 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
145};
146
147const struct iwl_cfg iwl3160_2ac_cfg = {
148 .name = "Intel(R) Dual Band Wireless AC 3160",
149 .fw_name_pre = IWL3160_FW_PRE,
150 IWL_DEVICE_7000,
151 .ht_params = &iwl7000_ht_params,
152 .nvm_ver = IWL3160_NVM_VERSION,
153 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
154};
155
156const struct iwl_cfg iwl3160_2n_cfg = {
157 .name = "Intel(R) Dual Band Wireless N 3160",
158 .fw_name_pre = IWL3160_FW_PRE,
159 IWL_DEVICE_7000,
160 .ht_params = &iwl7000_ht_params,
161 .nvm_ver = IWL3160_NVM_VERSION,
162 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
163};
164
165const struct iwl_cfg iwl3160_n_cfg = {
166 .name = "Intel(R) Wireless N 3160",
138 .fw_name_pre = IWL3160_FW_PRE, 167 .fw_name_pre = IWL3160_FW_PRE,
139 IWL_DEVICE_7000, 168 IWL_DEVICE_7000,
140 .ht_params = &iwl7000_ht_params, 169 .ht_params = &iwl7000_ht_params,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index c38aa8f77554..a193832fc790 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -136,17 +136,9 @@ enum iwl_led_mode {
136 * @led_compensation: compensate on the led on/off time per HW according 136 * @led_compensation: compensate on the led on/off time per HW according
137 * to the deviation to achieve the desired led frequency. 137 * to the deviation to achieve the desired led frequency.
138 * The detail algorithm is described in iwl-led.c 138 * The detail algorithm is described in iwl-led.c
139 * @chain_noise_num_beacons: number of beacons used to compute chain noise
140 * @adv_thermal_throttle: support advance thermal throttle
141 * @support_ct_kill_exit: support ct kill exit condition
142 * @plcp_delta_threshold: plcp error rate threshold used to trigger
143 * radio tuning when there is a high receiving plcp error rate
144 * @chain_noise_scale: default chain noise scale used for gain computation
145 * @wd_timeout: TX queues watchdog timeout 139 * @wd_timeout: TX queues watchdog timeout
146 * @max_event_log_size: size of event log buffer size for ucode event logging 140 * @max_event_log_size: size of event log buffer size for ucode event logging
147 * @shadow_reg_enable: HW shadow register support 141 * @shadow_reg_enable: HW shadow register support
148 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
149 * @no_idle_support: do not support idle mode
150 */ 142 */
151struct iwl_base_params { 143struct iwl_base_params {
152 int eeprom_size; 144 int eeprom_size;
@@ -157,31 +149,9 @@ struct iwl_base_params {
157 const u16 max_ll_items; 149 const u16 max_ll_items;
158 const bool shadow_ram_support; 150 const bool shadow_ram_support;
159 u16 led_compensation; 151 u16 led_compensation;
160 bool adv_thermal_throttle;
161 bool support_ct_kill_exit;
162 u8 plcp_delta_threshold;
163 s32 chain_noise_scale;
164 unsigned int wd_timeout; 152 unsigned int wd_timeout;
165 u32 max_event_log_size; 153 u32 max_event_log_size;
166 const bool shadow_reg_enable; 154 const bool shadow_reg_enable;
167 const bool hd_v2;
168 const bool no_idle_support;
169};
170
171/*
172 * @advanced_bt_coexist: support advanced bt coexist
173 * @bt_init_traffic_load: specify initial bt traffic load
174 * @bt_prio_boost: default bt priority boost value
175 * @agg_time_limit: maximum number of uSec in aggregation
176 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
177 */
178struct iwl_bt_params {
179 bool advanced_bt_coexist;
180 u8 bt_init_traffic_load;
181 u32 bt_prio_boost;
182 u16 agg_time_limit;
183 bool bt_sco_disable;
184 bool bt_session_2;
185}; 155};
186 156
187/* 157/*
@@ -231,16 +201,10 @@ struct iwl_eeprom_params {
231 * @nvm_calib_ver: NVM calibration version 201 * @nvm_calib_ver: NVM calibration version
232 * @lib: pointer to the lib ops 202 * @lib: pointer to the lib ops
233 * @base_params: pointer to basic parameters 203 * @base_params: pointer to basic parameters
234 * @ht_params: point to ht patameters 204 * @ht_params: point to ht parameters
235 * @bt_params: pointer to bt parameters
236 * @need_temp_offset_calib: need to perform temperature offset calibration
237 * @no_xtal_calib: some devices do not need crystal calibration data,
238 * don't send it to those
239 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) 205 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
240 * @adv_pm: advance power management
241 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity 206 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
242 * @internal_wimax_coex: internal wifi/wimax combo device 207 * @internal_wimax_coex: internal wifi/wimax combo device
243 * @temp_offset_v2: support v2 of temperature offset calibration
244 * 208 *
245 * We enable the driver to be backward compatible wrt. hardware features. 209 * We enable the driver to be backward compatible wrt. hardware features.
246 * API differences in uCode shouldn't be handled here but through TLVs 210 * API differences in uCode shouldn't be handled here but through TLVs
@@ -264,15 +228,10 @@ struct iwl_cfg {
264 const struct iwl_base_params *base_params; 228 const struct iwl_base_params *base_params;
265 /* params likely to change within a device family */ 229 /* params likely to change within a device family */
266 const struct iwl_ht_params *ht_params; 230 const struct iwl_ht_params *ht_params;
267 const struct iwl_bt_params *bt_params;
268 const struct iwl_eeprom_params *eeprom_params; 231 const struct iwl_eeprom_params *eeprom_params;
269 const bool need_temp_offset_calib; /* if used set to true */
270 const bool no_xtal_calib;
271 enum iwl_led_mode led_mode; 232 enum iwl_led_mode led_mode;
272 const bool adv_pm;
273 const bool rx_with_siso_diversity; 233 const bool rx_with_siso_diversity;
274 const bool internal_wimax_coex; 234 const bool internal_wimax_coex;
275 const bool temp_offset_v2;
276}; 235};
277 236
278/* 237/*
@@ -320,6 +279,10 @@ extern const struct iwl_cfg iwl105_bgn_cfg;
320extern const struct iwl_cfg iwl105_bgn_d_cfg; 279extern const struct iwl_cfg iwl105_bgn_d_cfg;
321extern const struct iwl_cfg iwl135_bgn_cfg; 280extern const struct iwl_cfg iwl135_bgn_cfg;
322extern const struct iwl_cfg iwl7260_2ac_cfg; 281extern const struct iwl_cfg iwl7260_2ac_cfg;
323extern const struct iwl_cfg iwl3160_ac_cfg; 282extern const struct iwl_cfg iwl7260_2n_cfg;
283extern const struct iwl_cfg iwl7260_n_cfg;
284extern const struct iwl_cfg iwl3160_2ac_cfg;
285extern const struct iwl_cfg iwl3160_2n_cfg;
286extern const struct iwl_cfg iwl3160_n_cfg;
324 287
325#endif /* __IWL_CONFIG_H__ */ 288#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 20e845d4da04..a276af476e2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -472,4 +472,23 @@
472#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) 472#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
473#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) 473#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
474 474
475/*****************************************************************************
476 * 7000/3000 series SHR DTS addresses *
477 *****************************************************************************/
478
479/* Diode Results Register Structure: */
480enum dtd_diode_reg {
481 DTS_DIODE_REG_DIG_VAL = 0x000000FF, /* bits [7:0] */
482 DTS_DIODE_REG_VREF_LOW = 0x0000FF00, /* bits [15:8] */
483 DTS_DIODE_REG_VREF_HIGH = 0x00FF0000, /* bits [23:16] */
484 DTS_DIODE_REG_VREF_ID = 0x03000000, /* bits [25:24] */
485 DTS_DIODE_REG_PASS_ONCE = 0x80000000, /* bits [31:31] */
486 DTS_DIODE_REG_FLAGS_MSK = 0xFF000000, /* bits [31:24] */
487/* Those are the masks INSIDE the flags bit-field: */
488 DTS_DIODE_REG_FLAGS_VREFS_ID_POS = 0,
489 DTS_DIODE_REG_FLAGS_VREFS_ID = 0x00000003, /* bits [1:0] */
490 DTS_DIODE_REG_FLAGS_PASS_ONCE_POS = 7,
491 DTS_DIODE_REG_FLAGS_PASS_ONCE = 0x00000080, /* bits [7:7] */
492};
493
475#endif /* !__iwl_csr_h__ */ 494#endif /* !__iwl_csr_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 39aad9893e0b..4f886133639a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1234,6 +1234,9 @@ MODULE_PARM_DESC(wd_disable,
1234 "Disable stuck queue watchdog timer 0=system default, " 1234 "Disable stuck queue watchdog timer 0=system default, "
1235 "1=disable, 2=enable (default: 0)"); 1235 "1=disable, 2=enable (default: 0)");
1236 1236
1237module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1238MODULE_PARM_DESC(nvm_file, "NVM file name");
1239
1237/* 1240/*
1238 * set bt_coex_active to true, uCode will do kill/defer 1241 * set bt_coex_active to true, uCode will do kill/defer
1239 * every time the priority line is asserted (BT is sending signals on the 1242 * every time the priority line is asserted (BT is sending signals on the
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 600c9fdd7f71..4c887f365908 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -732,17 +732,16 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
732void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 732void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
733 struct iwl_nvm_data *data, 733 struct iwl_nvm_data *data,
734 struct ieee80211_sta_ht_cap *ht_info, 734 struct ieee80211_sta_ht_cap *ht_info,
735 enum ieee80211_band band) 735 enum ieee80211_band band,
736 u8 tx_chains, u8 rx_chains)
736{ 737{
737 int max_bit_rate = 0; 738 int max_bit_rate = 0;
738 u8 rx_chains;
739 u8 tx_chains;
740 739
741 tx_chains = hweight8(data->valid_tx_ant); 740 tx_chains = hweight8(tx_chains);
742 if (cfg->rx_with_siso_diversity) 741 if (cfg->rx_with_siso_diversity)
743 rx_chains = 1; 742 rx_chains = 1;
744 else 743 else
745 rx_chains = hweight8(data->valid_rx_ant); 744 rx_chains = hweight8(rx_chains);
746 745
747 if (!(data->sku_cap_11n_enable) || !cfg->ht_params) { 746 if (!(data->sku_cap_11n_enable) || !cfg->ht_params) {
748 ht_info->ht_supported = false; 747 ht_info->ht_supported = false;
@@ -806,7 +805,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
806 sband->n_bitrates = N_RATES_24; 805 sband->n_bitrates = N_RATES_24;
807 n_used += iwl_init_sband_channels(data, sband, n_channels, 806 n_used += iwl_init_sband_channels(data, sband, n_channels,
808 IEEE80211_BAND_2GHZ); 807 IEEE80211_BAND_2GHZ);
809 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); 808 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
809 data->valid_tx_ant, data->valid_rx_ant);
810 810
811 sband = &data->bands[IEEE80211_BAND_5GHZ]; 811 sband = &data->bands[IEEE80211_BAND_5GHZ];
812 sband->band = IEEE80211_BAND_5GHZ; 812 sband->band = IEEE80211_BAND_5GHZ;
@@ -814,7 +814,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
814 sband->n_bitrates = N_RATES_52; 814 sband->n_bitrates = N_RATES_52;
815 n_used += iwl_init_sband_channels(data, sband, n_channels, 815 n_used += iwl_init_sband_channels(data, sband, n_channels,
816 IEEE80211_BAND_5GHZ); 816 IEEE80211_BAND_5GHZ);
817 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 817 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
818 data->valid_tx_ant, data->valid_rx_ant);
818 819
819 if (n_channels != n_used) 820 if (n_channels != n_used)
820 IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n", 821 IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 37f115390b19..d73304a23ec2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -133,6 +133,7 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
134 struct iwl_nvm_data *data, 134 struct iwl_nvm_data *data,
135 struct ieee80211_sta_ht_cap *ht_info, 135 struct ieee80211_sta_ht_cap *ht_info,
136 enum ieee80211_band band); 136 enum ieee80211_band band,
137 u8 tx_chains, u8 rx_chains);
137 138
138#endif /* __iwl_eeprom_parse_h__ */ 139#endif /* __iwl_eeprom_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index c4c446d41eb0..f844d5c748c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -106,11 +106,14 @@ enum iwl_ucode_type {
106 106
107/* 107/*
108 * enumeration of ucode section. 108 * enumeration of ucode section.
109 * This enumeration is used for legacy tlv style (before 16.0 uCode). 109 * This enumeration is used directly for older firmware (before 16.0).
110 * For new firmware, there can be up to 4 sections (see below) but the
111 * first one packaged into the firmware file is the DATA section and
112 * some debugging code accesses that.
110 */ 113 */
111enum iwl_ucode_sec { 114enum iwl_ucode_sec {
112 IWL_UCODE_SECTION_INST,
113 IWL_UCODE_SECTION_DATA, 115 IWL_UCODE_SECTION_DATA,
116 IWL_UCODE_SECTION_INST,
114}; 117};
115/* 118/*
116 * For 16.0 uCode and above, there is no differentiation between sections, 119 * For 16.0 uCode and above, there is no differentiation between sections,
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d6f6c37c09fd..36dfe0919f6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -119,6 +119,7 @@ struct iwl_mod_params {
119 int ant_coupling; 119 int ant_coupling;
120 bool bt_ch_announce; 120 bool bt_ch_announce;
121 bool auto_agg; 121 bool auto_agg;
122 char *nvm_file;
122}; 123};
123 124
124#endif /* #__iwl_modparams_h__ */ 125#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 6199a0a597a6..acd2665afb8c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -89,6 +89,7 @@ enum nvm_sku_bits {
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0), 89 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
90 NVM_SKU_CAP_BAND_52GHZ = BIT(1), 90 NVM_SKU_CAP_BAND_52GHZ = BIT(1),
91 NVM_SKU_CAP_11N_ENABLE = BIT(2), 91 NVM_SKU_CAP_11N_ENABLE = BIT(2),
92 NVM_SKU_CAP_11AC_ENABLE = BIT(3),
92}; 93};
93 94
94/* radio config bits (actual values from NVM definition) */ 95/* radio config bits (actual values from NVM definition) */
@@ -258,8 +259,6 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
258 struct iwl_nvm_data *data, 259 struct iwl_nvm_data *data,
259 struct ieee80211_sta_vht_cap *vht_cap) 260 struct ieee80211_sta_vht_cap *vht_cap)
260{ 261{
261 /* For now, assume new devices with NVM are VHT capable */
262
263 vht_cap->vht_supported = true; 262 vht_cap->vht_supported = true;
264 263
265 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | 264 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
@@ -292,7 +291,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
292} 291}
293 292
294static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 293static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
295 struct iwl_nvm_data *data, const __le16 *nvm_sw) 294 struct iwl_nvm_data *data, const __le16 *nvm_sw,
295 bool enable_vht, u8 tx_chains, u8 rx_chains)
296{ 296{
297 int n_channels = iwl_init_channel_map(dev, cfg, data, 297 int n_channels = iwl_init_channel_map(dev, cfg, data,
298 &nvm_sw[NVM_CHANNELS]); 298 &nvm_sw[NVM_CHANNELS]);
@@ -305,7 +305,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
305 sband->n_bitrates = N_RATES_24; 305 sband->n_bitrates = N_RATES_24;
306 n_used += iwl_init_sband_channels(data, sband, n_channels, 306 n_used += iwl_init_sband_channels(data, sband, n_channels,
307 IEEE80211_BAND_2GHZ); 307 IEEE80211_BAND_2GHZ);
308 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); 308 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
309 tx_chains, rx_chains);
309 310
310 sband = &data->bands[IEEE80211_BAND_5GHZ]; 311 sband = &data->bands[IEEE80211_BAND_5GHZ];
311 sband->band = IEEE80211_BAND_5GHZ; 312 sband->band = IEEE80211_BAND_5GHZ;
@@ -313,8 +314,10 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
313 sband->n_bitrates = N_RATES_52; 314 sband->n_bitrates = N_RATES_52;
314 n_used += iwl_init_sband_channels(data, sband, n_channels, 315 n_used += iwl_init_sband_channels(data, sband, n_channels,
315 IEEE80211_BAND_5GHZ); 316 IEEE80211_BAND_5GHZ);
316 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 317 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
317 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); 318 tx_chains, rx_chains);
319 if (enable_vht)
320 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
318 321
319 if (n_channels != n_used) 322 if (n_channels != n_used)
320 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", 323 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
@@ -324,7 +327,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
324struct iwl_nvm_data * 327struct iwl_nvm_data *
325iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 328iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
326 const __le16 *nvm_hw, const __le16 *nvm_sw, 329 const __le16 *nvm_hw, const __le16 *nvm_sw,
327 const __le16 *nvm_calib) 330 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
328{ 331{
329 struct iwl_nvm_data *data; 332 struct iwl_nvm_data *data;
330 u8 hw_addr[ETH_ALEN]; 333 u8 hw_addr[ETH_ALEN];
@@ -380,7 +383,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
380 data->hw_addr[4] = hw_addr[5]; 383 data->hw_addr[4] = hw_addr[5];
381 data->hw_addr[5] = hw_addr[4]; 384 data->hw_addr[5] = hw_addr[4];
382 385
383 iwl_init_sbands(dev, cfg, data, nvm_sw); 386 iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
387 tx_chains, rx_chains);
384 388
385 data->calib_version = 255; /* TODO: 389 data->calib_version = 255; /* TODO:
386 this value will prevent some checks from 390 this value will prevent some checks from
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index e57fb989661e..3325059c52d4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -75,6 +75,6 @@
75struct iwl_nvm_data * 75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw, 77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib); 78 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains);
79 79
80#endif /* __iwl_nvm_parse_h__ */ 80#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 386f2a7c87cb..ff8cc75c189d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -100,6 +100,18 @@
100/* Device system time */ 100/* Device system time */
101#define DEVICE_SYSTEM_TIME_REG 0xA0206C 101#define DEVICE_SYSTEM_TIME_REG 0xA0206C
102 102
103/*****************************************************************************
104 * 7000/3000 series SHR DTS addresses *
105 *****************************************************************************/
106
107#define SHR_MISC_WFM_DTS_EN (0x00a10024)
108#define DTSC_CFG_MODE (0x00a10604)
109#define DTSC_VREF_AVG (0x00a10648)
110#define DTSC_VREF5_AVG (0x00a1064c)
111#define DTSC_CFG_MODE_PERIODIC (0x2)
112#define DTSC_PTAT_AVG (0x00a10650)
113
114
103/** 115/**
104 * Tx Scheduler 116 * Tx Scheduler
105 * 117 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 7a13790b5bfe..84f1c8dc9741 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -189,7 +189,8 @@ enum CMD_MODE {
189 CMD_SYNC = 0, 189 CMD_SYNC = 0,
190 CMD_ASYNC = BIT(0), 190 CMD_ASYNC = BIT(0),
191 CMD_WANT_SKB = BIT(1), 191 CMD_WANT_SKB = BIT(1),
192 CMD_ON_DEMAND = BIT(2), 192 CMD_SEND_IN_RFKILL = BIT(2),
193 CMD_ON_DEMAND = BIT(3),
193}; 194};
194 195
195#define DEF_CMD_PAYLOAD_SIZE 320 196#define DEF_CMD_PAYLOAD_SIZE 320
@@ -455,7 +456,7 @@ struct iwl_trans_ops {
455 int (*read_mem)(struct iwl_trans *trans, u32 addr, 456 int (*read_mem)(struct iwl_trans *trans, u32 addr,
456 void *buf, int dwords); 457 void *buf, int dwords);
457 int (*write_mem)(struct iwl_trans *trans, u32 addr, 458 int (*write_mem)(struct iwl_trans *trans, u32 addr,
458 void *buf, int dwords); 459 const void *buf, int dwords);
459 void (*configure)(struct iwl_trans *trans, 460 void (*configure)(struct iwl_trans *trans,
460 const struct iwl_trans_config *trans_cfg); 461 const struct iwl_trans_config *trans_cfg);
461 void (*set_pmi)(struct iwl_trans *trans, bool state); 462 void (*set_pmi)(struct iwl_trans *trans, bool state);
@@ -761,7 +762,7 @@ static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr)
761} 762}
762 763
763static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, 764static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
764 void *buf, int dwords) 765 const void *buf, int dwords)
765{ 766{
766 return trans->ops->write_mem(trans, addr, buf, dwords); 767 return trans->ops->write_mem(trans, addr, buf, dwords);
767} 768}
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 2acc44b40986..ff856e543ae8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o bt-coex.o 5iwlmvm-y += power.o bt-coex.o
6iwlmvm-y += led.o 6iwlmvm-y += led.o tt.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 9
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 810bfa5f6de0..f03655f303aa 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -351,6 +351,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
351 enum ieee80211_band band; 351 enum ieee80211_band band;
352 int ave_rssi; 352 int ave_rssi;
353 353
354 lockdep_assert_held(&mvm->mutex);
354 if (vif->type != NL80211_IFTYPE_STATION) 355 if (vif->type != NL80211_IFTYPE_STATION)
355 return; 356 return;
356 357
@@ -365,7 +366,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
365 smps_mode = IEEE80211_SMPS_AUTOMATIC; 366 smps_mode = IEEE80211_SMPS_AUTOMATIC;
366 367
367 if (band != IEEE80211_BAND_2GHZ) { 368 if (band != IEEE80211_BAND_2GHZ) {
368 ieee80211_request_smps(vif, smps_mode); 369 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
370 smps_mode);
369 return; 371 return;
370 } 372 }
371 373
@@ -380,7 +382,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
380 mvmvif->id, data->notif->bt_status, 382 mvmvif->id, data->notif->bt_status,
381 data->notif->bt_traffic_load, smps_mode); 383 data->notif->bt_traffic_load, smps_mode);
382 384
383 ieee80211_request_smps(vif, smps_mode); 385 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
384 386
385 /* don't reduce the Tx power if in loose scheme */ 387 /* don't reduce the Tx power if in loose scheme */
386 if (is_loose_coex()) 388 if (is_loose_coex())
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 16bbdcc8627a..4d3c978b5c76 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1007,6 +1007,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1007 if (ret) 1007 if (ret)
1008 goto out; 1008 goto out;
1009 1009
1010 ret = iwl_mvm_power_update_mode(mvm, vif);
1011 if (ret)
1012 goto out;
1013
1010 /* must be last -- this switches firmware state */ 1014 /* must be last -- this switches firmware state */
1011 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1015 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
1012 sizeof(d3_cfg_cmd), &d3_cfg_cmd); 1016 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
@@ -1214,6 +1218,26 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1214 iwl_free_resp(&cmd); 1218 iwl_free_resp(&cmd);
1215} 1219}
1216 1220
1221static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
1222{
1223#ifdef CONFIG_IWLWIFI_DEBUGFS
1224 const struct fw_img *img = &mvm->fw->img[IWL_UCODE_WOWLAN];
1225 u32 len = img->sec[IWL_UCODE_SECTION_DATA].len;
1226 u32 offs = img->sec[IWL_UCODE_SECTION_DATA].offset;
1227
1228 if (!mvm->store_d3_resume_sram)
1229 return;
1230
1231 if (!mvm->d3_resume_sram) {
1232 mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
1233 if (!mvm->d3_resume_sram)
1234 return;
1235 }
1236
1237 iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
1238#endif
1239}
1240
1217int iwl_mvm_resume(struct ieee80211_hw *hw) 1241int iwl_mvm_resume(struct ieee80211_hw *hw)
1218{ 1242{
1219 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1243 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
@@ -1245,6 +1269,9 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
1245 goto out_unlock; 1269 goto out_unlock;
1246 } 1270 }
1247 1271
1272 /* query SRAM first in case we want event logging */
1273 iwl_mvm_read_d3_sram(mvm);
1274
1248 iwl_mvm_query_wakeup_reasons(mvm, vif); 1275 iwl_mvm_query_wakeup_reasons(mvm, vif);
1249 1276
1250 out_unlock: 1277 out_unlock:
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 2053dccefcd6..69e0806075a2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -145,15 +145,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
145 char *buf; 145 char *buf;
146 u8 *ptr; 146 u8 *ptr;
147 147
148 if (!mvm->ucode_loaded)
149 return -EINVAL;
150
148 /* default is to dump the entire data segment */ 151 /* default is to dump the entire data segment */
149 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { 152 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
150 mvm->dbgfs_sram_offset = 0x800000;
151 if (!mvm->ucode_loaded)
152 return -EINVAL;
153 img = &mvm->fw->img[mvm->cur_ucode]; 153 img = &mvm->fw->img[mvm->cur_ucode];
154 mvm->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; 154 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
155 len = img->sec[IWL_UCODE_SECTION_DATA].len;
156 } else {
157 ofs = mvm->dbgfs_sram_offset;
158 len = mvm->dbgfs_sram_len;
155 } 159 }
156 len = mvm->dbgfs_sram_len;
157 160
158 bufsz = len * 4 + 256; 161 bufsz = len * 4 + 256;
159 buf = kzalloc(bufsz, GFP_KERNEL); 162 buf = kzalloc(bufsz, GFP_KERNEL);
@@ -167,12 +170,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
167 } 170 }
168 171
169 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len); 172 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
170 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 173 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs);
171 mvm->dbgfs_sram_offset);
172 174
173 iwl_trans_read_mem_bytes(mvm->trans, 175 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
174 mvm->dbgfs_sram_offset,
175 ptr, len);
176 for (ofs = 0; ofs < len; ofs += 16) { 176 for (ofs = 0; ofs < len; ofs += 16) {
177 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs); 177 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
178 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos, 178 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
@@ -300,6 +300,146 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
300 return count; 300 return count;
301} 301}
302 302
303static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
304 struct ieee80211_vif *vif,
305 enum iwl_dbgfs_pm_mask param, int val)
306{
307 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
308 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
309
310 dbgfs_pm->mask |= param;
311
312 switch (param) {
313 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
314 struct ieee80211_hw *hw = mvm->hw;
315 int dtimper = hw->conf.ps_dtim_period ?: 1;
316 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
317
318 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
319 if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
320 IWL_WARN(mvm,
321 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
322 val * MSEC_PER_SEC, 3 * dtimper_msec);
323 }
324 dbgfs_pm->keep_alive_seconds = val;
325 break;
326 }
327 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
328 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
329 val ? "enabled" : "disabled");
330 dbgfs_pm->skip_over_dtim = val;
331 break;
332 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
333 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
334 dbgfs_pm->skip_dtim_periods = val;
335 break;
336 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
337 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
338 dbgfs_pm->rx_data_timeout = val;
339 break;
340 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
341 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
342 dbgfs_pm->tx_data_timeout = val;
343 break;
344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
346 dbgfs_pm->disable_power_off = val;
347 break;
348 }
349}
350
351static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
352 const char __user *user_buf,
353 size_t count, loff_t *ppos)
354{
355 struct ieee80211_vif *vif = file->private_data;
356 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
357 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
358 enum iwl_dbgfs_pm_mask param;
359 char buf[32] = {};
360 int val;
361 int ret;
362
363 if (copy_from_user(buf, user_buf, sizeof(buf)))
364 return -EFAULT;
365
366 if (!strncmp("keep_alive=", buf, 11)) {
367 if (sscanf(buf + 11, "%d", &val) != 1)
368 return -EINVAL;
369 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
370 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
371 if (sscanf(buf + 15, "%d", &val) != 1)
372 return -EINVAL;
373 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
374 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
375 if (sscanf(buf + 18, "%d", &val) != 1)
376 return -EINVAL;
377 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
378 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
379 if (sscanf(buf + 16, "%d", &val) != 1)
380 return -EINVAL;
381 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
382 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
383 if (sscanf(buf + 16, "%d", &val) != 1)
384 return -EINVAL;
385 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
386 } else if (!strncmp("disable_power_off=", buf, 18)) {
387 if (sscanf(buf + 18, "%d", &val) != 1)
388 return -EINVAL;
389 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
390 } else {
391 return -EINVAL;
392 }
393
394 mutex_lock(&mvm->mutex);
395 iwl_dbgfs_update_pm(mvm, vif, param, val);
396 ret = iwl_mvm_power_update_mode(mvm, vif);
397 mutex_unlock(&mvm->mutex);
398
399 return ret ?: count;
400}
401
402static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
403 char __user *user_buf,
404 size_t count, loff_t *ppos)
405{
406 struct ieee80211_vif *vif = file->private_data;
407 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
408 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
409 struct iwl_powertable_cmd cmd = {};
410 char buf[256];
411 int bufsz = sizeof(buf);
412 int pos = 0;
413
414 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
415
416 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
417 (cmd.flags &
418 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
419 0 : 1);
420 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
421 le32_to_cpu(cmd.skip_dtim_periods));
422 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
423 iwlmvm_mod_params.power_scheme);
424 pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n",
425 le16_to_cpu(cmd.flags));
426 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
427 cmd.keep_alive_seconds);
428
429 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
430 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
431 (cmd.flags &
432 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
433 1 : 0);
434 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
435 le32_to_cpu(cmd.rx_data_timeout));
436 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
437 le32_to_cpu(cmd.tx_data_timeout));
438 }
439
440 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
441}
442
303static ssize_t iwl_dbgfs_mac_params_read(struct file *file, 443static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
304 char __user *user_buf, 444 char __user *user_buf,
305 size_t count, loff_t *ppos) 445 size_t count, loff_t *ppos)
@@ -481,6 +621,255 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
481 return count; 621 return count;
482} 622}
483 623
624static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
625 enum iwl_dbgfs_bf_mask param, int value)
626{
627 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
628 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
629
630 dbgfs_bf->mask |= param;
631
632 switch (param) {
633 case MVM_DEBUGFS_BF_ENERGY_DELTA:
634 dbgfs_bf->bf_energy_delta = value;
635 break;
636 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
637 dbgfs_bf->bf_roaming_energy_delta = value;
638 break;
639 case MVM_DEBUGFS_BF_ROAMING_STATE:
640 dbgfs_bf->bf_roaming_state = value;
641 break;
642 case MVM_DEBUGFS_BF_TEMPERATURE_DELTA:
643 dbgfs_bf->bf_temperature_delta = value;
644 break;
645 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
646 dbgfs_bf->bf_enable_beacon_filter = value;
647 break;
648 case MVM_DEBUGFS_BF_DEBUG_FLAG:
649 dbgfs_bf->bf_debug_flag = value;
650 break;
651 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
652 dbgfs_bf->bf_escape_timer = value;
653 break;
654 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
655 dbgfs_bf->ba_enable_beacon_abort = value;
656 break;
657 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
658 dbgfs_bf->ba_escape_timer = value;
659 break;
660 }
661}
662
663static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
664 const char __user *user_buf,
665 size_t count, loff_t *ppos)
666{
667 struct ieee80211_vif *vif = file->private_data;
668 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
669 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
670 enum iwl_dbgfs_bf_mask param;
671 char buf[256];
672 int buf_size;
673 int value;
674 int ret = 0;
675
676 memset(buf, 0, sizeof(buf));
677 buf_size = min(count, sizeof(buf) - 1);
678 if (copy_from_user(buf, user_buf, buf_size))
679 return -EFAULT;
680
681 if (!strncmp("bf_energy_delta=", buf, 16)) {
682 if (sscanf(buf+16, "%d", &value) != 1)
683 return -EINVAL;
684 if (value < IWL_BF_ENERGY_DELTA_MIN ||
685 value > IWL_BF_ENERGY_DELTA_MAX)
686 return -EINVAL;
687 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
688 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
689 if (sscanf(buf+24, "%d", &value) != 1)
690 return -EINVAL;
691 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
692 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
693 return -EINVAL;
694 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
695 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
696 if (sscanf(buf+17, "%d", &value) != 1)
697 return -EINVAL;
698 if (value < IWL_BF_ROAMING_STATE_MIN ||
699 value > IWL_BF_ROAMING_STATE_MAX)
700 return -EINVAL;
701 param = MVM_DEBUGFS_BF_ROAMING_STATE;
702 } else if (!strncmp("bf_temperature_delta=", buf, 21)) {
703 if (sscanf(buf+21, "%d", &value) != 1)
704 return -EINVAL;
705 if (value < IWL_BF_TEMPERATURE_DELTA_MIN ||
706 value > IWL_BF_TEMPERATURE_DELTA_MAX)
707 return -EINVAL;
708 param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA;
709 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
710 if (sscanf(buf+24, "%d", &value) != 1)
711 return -EINVAL;
712 if (value < 0 || value > 1)
713 return -EINVAL;
714 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
715 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
716 if (sscanf(buf+14, "%d", &value) != 1)
717 return -EINVAL;
718 if (value < 0 || value > 1)
719 return -EINVAL;
720 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
721 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
722 if (sscanf(buf+16, "%d", &value) != 1)
723 return -EINVAL;
724 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
725 value > IWL_BF_ESCAPE_TIMER_MAX)
726 return -EINVAL;
727 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
728 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
729 if (sscanf(buf+16, "%d", &value) != 1)
730 return -EINVAL;
731 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
732 value > IWL_BA_ESCAPE_TIMER_MAX)
733 return -EINVAL;
734 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
735 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
736 if (sscanf(buf+23, "%d", &value) != 1)
737 return -EINVAL;
738 if (value < 0 || value > 1)
739 return -EINVAL;
740 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
741 } else {
742 return -EINVAL;
743 }
744
745 mutex_lock(&mvm->mutex);
746 iwl_dbgfs_update_bf(vif, param, value);
747 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
748 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
749 } else {
750 if (mvmvif->bf_enabled)
751 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
752 else
753 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
754 }
755 mutex_unlock(&mvm->mutex);
756
757 return ret ?: count;
758}
759
760static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
761 char __user *user_buf,
762 size_t count, loff_t *ppos)
763{
764 struct ieee80211_vif *vif = file->private_data;
765 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
766 char buf[256];
767 int pos = 0;
768 const size_t bufsz = sizeof(buf);
769 struct iwl_beacon_filter_cmd cmd = {
770 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,
771 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,
772 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,
773 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,
774 .bf_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_DEFAULT,
775 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
776 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
777 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
778 .ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
779 };
780
781 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
782 if (mvmvif->bf_enabled)
783 cmd.bf_enable_beacon_filter = 1;
784 else
785 cmd.bf_enable_beacon_filter = 0;
786
787 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
788 cmd.bf_energy_delta);
789 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
790 cmd.bf_roaming_energy_delta);
791 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
792 cmd.bf_roaming_state);
793 pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n",
794 cmd.bf_temperature_delta);
795 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
796 cmd.bf_enable_beacon_filter);
797 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
798 cmd.bf_debug_flag);
799 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
800 cmd.bf_escape_timer);
801 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
802 cmd.ba_escape_timer);
803 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
804 cmd.ba_enable_beacon_abort);
805
806 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
807}
808
809#ifdef CONFIG_PM_SLEEP
810static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
811 const char __user *user_buf,
812 size_t count, loff_t *ppos)
813{
814 struct iwl_mvm *mvm = file->private_data;
815 char buf[8] = {};
816 int store;
817
818 if (copy_from_user(buf, user_buf, sizeof(buf)))
819 return -EFAULT;
820
821 if (sscanf(buf, "%d", &store) != 1)
822 return -EINVAL;
823
824 mvm->store_d3_resume_sram = store;
825
826 return count;
827}
828
829static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
830 size_t count, loff_t *ppos)
831{
832 struct iwl_mvm *mvm = file->private_data;
833 const struct fw_img *img;
834 int ofs, len, pos = 0;
835 size_t bufsz, ret;
836 char *buf;
837 u8 *ptr = mvm->d3_resume_sram;
838
839 img = &mvm->fw->img[IWL_UCODE_WOWLAN];
840 len = img->sec[IWL_UCODE_SECTION_DATA].len;
841
842 bufsz = len * 4 + 256;
843 buf = kzalloc(bufsz, GFP_KERNEL);
844 if (!buf)
845 return -ENOMEM;
846
847 pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
848 mvm->store_d3_resume_sram ? "en" : "dis");
849
850 if (ptr) {
851 for (ofs = 0; ofs < len; ofs += 16) {
852 pos += scnprintf(buf + pos, bufsz - pos,
853 "0x%.4x ", ofs);
854 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
855 bufsz - pos, false);
856 pos += strlen(buf + pos);
857 if (bufsz - pos > 0)
858 buf[pos++] = '\n';
859 }
860 } else {
861 pos += scnprintf(buf + pos, bufsz - pos,
862 "(no data captured)\n");
863 }
864
865 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
866
867 kfree(buf);
868
869 return ret;
870}
871#endif
872
484#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 873#define MVM_DEBUGFS_READ_FILE_OPS(name) \
485static const struct file_operations iwl_dbgfs_##name##_ops = { \ 874static const struct file_operations iwl_dbgfs_##name##_ops = { \
486 .read = iwl_dbgfs_##name##_read, \ 875 .read = iwl_dbgfs_##name##_read, \
@@ -524,9 +913,14 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
524MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 913MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
525MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 914MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
526MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 915MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
916#ifdef CONFIG_PM_SLEEP
917MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
918#endif
527 919
528/* Interface specific debugfs entries */ 920/* Interface specific debugfs entries */
529MVM_DEBUGFS_READ_FILE_OPS(mac_params); 921MVM_DEBUGFS_READ_FILE_OPS(mac_params);
922MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
923MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
530 924
531int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 925int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
532{ 926{
@@ -542,6 +936,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
542 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 936 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
543 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 937 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
544 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 938 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
939#ifdef CONFIG_PM_SLEEP
940 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
941#endif
545 942
546 /* 943 /*
547 * Create a symlink with mac80211. It will be removed when mac80211 944 * Create a symlink with mac80211. It will be removed when mac80211
@@ -577,9 +974,19 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
577 return; 974 return;
578 } 975 }
579 976
977 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
978 vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
979 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
980 S_IRUSR);
981
580 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, 982 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
581 S_IRUSR); 983 S_IRUSR);
582 984
985 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
986 mvmvif == mvm->bf_allowed_vif)
987 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
988 S_IRUSR | S_IWUSR);
989
583 /* 990 /*
584 * Create symlink for convenience pointing to interface specific 991 * Create symlink for convenience pointing to interface specific
585 * debugfs entries for the driver. For example, under 992 * debugfs entries for the driver. For example, under
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 51e015d1dfb2..6f8b2c16ae17 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -75,13 +75,15 @@ enum iwl_d3_wakeup_flags {
75 * struct iwl_d3_manager_config - D3 manager configuration command 75 * struct iwl_d3_manager_config - D3 manager configuration command
76 * @min_sleep_time: minimum sleep time (in usec) 76 * @min_sleep_time: minimum sleep time (in usec)
77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags 77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags
78 * @wakeup_host_timer: force wakeup after this many seconds
78 * 79 *
79 * The structure is used for the D3_CONFIG_CMD command. 80 * The structure is used for the D3_CONFIG_CMD command.
80 */ 81 */
81struct iwl_d3_manager_config { 82struct iwl_d3_manager_config {
82 __le32 min_sleep_time; 83 __le32 min_sleep_time;
83 __le32 wakeup_flags; 84 __le32 wakeup_flags;
84} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_3 */ 85 __le32 wakeup_host_timer;
86} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_4 */
85 87
86 88
87/* TODO: OFFLOADS_QUERY_API_S_VER_1 */ 89/* TODO: OFFLOADS_QUERY_API_S_VER_1 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 81fe45f46be7..d8e19290b0f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -101,20 +101,107 @@ enum iwl_power_flags {
101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to 101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
102 * PSM transition - legacy PM 102 * PSM transition - legacy PM
103 * @sleep_interval: not in use 103 * @sleep_interval: not in use
104 * @keep_alive_beacons: not in use 104 * @skip_dtim_periods: Number of DTIM periods to skip if Skip over DTIM flag
105 * is set. For example, if it is required to skip over
106 * one DTIM, this value need to be set to 2 (DTIM periods).
105 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. 107 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
106 * Default: 80dbm 108 * Default: 80dbm
107 */ 109 */
108struct iwl_powertable_cmd { 110struct iwl_powertable_cmd {
109 /* PM_POWER_TABLE_CMD_API_S_VER_5 */ 111 /* PM_POWER_TABLE_CMD_API_S_VER_6 */
110 __le16 flags; 112 __le16 flags;
111 u8 keep_alive_seconds; 113 u8 keep_alive_seconds;
112 u8 debug_flags; 114 u8 debug_flags;
113 __le32 rx_data_timeout; 115 __le32 rx_data_timeout;
114 __le32 tx_data_timeout; 116 __le32 tx_data_timeout;
115 __le32 sleep_interval[IWL_POWER_VEC_SIZE]; 117 __le32 sleep_interval[IWL_POWER_VEC_SIZE];
116 __le32 keep_alive_beacons; 118 __le32 skip_dtim_periods;
117 __le32 lprx_rssi_threshold; 119 __le32 lprx_rssi_threshold;
118} __packed; 120} __packed;
119 121
122/**
123 * struct iwl_beacon_filter_cmd
124 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
125 * @id_and_color: MAC contex identifier
126 * @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
127 * to driver if delta in Energy values calculated for this and last
128 * passed beacon is greater than this threshold. Zero value means that
129 * the Energy change is ignored for beacon filtering, and beacon will
130 * not be forced to be sent to driver regardless of this delta. Typical
131 * energy delta 5dB.
132 * @bf_roaming_energy_delta: Used for RSSI filtering, if in 'roaming' state.
133 * Send beacon to driver if delta in Energy values calculated for this
134 * and last passed beacon is greater than this threshold. Zero value
135 * means that the Energy change is ignored for beacon filtering while in
136 * Roaming state, typical energy delta 1dB.
137 * @bf_roaming_state: Used for RSSI filtering. If absolute Energy values
138 * calculated for current beacon is less than the threshold, use
139 * Roaming Energy Delta Threshold, otherwise use normal Energy Delta
140 * Threshold. Typical energy threshold is -72dBm.
141 * @bf_temperature_delta: Send Beacon to driver if delta in temperature values
142 * calculated for this and the last passed beacon is greater than this
143 * threshold. Zero value means that the temperature changeis ignored for
144 * beacon filtering; beacons will not be forced to be sent to driver
145 * regardless of whether its temerature has been changed.
146 * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled.
147 * @bf_filter_escape_timer: Send beacons to to driver if no beacons were passed
148 * for a specific period of time. Units: Beacons.
149 * @ba_escape_timer: Fully receive and parse beacon if no beacons were passed
150 * for a longer period of time then this escape-timeout. Units: Beacons.
151 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled.
152 */
153struct iwl_beacon_filter_cmd {
154 u8 bf_energy_delta;
155 u8 bf_roaming_energy_delta;
156 u8 bf_roaming_state;
157 u8 bf_temperature_delta;
158 u8 bf_enable_beacon_filter;
159 u8 bf_debug_flag;
160 __le16 reserved1;
161 __le32 bf_escape_timer;
162 __le32 ba_escape_timer;
163 u8 ba_enable_beacon_abort;
164 u8 reserved2[3];
165} __packed;
166
167/* Beacon filtering and beacon abort */
168#define IWL_BF_ENERGY_DELTA_DEFAULT 5
169#define IWL_BF_ENERGY_DELTA_MAX 255
170#define IWL_BF_ENERGY_DELTA_MIN 0
171
172#define IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT 1
173#define IWL_BF_ROAMING_ENERGY_DELTA_MAX 255
174#define IWL_BF_ROAMING_ENERGY_DELTA_MIN 0
175
176#define IWL_BF_ROAMING_STATE_DEFAULT 72
177#define IWL_BF_ROAMING_STATE_MAX 255
178#define IWL_BF_ROAMING_STATE_MIN 0
179
180#define IWL_BF_TEMPERATURE_DELTA_DEFAULT 5
181#define IWL_BF_TEMPERATURE_DELTA_MAX 255
182#define IWL_BF_TEMPERATURE_DELTA_MIN 0
183
184#define IWL_BF_ENABLE_BEACON_FILTER_DEFAULT 1
185
186#define IWL_BF_DEBUG_FLAG_DEFAULT 0
187
188#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
189#define IWL_BF_ESCAPE_TIMER_MAX 1024
190#define IWL_BF_ESCAPE_TIMER_MIN 0
191
192#define IWL_BA_ESCAPE_TIMER_DEFAULT 3
193#define IWL_BA_ESCAPE_TIMER_MAX 1024
194#define IWL_BA_ESCAPE_TIMER_MIN 0
195
196#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
197
198#define IWL_BF_CMD_CONFIG_DEFAULTS \
199 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, \
200 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, \
201 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, \
202 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, \
203 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, \
204 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \
205 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
206
120#endif 207#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 007a93b25bd7..6994232f5726 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -134,6 +134,7 @@ enum iwl_tx_flags {
134#define TX_CMD_SEC_WEP 0x01 134#define TX_CMD_SEC_WEP 0x01
135#define TX_CMD_SEC_CCM 0x02 135#define TX_CMD_SEC_CCM 0x02
136#define TX_CMD_SEC_TKIP 0x03 136#define TX_CMD_SEC_TKIP 0x03
137#define TX_CMD_SEC_MSK 0x07
137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6 138#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0 139#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
139#define TX_CMD_SEC_KEY128 0x08 140#define TX_CMD_SEC_KEY128 0x08
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 191dcae8ba47..cbfb3beae783 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -139,6 +139,9 @@ enum {
139 /* Power */ 139 /* Power */
140 POWER_TABLE_CMD = 0x77, 140 POWER_TABLE_CMD = 0x77,
141 141
142 /* Thermal Throttling*/
143 REPLY_THERMAL_MNG_BACKOFF = 0x7e,
144
142 /* Scanning */ 145 /* Scanning */
143 SCAN_REQUEST_CMD = 0x80, 146 SCAN_REQUEST_CMD = 0x80,
144 SCAN_ABORT_CMD = 0x81, 147 SCAN_ABORT_CMD = 0x81,
@@ -161,6 +164,8 @@ enum {
161 CARD_STATE_CMD = 0xa0, 164 CARD_STATE_CMD = 0xa0,
162 CARD_STATE_NOTIFICATION = 0xa1, 165 CARD_STATE_NOTIFICATION = 0xa1,
163 166
167 MISSED_BEACONS_NOTIFICATION = 0xa2,
168
164 REPLY_RX_PHY_CMD = 0xc0, 169 REPLY_RX_PHY_CMD = 0xc0,
165 REPLY_RX_MPDU_CMD = 0xc1, 170 REPLY_RX_MPDU_CMD = 0xc1,
166 BA_NOTIF = 0xc5, 171 BA_NOTIF = 0xc5,
@@ -170,9 +175,13 @@ enum {
170 BT_COEX_PROT_ENV = 0xcd, 175 BT_COEX_PROT_ENV = 0xcd,
171 BT_PROFILE_NOTIFICATION = 0xce, 176 BT_PROFILE_NOTIFICATION = 0xce,
172 177
178 REPLY_BEACON_FILTERING_CMD = 0xd2,
179
173 REPLY_DEBUG_CMD = 0xf0, 180 REPLY_DEBUG_CMD = 0xf0,
174 DEBUG_LOG_MSG = 0xf7, 181 DEBUG_LOG_MSG = 0xf7,
175 182
183 MCAST_FILTER_CMD = 0xd0,
184
176 /* D3 commands/notifications */ 185 /* D3 commands/notifications */
177 D3_CONFIG_CMD = 0xd3, 186 D3_CONFIG_CMD = 0xd3,
178 PROT_OFFLOAD_CONFIG_CMD = 0xd4, 187 PROT_OFFLOAD_CONFIG_CMD = 0xd4,
@@ -936,6 +945,24 @@ struct iwl_card_state_notif {
936} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ 945} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
937 946
938/** 947/**
948 * struct iwl_missed_beacons_notif - information on missed beacons
949 * ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
950 * @mac_id: interface ID
951 * @consec_missed_beacons_since_last_rx: number of consecutive missed
952 * beacons since last RX.
953 * @consec_missed_beacons: number of consecutive missed beacons
954 * @num_expected_beacons:
955 * @num_recvd_beacons:
956 */
957struct iwl_missed_beacons_notif {
958 __le32 mac_id;
959 __le32 consec_missed_beacons_since_last_rx;
960 __le32 consec_missed_beacons;
961 __le32 num_expected_beacons;
962 __le32 num_recvd_beacons;
963} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
964
965/**
939 * struct iwl_set_calib_default_cmd - set default value for calibration. 966 * struct iwl_set_calib_default_cmd - set default value for calibration.
940 * ( SET_CALIB_DEFAULT_CMD = 0x8e ) 967 * ( SET_CALIB_DEFAULT_CMD = 0x8e )
941 * @calib_index: the calibration to set value for 968 * @calib_index: the calibration to set value for
@@ -948,4 +975,237 @@ struct iwl_set_calib_default_cmd {
948 u8 data[0]; 975 u8 data[0];
949} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ 976} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
950 977
978#define MAX_PORT_ID_NUM 2
979
980/**
981 * struct iwl_mcast_filter_cmd - configure multicast filter.
982 * @filter_own: Set 1 to filter out multicast packets sent by station itself
983 * @port_id: Multicast MAC addresses array specifier. This is a strange way
984 * to identify network interface adopted in host-device IF.
985 * It is used by FW as index in array of addresses. This array has
986 * MAX_PORT_ID_NUM members.
987 * @count: Number of MAC addresses in the array
988 * @pass_all: Set 1 to pass all multicast packets.
989 * @bssid: current association BSSID.
990 * @addr_list: Place holder for array of MAC addresses.
991 * IMPORTANT: add padding if necessary to ensure DWORD alignment.
992 */
993struct iwl_mcast_filter_cmd {
994 u8 filter_own;
995 u8 port_id;
996 u8 count;
997 u8 pass_all;
998 u8 bssid[6];
999 u8 reserved[2];
1000 u8 addr_list[0];
1001} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
1002
1003struct mvm_statistics_dbg {
1004 __le32 burst_check;
1005 __le32 burst_count;
1006 __le32 wait_for_silence_timeout_cnt;
1007 __le32 reserved[3];
1008} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
1009
1010struct mvm_statistics_div {
1011 __le32 tx_on_a;
1012 __le32 tx_on_b;
1013 __le32 exec_time;
1014 __le32 probe_time;
1015 __le32 rssi_ant;
1016 __le32 reserved2;
1017} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
1018
1019struct mvm_statistics_general_common {
1020 __le32 temperature; /* radio temperature */
1021 __le32 temperature_m; /* radio voltage */
1022 struct mvm_statistics_dbg dbg;
1023 __le32 sleep_time;
1024 __le32 slots_out;
1025 __le32 slots_idle;
1026 __le32 ttl_timestamp;
1027 struct mvm_statistics_div div;
1028 __le32 rx_enable_counter;
1029 /*
1030 * num_of_sos_states:
1031 * count the number of times we have to re-tune
1032 * in order to get out of bad PHY status
1033 */
1034 __le32 num_of_sos_states;
1035} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1036
1037struct mvm_statistics_rx_non_phy {
1038 __le32 bogus_cts; /* CTS received when not expecting CTS */
1039 __le32 bogus_ack; /* ACK received when not expecting ACK */
1040 __le32 non_bssid_frames; /* number of frames with BSSID that
1041 * doesn't belong to the STA BSSID */
1042 __le32 filtered_frames; /* count frames that were dumped in the
1043 * filtering process */
1044 __le32 non_channel_beacons; /* beacons with our bss id but not on
1045 * our serving channel */
1046 __le32 channel_beacons; /* beacons with our bss id and in our
1047 * serving channel */
1048 __le32 num_missed_bcon; /* number of missed beacons */
1049 __le32 adc_rx_saturation_time; /* count in 0.8us units the time the
1050 * ADC was in saturation */
1051 __le32 ina_detection_search_time;/* total time (in 0.8us) searched
1052 * for INA */
1053 __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */
1054 __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */
1055 __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */
1056 __le32 interference_data_flag; /* flag for interference data
1057 * availability. 1 when data is
1058 * available. */
1059 __le32 channel_load; /* counts RX Enable time in uSec */
1060 __le32 dsp_false_alarms; /* DSP false alarm (both OFDM
1061 * and CCK) counter */
1062 __le32 beacon_rssi_a;
1063 __le32 beacon_rssi_b;
1064 __le32 beacon_rssi_c;
1065 __le32 beacon_energy_a;
1066 __le32 beacon_energy_b;
1067 __le32 beacon_energy_c;
1068 __le32 num_bt_kills;
1069 __le32 mac_id;
1070 __le32 directed_data_mpdu;
1071} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
1072
1073struct mvm_statistics_rx_phy {
1074 __le32 ina_cnt;
1075 __le32 fina_cnt;
1076 __le32 plcp_err;
1077 __le32 crc32_err;
1078 __le32 overrun_err;
1079 __le32 early_overrun_err;
1080 __le32 crc32_good;
1081 __le32 false_alarm_cnt;
1082 __le32 fina_sync_err_cnt;
1083 __le32 sfd_timeout;
1084 __le32 fina_timeout;
1085 __le32 unresponded_rts;
1086 __le32 rxe_frame_limit_overrun;
1087 __le32 sent_ack_cnt;
1088 __le32 sent_cts_cnt;
1089 __le32 sent_ba_rsp_cnt;
1090 __le32 dsp_self_kill;
1091 __le32 mh_format_err;
1092 __le32 re_acq_main_rssi_sum;
1093 __le32 reserved;
1094} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
1095
1096struct mvm_statistics_rx_ht_phy {
1097 __le32 plcp_err;
1098 __le32 overrun_err;
1099 __le32 early_overrun_err;
1100 __le32 crc32_good;
1101 __le32 crc32_err;
1102 __le32 mh_format_err;
1103 __le32 agg_crc32_good;
1104 __le32 agg_mpdu_cnt;
1105 __le32 agg_cnt;
1106 __le32 unsupport_mcs;
1107} __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
1108
1109#define MAX_CHAINS 3
1110
1111struct mvm_statistics_tx_non_phy_agg {
1112 __le32 ba_timeout;
1113 __le32 ba_reschedule_frames;
1114 __le32 scd_query_agg_frame_cnt;
1115 __le32 scd_query_no_agg;
1116 __le32 scd_query_agg;
1117 __le32 scd_query_mismatch;
1118 __le32 frame_not_ready;
1119 __le32 underrun;
1120 __le32 bt_prio_kill;
1121 __le32 rx_ba_rsp_cnt;
1122 __s8 txpower[MAX_CHAINS];
1123 __s8 reserved;
1124 __le32 reserved2;
1125} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
1126
1127struct mvm_statistics_tx_channel_width {
1128 __le32 ext_cca_narrow_ch20[1];
1129 __le32 ext_cca_narrow_ch40[2];
1130 __le32 ext_cca_narrow_ch80[3];
1131 __le32 ext_cca_narrow_ch160[4];
1132 __le32 last_tx_ch_width_indx;
1133 __le32 rx_detected_per_ch_width[4];
1134 __le32 success_per_ch_width[4];
1135 __le32 fail_per_ch_width[4];
1136}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
1137
1138struct mvm_statistics_tx {
1139 __le32 preamble_cnt;
1140 __le32 rx_detected_cnt;
1141 __le32 bt_prio_defer_cnt;
1142 __le32 bt_prio_kill_cnt;
1143 __le32 few_bytes_cnt;
1144 __le32 cts_timeout;
1145 __le32 ack_timeout;
1146 __le32 expected_ack_cnt;
1147 __le32 actual_ack_cnt;
1148 __le32 dump_msdu_cnt;
1149 __le32 burst_abort_next_frame_mismatch_cnt;
1150 __le32 burst_abort_missing_next_frame_cnt;
1151 __le32 cts_timeout_collision;
1152 __le32 ack_or_ba_timeout_collision;
1153 struct mvm_statistics_tx_non_phy_agg agg;
1154 struct mvm_statistics_tx_channel_width channel_width;
1155} __packed; /* STATISTICS_TX_API_S_VER_4 */
1156
1157
1158struct mvm_statistics_bt_activity {
1159 __le32 hi_priority_tx_req_cnt;
1160 __le32 hi_priority_tx_denied_cnt;
1161 __le32 lo_priority_tx_req_cnt;
1162 __le32 lo_priority_tx_denied_cnt;
1163 __le32 hi_priority_rx_req_cnt;
1164 __le32 hi_priority_rx_denied_cnt;
1165 __le32 lo_priority_rx_req_cnt;
1166 __le32 lo_priority_rx_denied_cnt;
1167} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
1168
1169struct mvm_statistics_general {
1170 struct mvm_statistics_general_common common;
1171 __le32 beacon_filtered;
1172 __le32 missed_beacons;
1173 __s8 beacon_filter_everage_energy;
1174 __s8 beacon_filter_reason;
1175 __s8 beacon_filter_current_energy;
1176 __s8 beacon_filter_reserved;
1177 __le32 beacon_filter_delta_time;
1178 struct mvm_statistics_bt_activity bt_activity;
1179} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1180
1181struct mvm_statistics_rx {
1182 struct mvm_statistics_rx_phy ofdm;
1183 struct mvm_statistics_rx_phy cck;
1184 struct mvm_statistics_rx_non_phy general;
1185 struct mvm_statistics_rx_ht_phy ofdm_ht;
1186} __packed; /* STATISTICS_RX_API_S_VER_3 */
1187
1188/*
1189 * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
1190 *
1191 * By default, uCode issues this notification after receiving a beacon
1192 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
1193 * REPLY_STATISTICS_CMD 0x9c, above.
1194 *
1195 * Statistics counters continue to increment beacon after beacon, but are
1196 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
1197 * 0x9c with CLEAR_STATS bit set (see above).
1198 *
1199 * uCode also issues this notification during scans. uCode clears statistics
1200 * appropriately so that each notification contains statistics for only the
1201 * one channel that has just been scanned.
1202 */
1203
1204struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
1205 __le32 flag;
1206 struct mvm_statistics_rx rx;
1207 struct mvm_statistics_tx tx;
1208 struct mvm_statistics_general general;
1209} __packed;
1210
951#endif /* __fw_api_h__ */ 1211#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index e18c92dd60ec..cd7c0032cc58 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -326,6 +326,17 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
327 WARN_ON(ret); 327 WARN_ON(ret);
328 328
329 /*
330 * abort after reading the nvm in case RF Kill is on, we will complete
331 * the init seq later when RF kill will switch to off
332 */
333 if (iwl_mvm_is_radio_killed(mvm)) {
334 IWL_DEBUG_RF_KILL(mvm,
335 "jump over all phy activities due to RF kill\n");
336 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
337 return 1;
338 }
339
329 /* Send TX valid antennas before triggering calibrations */ 340 /* Send TX valid antennas before triggering calibrations */
330 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 341 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
331 if (ret) 342 if (ret)
@@ -388,6 +399,8 @@ out:
388int iwl_mvm_up(struct iwl_mvm *mvm) 399int iwl_mvm_up(struct iwl_mvm *mvm)
389{ 400{
390 int ret, i; 401 int ret, i;
402 struct ieee80211_channel *chan;
403 struct cfg80211_chan_def chandef;
391 404
392 lockdep_assert_held(&mvm->mutex); 405 lockdep_assert_held(&mvm->mutex);
393 406
@@ -400,8 +413,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
400 ret = iwl_run_init_mvm_ucode(mvm, false); 413 ret = iwl_run_init_mvm_ucode(mvm, false);
401 if (ret && !iwlmvm_mod_params.init_dbg) { 414 if (ret && !iwlmvm_mod_params.init_dbg) {
402 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); 415 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
416 /* this can't happen */
417 if (WARN_ON(ret > 0))
418 ret = -ERFKILL;
403 goto error; 419 goto error;
404 } 420 }
421 /* should stop & start HW since that INIT image just loaded */
422 iwl_trans_stop_hw(mvm->trans, false);
423 ret = iwl_trans_start_hw(mvm->trans);
424 if (ret)
425 return ret;
405 } 426 }
406 427
407 if (iwlmvm_mod_params.init_dbg) 428 if (iwlmvm_mod_params.init_dbg)
@@ -443,8 +464,22 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
443 if (ret) 464 if (ret)
444 goto error; 465 goto error;
445 466
446 IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); 467 /* Add all the PHY contexts */
468 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
469 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
470 for (i = 0; i < NUM_PHY_CTX; i++) {
471 /*
472 * The channel used here isn't relevant as it's
473 * going to be overwritten in the other flows.
474 * For now use the first channel we have.
475 */
476 ret = iwl_mvm_phy_ctxt_add(mvm, &mvm->phy_ctxts[i],
477 &chandef, 1, 1);
478 if (ret)
479 goto error;
480 }
447 481
482 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
448 return 0; 483 return 0;
449 error: 484 error:
450 iwl_trans_stop_device(mvm->trans); 485 iwl_trans_stop_device(mvm->trans);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index e6eca4d66f6c..b4e8e597d2b7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -227,7 +227,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
227 .found_vif = false, 227 .found_vif = false,
228 }; 228 };
229 u32 ac; 229 u32 ac;
230 int ret; 230 int ret, i;
231 231
232 /* 232 /*
233 * Allocate a MAC ID and a TSF for this MAC, along with the queues 233 * Allocate a MAC ID and a TSF for this MAC, along with the queues
@@ -335,6 +335,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT; 335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
337 337
338 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++)
339 mvmvif->smps_requests[i] = IEEE80211_SMPS_AUTOMATIC;
340
338 return 0; 341 return 0;
339 342
340exit_fail: 343exit_fail:
@@ -586,10 +589,12 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
586 */ 589 */
587static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm, 590static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
588 struct ieee80211_vif *vif, 591 struct ieee80211_vif *vif,
589 struct iwl_mac_data_sta *ctxt_sta) 592 struct iwl_mac_data_sta *ctxt_sta,
593 bool force_assoc_off)
590{ 594{
591 /* We need the dtim_period to set the MAC as associated */ 595 /* We need the dtim_period to set the MAC as associated */
592 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) { 596 if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
597 !force_assoc_off) {
593 u32 dtim_offs; 598 u32 dtim_offs;
594 599
595 /* 600 /*
@@ -659,7 +664,8 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
659 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); 664 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
660 665
661 /* Fill the data specific for station mode */ 666 /* Fill the data specific for station mode */
662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); 667 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta,
668 action == FW_CTXT_ACTION_ADD);
663 669
664 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 670 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
665} 671}
@@ -677,7 +683,8 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_client(struct iwl_mvm *mvm,
677 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 683 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
678 684
679 /* Fill the data specific for station mode */ 685 /* Fill the data specific for station mode */
680 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta); 686 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.p2p_sta.sta,
687 action == FW_CTXT_ACTION_ADD);
681 688
682 cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow & 689 cmd.p2p_sta.ctwin = cpu_to_le32(noa->oppps_ctwindow &
683 IEEE80211_P2P_OPPPS_CTWINDOW_MASK); 690 IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
@@ -1043,3 +1050,28 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1043 rate); 1050 rate);
1044 return 0; 1051 return 0;
1045} 1052}
1053
1054static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1055 struct ieee80211_vif *vif)
1056{
1057 u16 *id = _data;
1058 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1059
1060 if (mvmvif->id == *id)
1061 ieee80211_beacon_loss(vif);
1062}
1063
1064int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1065 struct iwl_rx_cmd_buffer *rxb,
1066 struct iwl_device_cmd *cmd)
1067{
1068 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1069 struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data;
1070 u16 id = (u16)le32_to_cpu(missed_beacons->mac_id);
1071
1072 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1073 IEEE80211_IFACE_ITER_NORMAL,
1074 iwl_mvm_beacon_loss_iterator,
1075 &id);
1076 return 0;
1077}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index dd158ec571fb..dc50020d746d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -127,6 +127,17 @@ static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
127}; 127};
128#endif 128#endif
129 129
130static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
131{
132 int i;
133
134 memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
135 for (i = 0; i < NUM_PHY_CTX; i++) {
136 mvm->phy_ctxts[i].id = i;
137 mvm->phy_ctxts[i].ref = 0;
138 }
139}
140
130int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 141int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
131{ 142{
132 struct ieee80211_hw *hw = mvm->hw; 143 struct ieee80211_hw *hw = mvm->hw;
@@ -141,7 +152,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
141 IEEE80211_HW_SUPPORTS_PS | 152 IEEE80211_HW_SUPPORTS_PS |
142 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
143 IEEE80211_HW_AMPDU_AGGREGATION | 154 IEEE80211_HW_AMPDU_AGGREGATION |
144 IEEE80211_HW_TIMING_BEACON_ONLY; 155 IEEE80211_HW_TIMING_BEACON_ONLY |
156 IEEE80211_HW_CONNECTION_MONITOR;
145 157
146 hw->queues = IWL_MVM_FIRST_AGG_QUEUE; 158 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
147 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 159 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -158,7 +170,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
158 170
159 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 171 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
160 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 172 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
161 hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt); 173 hw->chanctx_data_size = sizeof(u16);
162 174
163 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 175 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
164 BIT(NL80211_IFTYPE_P2P_CLIENT) | 176 BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -193,6 +205,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
193 hw->wiphy->n_addresses++; 205 hw->wiphy->n_addresses++;
194 } 206 }
195 207
208 iwl_mvm_reset_phy_ctxts(mvm);
209
196 /* we create the 802.11 header and a max-length SSID element */ 210 /* we create the 802.11 header and a max-length SSID element */
197 hw->wiphy->max_scan_ie_len = 211 hw->wiphy->max_scan_ie_len =
198 mvm->fw->ucode_capa.max_probe_length - 24 - 34; 212 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
@@ -252,8 +266,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
252{ 266{
253 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 267 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
254 268
255 if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) { 269 if (iwl_mvm_is_radio_killed(mvm)) {
256 IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n"); 270 IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
257 goto drop; 271 goto drop;
258 } 272 }
259 273
@@ -345,8 +359,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
345 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data); 359 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
346 spin_unlock_bh(&mvm->time_event_lock); 360 spin_unlock_bh(&mvm->time_event_lock);
347 361
348 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 362 mvmvif->phy_ctxt = NULL;
349 mvmvif->phy_ctxt = NULL;
350} 363}
351 364
352static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 365static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
@@ -363,6 +376,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
363 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 376 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
364 iwl_mvm_cleanup_iterator, mvm); 377 iwl_mvm_cleanup_iterator, mvm);
365 378
379 mvm->p2p_device_vif = NULL;
380
381 iwl_mvm_reset_phy_ctxts(mvm);
366 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 382 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
367 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained)); 383 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
368 384
@@ -456,6 +472,20 @@ static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
456 iwl_mvm_power_update_mode(mvm, vif); 472 iwl_mvm_power_update_mode(mvm, vif);
457} 473}
458 474
475static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
476{
477 u16 i;
478
479 lockdep_assert_held(&mvm->mutex);
480
481 for (i = 0; i < NUM_PHY_CTX; i++)
482 if (!mvm->phy_ctxts[i].ref)
483 return &mvm->phy_ctxts[i];
484
485 IWL_ERR(mvm, "No available PHY context\n");
486 return NULL;
487}
488
459static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, 489static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
460 struct ieee80211_vif *vif) 490 struct ieee80211_vif *vif)
461{ 491{
@@ -530,32 +560,34 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
530 */ 560 */
531 iwl_mvm_power_update_mode(mvm, vif); 561 iwl_mvm_power_update_mode(mvm, vif);
532 562
563 /* beacon filtering */
564 if (!mvm->bf_allowed_vif &&
565 vif->type == NL80211_IFTYPE_STATION && !vif->p2p){
566 mvm->bf_allowed_vif = mvmvif;
567 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
568 }
569
570 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
571 if (ret)
572 goto out_release;
573
533 /* 574 /*
534 * P2P_DEVICE interface does not have a channel context assigned to it, 575 * P2P_DEVICE interface does not have a channel context assigned to it,
535 * so a dedicated PHY context is allocated to it and the corresponding 576 * so a dedicated PHY context is allocated to it and the corresponding
536 * MAC context is bound to it at this stage. 577 * MAC context is bound to it at this stage.
537 */ 578 */
538 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 579 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
539 struct ieee80211_channel *chan;
540 struct cfg80211_chan_def chandef;
541
542 mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
543 580
544 /* 581 mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
545 * The channel used here isn't relevant as it's 582 if (!mvmvif->phy_ctxt) {
546 * going to be overwritten as part of the ROC flow. 583 ret = -ENOSPC;
547 * For now use the first channel we have.
548 */
549 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
550 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
551 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
552 &chandef, 1, 1);
553 if (ret)
554 goto out_remove_mac; 584 goto out_remove_mac;
585 }
555 586
587 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
556 ret = iwl_mvm_binding_add_vif(mvm, vif); 588 ret = iwl_mvm_binding_add_vif(mvm, vif);
557 if (ret) 589 if (ret)
558 goto out_remove_phy; 590 goto out_unref_phy;
559 591
560 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); 592 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
561 if (ret) 593 if (ret)
@@ -571,8 +603,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
571 603
572 out_unbind: 604 out_unbind:
573 iwl_mvm_binding_remove_vif(mvm, vif); 605 iwl_mvm_binding_remove_vif(mvm, vif);
574 out_remove_phy: 606 out_unref_phy:
575 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt); 607 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
576 out_remove_mac: 608 out_remove_mac:
577 mvmvif->phy_ctxt = NULL; 609 mvmvif->phy_ctxt = NULL;
578 iwl_mvm_mac_ctxt_remove(mvm, vif); 610 iwl_mvm_mac_ctxt_remove(mvm, vif);
@@ -646,6 +678,11 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
646 678
647 mutex_lock(&mvm->mutex); 679 mutex_lock(&mvm->mutex);
648 680
681 if (mvm->bf_allowed_vif == mvmvif) {
682 mvm->bf_allowed_vif = NULL;
683 vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
684 }
685
649 iwl_mvm_vif_dbgfs_clean(mvm, vif); 686 iwl_mvm_vif_dbgfs_clean(mvm, vif);
650 687
651 /* 688 /*
@@ -661,7 +698,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
661 mvm->p2p_device_vif = NULL; 698 mvm->p2p_device_vif = NULL;
662 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 699 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
663 iwl_mvm_binding_remove_vif(mvm, vif); 700 iwl_mvm_binding_remove_vif(mvm, vif);
664 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt); 701 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
665 mvmvif->phy_ctxt = NULL; 702 mvmvif->phy_ctxt = NULL;
666 } 703 }
667 704
@@ -701,6 +738,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
701 *total_flags = 0; 738 *total_flags = 0;
702} 739}
703 740
741static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm,
742 struct ieee80211_vif *vif)
743{
744 struct iwl_mcast_filter_cmd mcast_filter_cmd = {
745 .pass_all = 1,
746 };
747
748 memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN);
749
750 return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC,
751 sizeof(mcast_filter_cmd),
752 &mcast_filter_cmd);
753}
754
704static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, 755static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
705 struct ieee80211_vif *vif, 756 struct ieee80211_vif *vif,
706 struct ieee80211_bss_conf *bss_conf, 757 struct ieee80211_bss_conf *bss_conf,
@@ -722,6 +773,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
722 return; 773 return;
723 } 774 }
724 iwl_mvm_bt_coex_vif_assoc(mvm, vif); 775 iwl_mvm_bt_coex_vif_assoc(mvm, vif);
776 iwl_mvm_configure_mcast_filter(mvm, vif);
725 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 777 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
726 /* remove AP station now that the MAC is unassoc */ 778 /* remove AP station now that the MAC is unassoc */
727 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 779 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -931,7 +983,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
931 983
932 switch (cmd) { 984 switch (cmd) {
933 case STA_NOTIFY_SLEEP: 985 case STA_NOTIFY_SLEEP:
934 if (atomic_read(&mvmsta->pending_frames) > 0) 986 if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
935 ieee80211_sta_block_awake(hw, sta, true); 987 ieee80211_sta_block_awake(hw, sta, true);
936 /* 988 /*
937 * The fw updates the STA to be asleep. Tx packets on the Tx 989 * The fw updates the STA to be asleep. Tx packets on the Tx
@@ -984,9 +1036,13 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
984 mvmvif->phy_ctxt->channel->band); 1036 mvmvif->phy_ctxt->channel->band);
985 } else if (old_state == IEEE80211_STA_ASSOC && 1037 } else if (old_state == IEEE80211_STA_ASSOC &&
986 new_state == IEEE80211_STA_AUTHORIZED) { 1038 new_state == IEEE80211_STA_AUTHORIZED) {
1039 /* enable beacon filtering */
1040 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif));
987 ret = 0; 1041 ret = 0;
988 } else if (old_state == IEEE80211_STA_AUTHORIZED && 1042 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
989 new_state == IEEE80211_STA_ASSOC) { 1043 new_state == IEEE80211_STA_ASSOC) {
1044 /* disable beacon filtering */
1045 WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif));
990 ret = 0; 1046 ret = 0;
991 } else if (old_state == IEEE80211_STA_ASSOC && 1047 } else if (old_state == IEEE80211_STA_ASSOC &&
992 new_state == IEEE80211_STA_AUTH) { 1048 new_state == IEEE80211_STA_AUTH) {
@@ -1152,29 +1208,107 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1152 enum ieee80211_roc_type type) 1208 enum ieee80211_roc_type type)
1153{ 1209{
1154 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1210 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1211 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1155 struct cfg80211_chan_def chandef; 1212 struct cfg80211_chan_def chandef;
1156 int ret; 1213 struct iwl_mvm_phy_ctxt *phy_ctxt;
1214 int ret, i;
1215
1216 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1217 duration, type);
1157 1218
1158 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) { 1219 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1159 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type); 1220 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1160 return -EINVAL; 1221 return -EINVAL;
1161 } 1222 }
1162 1223
1163 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1164 duration, type);
1165
1166 mutex_lock(&mvm->mutex); 1224 mutex_lock(&mvm->mutex);
1167 1225
1226 for (i = 0; i < NUM_PHY_CTX; i++) {
1227 phy_ctxt = &mvm->phy_ctxts[i];
1228 if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
1229 continue;
1230
1231 if (phy_ctxt->ref && channel == phy_ctxt->channel) {
1232 /*
1233 * Unbind the P2P_DEVICE from the current PHY context,
1234 * and if the PHY context is not used remove it.
1235 */
1236 ret = iwl_mvm_binding_remove_vif(mvm, vif);
1237 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1238 goto out_unlock;
1239
1240 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1241
1242 /* Bind the P2P_DEVICE to the current PHY Context */
1243 mvmvif->phy_ctxt = phy_ctxt;
1244
1245 ret = iwl_mvm_binding_add_vif(mvm, vif);
1246 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1247 goto out_unlock;
1248
1249 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1250 goto schedule_time_event;
1251 }
1252 }
1253
1254 /* Need to update the PHY context only if the ROC channel changed */
1255 if (channel == mvmvif->phy_ctxt->channel)
1256 goto schedule_time_event;
1257
1168 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); 1258 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1169 ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1170 &chandef, 1, 1);
1171 1259
1260 /*
1261 * Change the PHY context configuration as it is currently referenced
1262 * only by the P2P Device MAC
1263 */
1264 if (mvmvif->phy_ctxt->ref == 1) {
1265 ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
1266 &chandef, 1, 1);
1267 if (ret)
1268 goto out_unlock;
1269 } else {
1270 /*
1271 * The PHY context is shared with other MACs. Need to remove the
1272 * P2P Device from the binding, allocate an new PHY context and
1273 * create a new binding
1274 */
1275 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1276 if (!phy_ctxt) {
1277 ret = -ENOSPC;
1278 goto out_unlock;
1279 }
1280
1281 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
1282 1, 1);
1283 if (ret) {
1284 IWL_ERR(mvm, "Failed to change PHY context\n");
1285 goto out_unlock;
1286 }
1287
1288 /* Unbind the P2P_DEVICE from the current PHY context */
1289 ret = iwl_mvm_binding_remove_vif(mvm, vif);
1290 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1291 goto out_unlock;
1292
1293 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1294
1295 /* Bind the P2P_DEVICE to the new allocated PHY context */
1296 mvmvif->phy_ctxt = phy_ctxt;
1297
1298 ret = iwl_mvm_binding_add_vif(mvm, vif);
1299 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1300 goto out_unlock;
1301
1302 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1303 }
1304
1305schedule_time_event:
1172 /* Schedule the time events */ 1306 /* Schedule the time events */
1173 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type); 1307 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1174 1308
1309out_unlock:
1175 mutex_unlock(&mvm->mutex); 1310 mutex_unlock(&mvm->mutex);
1176 IWL_DEBUG_MAC80211(mvm, "leave\n"); 1311 IWL_DEBUG_MAC80211(mvm, "leave\n");
1177
1178 return ret; 1312 return ret;
1179} 1313}
1180 1314
@@ -1196,15 +1330,30 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1196 struct ieee80211_chanctx_conf *ctx) 1330 struct ieee80211_chanctx_conf *ctx)
1197{ 1331{
1198 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1332 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1199 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1333 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1334 struct iwl_mvm_phy_ctxt *phy_ctxt;
1200 int ret; 1335 int ret;
1201 1336
1337 IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
1338
1202 mutex_lock(&mvm->mutex); 1339 mutex_lock(&mvm->mutex);
1340 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1341 if (!phy_ctxt) {
1342 ret = -ENOSPC;
1343 goto out;
1344 }
1345
1346 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1347 ctx->rx_chains_static,
1348 ctx->rx_chains_dynamic);
1349 if (ret) {
1350 IWL_ERR(mvm, "Failed to add PHY context\n");
1351 goto out;
1352 }
1203 1353
1204 IWL_DEBUG_MAC80211(mvm, "Add PHY context\n"); 1354 iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
1205 ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def, 1355 *phy_ctxt_id = phy_ctxt->id;
1206 ctx->rx_chains_static, 1356out:
1207 ctx->rx_chains_dynamic);
1208 mutex_unlock(&mvm->mutex); 1357 mutex_unlock(&mvm->mutex);
1209 return ret; 1358 return ret;
1210} 1359}
@@ -1213,10 +1362,11 @@ static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1213 struct ieee80211_chanctx_conf *ctx) 1362 struct ieee80211_chanctx_conf *ctx)
1214{ 1363{
1215 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1364 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1216 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1365 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1366 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1217 1367
1218 mutex_lock(&mvm->mutex); 1368 mutex_lock(&mvm->mutex);
1219 iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt); 1369 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
1220 mutex_unlock(&mvm->mutex); 1370 mutex_unlock(&mvm->mutex);
1221} 1371}
1222 1372
@@ -1225,7 +1375,16 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1225 u32 changed) 1375 u32 changed)
1226{ 1376{
1227 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1377 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1228 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1378 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1379 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1380
1381 if (WARN_ONCE((phy_ctxt->ref > 1) &&
1382 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1383 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1384 IEEE80211_CHANCTX_CHANGE_RADAR)),
1385 "Cannot change PHY. Ref=%d, changed=0x%X\n",
1386 phy_ctxt->ref, changed))
1387 return;
1229 1388
1230 mutex_lock(&mvm->mutex); 1389 mutex_lock(&mvm->mutex);
1231 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1390 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
@@ -1239,13 +1398,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1239 struct ieee80211_chanctx_conf *ctx) 1398 struct ieee80211_chanctx_conf *ctx)
1240{ 1399{
1241 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1400 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1242 struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv; 1401 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1402 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1243 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1403 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1244 int ret; 1404 int ret;
1245 1405
1246 mutex_lock(&mvm->mutex); 1406 mutex_lock(&mvm->mutex);
1247 1407
1248 mvmvif->phy_ctxt = phyctx; 1408 mvmvif->phy_ctxt = phy_ctxt;
1249 1409
1250 switch (vif->type) { 1410 switch (vif->type) {
1251 case NL80211_IFTYPE_AP: 1411 case NL80211_IFTYPE_AP:
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 8269bc562951..6a3220b6273e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -109,6 +109,7 @@ extern struct iwl_mvm_mod_params iwlmvm_mod_params;
109struct iwl_mvm_phy_ctxt { 109struct iwl_mvm_phy_ctxt {
110 u16 id; 110 u16 id;
111 u16 color; 111 u16 color;
112 u32 ref;
112 113
113 /* 114 /*
114 * TODO: This should probably be removed. Currently here only for rate 115 * TODO: This should probably be removed. Currently here only for rate
@@ -149,6 +150,60 @@ enum iwl_power_scheme {
149 150
150#define IWL_CONN_MAX_LISTEN_INTERVAL 70 151#define IWL_CONN_MAX_LISTEN_INTERVAL 70
151 152
153#ifdef CONFIG_IWLWIFI_DEBUGFS
154enum iwl_dbgfs_pm_mask {
155 MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0),
156 MVM_DEBUGFS_PM_SKIP_OVER_DTIM = BIT(1),
157 MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2),
158 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
159 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
160 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
161};
162
163struct iwl_dbgfs_pm {
164 u8 keep_alive_seconds;
165 u32 rx_data_timeout;
166 u32 tx_data_timeout;
167 bool skip_over_dtim;
168 u8 skip_dtim_periods;
169 bool disable_power_off;
170 int mask;
171};
172
173/* beacon filtering */
174
175enum iwl_dbgfs_bf_mask {
176 MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0),
177 MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1),
178 MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2),
179 MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3),
180 MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4),
181 MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5),
182 MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6),
183 MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7),
184 MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8),
185};
186
187struct iwl_dbgfs_bf {
188 u8 bf_energy_delta;
189 u8 bf_roaming_energy_delta;
190 u8 bf_roaming_state;
191 u8 bf_temperature_delta;
192 u8 bf_enable_beacon_filter;
193 u8 bf_debug_flag;
194 u32 bf_escape_timer;
195 u32 ba_escape_timer;
196 u8 ba_enable_beacon_abort;
197 int mask;
198};
199#endif
200
201enum iwl_mvm_smps_type_request {
202 IWL_MVM_SMPS_REQ_BT_COEX,
203 IWL_MVM_SMPS_REQ_TT,
204 NUM_IWL_MVM_SMPS_REQ,
205};
206
152/** 207/**
153 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context 208 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
154 * @id: between 0 and 3 209 * @id: between 0 and 3
@@ -163,6 +218,8 @@ enum iwl_power_scheme {
163 * @bcast_sta: station used for broadcast packets. Used by the following 218 * @bcast_sta: station used for broadcast packets. Used by the following
164 * vifs: P2P_DEVICE, GO and AP. 219 * vifs: P2P_DEVICE, GO and AP.
165 * @beacon_skb: the skb used to hold the AP/GO beacon template 220 * @beacon_skb: the skb used to hold the AP/GO beacon template
221 * @smps_requests: the requests of of differents parts of the driver, regard
222 the desired smps mode.
166 */ 223 */
167struct iwl_mvm_vif { 224struct iwl_mvm_vif {
168 u16 id; 225 u16 id;
@@ -172,6 +229,8 @@ struct iwl_mvm_vif {
172 bool uploaded; 229 bool uploaded;
173 bool ap_active; 230 bool ap_active;
174 bool monitor_active; 231 bool monitor_active;
232 /* indicate whether beacon filtering is enabled */
233 bool bf_enabled;
175 234
176 u32 ap_beacon_time; 235 u32 ap_beacon_time;
177 236
@@ -214,7 +273,11 @@ struct iwl_mvm_vif {
214 struct dentry *dbgfs_dir; 273 struct dentry *dbgfs_dir;
215 struct dentry *dbgfs_slink; 274 struct dentry *dbgfs_slink;
216 void *dbgfs_data; 275 void *dbgfs_data;
276 struct iwl_dbgfs_pm dbgfs_pm;
277 struct iwl_dbgfs_bf dbgfs_bf;
217#endif 278#endif
279
280 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
218}; 281};
219 282
220static inline struct iwl_mvm_vif * 283static inline struct iwl_mvm_vif *
@@ -223,12 +286,6 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
223 return (void *)vif->drv_priv; 286 return (void *)vif->drv_priv;
224} 287}
225 288
226enum iwl_mvm_status {
227 IWL_MVM_STATUS_HW_RFKILL,
228 IWL_MVM_STATUS_ROC_RUNNING,
229 IWL_MVM_STATUS_IN_HW_RESTART,
230};
231
232enum iwl_scan_status { 289enum iwl_scan_status {
233 IWL_MVM_SCAN_NONE, 290 IWL_MVM_SCAN_NONE,
234 IWL_MVM_SCAN_OS, 291 IWL_MVM_SCAN_OS,
@@ -246,6 +303,63 @@ struct iwl_nvm_section {
246 const u8 *data; 303 const u8 *data;
247}; 304};
248 305
306/*
307 * Tx-backoff threshold
308 * @temperature: The threshold in Celsius
309 * @backoff: The tx-backoff in uSec
310 */
311struct iwl_tt_tx_backoff {
312 s32 temperature;
313 u32 backoff;
314};
315
316#define TT_TX_BACKOFF_SIZE 6
317
318/**
319 * struct iwl_tt_params - thermal throttling parameters
320 * @ct_kill_entry: CT Kill entry threshold
321 * @ct_kill_exit: CT Kill exit threshold
322 * @ct_kill_duration: The time intervals (in uSec) in which the driver needs
323 * to checks whether to exit CT Kill.
324 * @dynamic_smps_entry: Dynamic SMPS entry threshold
325 * @dynamic_smps_exit: Dynamic SMPS exit threshold
326 * @tx_protection_entry: TX protection entry threshold
327 * @tx_protection_exit: TX protection exit threshold
328 * @tx_backoff: Array of thresholds for tx-backoff , in ascending order.
329 * @support_ct_kill: Support CT Kill?
330 * @support_dynamic_smps: Support dynamic SMPS?
331 * @support_tx_protection: Support tx protection?
332 * @support_tx_backoff: Support tx-backoff?
333 */
334struct iwl_tt_params {
335 s32 ct_kill_entry;
336 s32 ct_kill_exit;
337 u32 ct_kill_duration;
338 s32 dynamic_smps_entry;
339 s32 dynamic_smps_exit;
340 s32 tx_protection_entry;
341 s32 tx_protection_exit;
342 struct iwl_tt_tx_backoff tx_backoff[TT_TX_BACKOFF_SIZE];
343 bool support_ct_kill;
344 bool support_dynamic_smps;
345 bool support_tx_protection;
346 bool support_tx_backoff;
347};
348
349/**
350 * struct iwl_mvm_tt_mgnt - Thermal Throttling Management structure
351 * @ct_kill_exit: worker to exit thermal kill
352 * @dynamic_smps: Is thermal throttling enabled dynamic_smps?
353 * @tx_backoff: The current thremal throttling tx backoff in uSec.
354 * @params: Parameters to configure the thermal throttling algorithm.
355 */
356struct iwl_mvm_tt_mgmt {
357 struct delayed_work ct_kill_exit;
358 bool dynamic_smps;
359 u32 tx_backoff;
360 const struct iwl_tt_params *params;
361};
362
249struct iwl_mvm { 363struct iwl_mvm {
250 /* for logger access */ 364 /* for logger access */
251 struct device *dev; 365 struct device *dev;
@@ -266,6 +380,12 @@ struct iwl_mvm {
266 380
267 unsigned long status; 381 unsigned long status;
268 382
383 /*
384 * for beacon filtering -
385 * currently only one interface can be supported
386 */
387 struct iwl_mvm_vif *bf_allowed_vif;
388
269 enum iwl_ucode_type cur_ucode; 389 enum iwl_ucode_type cur_ucode;
270 bool ucode_loaded; 390 bool ucode_loaded;
271 bool init_ucode_run; 391 bool init_ucode_run;
@@ -292,6 +412,7 @@ struct iwl_mvm {
292 struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT]; 412 struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
293 struct work_struct sta_drained_wk; 413 struct work_struct sta_drained_wk;
294 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; 414 unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
415 atomic_t pending_frames[IWL_MVM_STATION_COUNT];
295 416
296 /* configured by mac80211 */ 417 /* configured by mac80211 */
297 u32 rts_threshold; 418 u32 rts_threshold;
@@ -312,7 +433,7 @@ struct iwl_mvm {
312 bool prevent_power_down_d3; 433 bool prevent_power_down_d3;
313#endif 434#endif
314 435
315 struct iwl_mvm_phy_ctxt phy_ctxt_roc; 436 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
316 437
317 struct list_head time_event_list; 438 struct list_head time_event_list;
318 spinlock_t time_event_lock; 439 spinlock_t time_event_lock;
@@ -337,11 +458,19 @@ struct iwl_mvm {
337 458
338#ifdef CONFIG_PM_SLEEP 459#ifdef CONFIG_PM_SLEEP
339 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 460 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
461#ifdef CONFIG_IWLWIFI_DEBUGFS
462 bool store_d3_resume_sram;
463 void *d3_resume_sram;
464#endif
340#endif 465#endif
341 466
342 /* BT-Coex */ 467 /* BT-Coex */
343 u8 bt_kill_msk; 468 u8 bt_kill_msk;
344 struct iwl_bt_coex_profile_notif last_bt_notif; 469 struct iwl_bt_coex_profile_notif last_bt_notif;
470
471 /* Thermal Throttling and CTkill */
472 struct iwl_mvm_tt_mgmt thermal_throttle;
473 s32 temperature; /* Celsius */
345}; 474};
346 475
347/* Extract MVM priv from op_mode and _hw */ 476/* Extract MVM priv from op_mode and _hw */
@@ -351,6 +480,19 @@ struct iwl_mvm {
351#define IWL_MAC80211_GET_MVM(_hw) \ 480#define IWL_MAC80211_GET_MVM(_hw) \
352 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv)) 481 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
353 482
483enum iwl_mvm_status {
484 IWL_MVM_STATUS_HW_RFKILL,
485 IWL_MVM_STATUS_HW_CTKILL,
486 IWL_MVM_STATUS_ROC_RUNNING,
487 IWL_MVM_STATUS_IN_HW_RESTART,
488};
489
490static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
491{
492 return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status) ||
493 test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
494}
495
354extern const u8 iwl_mvm_ac_to_tx_fifo[]; 496extern const u8 iwl_mvm_ac_to_tx_fifo[];
355 497
356struct iwl_rate_info { 498struct iwl_rate_info {
@@ -442,8 +584,10 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
442int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 584int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
443 struct cfg80211_chan_def *chandef, 585 struct cfg80211_chan_def *chandef,
444 u8 chains_static, u8 chains_dynamic); 586 u8 chains_static, u8 chains_dynamic);
445void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, 587void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
446 struct iwl_mvm_phy_ctxt *ctxt); 588 struct iwl_mvm_phy_ctxt *ctxt);
589void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
590 struct iwl_mvm_phy_ctxt *ctxt);
447 591
448/* MAC (virtual interface) programming */ 592/* MAC (virtual interface) programming */
449int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 593int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -458,6 +602,9 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
458int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, 602int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
459 struct iwl_rx_cmd_buffer *rxb, 603 struct iwl_rx_cmd_buffer *rxb,
460 struct iwl_device_cmd *cmd); 604 struct iwl_device_cmd *cmd);
605int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
606 struct iwl_rx_cmd_buffer *rxb,
607 struct iwl_device_cmd *cmd);
461 608
462/* Bindings */ 609/* Bindings */
463int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 610int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -533,4 +680,36 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
533 enum ieee80211_rssi_event rssi_event); 680 enum ieee80211_rssi_event rssi_event);
534void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 681void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
535 682
683/* beacon filtering */
684#ifdef CONFIG_IWLWIFI_DEBUGFS
685void
686iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
687 struct iwl_beacon_filter_cmd *cmd);
688int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm);
689#else
690static inline void
691iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
692 struct iwl_beacon_filter_cmd *cmd)
693{}
694static inline int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm)
695{
696 return 0;
697}
698#endif
699int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
700 struct ieee80211_vif *vif);
701int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
702 struct ieee80211_vif *vif);
703
704/* SMPS */
705void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
706 enum iwl_mvm_smps_type_request req_type,
707 enum ieee80211_smps_mode smps_request);
708
709/* Thermal management and CT-kill */
710void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
711void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
712void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
713void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
714
536#endif /* __IWL_MVM_H__ */ 715#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index b8ec02f89acc..edb94ea31654 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -60,6 +60,7 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/firmware.h>
63#include "iwl-trans.h" 64#include "iwl-trans.h"
64#include "mvm.h" 65#include "mvm.h"
65#include "iwl-eeprom-parse.h" 66#include "iwl-eeprom-parse.h"
@@ -75,31 +76,56 @@ static const int nvm_to_read[] = {
75}; 76};
76 77
77/* Default NVM size to read */ 78/* Default NVM size to read */
78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); 79#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
80#define IWL_MAX_NVM_SECTION_SIZE 6000
79 81
80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd, 82#define NVM_WRITE_OPCODE 1
81 u16 offset, u16 length, u16 section) 83#define NVM_READ_OPCODE 0
84
85/*
86 * prepare the NVM host command w/ the pointers to the nvm buffer
87 * and send it to fw
88 */
89static int iwl_nvm_write_chunk(struct iwl_mvm *mvm, u16 section,
90 u16 offset, u16 length, const u8 *data)
82{ 91{
83 cmd->offset = cpu_to_le16(offset); 92 struct iwl_nvm_access_cmd nvm_access_cmd = {
84 cmd->length = cpu_to_le16(length); 93 .offset = cpu_to_le16(offset),
85 cmd->type = cpu_to_le16(section); 94 .length = cpu_to_le16(length),
95 .type = cpu_to_le16(section),
96 .op_code = NVM_WRITE_OPCODE,
97 };
98 struct iwl_host_cmd cmd = {
99 .id = NVM_ACCESS_CMD,
100 .len = { sizeof(struct iwl_nvm_access_cmd), length },
101 .flags = CMD_SYNC | CMD_SEND_IN_RFKILL,
102 .data = { &nvm_access_cmd, data },
103 /* data may come from vmalloc, so use _DUP */
104 .dataflags = { 0, IWL_HCMD_DFL_DUP },
105 };
106
107 return iwl_mvm_send_cmd(mvm, &cmd);
86} 108}
87 109
88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 110static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
89 u16 offset, u16 length, u8 *data) 111 u16 offset, u16 length, u8 *data)
90{ 112{
91 struct iwl_nvm_access_cmd nvm_access_cmd = {}; 113 struct iwl_nvm_access_cmd nvm_access_cmd = {
114 .offset = cpu_to_le16(offset),
115 .length = cpu_to_le16(length),
116 .type = cpu_to_le16(section),
117 .op_code = NVM_READ_OPCODE,
118 };
92 struct iwl_nvm_access_resp *nvm_resp; 119 struct iwl_nvm_access_resp *nvm_resp;
93 struct iwl_rx_packet *pkt; 120 struct iwl_rx_packet *pkt;
94 struct iwl_host_cmd cmd = { 121 struct iwl_host_cmd cmd = {
95 .id = NVM_ACCESS_CMD, 122 .id = NVM_ACCESS_CMD,
96 .flags = CMD_SYNC | CMD_WANT_SKB, 123 .flags = CMD_SYNC | CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
97 .data = { &nvm_access_cmd, }, 124 .data = { &nvm_access_cmd, },
98 }; 125 };
99 int ret, bytes_read, offset_read; 126 int ret, bytes_read, offset_read;
100 u8 *resp_data; 127 u8 *resp_data;
101 128
102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd); 129 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
104 130
105 ret = iwl_mvm_send_cmd(mvm, &cmd); 131 ret = iwl_mvm_send_cmd(mvm, &cmd);
@@ -144,6 +170,30 @@ exit:
144 return ret; 170 return ret;
145} 171}
146 172
173static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
174 const u8 *data, u16 length)
175{
176 int offset = 0;
177
178 /* copy data in chunks of 2k (and remainder if any) */
179
180 while (offset < length) {
181 int chunk_size, ret;
182
183 chunk_size = min(IWL_NVM_DEFAULT_CHUNK_SIZE,
184 length - offset);
185
186 ret = iwl_nvm_write_chunk(mvm, section, offset,
187 chunk_size, data + offset);
188 if (ret < 0)
189 return ret;
190
191 offset += chunk_size;
192 }
193
194 return 0;
195}
196
147/* 197/*
148 * Reads an NVM section completely. 198 * Reads an NVM section completely.
149 * NICs prior to 7000 family doesn't have a real NVM, but just read 199 * NICs prior to 7000 family doesn't have a real NVM, but just read
@@ -177,7 +227,8 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
177 offset += ret; 227 offset += ret;
178 } 228 }
179 229
180 IWL_INFO(mvm, "NVM section %d read completed\n", section); 230 IWL_DEBUG_EEPROM(mvm->trans->dev,
231 "NVM section %d read completed\n", section);
181 return offset; 232 return offset;
182} 233}
183 234
@@ -200,7 +251,130 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
200 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data; 251 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data;
201 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 252 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
202 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 253 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
203 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib); 254 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
255 iwl_fw_valid_tx_ant(mvm->fw),
256 iwl_fw_valid_rx_ant(mvm->fw));
257}
258
259#define MAX_NVM_FILE_LEN 16384
260
261/*
262 * HOW TO CREATE THE NVM FILE FORMAT:
263 * ------------------------------
264 * 1. create hex file, format:
265 * 3800 -> header
266 * 0000 -> header
267 * 5a40 -> data
268 *
269 * rev - 6 bit (word1)
270 * len - 10 bit (word1)
271 * id - 4 bit (word2)
272 * rsv - 12 bit (word2)
273 *
274 * 2. flip 8bits with 8 bits per line to get the right NVM file format
275 *
276 * 3. create binary file from the hex file
277 *
278 * 4. save as "iNVM_xxx.bin" under /lib/firmware
279 */
280static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
281{
282 int ret, section_id, section_size;
283 const struct firmware *fw_entry;
284 const struct {
285 __le16 word1;
286 __le16 word2;
287 u8 data[];
288 } *file_sec;
289 const u8 *eof;
290
291#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
292#define NVM_WORD2_ID(x) (x >> 12)
293
294 /*
295 * Obtain NVM image via request_firmware. Since we already used
296 * request_firmware_nowait() for the firmware binary load and only
297 * get here after that we assume the NVM request can be satisfied
298 * synchronously.
299 */
300 ret = request_firmware(&fw_entry, iwlwifi_mod_params.nvm_file,
301 mvm->trans->dev);
302 if (ret) {
303 IWL_ERR(mvm, "ERROR: %s isn't available %d\n",
304 iwlwifi_mod_params.nvm_file, ret);
305 return ret;
306 }
307
308 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
309 iwlwifi_mod_params.nvm_file, fw_entry->size);
310
311 if (fw_entry->size < sizeof(*file_sec)) {
312 IWL_ERR(mvm, "NVM file too small\n");
313 ret = -EINVAL;
314 goto out;
315 }
316
317 if (fw_entry->size > MAX_NVM_FILE_LEN) {
318 IWL_ERR(mvm, "NVM file too large\n");
319 ret = -EINVAL;
320 goto out;
321 }
322
323 eof = fw_entry->data + fw_entry->size;
324
325 file_sec = (void *)fw_entry->data;
326
327 while (true) {
328 if (file_sec->data > eof) {
329 IWL_ERR(mvm,
330 "ERROR - NVM file too short for section header\n");
331 ret = -EINVAL;
332 break;
333 }
334
335 /* check for EOF marker */
336 if (!file_sec->word1 && !file_sec->word2) {
337 ret = 0;
338 break;
339 }
340
341 section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
342 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
343
344 if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
345 IWL_ERR(mvm, "ERROR - section too large (%d)\n",
346 section_size);
347 ret = -EINVAL;
348 break;
349 }
350
351 if (!section_size) {
352 IWL_ERR(mvm, "ERROR - section empty\n");
353 ret = -EINVAL;
354 break;
355 }
356
357 if (file_sec->data + section_size > eof) {
358 IWL_ERR(mvm,
359 "ERROR - NVM file too short for section (%d bytes)\n",
360 section_size);
361 ret = -EINVAL;
362 break;
363 }
364
365 ret = iwl_nvm_write_section(mvm, section_id, file_sec->data,
366 section_size);
367 if (ret < 0) {
368 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
369 break;
370 }
371
372 /* advance to the next section */
373 file_sec = (void *)(file_sec->data + section_size);
374 }
375out:
376 release_firmware(fw_entry);
377 return ret;
204} 378}
205 379
206int iwl_nvm_init(struct iwl_mvm *mvm) 380int iwl_nvm_init(struct iwl_mvm *mvm)
@@ -208,6 +382,17 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
208 int ret, i, section; 382 int ret, i, section;
209 u8 *nvm_buffer, *temp; 383 u8 *nvm_buffer, *temp;
210 384
385 /* load external NVM if configured */
386 if (iwlwifi_mod_params.nvm_file) {
387 /* move to External NVM flow */
388 ret = iwl_mvm_load_external_nvm(mvm);
389 if (ret)
390 return ret;
391 }
392
393 /* Read From FW NVM */
394 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
395
211 /* TODO: find correct NVM max size for a section */ 396 /* TODO: find correct NVM max size for a section */
212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 397 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
213 GFP_KERNEL); 398 GFP_KERNEL);
@@ -231,8 +416,9 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
231 if (ret < 0) 416 if (ret < 0)
232 return ret; 417 return ret;
233 418
234 ret = 0;
235 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 419 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
420 if (!mvm->nvm_data)
421 return -ENODATA;
236 422
237 return ret; 423 return 0;
238} 424}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index fe031d304d1e..d7a199b1cdef 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -222,10 +222,14 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
222 222
223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), 223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false), 224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
225 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
225 226
226 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 227 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
227 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 228 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
228 229
230 RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
231 false),
232
229 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), 233 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
230}; 234};
231#undef RX_HANDLER 235#undef RX_HANDLER
@@ -288,10 +292,14 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
288 CMD(NET_DETECT_HOTSPOTS_CMD), 292 CMD(NET_DETECT_HOTSPOTS_CMD),
289 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 293 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
290 CMD(CARD_STATE_NOTIFICATION), 294 CMD(CARD_STATE_NOTIFICATION),
295 CMD(MISSED_BEACONS_NOTIFICATION),
291 CMD(BT_COEX_PRIO_TABLE), 296 CMD(BT_COEX_PRIO_TABLE),
292 CMD(BT_COEX_PROT_ENV), 297 CMD(BT_COEX_PROT_ENV),
293 CMD(BT_PROFILE_NOTIFICATION), 298 CMD(BT_PROFILE_NOTIFICATION),
294 CMD(BT_CONFIG), 299 CMD(BT_CONFIG),
300 CMD(MCAST_FILTER_CMD),
301 CMD(REPLY_BEACON_FILTERING_CMD),
302 CMD(REPLY_THERMAL_MNG_BACKOFF),
295}; 303};
296#undef CMD 304#undef CMD
297 305
@@ -392,10 +400,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
392 if (err) 400 if (err)
393 goto out_free; 401 goto out_free;
394 402
403 iwl_mvm_tt_initialize(mvm);
404
395 mutex_lock(&mvm->mutex); 405 mutex_lock(&mvm->mutex);
396 err = iwl_run_init_mvm_ucode(mvm, true); 406 err = iwl_run_init_mvm_ucode(mvm, true);
397 mutex_unlock(&mvm->mutex); 407 mutex_unlock(&mvm->mutex);
398 if (err && !iwlmvm_mod_params.init_dbg) { 408 /* returns 0 if successful, 1 if success but in rfkill */
409 if (err < 0 && !iwlmvm_mod_params.init_dbg) {
399 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); 410 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
400 goto out_free; 411 goto out_free;
401 } 412 }
@@ -438,10 +449,16 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
438 449
439 iwl_mvm_leds_exit(mvm); 450 iwl_mvm_leds_exit(mvm);
440 451
452 iwl_mvm_tt_exit(mvm);
453
441 ieee80211_unregister_hw(mvm->hw); 454 ieee80211_unregister_hw(mvm->hw);
442 455
443 kfree(mvm->scan_cmd); 456 kfree(mvm->scan_cmd);
444 457
458#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
459 kfree(mvm->d3_resume_sram);
460#endif
461
445 iwl_trans_stop_hw(mvm->trans, true); 462 iwl_trans_stop_hw(mvm->trans, true);
446 463
447 iwl_phy_db_free(mvm->phy_db); 464 iwl_phy_db_free(mvm->phy_db);
@@ -588,6 +605,16 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
588 ieee80211_wake_queue(mvm->hw, mq); 605 ieee80211_wake_queue(mvm->hw, mq);
589} 606}
590 607
608void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
609{
610 if (state)
611 set_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
612 else
613 clear_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
614
615 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
616}
617
591static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) 618static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
592{ 619{
593 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 620 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
@@ -597,7 +624,7 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
597 else 624 else
598 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 625 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
599 626
600 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, state); 627 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
601} 628}
602 629
603static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) 630static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index a28a1d1f23eb..1b4db25d53fb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -195,21 +195,6 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
195 return ret; 195 return ret;
196} 196}
197 197
198
199struct phy_ctx_used_data {
200 unsigned long used[BITS_TO_LONGS(NUM_PHY_CTX)];
201};
202
203static void iwl_mvm_phy_ctx_used_iter(struct ieee80211_hw *hw,
204 struct ieee80211_chanctx_conf *ctx,
205 void *_data)
206{
207 struct phy_ctx_used_data *data = _data;
208 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
209
210 __set_bit(phy_ctxt->id, data->used);
211}
212
213/* 198/*
214 * Send a command to add a PHY context based on the current HW configuration. 199 * Send a command to add a PHY context based on the current HW configuration.
215 */ 200 */
@@ -217,34 +202,27 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
217 struct cfg80211_chan_def *chandef, 202 struct cfg80211_chan_def *chandef,
218 u8 chains_static, u8 chains_dynamic) 203 u8 chains_static, u8 chains_dynamic)
219{ 204{
220 struct phy_ctx_used_data data = { 205 int ret;
221 .used = { },
222 };
223
224 /*
225 * If this is a regular PHY context (not the ROC one)
226 * skip the ROC PHY context's ID.
227 */
228 if (ctxt != &mvm->phy_ctxt_roc)
229 __set_bit(mvm->phy_ctxt_roc.id, data.used);
230 206
207 WARN_ON(ctxt->ref);
231 lockdep_assert_held(&mvm->mutex); 208 lockdep_assert_held(&mvm->mutex);
232 ctxt->color++;
233 209
234 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 210 ctxt->channel = chandef->chan;
235 ieee80211_iter_chan_contexts_atomic( 211 ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
236 mvm->hw, iwl_mvm_phy_ctx_used_iter, &data); 212 chains_static, chains_dynamic,
213 FW_CTXT_ACTION_ADD, 0);
237 214
238 ctxt->id = find_first_zero_bit(data.used, NUM_PHY_CTX); 215 return ret;
239 if (WARN_ONCE(ctxt->id == NUM_PHY_CTX, 216}
240 "Failed to init PHY context - no free ID!\n"))
241 return -EIO;
242 }
243 217
244 ctxt->channel = chandef->chan; 218/*
245 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 219 * Update the number of references to the given PHY context. This is valid only
246 chains_static, chains_dynamic, 220 * in case the PHY context was already created, i.e., its reference count > 0.
247 FW_CTXT_ACTION_ADD, 0); 221 */
222void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
223{
224 lockdep_assert_held(&mvm->mutex);
225 ctxt->ref++;
248} 226}
249 227
250/* 228/*
@@ -264,23 +242,12 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
264 FW_CTXT_ACTION_MODIFY, 0); 242 FW_CTXT_ACTION_MODIFY, 0);
265} 243}
266 244
267/* 245void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
268 * Send a command to the FW to remove the given phy context.
269 * Once the command is sent, regardless of success or failure, the context is
270 * marked as invalid
271 */
272void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
273{ 246{
274 struct iwl_phy_context_cmd cmd;
275 int ret;
276
277 lockdep_assert_held(&mvm->mutex); 247 lockdep_assert_held(&mvm->mutex);
278 248
279 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0); 249 if (WARN_ON_ONCE(!ctxt))
280 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC, 250 return;
281 sizeof(struct iwl_phy_context_cmd), 251
282 &cmd); 252 ctxt->ref--;
283 if (ret)
284 IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
285 ctxt->id);
286} 253}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index ed77e437aac4..67cf24aa72f9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -75,6 +75,54 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
79 struct iwl_beacon_filter_cmd *cmd)
80{
81 int ret;
82
83 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
84 sizeof(struct iwl_beacon_filter_cmd), cmd);
85
86 if (!ret) {
87 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
88 cmd->ba_enable_beacon_abort);
89 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
90 cmd->ba_escape_timer);
91 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
92 cmd->bf_debug_flag);
93 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
94 cmd->bf_enable_beacon_filter);
95 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
96 cmd->bf_energy_delta);
97 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
98 cmd->bf_escape_timer);
99 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
100 cmd->bf_roaming_energy_delta);
101 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
102 cmd->bf_roaming_state);
103 IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
104 cmd->bf_temperature_delta);
105 }
106 return ret;
107}
108
109static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
110 struct ieee80211_vif *vif, bool enable)
111{
112 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
113 struct iwl_beacon_filter_cmd cmd = {
114 IWL_BF_CMD_CONFIG_DEFAULTS,
115 .bf_enable_beacon_filter = 1,
116 .ba_enable_beacon_abort = enable,
117 };
118
119 if (!mvmvif->bf_enabled)
120 return 0;
121
122 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
123 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
124}
125
78static void iwl_mvm_power_log(struct iwl_mvm *mvm, 126static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd) 127 struct iwl_powertable_cmd *cmd)
80{ 128{
@@ -91,6 +139,9 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
91 le32_to_cpu(cmd->tx_data_timeout)); 139 le32_to_cpu(cmd->tx_data_timeout));
92 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", 140 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
93 cmd->lprx_rssi_threshold); 141 cmd->lprx_rssi_threshold);
142 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
143 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
144 le32_to_cpu(cmd->skip_dtim_periods));
94 } 145 }
95} 146}
96 147
@@ -103,6 +154,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
103 int dtimper, dtimper_msec; 154 int dtimper, dtimper_msec;
104 int keep_alive; 155 int keep_alive;
105 bool radar_detect = false; 156 bool radar_detect = false;
157 struct iwl_mvm_vif *mvmvif __maybe_unused =
158 iwl_mvm_vif_from_mac80211(vif);
106 159
107 /* 160 /*
108 * Regardless of power management state the driver must set 161 * Regardless of power management state the driver must set
@@ -116,6 +169,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
116 169
117 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 170 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
118 171
172#ifdef CONFIG_IWLWIFI_DEBUGFS
173 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
174 mvmvif->dbgfs_pm.disable_power_off)
175 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
176#endif
119 if (!vif->bss_conf.ps) 177 if (!vif->bss_conf.ps)
120 return; 178 return;
121 179
@@ -135,8 +193,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
135 193
136 /* Check skip over DTIM conditions */ 194 /* Check skip over DTIM conditions */
137 if (!radar_detect && (dtimper <= 10) && 195 if (!radar_detect && (dtimper <= 10) &&
138 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) 196 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
197 mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
139 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); 198 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
199 cmd->skip_dtim_periods = cpu_to_le32(3);
200 }
140 201
141 /* Check that keep alive period is at least 3 * DTIM */ 202 /* Check that keep alive period is at least 3 * DTIM */
142 dtimper_msec = dtimper * vif->bss_conf.beacon_int; 203 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
@@ -145,12 +206,41 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
145 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 206 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
146 cmd->keep_alive_seconds = keep_alive; 207 cmd->keep_alive_seconds = keep_alive;
147 208
148 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 209 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
149 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 210 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
211 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
212 } else {
213 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
214 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
215 }
216
217#ifdef CONFIG_IWLWIFI_DEBUGFS
218 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
219 cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds;
220 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
221 if (mvmvif->dbgfs_pm.skip_over_dtim)
222 cmd->flags |=
223 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
224 else
225 cmd->flags &=
226 cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK);
227 }
228 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT)
229 cmd->rx_data_timeout =
230 cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout);
231 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT)
232 cmd->tx_data_timeout =
233 cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
234 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
235 cmd->skip_dtim_periods =
236 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
237#endif /* CONFIG_IWLWIFI_DEBUGFS */
150} 238}
151 239
152int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 240int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
153{ 241{
242 int ret;
243 bool ba_enable;
154 struct iwl_powertable_cmd cmd = {}; 244 struct iwl_powertable_cmd cmd = {};
155 245
156 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 246 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
@@ -159,13 +249,22 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
159 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 249 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
160 iwl_mvm_power_log(mvm, &cmd); 250 iwl_mvm_power_log(mvm, &cmd);
161 251
162 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 252 ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
163 sizeof(cmd), &cmd); 253 sizeof(cmd), &cmd);
254 if (ret)
255 return ret;
256
257 ba_enable = !!(cmd.flags &
258 cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
259
260 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
164} 261}
165 262
166int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 263int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
167{ 264{
168 struct iwl_powertable_cmd cmd = {}; 265 struct iwl_powertable_cmd cmd = {};
266 struct iwl_mvm_vif *mvmvif __maybe_unused =
267 iwl_mvm_vif_from_mac80211(vif);
169 268
170 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 269 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
171 return 0; 270 return 0;
@@ -173,8 +272,82 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
173 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 272 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
174 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 273 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
175 274
275#ifdef CONFIG_IWLWIFI_DEBUGFS
276 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
277 mvmvif->dbgfs_pm.disable_power_off)
278 cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
279#endif
176 iwl_mvm_power_log(mvm, &cmd); 280 iwl_mvm_power_log(mvm, &cmd);
177 281
178 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 282 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
179 sizeof(cmd), &cmd); 283 sizeof(cmd), &cmd);
180} 284}
285
286#ifdef CONFIG_IWLWIFI_DEBUGFS
287void
288iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
289 struct iwl_beacon_filter_cmd *cmd)
290{
291 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
292 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
293
294 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA)
295 cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta;
296 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA)
297 cmd->bf_roaming_energy_delta =
298 dbgfs_bf->bf_roaming_energy_delta;
299 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE)
300 cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state;
301 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA)
302 cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta;
303 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG)
304 cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag;
305 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER)
306 cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer);
307 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER)
308 cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer);
309 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT)
310 cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort;
311}
312#endif
313
314int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
315 struct ieee80211_vif *vif)
316{
317 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
318 struct iwl_beacon_filter_cmd cmd = {
319 IWL_BF_CMD_CONFIG_DEFAULTS,
320 .bf_enable_beacon_filter = 1,
321 };
322 int ret;
323
324 if (mvmvif != mvm->bf_allowed_vif ||
325 vif->type != NL80211_IFTYPE_STATION || vif->p2p)
326 return 0;
327
328 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
329 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
330
331 if (!ret)
332 mvmvif->bf_enabled = true;
333
334 return ret;
335}
336
337int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
338 struct ieee80211_vif *vif)
339{
340 struct iwl_beacon_filter_cmd cmd = {};
341 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
342 int ret;
343
344 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
345 return 0;
346
347 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
348
349 if (!ret)
350 mvmvif->bf_enabled = false;
351
352 return ret;
353}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 55334d542e26..6a050c69e7d0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -3080,3 +3080,29 @@ void iwl_mvm_rate_control_unregister(void)
3080{ 3080{
3081 ieee80211_rate_control_unregister(&rs_mvm_ops); 3081 ieee80211_rate_control_unregister(&rs_mvm_ops);
3082} 3082}
3083
3084/**
3085 * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable
3086 * Tx protection, according to this rquest and previous requests,
3087 * and send the LQ command.
3088 * @lq: The LQ command
3089 * @mvmsta: The station
3090 * @enable: Enable Tx protection?
3091 */
3092int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
3093 struct iwl_mvm_sta *mvmsta, bool enable)
3094{
3095 lockdep_assert_held(&mvm->mutex);
3096
3097 if (enable) {
3098 if (mvmsta->tx_protection == 0)
3099 lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
3100 mvmsta->tx_protection++;
3101 } else {
3102 mvmsta->tx_protection--;
3103 if (mvmsta->tx_protection == 0)
3104 lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK;
3105 }
3106
3107 return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false);
3108}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 219c6857cc0f..f66155a57238 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -390,4 +390,9 @@ extern int iwl_mvm_rate_control_register(void);
390 */ 390 */
391extern void iwl_mvm_rate_control_unregister(void); 391extern void iwl_mvm_rate_control_unregister(void);
392 392
393struct iwl_mvm_sta;
394
395int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
396 struct iwl_mvm_sta *mvmsta, bool enable);
397
393#endif /* __rs__ */ 398#endif /* __rs__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 4dfc21a3e83e..e4930d5027d2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -363,3 +363,25 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
363 rxb, &rx_status); 363 rxb, &rx_status);
364 return 0; 364 return 0;
365} 365}
366
367/*
368 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler
369 *
370 * TODO: This handler is implemented partially.
371 * It only gets the NIC's temperature.
372 */
373int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
374 struct iwl_rx_cmd_buffer *rxb,
375 struct iwl_device_cmd *cmd)
376{
377 struct iwl_rx_packet *pkt = rxb_addr(rxb);
378 struct iwl_notif_statistics *stats = (void *)&pkt->data;
379 struct mvm_statistics_general_common *common = &stats->general.common;
380
381 if (mvm->temperature != le32_to_cpu(common->temperature)) {
382 mvm->temperature = le32_to_cpu(common->temperature);
383 iwl_mvm_tt_handler(mvm);
384 }
385
386 return 0;
387}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 0fd96e4da461..2278858d5658 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -64,6 +64,7 @@
64 64
65#include "mvm.h" 65#include "mvm.h"
66#include "sta.h" 66#include "sta.h"
67#include "rs.h"
67 68
68static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) 69static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
69{ 70{
@@ -217,9 +218,11 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
217 mvmvif->color); 218 mvmvif->color);
218 mvm_sta->vif = vif; 219 mvm_sta->vif = vif;
219 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 220 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
221 mvm_sta->tx_protection = 0;
222 mvm_sta->tt_tx_protection = false;
220 223
221 /* HW restart, don't assume the memory has been zeroed */ 224 /* HW restart, don't assume the memory has been zeroed */
222 atomic_set(&mvm_sta->pending_frames, 0); 225 atomic_set(&mvm->pending_frames[sta_id], 0);
223 mvm_sta->tid_disable_agg = 0; 226 mvm_sta->tid_disable_agg = 0;
224 mvm_sta->tfd_queue_msk = 0; 227 mvm_sta->tfd_queue_msk = 0;
225 for (i = 0; i < IEEE80211_NUM_ACS; i++) 228 for (i = 0; i < IEEE80211_NUM_ACS; i++)
@@ -407,14 +410,21 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
407 } 410 }
408 411
409 /* 412 /*
413 * Make sure that the tx response code sees the station as -EBUSY and
414 * calls the drain worker.
415 */
416 spin_lock_bh(&mvm_sta->lock);
417 /*
410 * There are frames pending on the AC queues for this station. 418 * There are frames pending on the AC queues for this station.
411 * We need to wait until all the frames are drained... 419 * We need to wait until all the frames are drained...
412 */ 420 */
413 if (atomic_read(&mvm_sta->pending_frames)) { 421 if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) {
414 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
415 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 422 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
416 ERR_PTR(-EBUSY)); 423 ERR_PTR(-EBUSY));
424 spin_unlock_bh(&mvm_sta->lock);
425 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
417 } else { 426 } else {
427 spin_unlock_bh(&mvm_sta->lock);
418 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); 428 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
419 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); 429 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
420 } 430 }
@@ -791,21 +801,23 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
791 min(mvmsta->max_agg_bufsize, buf_size); 801 min(mvmsta->max_agg_bufsize, buf_size);
792 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize; 802 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
793 803
804 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
805 sta->addr, tid);
806
794 if (mvm->cfg->ht_params->use_rts_for_aggregation) { 807 if (mvm->cfg->ht_params->use_rts_for_aggregation) {
795 /* 808 /*
796 * switch to RTS/CTS if it is the prefer protection 809 * switch to RTS/CTS if it is the prefer protection
797 * method for HT traffic 810 * method for HT traffic
811 * this function also sends the LQ command
798 */ 812 */
799 mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK; 813 return iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
814 mvmsta, true);
800 /* 815 /*
801 * TODO: remove the TLC_RTS flag when we tear down the last 816 * TODO: remove the TLC_RTS flag when we tear down the last
802 * AGG session (agg_tids_count in DVM) 817 * AGG session (agg_tids_count in DVM)
803 */ 818 */
804 } 819 }
805 820
806 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
807 sta->addr, tid);
808
809 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false); 821 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
810} 822}
811 823
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 12abd2d71835..3efa0a0cc987 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -274,8 +274,9 @@ struct iwl_mvm_tid_data {
274 * @bt_reduced_txpower: is reduced tx power enabled for this station 274 * @bt_reduced_txpower: is reduced tx power enabled for this station
275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx 275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
276 * and from Tx response flow, it needs a spinlock. 276 * and from Tx response flow, it needs a spinlock.
277 * @pending_frames: number of frames for this STA on the shared Tx queues.
278 * @tid_data: per tid data. Look at %iwl_mvm_tid_data. 277 * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
278 * @tx_protection: reference counter for controlling the Tx protection.
279 * @tt_tx_protection: is thermal throttling enable Tx protection?
279 * 280 *
280 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 281 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
281 * in the structure for use by driver. This structure is placed in that 282 * in the structure for use by driver. This structure is placed in that
@@ -290,7 +291,6 @@ struct iwl_mvm_sta {
290 u8 max_agg_bufsize; 291 u8 max_agg_bufsize;
291 bool bt_reduced_txpower; 292 bool bt_reduced_txpower;
292 spinlock_t lock; 293 spinlock_t lock;
293 atomic_t pending_frames;
294 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; 294 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
295 struct iwl_lq_sta lq_sta; 295 struct iwl_lq_sta lq_sta;
296 struct ieee80211_vif *vif; 296 struct ieee80211_vif *vif;
@@ -298,6 +298,10 @@ struct iwl_mvm_sta {
298#ifdef CONFIG_PM_SLEEP 298#ifdef CONFIG_PM_SLEEP
299 u16 last_seq_ctl; 299 u16 last_seq_ctl;
300#endif 300#endif
301
302 /* Temporary, until the new TLC will control the Tx protection */
303 s8 tx_protection;
304 bool tt_tx_protection;
301}; 305};
302 306
303/** 307/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
new file mode 100644
index 000000000000..4665fc033c17
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -0,0 +1,509 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include "mvm.h"
65#include "iwl-config.h"
66#include "iwl-io.h"
67#include "iwl-csr.h"
68#include "iwl-prph.h"
69
70#define OTP_DTS_DIODE_DEVIATION 96 /*in words*/
71/* VBG - Voltage Band Gap error data (temperature offset) */
72#define OTP_WP_DTS_VBG (OTP_DTS_DIODE_DEVIATION + 2)
73#define MEAS_VBG_MIN_VAL 2300
74#define MEAS_VBG_MAX_VAL 3000
75#define MEAS_VBG_DEFAULT_VAL 2700
76#define DTS_DIODE_VALID(flags) (flags & DTS_DIODE_REG_FLAGS_PASS_ONCE)
77#define MIN_TEMPERATURE 0
78#define MAX_TEMPERATURE 125
79#define TEMPERATURE_ERROR (MAX_TEMPERATURE + 1)
80#define PTAT_DIGITAL_VALUE_MIN_VALUE 0
81#define PTAT_DIGITAL_VALUE_MAX_VALUE 0xFF
82#define DTS_VREFS_NUM 5
83static inline u32 DTS_DIODE_GET_VREFS_ID(u32 flags)
84{
85 return (flags & DTS_DIODE_REG_FLAGS_VREFS_ID) >>
86 DTS_DIODE_REG_FLAGS_VREFS_ID_POS;
87}
88
89#define CALC_VREFS_MIN_DIFF 43
90#define CALC_VREFS_MAX_DIFF 51
91#define CALC_LUT_SIZE (1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF)
92#define CALC_LUT_INDEX_OFFSET CALC_VREFS_MIN_DIFF
93#define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET 23
94
95/*
96 * @digital_value: The diode's digital-value sampled (temperature/voltage)
97 * @vref_low: The lower voltage-reference (the vref just below the diode's
98 * sampled digital-value)
99 * @vref_high: The higher voltage-reference (the vref just above the diode's
100 * sampled digital-value)
101 * @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref)
102 * bits[6:2]: Reserved.
103 * bits[7:7]: Indicates completion of at least 1 successful sample
104 * since last DTS reset.
105 */
106struct iwl_mvm_dts_diode_bits {
107 u8 digital_value;
108 u8 vref_low;
109 u8 vref_high;
110 u8 flags;
111} __packed;
112
113union dts_diode_results {
114 u32 reg_value;
115 struct iwl_mvm_dts_diode_bits bits;
116} __packed;
117
118static s16 iwl_mvm_dts_get_volt_band_gap(struct iwl_mvm *mvm)
119{
120 struct iwl_nvm_section calib_sec;
121 const __le16 *calib;
122 u16 vbg;
123
124 /* TODO: move parsing to NVM code */
125 calib_sec = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION];
126 calib = (__le16 *)calib_sec.data;
127
128 vbg = le16_to_cpu(calib[OTP_WP_DTS_VBG]);
129
130 if (vbg < MEAS_VBG_MIN_VAL || vbg > MEAS_VBG_MAX_VAL)
131 vbg = MEAS_VBG_DEFAULT_VAL;
132
133 return vbg;
134}
135
136static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm)
137{
138 const u8 *calib;
139 u8 ptat, pa1, pa2, median;
140
141 /* TODO: move parsing to NVM code */
142 calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data;
143 ptat = calib[OTP_DTS_DIODE_DEVIATION];
144 pa1 = calib[OTP_DTS_DIODE_DEVIATION + 1];
145 pa2 = calib[OTP_DTS_DIODE_DEVIATION + 2];
146
147 /* get the median: */
148 if (ptat > pa1) {
149 if (ptat > pa2)
150 median = (pa1 > pa2) ? pa1 : pa2;
151 else
152 median = ptat;
153 } else {
154 if (pa1 > pa2)
155 median = (ptat > pa2) ? ptat : pa2;
156 else
157 median = pa1;
158 }
159
160 return ptat - median;
161}
162
163static u8 iwl_mvm_dts_calibrate_ptat_deviation(struct iwl_mvm *mvm, u8 value)
164{
165 /* Calibrate the PTAT digital value, based on PTAT deviation data: */
166 s16 new_val = value - iwl_mvm_dts_get_ptat_deviation_offset(mvm);
167
168 if (new_val > PTAT_DIGITAL_VALUE_MAX_VALUE)
169 new_val = PTAT_DIGITAL_VALUE_MAX_VALUE;
170 else if (new_val < PTAT_DIGITAL_VALUE_MIN_VALUE)
171 new_val = PTAT_DIGITAL_VALUE_MIN_VALUE;
172
173 return new_val;
174}
175
176static bool dts_get_adjacent_vrefs(struct iwl_mvm *mvm,
177 union dts_diode_results *avg_ptat)
178{
179 u8 vrefs_results[DTS_VREFS_NUM];
180 u8 low_vref_index = 0, flags;
181 u32 reg;
182
183 reg = iwl_read_prph(mvm->trans, DTSC_VREF_AVG);
184 memcpy(vrefs_results, &reg, sizeof(reg));
185 reg = iwl_read_prph(mvm->trans, DTSC_VREF5_AVG);
186 vrefs_results[4] = reg & 0xff;
187
188 if (avg_ptat->bits.digital_value < vrefs_results[0] ||
189 avg_ptat->bits.digital_value > vrefs_results[4])
190 return false;
191
192 if (avg_ptat->bits.digital_value > vrefs_results[3])
193 low_vref_index = 3;
194 else if (avg_ptat->bits.digital_value > vrefs_results[2])
195 low_vref_index = 2;
196 else if (avg_ptat->bits.digital_value > vrefs_results[1])
197 low_vref_index = 1;
198
199 avg_ptat->bits.vref_low = vrefs_results[low_vref_index];
200 avg_ptat->bits.vref_high = vrefs_results[low_vref_index + 1];
201 flags = avg_ptat->bits.flags;
202 avg_ptat->bits.flags =
203 (flags & ~DTS_DIODE_REG_FLAGS_VREFS_ID) |
204 (low_vref_index & DTS_DIODE_REG_FLAGS_VREFS_ID);
205 return true;
206}
207
208/*
209 * return true it the results are valid, and false otherwise.
210 */
211static bool dts_read_ptat_avg_results(struct iwl_mvm *mvm,
212 union dts_diode_results *avg_ptat)
213{
214 u32 reg;
215 u8 tmp;
216
217 /* fill the diode value and pass_once with avg-reg results */
218 reg = iwl_read_prph(mvm->trans, DTSC_PTAT_AVG);
219 reg &= DTS_DIODE_REG_DIG_VAL | DTS_DIODE_REG_PASS_ONCE;
220 avg_ptat->reg_value = reg;
221
222 /* calibrate the PTAT digital value */
223 tmp = avg_ptat->bits.digital_value;
224 tmp = iwl_mvm_dts_calibrate_ptat_deviation(mvm, tmp);
225 avg_ptat->bits.digital_value = tmp;
226
227 /*
228 * fill vrefs fields, based on the avgVrefs results
229 * and the diode value
230 */
231 return dts_get_adjacent_vrefs(mvm, avg_ptat) &&
232 DTS_DIODE_VALID(avg_ptat->bits.flags);
233}
234
235static s32 calculate_nic_temperature(union dts_diode_results avg_ptat,
236 u16 volt_band_gap)
237{
238 u32 tmp_result;
239 u8 vrefs_diff;
240 /*
241 * For temperature calculation (at the end, shift right by 23)
242 * LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) }
243 * (D2-D1) == 43 44 45 46 47 48 49 50 51
244 */
245 static const u16 calc_lut[CALC_LUT_SIZE] = {
246 2168, 2118, 2071, 2026, 1983, 1942, 1902, 1864, 1828,
247 };
248
249 /*
250 * The diff between the high and low voltage-references is assumed
251 * to be strictly be in range of [60,68]
252 */
253 vrefs_diff = avg_ptat.bits.vref_high - avg_ptat.bits.vref_low;
254
255 if (vrefs_diff < CALC_VREFS_MIN_DIFF ||
256 vrefs_diff > CALC_VREFS_MAX_DIFF)
257 return TEMPERATURE_ERROR;
258
259 /* calculate the result: */
260 tmp_result =
261 vrefs_diff * (DTS_DIODE_GET_VREFS_ID(avg_ptat.bits.flags) + 9);
262 tmp_result += avg_ptat.bits.digital_value;
263 tmp_result -= avg_ptat.bits.vref_high;
264
265 /* multiply by the LUT value (based on the diff) */
266 tmp_result *= calc_lut[vrefs_diff - CALC_LUT_INDEX_OFFSET];
267
268 /*
269 * Get the BandGap (the voltage refereces source) error data
270 * (temperature offset)
271 */
272 tmp_result *= volt_band_gap;
273
274 /*
275 * here, tmp_result value can be up to 32-bits. We want to right-shift
276 * it *without* sign-extend.
277 */
278 tmp_result = tmp_result >> CALC_TEMPERATURE_RESULT_SHIFT_OFFSET;
279
280 /*
281 * at this point, tmp_result should be in the range:
282 * 200 <= tmp_result <= 365
283 */
284 return (s16)tmp_result - 240;
285}
286
287static s32 check_nic_temperature(struct iwl_mvm *mvm)
288{
289 u16 volt_band_gap;
290 union dts_diode_results avg_ptat;
291
292 volt_band_gap = iwl_mvm_dts_get_volt_band_gap(mvm);
293
294 /* disable DTS */
295 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
296
297 /* SV initialization */
298 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 1);
299 iwl_write_prph(mvm->trans, DTSC_CFG_MODE,
300 DTSC_CFG_MODE_PERIODIC);
301
302 /* wait for results */
303 msleep(100);
304 if (!dts_read_ptat_avg_results(mvm, &avg_ptat))
305 return TEMPERATURE_ERROR;
306
307 /* disable DTS */
308 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
309
310 return calculate_nic_temperature(avg_ptat, volt_band_gap);
311}
312
313static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
314{
315 u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
316
317 IWL_ERR(mvm, "Enter CT Kill\n");
318 iwl_mvm_set_hw_ctkill_state(mvm, true);
319 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
320 round_jiffies_relative(duration * HZ));
321}
322
323static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
324{
325 IWL_ERR(mvm, "Exit CT Kill\n");
326 iwl_mvm_set_hw_ctkill_state(mvm, false);
327}
328
329static void check_exit_ctkill(struct work_struct *work)
330{
331 struct iwl_mvm_tt_mgmt *tt;
332 struct iwl_mvm *mvm;
333 u32 duration;
334 s32 temp;
335
336 tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work);
337 mvm = container_of(tt, struct iwl_mvm, thermal_throttle);
338
339 duration = tt->params->ct_kill_duration;
340
341 iwl_trans_start_hw(mvm->trans);
342 temp = check_nic_temperature(mvm);
343 iwl_trans_stop_hw(mvm->trans, false);
344
345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
347 goto reschedule;
348 }
349 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp);
350
351 if (temp <= tt->params->ct_kill_exit) {
352 iwl_mvm_exit_ctkill(mvm);
353 return;
354 }
355
356reschedule:
357 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
358 round_jiffies(duration * HZ));
359}
360
361static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
362 struct ieee80211_vif *vif)
363{
364 struct iwl_mvm *mvm = _data;
365 enum ieee80211_smps_mode smps_mode;
366
367 lockdep_assert_held(&mvm->mutex);
368
369 if (mvm->thermal_throttle.dynamic_smps)
370 smps_mode = IEEE80211_SMPS_DYNAMIC;
371 else
372 smps_mode = IEEE80211_SMPS_AUTOMATIC;
373
374 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, smps_mode);
375}
376
377static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
378{
379 struct ieee80211_sta *sta;
380 struct iwl_mvm_sta *mvmsta;
381 int i, err;
382
383 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
384 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
385 lockdep_is_held(&mvm->mutex));
386 if (IS_ERR_OR_NULL(sta))
387 continue;
388 mvmsta = (void *)sta->drv_priv;
389 if (enable == mvmsta->tt_tx_protection)
390 continue;
391 err = iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
392 mvmsta, enable);
393 if (err) {
394 IWL_ERR(mvm, "Failed to %s Tx protection\n",
395 enable ? "enable" : "disable");
396 } else {
397 IWL_DEBUG_TEMP(mvm, "%s Tx protection\n",
398 enable ? "Enable" : "Disable");
399 mvmsta->tt_tx_protection = enable;
400 }
401 }
402}
403
404static void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff)
405{
406 struct iwl_host_cmd cmd = {
407 .id = REPLY_THERMAL_MNG_BACKOFF,
408 .len = { sizeof(u32), },
409 .data = { &backoff, },
410 .flags = CMD_SYNC,
411 };
412
413 if (iwl_mvm_send_cmd(mvm, &cmd) == 0) {
414 IWL_DEBUG_TEMP(mvm, "Set Thermal Tx backoff to: %u\n",
415 backoff);
416 mvm->thermal_throttle.tx_backoff = backoff;
417 } else {
418 IWL_ERR(mvm, "Failed to change Thermal Tx backoff\n");
419 }
420}
421
422void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
423{
424 const struct iwl_tt_params *params = mvm->thermal_throttle.params;
425 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
426 s32 temperature = mvm->temperature;
427 int i;
428 u32 tx_backoff;
429
430 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", mvm->temperature);
431
432 if (params->support_ct_kill && temperature >= params->ct_kill_entry) {
433 iwl_mvm_enter_ctkill(mvm);
434 return;
435 }
436
437 if (params->support_dynamic_smps) {
438 if (!tt->dynamic_smps &&
439 temperature >= params->dynamic_smps_entry) {
440 IWL_DEBUG_TEMP(mvm, "Enable dynamic SMPS\n");
441 tt->dynamic_smps = true;
442 ieee80211_iterate_active_interfaces_atomic(
443 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
444 iwl_mvm_tt_smps_iterator, mvm);
445 } else if (tt->dynamic_smps &&
446 temperature <= params->dynamic_smps_exit) {
447 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n");
448 tt->dynamic_smps = false;
449 ieee80211_iterate_active_interfaces_atomic(
450 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
451 iwl_mvm_tt_smps_iterator, mvm);
452 }
453 }
454
455 if (params->support_tx_protection) {
456 if (temperature >= params->tx_protection_entry)
457 iwl_mvm_tt_tx_protection(mvm, true);
458 else if (temperature <= params->tx_protection_exit)
459 iwl_mvm_tt_tx_protection(mvm, false);
460 }
461
462 if (params->support_tx_backoff) {
463 tx_backoff = 0;
464 for (i = 0; i < TT_TX_BACKOFF_SIZE; i++) {
465 if (temperature < params->tx_backoff[i].temperature)
466 break;
467 tx_backoff = params->tx_backoff[i].backoff;
468 }
469 if (tt->tx_backoff != tx_backoff)
470 iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
471 }
472}
473
474static const struct iwl_tt_params iwl7000_tt_params = {
475 .ct_kill_entry = 118,
476 .ct_kill_exit = 96,
477 .ct_kill_duration = 5,
478 .dynamic_smps_entry = 114,
479 .dynamic_smps_exit = 110,
480 .tx_protection_entry = 114,
481 .tx_protection_exit = 108,
482 .tx_backoff = {
483 {.temperature = 112, .backoff = 200},
484 {.temperature = 113, .backoff = 600},
485 {.temperature = 114, .backoff = 1200},
486 {.temperature = 115, .backoff = 2000},
487 {.temperature = 116, .backoff = 4000},
488 {.temperature = 117, .backoff = 10000},
489 },
490 .support_ct_kill = true,
491 .support_dynamic_smps = true,
492 .support_tx_protection = true,
493 .support_tx_backoff = true,
494};
495
496void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
497{
498 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
499
500 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
501 tt->params = &iwl7000_tt_params;
502 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
503}
504
505void iwl_mvm_tt_exit(struct iwl_mvm *mvm)
506{
507 cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit);
508 IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n");
509}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 479074303bd7..f212f16502ff 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
416 416
417 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
418 418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP && 419 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE)
420 txq_id < IWL_MVM_FIRST_AGG_QUEUE) 420 atomic_inc(&mvm->pending_frames[mvmsta->sta_id]);
421 atomic_inc(&mvmsta->pending_frames);
422 421
423 return 0; 422 return 0;
424 423
@@ -680,16 +679,41 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
680 /* 679 /*
681 * If the txq is not an AMPDU queue, there is no chance we freed 680 * If the txq is not an AMPDU queue, there is no chance we freed
682 * several skbs. Check that out... 681 * several skbs. Check that out...
683 * If there are no pending frames for this STA, notify mac80211 that
684 * this station can go to sleep in its STA table.
685 */ 682 */
686 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta && 683 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) &&
687 !WARN_ON(skb_freed > 1) && 684 atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
688 mvmsta->vif->type == NL80211_IFTYPE_AP && 685 if (mvmsta) {
689 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { 686 /*
690 ieee80211_sta_block_awake(mvm->hw, sta, false); 687 * If there are no pending frames for this STA, notify
691 set_bit(sta_id, mvm->sta_drained); 688 * mac80211 that this station can go to sleep in its
692 schedule_work(&mvm->sta_drained_wk); 689 * STA table.
690 */
691 if (mvmsta->vif->type == NL80211_IFTYPE_AP)
692 ieee80211_sta_block_awake(mvm->hw, sta, false);
693 /*
694 * We might very well have taken mvmsta pointer while
695 * the station was being removed. The remove flow might
696 * have seen a pending_frame (because we didn't take
697 * the lock) even if now the queues are drained. So make
698 * really sure now that this the station is not being
699 * removed. If it is, run the drain worker to remove it.
700 */
701 spin_lock_bh(&mvmsta->lock);
702 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
703 if (IS_ERR_OR_NULL(sta)) {
704 /*
705 * Station disappeared in the meantime:
706 * so we are draining.
707 */
708 set_bit(sta_id, mvm->sta_drained);
709 schedule_work(&mvm->sta_drained_wk);
710 }
711 spin_unlock_bh(&mvmsta->lock);
712 } else if (!mvmsta) {
713 /* Tx response without STA, so we are draining */
714 set_bit(sta_id, mvm->sta_drained);
715 schedule_work(&mvm->sta_drained_wk);
716 }
693 } 717 }
694 718
695 rcu_read_unlock(); 719 rcu_read_unlock();
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 687b34e387ac..c9b44ab4af07 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -471,3 +471,34 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
471 471
472 return iwl_mvm_send_cmd(mvm, &cmd); 472 return iwl_mvm_send_cmd(mvm, &cmd);
473} 473}
474
475/**
476 * iwl_mvm_update_smps - Get a requst to change the SMPS mode
477 * @req_type: The part of the driver who call for a change.
478 * @smps_requests: The request to change the SMPS mode.
479 *
480 * Get a requst to change the SMPS mode,
481 * and change it according to all other requests in the driver.
482 */
483void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
484 enum iwl_mvm_smps_type_request req_type,
485 enum ieee80211_smps_mode smps_request)
486{
487 struct iwl_mvm_vif *mvmvif;
488 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
489 int i;
490
491 lockdep_assert_held(&mvm->mutex);
492 mvmvif = iwl_mvm_vif_from_mac80211(vif);
493 mvmvif->smps_requests[req_type] = smps_request;
494 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
495 if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC) {
496 smps_mode = IEEE80211_SMPS_STATIC;
497 break;
498 }
499 if (mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
500 smps_mode = IEEE80211_SMPS_DYNAMIC;
501 }
502
503 ieee80211_request_smps(vif, smps_mode);
504}
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 8cb53ec2b77b..db7bdd35a9c5 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -256,10 +256,54 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
256 256
257/* 7000 Series */ 257/* 7000 Series */
258 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, 258 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
259 {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_2ac_cfg)}, 259 {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
261 {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
262 {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
263 {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
264 {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
265 {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
266 {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
267 {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
268 {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
269 {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
270 {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
271 {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
272 {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg)},
273 {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg)},
274 {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg)},
275 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
276 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
277 {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, 278 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
261 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)}, 279 {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
262 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)}, 280 {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
281 {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
282 {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
283 {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
284 {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
285 {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
286 {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
287 {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
288 {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
289 {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
290 {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
291 {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
292 {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
293
294/* 3160 Series */
295 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
296 {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
297 {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
298 {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
299 {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
301 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
302 {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
303 {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
304 {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
305 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
306 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
263 307
264 {0} 308 {0}
265}; 309};
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 50ba0a468f94..0b021305eedf 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -405,20 +405,27 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
405{ 405{
406 u8 *v_addr; 406 u8 *v_addr;
407 dma_addr_t p_addr; 407 dma_addr_t p_addr;
408 u32 offset; 408 u32 offset, chunk_sz = section->len;
409 int ret = 0; 409 int ret = 0;
410 410
411 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", 411 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
412 section_num); 412 section_num);
413 413
414 v_addr = dma_alloc_coherent(trans->dev, PAGE_SIZE, &p_addr, GFP_KERNEL); 414 v_addr = dma_alloc_coherent(trans->dev, chunk_sz, &p_addr,
415 if (!v_addr) 415 GFP_KERNEL | __GFP_NOWARN);
416 return -ENOMEM; 416 if (!v_addr) {
417 IWL_DEBUG_INFO(trans, "Falling back to small chunks of DMA\n");
418 chunk_sz = PAGE_SIZE;
419 v_addr = dma_alloc_coherent(trans->dev, chunk_sz,
420 &p_addr, GFP_KERNEL);
421 if (!v_addr)
422 return -ENOMEM;
423 }
417 424
418 for (offset = 0; offset < section->len; offset += PAGE_SIZE) { 425 for (offset = 0; offset < section->len; offset += chunk_sz) {
419 u32 copy_size; 426 u32 copy_size;
420 427
421 copy_size = min_t(u32, PAGE_SIZE, section->len - offset); 428 copy_size = min_t(u32, chunk_sz, section->len - offset);
422 429
423 memcpy(v_addr, (u8 *)section->data + offset, copy_size); 430 memcpy(v_addr, (u8 *)section->data + offset, copy_size);
424 ret = iwl_pcie_load_firmware_chunk(trans, 431 ret = iwl_pcie_load_firmware_chunk(trans,
@@ -432,7 +439,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
432 } 439 }
433 } 440 }
434 441
435 dma_free_coherent(trans->dev, PAGE_SIZE, v_addr, p_addr); 442 dma_free_coherent(trans->dev, chunk_sz, v_addr, p_addr);
436 return ret; 443 return ret;
437} 444}
438 445
@@ -573,10 +580,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
573 580
574static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans) 581static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans)
575{ 582{
576 /* let the ucode operate on its own */
577 iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
578 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
579
580 iwl_disable_interrupts(trans); 583 iwl_disable_interrupts(trans);
581 iwl_pcie_disable_ict(trans); 584 iwl_pcie_disable_ict(trans);
582 585
@@ -636,9 +639,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
636 return ret; 639 return ret;
637 } 640 }
638 641
639 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
640 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
641
642 *status = IWL_D3_STATUS_ALIVE; 642 *status = IWL_D3_STATUS_ALIVE;
643 return 0; 643 return 0;
644} 644}
@@ -917,11 +917,11 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
917} 917}
918 918
919static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, 919static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
920 void *buf, int dwords) 920 const void *buf, int dwords)
921{ 921{
922 unsigned long flags; 922 unsigned long flags;
923 int offs, ret = 0; 923 int offs, ret = 0;
924 u32 *vals = buf; 924 const u32 *vals = buf;
925 925
926 if (iwl_trans_grab_nic_access(trans, false, &flags)) { 926 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
927 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 927 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index c5e30294c5ac..bf5f8246385e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1045,6 +1045,10 @@ static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans,
1045 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); 1045 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1046} 1046}
1047 1047
1048/* Receiver address (actually, Rx station's index into station table),
1049 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
1050#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1051
1048void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 1052void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
1049 int sta_id, int tid, int frame_limit, u16 ssn) 1053 int sta_id, int tid, int frame_limit, u16 ssn)
1050{ 1054{
@@ -1518,6 +1522,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1518 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { 1522 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
1519 IWL_ERR(trans, "FW error in SYNC CMD %s\n", 1523 IWL_ERR(trans, "FW error in SYNC CMD %s\n",
1520 get_cmd_string(trans_pcie, cmd->id)); 1524 get_cmd_string(trans_pcie, cmd->id));
1525 dump_stack();
1521 ret = -EIO; 1526 ret = -EIO;
1522 goto cancel; 1527 goto cancel;
1523 } 1528 }
@@ -1564,7 +1569,8 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1564 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) 1569 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1565 return -EIO; 1570 return -EIO;
1566 1571
1567 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { 1572 if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
1573 test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1568 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", 1574 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
1569 cmd->id); 1575 cmd->id);
1570 return -ERFKILL; 1576 return -ERFKILL;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index af79daa331d0..00a82817eb6b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2282,9 +2282,6 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2282 if (wdev->netdev->reg_state == NETREG_REGISTERED) 2282 if (wdev->netdev->reg_state == NETREG_REGISTERED)
2283 unregister_netdevice(wdev->netdev); 2283 unregister_netdevice(wdev->netdev);
2284 2284
2285 if (wdev->netdev->reg_state == NETREG_UNREGISTERED)
2286 free_netdev(wdev->netdev);
2287
2288 /* Clear the priv in adapter */ 2285 /* Clear the priv in adapter */
2289 priv->netdev = NULL; 2286 priv->netdev = NULL;
2290 2287
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 4a32f2795c64..2d761477d15e 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1192,6 +1192,7 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
1192 adapter->if_ops.wakeup(adapter); 1192 adapter->if_ops.wakeup(adapter);
1193 adapter->hs_activated = false; 1193 adapter->hs_activated = false;
1194 adapter->is_hs_configured = false; 1194 adapter->is_hs_configured = false;
1195 adapter->is_suspended = false;
1195 mwifiex_hs_activated_event(mwifiex_get_priv(adapter, 1196 mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
1196 MWIFIEX_BSS_ROLE_ANY), 1197 MWIFIEX_BSS_ROLE_ANY),
1197 false); 1198 false);
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 29d83f0c1fb8..5bc7ef8d04d6 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -669,6 +669,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
669 struct net_device *dev) 669 struct net_device *dev)
670{ 670{
671 dev->netdev_ops = &mwifiex_netdev_ops; 671 dev->netdev_ops = &mwifiex_netdev_ops;
672 dev->destructor = free_netdev;
672 /* Initialize private structure */ 673 /* Initialize private structure */
673 priv->current_key_index = 0; 674 priv->current_key_index = 0;
674 priv->media_connected = false; 675 priv->media_connected = false;
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 311d0b26b81c..1a8a19dbd635 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -96,7 +96,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
96 } else { 96 } else {
97 /* Multicast */ 97 /* Multicast */
98 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; 98 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
99 if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) { 99 if (mcast_list->mode == MWIFIEX_ALL_MULTI_MODE) {
100 dev_dbg(priv->adapter->dev, 100 dev_dbg(priv->adapter->dev,
101 "info: Enabling All Multicast!\n"); 101 "info: Enabling All Multicast!\n");
102 priv->curr_pkt_filter |= 102 priv->curr_pkt_filter |=
@@ -108,20 +108,11 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
108 dev_dbg(priv->adapter->dev, 108 dev_dbg(priv->adapter->dev,
109 "info: Set multicast list=%d\n", 109 "info: Set multicast list=%d\n",
110 mcast_list->num_multicast_addr); 110 mcast_list->num_multicast_addr);
111 /* Set multicast addresses to firmware */ 111 /* Send multicast addresses to firmware */
112 if (old_pkt_filter == priv->curr_pkt_filter) { 112 ret = mwifiex_send_cmd_async(priv,
113 /* Send request to firmware */ 113 HostCmd_CMD_MAC_MULTICAST_ADR,
114 ret = mwifiex_send_cmd_async(priv, 114 HostCmd_ACT_GEN_SET, 0,
115 HostCmd_CMD_MAC_MULTICAST_ADR, 115 mcast_list);
116 HostCmd_ACT_GEN_SET, 0,
117 mcast_list);
118 } else {
119 /* Send request to firmware */
120 ret = mwifiex_send_cmd_async(priv,
121 HostCmd_CMD_MAC_MULTICAST_ADR,
122 HostCmd_ACT_GEN_SET, 0,
123 mcast_list);
124 }
125 } 116 }
126 } 117 }
127 } 118 }