diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-09-04 13:45:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-04 13:45:56 -0400 |
commit | d17ec4d55223d9487df195012762da6f85862d4c (patch) | |
tree | 7dd8d60ed5f642add44b53f67c5a987b1145a030 | |
parent | ef4ead3f29256ed83991cd77b39334aadd25672a (diff) | |
parent | 712b24adc105518f7cbbb6f9f353efea48954bb9 (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
57 files changed, 1053 insertions, 315 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 6451d2b6abcf..760e96f63bb0 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -87,6 +87,16 @@ config IWLWIFI_BCAST_FILTERING | |||
87 | If unsure, don't enable this option, as some programs might | 87 | If unsure, don't enable this option, as some programs might |
88 | expect incoming broadcasts for their normal operations. | 88 | expect incoming broadcasts for their normal operations. |
89 | 89 | ||
90 | config IWLWIFI_UAPSD | ||
91 | bool "enable U-APSD by default" | ||
92 | depends on IWLMVM | ||
93 | help | ||
94 | Say Y here to enable U-APSD by default. This may cause | ||
95 | interoperability problems with some APs, manifesting in lower than | ||
96 | expected throughput due to those APs not enabling aggregation | ||
97 | |||
98 | If unsure, say N. | ||
99 | |||
90 | menu "Debugging Options" | 100 | menu "Debugging Options" |
91 | 101 | ||
92 | config IWLWIFI_DEBUG | 102 | config IWLWIFI_DEBUG |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 3255a1723d17..d1ce3ce13591 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -580,7 +580,7 @@ turn_off: | |||
580 | * time, or we hadn't time to drain the AC queues. | 580 | * time, or we hadn't time to drain the AC queues. |
581 | */ | 581 | */ |
582 | if (agg_state == IWL_AGG_ON) | 582 | if (agg_state == IWL_AGG_ON) |
583 | iwl_trans_txq_disable(priv->trans, txq_id); | 583 | iwl_trans_txq_disable(priv->trans, txq_id, true); |
584 | else | 584 | else |
585 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | 585 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", |
586 | agg_state); | 586 | agg_state); |
@@ -686,7 +686,7 @@ int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
686 | * time, or we hadn't time to drain the AC queues. | 686 | * time, or we hadn't time to drain the AC queues. |
687 | */ | 687 | */ |
688 | if (agg_state == IWL_AGG_ON) | 688 | if (agg_state == IWL_AGG_ON) |
689 | iwl_trans_txq_disable(priv->trans, txq_id); | 689 | iwl_trans_txq_disable(priv->trans, txq_id, true); |
690 | else | 690 | else |
691 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | 691 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", |
692 | agg_state); | 692 | agg_state); |
@@ -781,7 +781,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | |||
781 | "Can continue DELBA flow ssn = next_recl = %d\n", | 781 | "Can continue DELBA flow ssn = next_recl = %d\n", |
782 | tid_data->next_reclaimed); | 782 | tid_data->next_reclaimed); |
783 | iwl_trans_txq_disable(priv->trans, | 783 | iwl_trans_txq_disable(priv->trans, |
784 | tid_data->agg.txq_id); | 784 | tid_data->agg.txq_id, true); |
785 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); | 785 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); |
786 | tid_data->agg.state = IWL_AGG_OFF; | 786 | tid_data->agg.state = IWL_AGG_OFF; |
787 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | 787 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 48730064da73..446654aed017 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 44b19e015102..90388e70db9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index fe129c94ae3e..23d059af6476 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 295083510e72..0a70bcd241f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -145,6 +145,7 @@ do { \ | |||
145 | #define IWL_DL_HCMD 0x00000004 | 145 | #define IWL_DL_HCMD 0x00000004 |
146 | #define IWL_DL_STATE 0x00000008 | 146 | #define IWL_DL_STATE 0x00000008 |
147 | /* 0x000000F0 - 0x00000010 */ | 147 | /* 0x000000F0 - 0x00000010 */ |
148 | #define IWL_DL_QUOTA 0x00000010 | ||
148 | #define IWL_DL_TE 0x00000020 | 149 | #define IWL_DL_TE 0x00000020 |
149 | #define IWL_DL_EEPROM 0x00000040 | 150 | #define IWL_DL_EEPROM 0x00000040 |
150 | #define IWL_DL_RADIO 0x00000080 | 151 | #define IWL_DL_RADIO 0x00000080 |
@@ -189,6 +190,7 @@ do { \ | |||
189 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) | 190 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) |
190 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) | 191 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) |
191 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) | 192 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) |
193 | #define IWL_DEBUG_QUOTA(p, f, a...) IWL_DEBUG(p, IWL_DL_QUOTA, f, ## a) | ||
192 | #define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a) | 194 | #define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a) |
193 | #define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) | 195 | #define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) |
194 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) | 196 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 23e7351e02de..90987d6f348e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -36,15 +36,8 @@ | |||
36 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8); | 36 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8); |
37 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); | 37 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32); |
38 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); | 38 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32); |
39 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); | ||
40 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_tx); | ||
41 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); | 39 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); |
42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); | 40 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); |
43 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); | 41 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); |
44 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); | 42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); |
45 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_info); | ||
46 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_warn); | ||
47 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_crit); | ||
48 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_err); | ||
49 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dbg); | ||
50 | #endif | 43 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 77e3178040b2..aefd94cb6e91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -1254,7 +1256,9 @@ struct iwl_mod_params iwlwifi_mod_params = { | |||
1254 | .bt_coex_active = true, | 1256 | .bt_coex_active = true, |
1255 | .power_level = IWL_POWER_INDEX_1, | 1257 | .power_level = IWL_POWER_INDEX_1, |
1256 | .wd_disable = true, | 1258 | .wd_disable = true, |
1257 | .uapsd_disable = false, | 1259 | #ifndef CONFIG_IWLWIFI_UAPSD |
1260 | .uapsd_disable = true, | ||
1261 | #endif /* CONFIG_IWLWIFI_UAPSD */ | ||
1258 | /* the rest are 0 by default */ | 1262 | /* the rest are 0 by default */ |
1259 | }; | 1263 | }; |
1260 | IWL_EXPORT_SYMBOL(iwlwifi_mod_params); | 1264 | IWL_EXPORT_SYMBOL(iwlwifi_mod_params); |
@@ -1370,7 +1374,11 @@ MODULE_PARM_DESC(nvm_file, "NVM file name"); | |||
1370 | 1374 | ||
1371 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, | 1375 | module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, |
1372 | bool, S_IRUGO); | 1376 | bool, S_IRUGO); |
1377 | #ifdef CONFIG_IWLWIFI_UAPSD | ||
1373 | MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); | 1378 | MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); |
1379 | #else | ||
1380 | MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: Y)"); | ||
1381 | #endif | ||
1374 | 1382 | ||
1375 | /* | 1383 | /* |
1376 | * set bt_coex_active to true, uCode will do kill/defer | 1384 | * set bt_coex_active to true, uCode will do kill/defer |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 3c72cb710b0c..be4f8972241a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index de5994a776c7..e30a41d04c8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 929a8063354c..401f7be36b93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 1bb5193c5b1b..f68cba4e0444 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -125,6 +127,8 @@ enum iwl_ucode_tlv_flag { | |||
125 | * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. | 127 | * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. |
126 | * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. | 128 | * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. |
127 | * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. | 129 | * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. |
130 | * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time | ||
131 | * longer than the passive one, which is essential for fragmented scan. | ||
128 | */ | 132 | */ |
129 | enum iwl_ucode_tlv_api { | 133 | enum iwl_ucode_tlv_api { |
130 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), | 134 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), |
@@ -133,6 +137,7 @@ enum iwl_ucode_tlv_api { | |||
133 | IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), | 137 | IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), |
134 | IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), | 138 | IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), |
135 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), | 139 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), |
140 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), | ||
136 | }; | 141 | }; |
137 | 142 | ||
138 | /** | 143 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 018af2957d3b..8e7af798abd1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 99785c892f96..b6d666ee8359 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 47033a35a402..1560f4576c7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -281,6 +283,7 @@ | |||
281 | #define SCD_CHAINEXT_EN (SCD_BASE + 0x244) | 283 | #define SCD_CHAINEXT_EN (SCD_BASE + 0x244) |
282 | #define SCD_AGGR_SEL (SCD_BASE + 0x248) | 284 | #define SCD_AGGR_SEL (SCD_BASE + 0x248) |
283 | #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) | 285 | #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) |
286 | #define SCD_EN_CTRL (SCD_BASE + 0x254) | ||
284 | 287 | ||
285 | static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) | 288 | static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) |
286 | { | 289 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scd.h b/drivers/net/wireless/iwlwifi/iwl-scd.h new file mode 100644 index 000000000000..6c622b21bba7 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-scd.h | |||
@@ -0,0 +1,118 @@ | |||
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) 2014 Intel Mobile Communications GmbH | ||
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) 2014 Intel Mobile Communications GmbH | ||
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 | #ifndef __iwl_scd_h__ | ||
65 | #define __iwl_scd_h__ | ||
66 | |||
67 | #include "iwl-trans.h" | ||
68 | #include "iwl-io.h" | ||
69 | #include "iwl-prph.h" | ||
70 | |||
71 | |||
72 | static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans, | ||
73 | u16 txq_id) | ||
74 | { | ||
75 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), | ||
76 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
77 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
78 | } | ||
79 | |||
80 | static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans, | ||
81 | u16 txq_id) | ||
82 | { | ||
83 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | ||
84 | } | ||
85 | |||
86 | static inline void iwl_scd_txq_enable_agg(struct iwl_trans *trans, | ||
87 | u16 txq_id) | ||
88 | { | ||
89 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | ||
90 | } | ||
91 | |||
92 | static inline void iwl_scd_txq_disable_agg(struct iwl_trans *trans, | ||
93 | u16 txq_id) | ||
94 | { | ||
95 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | ||
96 | } | ||
97 | |||
98 | static inline void iwl_scd_disable_agg(struct iwl_trans *trans) | ||
99 | { | ||
100 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, 0); | ||
101 | } | ||
102 | |||
103 | static inline void iwl_scd_activate_fifos(struct iwl_trans *trans) | ||
104 | { | ||
105 | iwl_write_prph(trans, SCD_TXFACT, IWL_MASK(0, 7)); | ||
106 | } | ||
107 | |||
108 | static inline void iwl_scd_deactivate_fifos(struct iwl_trans *trans) | ||
109 | { | ||
110 | iwl_write_prph(trans, SCD_TXFACT, 0); | ||
111 | } | ||
112 | |||
113 | static inline void iwl_scd_enable_set_active(struct iwl_trans *trans, | ||
114 | u32 value) | ||
115 | { | ||
116 | iwl_write_prph(trans, SCD_EN_CTRL, value); | ||
117 | } | ||
118 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 656371a668da..c89985a58803 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -401,6 +403,14 @@ struct iwl_trans_dump_data { | |||
401 | 403 | ||
402 | struct iwl_trans; | 404 | struct iwl_trans; |
403 | 405 | ||
406 | struct iwl_trans_txq_scd_cfg { | ||
407 | u8 fifo; | ||
408 | s8 sta_id; | ||
409 | u8 tid; | ||
410 | bool aggregate; | ||
411 | int frame_limit; | ||
412 | }; | ||
413 | |||
404 | /** | 414 | /** |
405 | * struct iwl_trans_ops - transport specific operations | 415 | * struct iwl_trans_ops - transport specific operations |
406 | * | 416 | * |
@@ -437,7 +447,9 @@ struct iwl_trans; | |||
437 | * Must be atomic | 447 | * Must be atomic |
438 | * @txq_enable: setup a queue. To setup an AC queue, use the | 448 | * @txq_enable: setup a queue. To setup an AC queue, use the |
439 | * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before | 449 | * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before |
440 | * this one. The op_mode must not configure the HCMD queue. May sleep. | 450 | * this one. The op_mode must not configure the HCMD queue. The scheduler |
451 | * configuration may be %NULL, in which case the hardware will not be | ||
452 | * configured. May sleep. | ||
441 | * @txq_disable: de-configure a Tx queue to send AMPDUs | 453 | * @txq_disable: de-configure a Tx queue to send AMPDUs |
442 | * Must be atomic | 454 | * Must be atomic |
443 | * @wait_tx_queue_empty: wait until tx queues are empty. May sleep. | 455 | * @wait_tx_queue_empty: wait until tx queues are empty. May sleep. |
@@ -492,9 +504,10 @@ struct iwl_trans_ops { | |||
492 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, | 504 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, |
493 | struct sk_buff_head *skbs); | 505 | struct sk_buff_head *skbs); |
494 | 506 | ||
495 | void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo, | 507 | void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn, |
496 | int sta_id, int tid, int frame_limit, u16 ssn); | 508 | const struct iwl_trans_txq_scd_cfg *cfg); |
497 | void (*txq_disable)(struct iwl_trans *trans, int queue); | 509 | void (*txq_disable)(struct iwl_trans *trans, int queue, |
510 | bool configure_scd); | ||
498 | 511 | ||
499 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 512 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
500 | int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm); | 513 | int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm); |
@@ -766,29 +779,57 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, | |||
766 | trans->ops->reclaim(trans, queue, ssn, skbs); | 779 | trans->ops->reclaim(trans, queue, ssn, skbs); |
767 | } | 780 | } |
768 | 781 | ||
769 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) | 782 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue, |
783 | bool configure_scd) | ||
770 | { | 784 | { |
771 | trans->ops->txq_disable(trans, queue); | 785 | trans->ops->txq_disable(trans, queue, configure_scd); |
772 | } | 786 | } |
773 | 787 | ||
774 | static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | 788 | static inline void |
775 | int fifo, int sta_id, int tid, | 789 | iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn, |
776 | int frame_limit, u16 ssn) | 790 | const struct iwl_trans_txq_scd_cfg *cfg) |
777 | { | 791 | { |
778 | might_sleep(); | 792 | might_sleep(); |
779 | 793 | ||
780 | if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) | 794 | if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) |
781 | IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); | 795 | IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); |
782 | 796 | ||
783 | trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, | 797 | trans->ops->txq_enable(trans, queue, ssn, cfg); |
784 | frame_limit, ssn); | 798 | } |
799 | |||
800 | static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, | ||
801 | int fifo, int sta_id, int tid, | ||
802 | int frame_limit, u16 ssn) | ||
803 | { | ||
804 | struct iwl_trans_txq_scd_cfg cfg = { | ||
805 | .fifo = fifo, | ||
806 | .sta_id = sta_id, | ||
807 | .tid = tid, | ||
808 | .frame_limit = frame_limit, | ||
809 | .aggregate = sta_id >= 0, | ||
810 | }; | ||
811 | |||
812 | iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg); | ||
785 | } | 813 | } |
786 | 814 | ||
787 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, | 815 | static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, |
788 | int fifo) | 816 | int fifo) |
789 | { | 817 | { |
790 | iwl_trans_txq_enable(trans, queue, fifo, -1, | 818 | struct iwl_trans_txq_scd_cfg cfg = { |
791 | IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); | 819 | .fifo = fifo, |
820 | .sta_id = -1, | ||
821 | .tid = IWL_MAX_TID_COUNT, | ||
822 | .frame_limit = IWL_FRAME_LIMIT, | ||
823 | .aggregate = false, | ||
824 | }; | ||
825 | |||
826 | iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); | ||
827 | } | ||
828 | |||
829 | static inline void | ||
830 | iwl_trans_txq_enable_no_scd(struct iwl_trans *trans, int queue, u16 ssn) | ||
831 | { | ||
832 | iwl_trans_txq_enable_cfg(trans, queue, ssn, NULL); | ||
792 | } | 833 | } |
793 | 834 | ||
794 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, | 835 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 2291bbcaaeab..2262d6dc61ae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index a3be33359927..585c0ab4a3ec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index ca79f7160573..dd00e8f7f765 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 645b3cfc29a5..c17be0fb7283 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -700,7 +702,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
700 | return ret; | 702 | return ret; |
701 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); | 703 | rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta); |
702 | 704 | ||
703 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 705 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); |
704 | if (ret) | 706 | if (ret) |
705 | return ret; | 707 | return ret; |
706 | 708 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c index 2e90ff795c13..d919b4ebc83c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -119,6 +121,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, | |||
119 | IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val); | 121 | IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val); |
120 | dbgfs_pm->uapsd_misbehaving = val; | 122 | dbgfs_pm->uapsd_misbehaving = val; |
121 | break; | 123 | break; |
124 | case MVM_DEBUGFS_PM_USE_PS_POLL: | ||
125 | IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val); | ||
126 | dbgfs_pm->use_ps_poll = val; | ||
127 | break; | ||
122 | } | 128 | } |
123 | } | 129 | } |
124 | 130 | ||
@@ -169,6 +175,10 @@ static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf, | |||
169 | if (sscanf(buf + 18, "%d", &val) != 1) | 175 | if (sscanf(buf + 18, "%d", &val) != 1) |
170 | return -EINVAL; | 176 | return -EINVAL; |
171 | param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING; | 177 | param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING; |
178 | } else if (!strncmp("use_ps_poll=", buf, 12)) { | ||
179 | if (sscanf(buf + 12, "%d", &val) != 1) | ||
180 | return -EINVAL; | ||
181 | param = MVM_DEBUGFS_PM_USE_PS_POLL; | ||
172 | } else { | 182 | } else { |
173 | return -EINVAL; | 183 | return -EINVAL; |
174 | } | 184 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 7d18f466fbb3..d98ee109c5e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -257,6 +259,70 @@ static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf, | |||
257 | return count; | 259 | return count; |
258 | } | 260 | } |
259 | 261 | ||
262 | static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file, | ||
263 | char __user *user_buf, | ||
264 | size_t count, loff_t *ppos) | ||
265 | { | ||
266 | struct iwl_mvm *mvm = file->private_data; | ||
267 | char buf[16]; | ||
268 | int pos; | ||
269 | |||
270 | if (!mvm->temperature_test) | ||
271 | pos = scnprintf(buf , sizeof(buf), "disabled\n"); | ||
272 | else | ||
273 | pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature); | ||
274 | |||
275 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * Set NIC Temperature | ||
280 | * Cause the driver to ignore the actual NIC temperature reported by the FW | ||
281 | * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN - | ||
282 | * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX | ||
283 | * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE | ||
284 | */ | ||
285 | static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm, | ||
286 | char *buf, size_t count, | ||
287 | loff_t *ppos) | ||
288 | { | ||
289 | int temperature; | ||
290 | |||
291 | if (kstrtoint(buf, 10, &temperature)) | ||
292 | return -EINVAL; | ||
293 | /* not a legal temperature */ | ||
294 | if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX && | ||
295 | temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) || | ||
296 | temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN) | ||
297 | return -EINVAL; | ||
298 | |||
299 | mutex_lock(&mvm->mutex); | ||
300 | if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) { | ||
301 | if (!mvm->temperature_test) | ||
302 | goto out; | ||
303 | |||
304 | mvm->temperature_test = false; | ||
305 | /* Since we can't read the temp while awake, just set | ||
306 | * it to zero until we get the next RX stats from the | ||
307 | * firmware. | ||
308 | */ | ||
309 | mvm->temperature = 0; | ||
310 | } else { | ||
311 | mvm->temperature_test = true; | ||
312 | mvm->temperature = temperature; | ||
313 | } | ||
314 | IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n", | ||
315 | mvm->temperature_test ? "En" : "Dis" , | ||
316 | mvm->temperature); | ||
317 | /* handle the temperature change */ | ||
318 | iwl_mvm_tt_handler(mvm); | ||
319 | |||
320 | out: | ||
321 | mutex_unlock(&mvm->mutex); | ||
322 | |||
323 | return count; | ||
324 | } | ||
325 | |||
260 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 326 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
261 | size_t count, loff_t *ppos) | 327 | size_t count, loff_t *ppos) |
262 | { | 328 | { |
@@ -1296,6 +1362,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); | |||
1296 | MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); | 1362 | MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); |
1297 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); | 1363 | MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); |
1298 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); | 1364 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); |
1365 | MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64); | ||
1299 | MVM_DEBUGFS_READ_FILE_OPS(stations); | 1366 | MVM_DEBUGFS_READ_FILE_OPS(stations); |
1300 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); | 1367 | MVM_DEBUGFS_READ_FILE_OPS(bt_notif); |
1301 | MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); | 1368 | MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); |
@@ -1336,6 +1403,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1336 | MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); | 1403 | MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR); |
1337 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); | 1404 | MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); |
1338 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); | 1405 | MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); |
1406 | MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, | ||
1407 | S_IWUSR | S_IRUSR); | ||
1339 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); | 1408 | MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); |
1340 | MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); | 1409 | MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); |
1341 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); | 1410 | MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); |
@@ -1380,6 +1449,13 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) | |||
1380 | goto err; | 1449 | goto err; |
1381 | #endif | 1450 | #endif |
1382 | 1451 | ||
1452 | if (!debugfs_create_u8("low_latency_agg_frame_limit", S_IRUSR | S_IWUSR, | ||
1453 | mvm->debugfs_dir, | ||
1454 | &mvm->low_latency_agg_frame_limit)) | ||
1455 | goto err; | ||
1456 | if (!debugfs_create_u8("ps_disabled", S_IRUSR, | ||
1457 | mvm->debugfs_dir, &mvm->ps_disabled)) | ||
1458 | goto err; | ||
1383 | if (!debugfs_create_blob("nvm_hw", S_IRUSR, | 1459 | if (!debugfs_create_blob("nvm_hw", S_IRUSR, |
1384 | mvm->debugfs_dir, &mvm->nvm_hw_blob)) | 1460 | mvm->debugfs_dir, &mvm->nvm_hw_blob)) |
1385 | goto err; | 1461 | goto err; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h index e3a9774af495..8c4190e7e027 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.h +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h index 69875716dcdb..816883f9ff94 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index 13696fe419b7..e74cdf2132f8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index c3a8c86b550d..27dd86395b39 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index c02a9e45ec5e..8f2216694004 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 47bd0406355d..21dd5b771660 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 95f5b3274efb..9c975f9ecfcb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -73,16 +75,20 @@ | |||
73 | #include "fw-api-coex.h" | 75 | #include "fw-api-coex.h" |
74 | #include "fw-api-scan.h" | 76 | #include "fw-api-scan.h" |
75 | 77 | ||
76 | /* maximal number of Tx queues in any platform */ | ||
77 | #define IWL_MVM_MAX_QUEUES 20 | ||
78 | |||
79 | /* Tx queue numbers */ | 78 | /* Tx queue numbers */ |
80 | enum { | 79 | enum { |
81 | IWL_MVM_OFFCHANNEL_QUEUE = 8, | 80 | IWL_MVM_OFFCHANNEL_QUEUE = 8, |
82 | IWL_MVM_CMD_QUEUE = 9, | 81 | IWL_MVM_CMD_QUEUE = 9, |
83 | }; | 82 | }; |
84 | 83 | ||
85 | #define IWL_MVM_CMD_FIFO 7 | 84 | enum iwl_mvm_tx_fifo { |
85 | IWL_MVM_TX_FIFO_BK = 0, | ||
86 | IWL_MVM_TX_FIFO_BE, | ||
87 | IWL_MVM_TX_FIFO_VI, | ||
88 | IWL_MVM_TX_FIFO_VO, | ||
89 | IWL_MVM_TX_FIFO_MCAST = 5, | ||
90 | IWL_MVM_TX_FIFO_CMD = 7, | ||
91 | }; | ||
86 | 92 | ||
87 | #define IWL_MVM_STATION_COUNT 16 | 93 | #define IWL_MVM_STATION_COUNT 16 |
88 | 94 | ||
@@ -184,6 +190,8 @@ enum { | |||
184 | REPLY_RX_MPDU_CMD = 0xc1, | 190 | REPLY_RX_MPDU_CMD = 0xc1, |
185 | BA_NOTIF = 0xc5, | 191 | BA_NOTIF = 0xc5, |
186 | 192 | ||
193 | MARKER_CMD = 0xcb, | ||
194 | |||
187 | /* BT Coex */ | 195 | /* BT Coex */ |
188 | BT_COEX_PRIO_TABLE = 0xcc, | 196 | BT_COEX_PRIO_TABLE = 0xcc, |
189 | BT_COEX_PROT_ENV = 0xcd, | 197 | BT_COEX_PROT_ENV = 0xcd, |
@@ -1307,6 +1315,38 @@ struct iwl_bcast_filter_cmd { | |||
1307 | struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER]; | 1315 | struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER]; |
1308 | } __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */ | 1316 | } __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */ |
1309 | 1317 | ||
1318 | /* | ||
1319 | * enum iwl_mvm_marker_id - maker ids | ||
1320 | * | ||
1321 | * The ids for different type of markers to insert into the usniffer logs | ||
1322 | */ | ||
1323 | enum iwl_mvm_marker_id { | ||
1324 | MARKER_ID_TX_FRAME_LATENCY = 1, | ||
1325 | }; /* MARKER_ID_API_E_VER_1 */ | ||
1326 | |||
1327 | /** | ||
1328 | * struct iwl_mvm_marker - mark info into the usniffer logs | ||
1329 | * | ||
1330 | * (MARKER_CMD = 0xcb) | ||
1331 | * | ||
1332 | * Mark the UTC time stamp into the usniffer logs together with additional | ||
1333 | * metadata, so the usniffer output can be parsed. | ||
1334 | * In the command response the ucode will return the GP2 time. | ||
1335 | * | ||
1336 | * @dw_len: The amount of dwords following this byte including this byte. | ||
1337 | * @marker_id: A unique marker id (iwl_mvm_marker_id). | ||
1338 | * @reserved: reserved. | ||
1339 | * @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC | ||
1340 | * @metadata: additional meta data that will be written to the unsiffer log | ||
1341 | */ | ||
1342 | struct iwl_mvm_marker { | ||
1343 | u8 dwLen; | ||
1344 | u8 markerId; | ||
1345 | __le16 reserved; | ||
1346 | __le64 timestamp; | ||
1347 | __le32 metadata[0]; | ||
1348 | } __packed; /* MARKER_API_S_VER_1 */ | ||
1349 | |||
1310 | struct mvm_statistics_dbg { | 1350 | struct mvm_statistics_dbg { |
1311 | __le32 burst_check; | 1351 | __le32 burst_check; |
1312 | __le32 burst_count; | 1352 | __le32 burst_count; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 883e702152d5..21d606028ca6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -242,10 +244,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, | |||
242 | mvm->queue_to_mac80211[i] = i; | 244 | mvm->queue_to_mac80211[i] = i; |
243 | else | 245 | else |
244 | mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; | 246 | mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; |
245 | atomic_set(&mvm->queue_stop_count[i], 0); | ||
246 | } | 247 | } |
247 | 248 | ||
248 | mvm->transport_queue_stop = 0; | 249 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) |
250 | atomic_set(&mvm->mac80211_queue_stop_count[i], 0); | ||
249 | 251 | ||
250 | mvm->ucode_loaded = true; | 252 | mvm->ucode_loaded = true; |
251 | 253 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 0e523e28cabf..9cbb192f680e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -81,7 +83,7 @@ struct iwl_mvm_mac_iface_iterator_data { | |||
81 | struct ieee80211_vif *vif; | 83 | struct ieee80211_vif *vif; |
82 | unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; | 84 | unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; |
83 | unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; | 85 | unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; |
84 | unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)]; | 86 | u32 used_hw_queues; |
85 | enum iwl_tsf_id preferred_tsf; | 87 | enum iwl_tsf_id preferred_tsf; |
86 | bool found_vif; | 88 | bool found_vif; |
87 | }; | 89 | }; |
@@ -192,12 +194,31 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac, | |||
192 | data->preferred_tsf = NUM_TSF_IDS; | 194 | data->preferred_tsf = NUM_TSF_IDS; |
193 | } | 195 | } |
194 | 196 | ||
197 | /* | ||
198 | * Get the mask of the queues used by the vif | ||
199 | */ | ||
200 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | ||
201 | struct ieee80211_vif *vif) | ||
202 | { | ||
203 | u32 qmask = 0, ac; | ||
204 | |||
205 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) | ||
206 | return BIT(IWL_MVM_OFFCHANNEL_QUEUE); | ||
207 | |||
208 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
209 | qmask |= BIT(vif->hw_queue[ac]); | ||
210 | |||
211 | if (vif->type == NL80211_IFTYPE_AP) | ||
212 | qmask |= BIT(vif->cab_queue); | ||
213 | |||
214 | return qmask; | ||
215 | } | ||
216 | |||
195 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | 217 | static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, |
196 | struct ieee80211_vif *vif) | 218 | struct ieee80211_vif *vif) |
197 | { | 219 | { |
198 | struct iwl_mvm_mac_iface_iterator_data *data = _data; | 220 | struct iwl_mvm_mac_iface_iterator_data *data = _data; |
199 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 221 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
200 | u32 ac; | ||
201 | 222 | ||
202 | /* Iterator may already find the interface being added -- skip it */ | 223 | /* Iterator may already find the interface being added -- skip it */ |
203 | if (vif == data->vif) { | 224 | if (vif == data->vif) { |
@@ -206,12 +227,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
206 | } | 227 | } |
207 | 228 | ||
208 | /* Mark the queues used by the vif */ | 229 | /* Mark the queues used by the vif */ |
209 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 230 | data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif); |
210 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
211 | __set_bit(vif->hw_queue[ac], data->used_hw_queues); | ||
212 | |||
213 | if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
214 | __set_bit(vif->cab_queue, data->used_hw_queues); | ||
215 | 231 | ||
216 | /* Mark MAC IDs as used by clearing the available bit, and | 232 | /* Mark MAC IDs as used by clearing the available bit, and |
217 | * (below) mark TSFs as used if their existing use is not | 233 | * (below) mark TSFs as used if their existing use is not |
@@ -225,24 +241,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, | |||
225 | iwl_mvm_mac_tsf_id_iter(_data, mac, vif); | 241 | iwl_mvm_mac_tsf_id_iter(_data, mac, vif); |
226 | } | 242 | } |
227 | 243 | ||
228 | /* | ||
229 | * Get the mask of the queus used by the vif | ||
230 | */ | ||
231 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | ||
232 | struct ieee80211_vif *vif) | ||
233 | { | ||
234 | u32 qmask = 0, ac; | ||
235 | |||
236 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) | ||
237 | return BIT(IWL_MVM_OFFCHANNEL_QUEUE); | ||
238 | |||
239 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
240 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
241 | qmask |= BIT(vif->hw_queue[ac]); | ||
242 | |||
243 | return qmask; | ||
244 | } | ||
245 | |||
246 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, | 244 | void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, |
247 | struct ieee80211_vif *vif) | 245 | struct ieee80211_vif *vif) |
248 | { | 246 | { |
@@ -277,15 +275,15 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | |||
277 | .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, | 275 | .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 }, |
278 | /* no preference yet */ | 276 | /* no preference yet */ |
279 | .preferred_tsf = NUM_TSF_IDS, | 277 | .preferred_tsf = NUM_TSF_IDS, |
280 | .used_hw_queues = { | 278 | .used_hw_queues = |
281 | BIT(IWL_MVM_OFFCHANNEL_QUEUE) | | 279 | BIT(IWL_MVM_OFFCHANNEL_QUEUE) | |
282 | BIT(mvm->aux_queue) | | 280 | BIT(mvm->aux_queue) | |
283 | BIT(IWL_MVM_CMD_QUEUE) | 281 | BIT(IWL_MVM_CMD_QUEUE), |
284 | }, | ||
285 | .found_vif = false, | 282 | .found_vif = false, |
286 | }; | 283 | }; |
287 | u32 ac; | 284 | u32 ac; |
288 | int ret, i; | 285 | int ret, i; |
286 | unsigned long used_hw_queues; | ||
289 | 287 | ||
290 | /* | 288 | /* |
291 | * Allocate a MAC ID and a TSF for this MAC, along with the queues | 289 | * Allocate a MAC ID and a TSF for this MAC, along with the queues |
@@ -368,9 +366,11 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | |||
368 | return 0; | 366 | return 0; |
369 | } | 367 | } |
370 | 368 | ||
369 | used_hw_queues = data.used_hw_queues; | ||
370 | |||
371 | /* Find available queues, and allocate them to the ACs */ | 371 | /* Find available queues, and allocate them to the ACs */ |
372 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 372 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
373 | u8 queue = find_first_zero_bit(data.used_hw_queues, | 373 | u8 queue = find_first_zero_bit(&used_hw_queues, |
374 | mvm->first_agg_queue); | 374 | mvm->first_agg_queue); |
375 | 375 | ||
376 | if (queue >= mvm->first_agg_queue) { | 376 | if (queue >= mvm->first_agg_queue) { |
@@ -379,13 +379,13 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, | |||
379 | goto exit_fail; | 379 | goto exit_fail; |
380 | } | 380 | } |
381 | 381 | ||
382 | __set_bit(queue, data.used_hw_queues); | 382 | __set_bit(queue, &used_hw_queues); |
383 | vif->hw_queue[ac] = queue; | 383 | vif->hw_queue[ac] = queue; |
384 | } | 384 | } |
385 | 385 | ||
386 | /* Allocate the CAB queue for softAP and GO interfaces */ | 386 | /* Allocate the CAB queue for softAP and GO interfaces */ |
387 | if (vif->type == NL80211_IFTYPE_AP) { | 387 | if (vif->type == NL80211_IFTYPE_AP) { |
388 | u8 queue = find_first_zero_bit(data.used_hw_queues, | 388 | u8 queue = find_first_zero_bit(&used_hw_queues, |
389 | mvm->first_agg_queue); | 389 | mvm->first_agg_queue); |
390 | 390 | ||
391 | if (queue >= mvm->first_agg_queue) { | 391 | if (queue >= mvm->first_agg_queue) { |
@@ -452,14 +452,16 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
452 | 452 | ||
453 | switch (vif->type) { | 453 | switch (vif->type) { |
454 | case NL80211_IFTYPE_P2P_DEVICE: | 454 | case NL80211_IFTYPE_P2P_DEVICE: |
455 | iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE); | 455 | iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE, |
456 | true); | ||
456 | break; | 457 | break; |
457 | case NL80211_IFTYPE_AP: | 458 | case NL80211_IFTYPE_AP: |
458 | iwl_trans_txq_disable(mvm->trans, vif->cab_queue); | 459 | iwl_trans_txq_disable(mvm->trans, vif->cab_queue, true); |
459 | /* fall through */ | 460 | /* fall through */ |
460 | default: | 461 | default: |
461 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 462 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
462 | iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]); | 463 | iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac], |
464 | true); | ||
463 | } | 465 | } |
464 | } | 466 | } |
465 | 467 | ||
@@ -586,6 +588,7 @@ static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm, | |||
586 | static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | 588 | static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, |
587 | struct ieee80211_vif *vif, | 589 | struct ieee80211_vif *vif, |
588 | struct iwl_mac_ctx_cmd *cmd, | 590 | struct iwl_mac_ctx_cmd *cmd, |
591 | const u8 *bssid_override, | ||
589 | u32 action) | 592 | u32 action) |
590 | { | 593 | { |
591 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 594 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
@@ -593,6 +596,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | |||
593 | bool ht_enabled = !!(vif->bss_conf.ht_operation_mode & | 596 | bool ht_enabled = !!(vif->bss_conf.ht_operation_mode & |
594 | IEEE80211_HT_OP_MODE_PROTECTION); | 597 | IEEE80211_HT_OP_MODE_PROTECTION); |
595 | u8 cck_ack_rates, ofdm_ack_rates; | 598 | u8 cck_ack_rates, ofdm_ack_rates; |
599 | const u8 *bssid = bssid_override ?: vif->bss_conf.bssid; | ||
596 | int i; | 600 | int i; |
597 | 601 | ||
598 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, | 602 | cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, |
@@ -625,8 +629,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, | |||
625 | cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id); | 629 | cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id); |
626 | 630 | ||
627 | memcpy(cmd->node_addr, vif->addr, ETH_ALEN); | 631 | memcpy(cmd->node_addr, vif->addr, ETH_ALEN); |
628 | if (vif->bss_conf.bssid) | 632 | |
629 | memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN); | 633 | if (bssid) |
634 | memcpy(cmd->bssid_addr, bssid, ETH_ALEN); | ||
630 | else | 635 | else |
631 | eth_broadcast_addr(cmd->bssid_addr); | 636 | eth_broadcast_addr(cmd->bssid_addr); |
632 | 637 | ||
@@ -695,7 +700,8 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm, | |||
695 | 700 | ||
696 | static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, | 701 | static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, |
697 | struct ieee80211_vif *vif, | 702 | struct ieee80211_vif *vif, |
698 | u32 action, bool force_assoc_off) | 703 | u32 action, bool force_assoc_off, |
704 | const u8 *bssid_override) | ||
699 | { | 705 | { |
700 | struct iwl_mac_ctx_cmd cmd = {}; | 706 | struct iwl_mac_ctx_cmd cmd = {}; |
701 | struct iwl_mac_data_sta *ctxt_sta; | 707 | struct iwl_mac_data_sta *ctxt_sta; |
@@ -703,7 +709,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, | |||
703 | WARN_ON(vif->type != NL80211_IFTYPE_STATION); | 709 | WARN_ON(vif->type != NL80211_IFTYPE_STATION); |
704 | 710 | ||
705 | /* Fill the common data for all mac context types */ | 711 | /* Fill the common data for all mac context types */ |
706 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 712 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, bssid_override, action); |
707 | 713 | ||
708 | if (vif->p2p) { | 714 | if (vif->p2p) { |
709 | struct ieee80211_p2p_noa_attr *noa = | 715 | struct ieee80211_p2p_noa_attr *noa = |
@@ -784,7 +790,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, | |||
784 | 790 | ||
785 | WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); | 791 | WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); |
786 | 792 | ||
787 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 793 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
788 | 794 | ||
789 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | | 795 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | |
790 | MAC_FILTER_IN_CONTROL_AND_MGMT | | 796 | MAC_FILTER_IN_CONTROL_AND_MGMT | |
@@ -805,7 +811,7 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm, | |||
805 | 811 | ||
806 | WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); | 812 | WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); |
807 | 813 | ||
808 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 814 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
809 | 815 | ||
810 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON | | 816 | cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON | |
811 | MAC_FILTER_IN_PROBE_REQUEST); | 817 | MAC_FILTER_IN_PROBE_REQUEST); |
@@ -844,7 +850,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm, | |||
844 | 850 | ||
845 | WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE); | 851 | WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE); |
846 | 852 | ||
847 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 853 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
848 | 854 | ||
849 | cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); | 855 | cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); |
850 | 856 | ||
@@ -1072,7 +1078,7 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, | |||
1072 | WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p); | 1078 | WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p); |
1073 | 1079 | ||
1074 | /* Fill the common data for all mac context types */ | 1080 | /* Fill the common data for all mac context types */ |
1075 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 1081 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
1076 | 1082 | ||
1077 | /* | 1083 | /* |
1078 | * pass probe requests and beacons from other APs (needed | 1084 | * pass probe requests and beacons from other APs (needed |
@@ -1098,7 +1104,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
1098 | WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); | 1104 | WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p); |
1099 | 1105 | ||
1100 | /* Fill the common data for all mac context types */ | 1106 | /* Fill the common data for all mac context types */ |
1101 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); | 1107 | iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action); |
1102 | 1108 | ||
1103 | /* | 1109 | /* |
1104 | * pass probe requests and beacons from other APs (needed | 1110 | * pass probe requests and beacons from other APs (needed |
@@ -1121,12 +1127,14 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, | |||
1121 | } | 1127 | } |
1122 | 1128 | ||
1123 | static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1129 | static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1124 | u32 action, bool force_assoc_off) | 1130 | u32 action, bool force_assoc_off, |
1131 | const u8 *bssid_override) | ||
1125 | { | 1132 | { |
1126 | switch (vif->type) { | 1133 | switch (vif->type) { |
1127 | case NL80211_IFTYPE_STATION: | 1134 | case NL80211_IFTYPE_STATION: |
1128 | return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action, | 1135 | return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action, |
1129 | force_assoc_off); | 1136 | force_assoc_off, |
1137 | bssid_override); | ||
1130 | break; | 1138 | break; |
1131 | case NL80211_IFTYPE_AP: | 1139 | case NL80211_IFTYPE_AP: |
1132 | if (!vif->p2p) | 1140 | if (!vif->p2p) |
@@ -1157,7 +1165,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
1157 | return -EIO; | 1165 | return -EIO; |
1158 | 1166 | ||
1159 | ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD, | 1167 | ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD, |
1160 | true); | 1168 | true, NULL); |
1161 | if (ret) | 1169 | if (ret) |
1162 | return ret; | 1170 | return ret; |
1163 | 1171 | ||
@@ -1169,7 +1177,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
1169 | } | 1177 | } |
1170 | 1178 | ||
1171 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1179 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1172 | bool force_assoc_off) | 1180 | bool force_assoc_off, const u8 *bssid_override) |
1173 | { | 1181 | { |
1174 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1182 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
1175 | 1183 | ||
@@ -1178,7 +1186,7 @@ int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1178 | return -EIO; | 1186 | return -EIO; |
1179 | 1187 | ||
1180 | return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY, | 1188 | return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY, |
1181 | force_assoc_off); | 1189 | force_assoc_off, bssid_override); |
1182 | } | 1190 | } |
1183 | 1191 | ||
1184 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | 1192 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 7c8796584c25..8d1d4b40b0a3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -776,6 +778,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
776 | iwl_trans_stop_device(mvm->trans); | 778 | iwl_trans_stop_device(mvm->trans); |
777 | 779 | ||
778 | mvm->scan_status = IWL_MVM_SCAN_NONE; | 780 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
781 | mvm->ps_disabled = false; | ||
779 | 782 | ||
780 | /* just in case one was running */ | 783 | /* just in case one was running */ |
781 | ieee80211_remain_on_channel_expired(mvm->hw); | 784 | ieee80211_remain_on_channel_expired(mvm->hw); |
@@ -803,6 +806,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
803 | * ucode_down ref until reconfig is complete */ | 806 | * ucode_down ref until reconfig is complete */ |
804 | iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); | 807 | iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); |
805 | 808 | ||
809 | /* clear any stale d0i3 state */ | ||
810 | clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); | ||
811 | |||
806 | mvm->vif_count = 0; | 812 | mvm->vif_count = 0; |
807 | mvm->rx_ba_sessions = 0; | 813 | mvm->rx_ba_sessions = 0; |
808 | } | 814 | } |
@@ -880,7 +886,7 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) | |||
880 | /* async_handlers_list is empty and will stay empty: HW is stopped */ | 886 | /* async_handlers_list is empty and will stay empty: HW is stopped */ |
881 | 887 | ||
882 | /* the fw is stopped, the aux sta is dead: clean up driver state */ | 888 | /* the fw is stopped, the aux sta is dead: clean up driver state */ |
883 | iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); | 889 | iwl_mvm_del_aux_sta(mvm); |
884 | 890 | ||
885 | mutex_unlock(&mvm->mutex); | 891 | mutex_unlock(&mvm->mutex); |
886 | 892 | ||
@@ -965,10 +971,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
965 | */ | 971 | */ |
966 | if (vif->type == NL80211_IFTYPE_AP || | 972 | if (vif->type == NL80211_IFTYPE_AP || |
967 | vif->type == NL80211_IFTYPE_ADHOC) { | 973 | vif->type == NL80211_IFTYPE_ADHOC) { |
968 | u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | 974 | ret = iwl_mvm_alloc_bcast_sta(mvm, vif); |
969 | ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, | ||
970 | qmask, | ||
971 | ieee80211_vif_type_p2p(vif)); | ||
972 | if (ret) { | 975 | if (ret) { |
973 | IWL_ERR(mvm, "Failed to allocate bcast sta\n"); | 976 | IWL_ERR(mvm, "Failed to allocate bcast sta\n"); |
974 | goto out_release; | 977 | goto out_release; |
@@ -1016,7 +1019,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
1016 | if (ret) | 1019 | if (ret) |
1017 | goto out_unref_phy; | 1020 | goto out_unref_phy; |
1018 | 1021 | ||
1019 | ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); | 1022 | ret = iwl_mvm_add_bcast_sta(mvm, vif); |
1020 | if (ret) | 1023 | if (ret) |
1021 | goto out_unbind; | 1024 | goto out_unbind; |
1022 | 1025 | ||
@@ -1057,14 +1060,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
1057 | static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, | 1060 | static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, |
1058 | struct ieee80211_vif *vif) | 1061 | struct ieee80211_vif *vif) |
1059 | { | 1062 | { |
1060 | u32 tfd_msk = 0, ac; | 1063 | u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif); |
1061 | |||
1062 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
1063 | if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE) | ||
1064 | tfd_msk |= BIT(vif->hw_queue[ac]); | ||
1065 | |||
1066 | if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) | ||
1067 | tfd_msk |= BIT(vif->cab_queue); | ||
1068 | 1064 | ||
1069 | if (tfd_msk) { | 1065 | if (tfd_msk) { |
1070 | mutex_lock(&mvm->mutex); | 1066 | mutex_lock(&mvm->mutex); |
@@ -1120,13 +1116,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
1120 | mvm->noa_duration = 0; | 1116 | mvm->noa_duration = 0; |
1121 | } | 1117 | } |
1122 | #endif | 1118 | #endif |
1123 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | 1119 | iwl_mvm_dealloc_bcast_sta(mvm, vif); |
1124 | goto out_release; | 1120 | goto out_release; |
1125 | } | 1121 | } |
1126 | 1122 | ||
1127 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | 1123 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
1128 | mvm->p2p_device_vif = NULL; | 1124 | mvm->p2p_device_vif = NULL; |
1129 | iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1125 | iwl_mvm_rm_bcast_sta(mvm, vif); |
1130 | iwl_mvm_binding_remove_vif(mvm, vif); | 1126 | iwl_mvm_binding_remove_vif(mvm, vif); |
1131 | iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); | 1127 | iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); |
1132 | mvmvif->phy_ctxt = NULL; | 1128 | mvmvif->phy_ctxt = NULL; |
@@ -1445,10 +1441,23 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
1445 | if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) | 1441 | if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) |
1446 | iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); | 1442 | iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif); |
1447 | 1443 | ||
1448 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 1444 | /* |
1445 | * If we're not associated yet, take the (new) BSSID before associating | ||
1446 | * so the firmware knows. If we're already associated, then use the old | ||
1447 | * BSSID here, and we'll send a cleared one later in the CHANGED_ASSOC | ||
1448 | * branch for disassociation below. | ||
1449 | */ | ||
1450 | if (changes & BSS_CHANGED_BSSID && !mvmvif->associated) | ||
1451 | memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN); | ||
1452 | |||
1453 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid); | ||
1449 | if (ret) | 1454 | if (ret) |
1450 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); | 1455 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); |
1451 | 1456 | ||
1457 | /* after sending it once, adopt mac80211 data */ | ||
1458 | memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN); | ||
1459 | mvmvif->associated = bss_conf->assoc; | ||
1460 | |||
1452 | if (changes & BSS_CHANGED_ASSOC) { | 1461 | if (changes & BSS_CHANGED_ASSOC) { |
1453 | if (bss_conf->assoc) { | 1462 | if (bss_conf->assoc) { |
1454 | /* add quota for this interface */ | 1463 | /* add quota for this interface */ |
@@ -1476,13 +1485,17 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
1476 | */ | 1485 | */ |
1477 | u32 dur = (11 * vif->bss_conf.beacon_int) / 10; | 1486 | u32 dur = (11 * vif->bss_conf.beacon_int) / 10; |
1478 | iwl_mvm_protect_session(mvm, vif, dur, dur, | 1487 | iwl_mvm_protect_session(mvm, vif, dur, dur, |
1479 | 5 * dur); | 1488 | 5 * dur, false); |
1480 | } | 1489 | } |
1481 | 1490 | ||
1482 | iwl_mvm_sf_update(mvm, vif, false); | 1491 | iwl_mvm_sf_update(mvm, vif, false); |
1483 | iwl_mvm_power_vif_assoc(mvm, vif); | 1492 | iwl_mvm_power_vif_assoc(mvm, vif); |
1484 | if (vif->p2p) | 1493 | if (vif->p2p) { |
1485 | iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT); | 1494 | iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT); |
1495 | iwl_mvm_update_smps(mvm, vif, | ||
1496 | IWL_MVM_SMPS_REQ_PROT, | ||
1497 | IEEE80211_SMPS_DYNAMIC); | ||
1498 | } | ||
1486 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { | 1499 | } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { |
1487 | /* | 1500 | /* |
1488 | * If update fails - SF might be running in associated | 1501 | * If update fails - SF might be running in associated |
@@ -1506,6 +1519,13 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | |||
1506 | 1519 | ||
1507 | if (vif->p2p) | 1520 | if (vif->p2p) |
1508 | iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT); | 1521 | iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT); |
1522 | |||
1523 | /* this will take the cleared BSSID from bss_conf */ | ||
1524 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); | ||
1525 | if (ret) | ||
1526 | IWL_ERR(mvm, | ||
1527 | "failed to update MAC %pM (clear after unassoc)\n", | ||
1528 | vif->addr); | ||
1509 | } | 1529 | } |
1510 | 1530 | ||
1511 | iwl_mvm_recalc_multicast(mvm); | 1531 | iwl_mvm_recalc_multicast(mvm); |
@@ -1601,7 +1621,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1601 | 1621 | ||
1602 | /* Send the bcast station. At this stage the TBTT and DTIM time events | 1622 | /* Send the bcast station. At this stage the TBTT and DTIM time events |
1603 | * are added and applied to the scheduler */ | 1623 | * are added and applied to the scheduler */ |
1604 | ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta); | 1624 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
1605 | if (ret) | 1625 | if (ret) |
1606 | goto out_unbind; | 1626 | goto out_unbind; |
1607 | 1627 | ||
@@ -1617,7 +1637,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1617 | 1637 | ||
1618 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ | 1638 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ |
1619 | if (vif->p2p && mvm->p2p_device_vif) | 1639 | if (vif->p2p && mvm->p2p_device_vif) |
1620 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); | 1640 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); |
1621 | 1641 | ||
1622 | iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS); | 1642 | iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS); |
1623 | 1643 | ||
@@ -1633,7 +1653,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1633 | out_quota_failed: | 1653 | out_quota_failed: |
1634 | iwl_mvm_power_update_mac(mvm); | 1654 | iwl_mvm_power_update_mac(mvm); |
1635 | mvmvif->ap_ibss_active = false; | 1655 | mvmvif->ap_ibss_active = false; |
1636 | iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1656 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
1637 | out_unbind: | 1657 | out_unbind: |
1638 | iwl_mvm_binding_remove_vif(mvm, vif); | 1658 | iwl_mvm_binding_remove_vif(mvm, vif); |
1639 | out_remove: | 1659 | out_remove: |
@@ -1675,10 +1695,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, | |||
1675 | 1695 | ||
1676 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ | 1696 | /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ |
1677 | if (vif->p2p && mvm->p2p_device_vif) | 1697 | if (vif->p2p && mvm->p2p_device_vif) |
1678 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false); | 1698 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); |
1679 | 1699 | ||
1680 | iwl_mvm_update_quotas(mvm, NULL); | 1700 | iwl_mvm_update_quotas(mvm, NULL); |
1681 | iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1701 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
1682 | iwl_mvm_binding_remove_vif(mvm, vif); | 1702 | iwl_mvm_binding_remove_vif(mvm, vif); |
1683 | 1703 | ||
1684 | iwl_mvm_power_update_mac(mvm); | 1704 | iwl_mvm_power_update_mac(mvm); |
@@ -1702,7 +1722,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm, | |||
1702 | 1722 | ||
1703 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | | 1723 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | |
1704 | BSS_CHANGED_BANDWIDTH) && | 1724 | BSS_CHANGED_BANDWIDTH) && |
1705 | iwl_mvm_mac_ctxt_changed(mvm, vif, false)) | 1725 | iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL)) |
1706 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); | 1726 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); |
1707 | 1727 | ||
1708 | /* Need to send a new beacon template to the FW */ | 1728 | /* Need to send a new beacon template to the FW */ |
@@ -2113,7 +2133,7 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw, | |||
2113 | int ret; | 2133 | int ret; |
2114 | 2134 | ||
2115 | mutex_lock(&mvm->mutex); | 2135 | mutex_lock(&mvm->mutex); |
2116 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 2136 | ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); |
2117 | mutex_unlock(&mvm->mutex); | 2137 | mutex_unlock(&mvm->mutex); |
2118 | return ret; | 2138 | return ret; |
2119 | } | 2139 | } |
@@ -2141,7 +2161,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, | |||
2141 | 2161 | ||
2142 | mutex_lock(&mvm->mutex); | 2162 | mutex_lock(&mvm->mutex); |
2143 | /* Try really hard to protect the session and hear a beacon */ | 2163 | /* Try really hard to protect the session and hear a beacon */ |
2144 | iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500); | 2164 | iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false); |
2145 | mutex_unlock(&mvm->mutex); | 2165 | mutex_unlock(&mvm->mutex); |
2146 | 2166 | ||
2147 | iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); | 2167 | iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); |
@@ -2162,7 +2182,7 @@ static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, | |||
2162 | 2182 | ||
2163 | mutex_lock(&mvm->mutex); | 2183 | mutex_lock(&mvm->mutex); |
2164 | /* Protect the session to hear the TDLS setup response on the channel */ | 2184 | /* Protect the session to hear the TDLS setup response on the channel */ |
2165 | iwl_mvm_protect_session(mvm, vif, duration, duration, 100); | 2185 | iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true); |
2166 | mutex_unlock(&mvm->mutex); | 2186 | mutex_unlock(&mvm->mutex); |
2167 | 2187 | ||
2168 | iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); | 2188 | iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); |
@@ -2700,7 +2720,10 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
2700 | ret = 0; | 2720 | ret = 0; |
2701 | goto out; | 2721 | goto out; |
2702 | case NL80211_IFTYPE_STATION: | 2722 | case NL80211_IFTYPE_STATION: |
2723 | break; | ||
2703 | case NL80211_IFTYPE_MONITOR: | 2724 | case NL80211_IFTYPE_MONITOR: |
2725 | /* always disable PS when a monitor interface is active */ | ||
2726 | mvmvif->ps_disabled = true; | ||
2704 | break; | 2727 | break; |
2705 | default: | 2728 | default: |
2706 | ret = -EINVAL; | 2729 | ret = -EINVAL; |
@@ -2732,7 +2755,20 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, | |||
2732 | if ((vif->type == NL80211_IFTYPE_AP) || | 2755 | if ((vif->type == NL80211_IFTYPE_AP) || |
2733 | (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) { | 2756 | (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) { |
2734 | iwl_mvm_update_quotas(mvm, NULL); | 2757 | iwl_mvm_update_quotas(mvm, NULL); |
2735 | iwl_mvm_mac_ctxt_changed(mvm, vif, false); | 2758 | iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); |
2759 | } | ||
2760 | |||
2761 | if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) { | ||
2762 | struct iwl_mvm_sta *mvmsta; | ||
2763 | |||
2764 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, | ||
2765 | mvmvif->ap_sta_id); | ||
2766 | |||
2767 | if (WARN_ON(!mvmsta)) | ||
2768 | goto out; | ||
2769 | |||
2770 | /* TODO: only re-enable after the first beacon */ | ||
2771 | iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); | ||
2736 | } | 2772 | } |
2737 | 2773 | ||
2738 | goto out; | 2774 | goto out; |
@@ -2766,6 +2802,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, | |||
2766 | { | 2802 | { |
2767 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 2803 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
2768 | struct ieee80211_vif *disabled_vif = NULL; | 2804 | struct ieee80211_vif *disabled_vif = NULL; |
2805 | struct iwl_mvm_sta *mvmsta; | ||
2769 | 2806 | ||
2770 | lockdep_assert_held(&mvm->mutex); | 2807 | lockdep_assert_held(&mvm->mutex); |
2771 | 2808 | ||
@@ -2776,6 +2813,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, | |||
2776 | goto out; | 2813 | goto out; |
2777 | case NL80211_IFTYPE_MONITOR: | 2814 | case NL80211_IFTYPE_MONITOR: |
2778 | mvmvif->monitor_active = false; | 2815 | mvmvif->monitor_active = false; |
2816 | mvmvif->ps_disabled = false; | ||
2779 | break; | 2817 | break; |
2780 | case NL80211_IFTYPE_AP: | 2818 | case NL80211_IFTYPE_AP: |
2781 | /* This part is triggered only during CSA */ | 2819 | /* This part is triggered only during CSA */ |
@@ -2796,7 +2834,13 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, | |||
2796 | 2834 | ||
2797 | disabled_vif = vif; | 2835 | disabled_vif = vif; |
2798 | 2836 | ||
2799 | iwl_mvm_mac_ctxt_changed(mvm, vif, true); | 2837 | mvmsta = iwl_mvm_sta_from_staid_protected(mvm, |
2838 | mvmvif->ap_sta_id); | ||
2839 | |||
2840 | if (!WARN_ON(!mvmsta)) | ||
2841 | iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true); | ||
2842 | |||
2843 | iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL); | ||
2800 | break; | 2844 | break; |
2801 | default: | 2845 | default: |
2802 | break; | 2846 | break; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 2e73d3bd7757..e292de96e09a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -103,14 +105,6 @@ | |||
103 | */ | 105 | */ |
104 | #define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3 | 106 | #define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3 |
105 | 107 | ||
106 | enum iwl_mvm_tx_fifo { | ||
107 | IWL_MVM_TX_FIFO_BK = 0, | ||
108 | IWL_MVM_TX_FIFO_BE, | ||
109 | IWL_MVM_TX_FIFO_VI, | ||
110 | IWL_MVM_TX_FIFO_VO, | ||
111 | IWL_MVM_TX_FIFO_MCAST = 5, | ||
112 | }; | ||
113 | |||
114 | extern const struct ieee80211_ops iwl_mvm_hw_ops; | 108 | extern const struct ieee80211_ops iwl_mvm_hw_ops; |
115 | 109 | ||
116 | /** | 110 | /** |
@@ -203,6 +197,7 @@ enum iwl_dbgfs_pm_mask { | |||
203 | MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), | 197 | MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), |
204 | MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), | 198 | MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), |
205 | MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9), | 199 | MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9), |
200 | MVM_DEBUGFS_PM_USE_PS_POLL = BIT(10), | ||
206 | }; | 201 | }; |
207 | 202 | ||
208 | struct iwl_dbgfs_pm { | 203 | struct iwl_dbgfs_pm { |
@@ -215,6 +210,7 @@ struct iwl_dbgfs_pm { | |||
215 | u32 lprx_rssi_threshold; | 210 | u32 lprx_rssi_threshold; |
216 | bool snooze_ena; | 211 | bool snooze_ena; |
217 | bool uapsd_misbehaving; | 212 | bool uapsd_misbehaving; |
213 | bool use_ps_poll; | ||
218 | int mask; | 214 | int mask; |
219 | }; | 215 | }; |
220 | 216 | ||
@@ -253,6 +249,7 @@ struct iwl_dbgfs_bf { | |||
253 | enum iwl_mvm_smps_type_request { | 249 | enum iwl_mvm_smps_type_request { |
254 | IWL_MVM_SMPS_REQ_BT_COEX, | 250 | IWL_MVM_SMPS_REQ_BT_COEX, |
255 | IWL_MVM_SMPS_REQ_TT, | 251 | IWL_MVM_SMPS_REQ_TT, |
252 | IWL_MVM_SMPS_REQ_PROT, | ||
256 | NUM_IWL_MVM_SMPS_REQ, | 253 | NUM_IWL_MVM_SMPS_REQ, |
257 | }; | 254 | }; |
258 | 255 | ||
@@ -315,6 +312,9 @@ struct iwl_mvm_vif_bf_data { | |||
315 | * @id: between 0 and 3 | 312 | * @id: between 0 and 3 |
316 | * @color: to solve races upon MAC addition and removal | 313 | * @color: to solve races upon MAC addition and removal |
317 | * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA | 314 | * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA |
315 | * @bssid: BSSID for this (client) interface | ||
316 | * @associated: indicates that we're currently associated, used only for | ||
317 | * managing the firmware state in iwl_mvm_bss_info_changed_station() | ||
318 | * @uploaded: indicates the MAC context has been added to the device | 318 | * @uploaded: indicates the MAC context has been added to the device |
319 | * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface | 319 | * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface |
320 | * should get quota etc. | 320 | * should get quota etc. |
@@ -323,6 +323,7 @@ struct iwl_mvm_vif_bf_data { | |||
323 | * interface should get quota etc. | 323 | * interface should get quota etc. |
324 | * @low_latency: indicates that this interface is in low-latency mode | 324 | * @low_latency: indicates that this interface is in low-latency mode |
325 | * (VMACLowLatencyMode) | 325 | * (VMACLowLatencyMode) |
326 | * @ps_disabled: indicates that this interface requires PS to be disabled | ||
326 | * @queue_params: QoS params for this MAC | 327 | * @queue_params: QoS params for this MAC |
327 | * @bcast_sta: station used for broadcast packets. Used by the following | 328 | * @bcast_sta: station used for broadcast packets. Used by the following |
328 | * vifs: P2P_DEVICE, GO and AP. | 329 | * vifs: P2P_DEVICE, GO and AP. |
@@ -335,11 +336,15 @@ struct iwl_mvm_vif { | |||
335 | u16 color; | 336 | u16 color; |
336 | u8 ap_sta_id; | 337 | u8 ap_sta_id; |
337 | 338 | ||
339 | u8 bssid[ETH_ALEN]; | ||
340 | bool associated; | ||
341 | |||
338 | bool uploaded; | 342 | bool uploaded; |
339 | bool ap_ibss_active; | 343 | bool ap_ibss_active; |
340 | bool pm_enabled; | 344 | bool pm_enabled; |
341 | bool monitor_active; | 345 | bool monitor_active; |
342 | bool low_latency; | 346 | bool low_latency; |
347 | bool ps_disabled; | ||
343 | struct iwl_mvm_vif_bf_data bf_data; | 348 | struct iwl_mvm_vif_bf_data bf_data; |
344 | 349 | ||
345 | u32 ap_beacon_time; | 350 | u32 ap_beacon_time; |
@@ -512,6 +517,10 @@ enum { | |||
512 | D0I3_PENDING_WAKEUP, | 517 | D0I3_PENDING_WAKEUP, |
513 | }; | 518 | }; |
514 | 519 | ||
520 | #define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff | ||
521 | #define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100 | ||
522 | #define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200 | ||
523 | |||
515 | struct iwl_mvm { | 524 | struct iwl_mvm { |
516 | /* for logger access */ | 525 | /* for logger access */ |
517 | struct device *dev; | 526 | struct device *dev; |
@@ -553,9 +562,8 @@ struct iwl_mvm { | |||
553 | 562 | ||
554 | struct mvm_statistics_rx rx_stats; | 563 | struct mvm_statistics_rx rx_stats; |
555 | 564 | ||
556 | unsigned long transport_queue_stop; | ||
557 | u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; | 565 | u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; |
558 | atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; | 566 | atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES]; |
559 | 567 | ||
560 | const char *nvm_file_name; | 568 | const char *nvm_file_name; |
561 | struct iwl_nvm_data *nvm_data; | 569 | struct iwl_nvm_data *nvm_data; |
@@ -694,6 +702,12 @@ struct iwl_mvm { | |||
694 | /* Thermal Throttling and CTkill */ | 702 | /* Thermal Throttling and CTkill */ |
695 | struct iwl_mvm_tt_mgmt thermal_throttle; | 703 | struct iwl_mvm_tt_mgmt thermal_throttle; |
696 | s32 temperature; /* Celsius */ | 704 | s32 temperature; /* Celsius */ |
705 | /* | ||
706 | * Debug option to set the NIC temperature. This option makes the | ||
707 | * driver think this is the actual NIC temperature, and ignore the | ||
708 | * real temperature that is received from the fw | ||
709 | */ | ||
710 | bool temperature_test; /* Debug test temperature is enabled */ | ||
697 | 711 | ||
698 | #ifdef CONFIG_NL80211_TESTMODE | 712 | #ifdef CONFIG_NL80211_TESTMODE |
699 | u32 noa_duration; | 713 | u32 noa_duration; |
@@ -706,7 +720,7 @@ struct iwl_mvm { | |||
706 | u8 last_agg_queue; | 720 | u8 last_agg_queue; |
707 | 721 | ||
708 | /* Indicate if device power save is allowed */ | 722 | /* Indicate if device power save is allowed */ |
709 | bool ps_disabled; | 723 | u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */ |
710 | 724 | ||
711 | struct ieee80211_vif __rcu *csa_vif; | 725 | struct ieee80211_vif __rcu *csa_vif; |
712 | struct ieee80211_vif __rcu *csa_tx_blocked_vif; | 726 | struct ieee80211_vif __rcu *csa_tx_blocked_vif; |
@@ -714,6 +728,8 @@ struct iwl_mvm { | |||
714 | 728 | ||
715 | /* system time of last beacon (for AP/GO interface) */ | 729 | /* system time of last beacon (for AP/GO interface) */ |
716 | u32 ap_last_beacon_gp2; | 730 | u32 ap_last_beacon_gp2; |
731 | |||
732 | u8 low_latency_agg_frame_limit; | ||
717 | }; | 733 | }; |
718 | 734 | ||
719 | /* Extract MVM priv from op_mode and _hw */ | 735 | /* Extract MVM priv from op_mode and _hw */ |
@@ -878,7 +894,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | |||
878 | void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 894 | void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
879 | int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 895 | int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
880 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 896 | int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
881 | bool force_assoc_off); | 897 | bool force_assoc_off, const u8 *bssid_override); |
882 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 898 | int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
883 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, | 899 | u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm, |
884 | struct ieee80211_vif *vif); | 900 | struct ieee80211_vif *vif); |
@@ -968,6 +984,7 @@ int rs_pretty_print_rate(char *buf, const u32 rate); | |||
968 | /* power management */ | 984 | /* power management */ |
969 | int iwl_mvm_power_update_device(struct iwl_mvm *mvm); | 985 | int iwl_mvm_power_update_device(struct iwl_mvm *mvm); |
970 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm); | 986 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm); |
987 | int iwl_mvm_power_update_ps(struct iwl_mvm *mvm); | ||
971 | int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 988 | int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
972 | char *buf, int bufsz); | 989 | char *buf, int bufsz); |
973 | 990 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index cfdd314fdd5d..4fafd4bd89f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/offloading.c b/drivers/net/wireless/iwlwifi/mvm/offloading.c index 9bfb95e89cfb..adcbf4c8edd8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/offloading.c +++ b/drivers/net/wireless/iwlwifi/mvm/offloading.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 610dbcb0dc27..87f278cc9b2c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -415,6 +417,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
415 | mvm->first_agg_queue = 12; | 417 | mvm->first_agg_queue = 12; |
416 | } | 418 | } |
417 | mvm->sf_state = SF_UNINIT; | 419 | mvm->sf_state = SF_UNINIT; |
420 | mvm->low_latency_agg_frame_limit = 1; | ||
418 | 421 | ||
419 | mutex_init(&mvm->mutex); | 422 | mutex_init(&mvm->mutex); |
420 | mutex_init(&mvm->d0i3_suspend_mutex); | 423 | mutex_init(&mvm->d0i3_suspend_mutex); |
@@ -456,7 +459,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
456 | trans_cfg.command_names = iwl_mvm_cmd_strings; | 459 | trans_cfg.command_names = iwl_mvm_cmd_strings; |
457 | 460 | ||
458 | trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; | 461 | trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; |
459 | trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO; | 462 | trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; |
460 | 463 | ||
461 | snprintf(mvm->hw->wiphy->fw_version, | 464 | snprintf(mvm->hw->wiphy->fw_version, |
462 | sizeof(mvm->hw->wiphy->fw_version), | 465 | sizeof(mvm->hw->wiphy->fw_version), |
@@ -494,7 +497,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
494 | goto out_free; | 497 | goto out_free; |
495 | 498 | ||
496 | /* | 499 | /* |
497 | * Even if nvm exists in the nvm_file driver should read agin the nvm | 500 | * Even if nvm exists in the nvm_file driver should read again the nvm |
498 | * from the nic because there might be entries that exist in the OTP | 501 | * from the nic because there might be entries that exist in the OTP |
499 | * and not in the file. | 502 | * and not in the file. |
500 | * for nics with no_power_up_nic_in_init: rely completley on nvm_file | 503 | * for nics with no_power_up_nic_in_init: rely completley on nvm_file |
@@ -700,14 +703,13 @@ static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
700 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) | 703 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) |
701 | return; | 704 | return; |
702 | 705 | ||
703 | if (atomic_inc_return(&mvm->queue_stop_count[mq]) > 1) { | 706 | if (atomic_inc_return(&mvm->mac80211_queue_stop_count[mq]) > 1) { |
704 | IWL_DEBUG_TX_QUEUES(mvm, | 707 | IWL_DEBUG_TX_QUEUES(mvm, |
705 | "queue %d (mac80211 %d) already stopped\n", | 708 | "queue %d (mac80211 %d) already stopped\n", |
706 | queue, mq); | 709 | queue, mq); |
707 | return; | 710 | return; |
708 | } | 711 | } |
709 | 712 | ||
710 | set_bit(mq, &mvm->transport_queue_stop); | ||
711 | ieee80211_stop_queue(mvm->hw, mq); | 713 | ieee80211_stop_queue(mvm->hw, mq); |
712 | } | 714 | } |
713 | 715 | ||
@@ -719,15 +721,13 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
719 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) | 721 | if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE)) |
720 | return; | 722 | return; |
721 | 723 | ||
722 | if (atomic_dec_return(&mvm->queue_stop_count[mq]) > 0) { | 724 | if (atomic_dec_return(&mvm->mac80211_queue_stop_count[mq]) > 0) { |
723 | IWL_DEBUG_TX_QUEUES(mvm, | 725 | IWL_DEBUG_TX_QUEUES(mvm, |
724 | "queue %d (mac80211 %d) already awake\n", | 726 | "queue %d (mac80211 %d) still stopped\n", |
725 | queue, mq); | 727 | queue, mq); |
726 | return; | 728 | return; |
727 | } | 729 | } |
728 | 730 | ||
729 | clear_bit(mq, &mvm->transport_queue_stop); | ||
730 | |||
731 | ieee80211_wake_queue(mvm->hw, mq); | 731 | ieee80211_wake_queue(mvm->hw, mq); |
732 | } | 732 | } |
733 | 733 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 6cc243f7cf60..12283b55ee84 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 2b2d10800a55..e7a6626fe839 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -198,8 +200,15 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, | |||
198 | } | 200 | } |
199 | } | 201 | } |
200 | 202 | ||
201 | if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) | 203 | if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { |
204 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
205 | /* set advanced pm flag with no uapsd ACs to enable ps-poll */ | ||
206 | if (mvmvif->dbgfs_pm.use_ps_poll) | ||
207 | cmd->flags |= | ||
208 | cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); | ||
209 | #endif | ||
202 | return; | 210 | return; |
211 | } | ||
203 | 212 | ||
204 | cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK); | 213 | cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK); |
205 | 214 | ||
@@ -497,13 +506,31 @@ struct iwl_power_vifs { | |||
497 | bool p2p_tdls; | 506 | bool p2p_tdls; |
498 | }; | 507 | }; |
499 | 508 | ||
500 | static void iwl_mvm_power_iterator(void *_data, u8 *mac, | 509 | static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac, |
501 | struct ieee80211_vif *vif) | 510 | struct ieee80211_vif *vif) |
502 | { | 511 | { |
503 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 512 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
504 | struct iwl_power_vifs *power_iterator = _data; | ||
505 | 513 | ||
506 | mvmvif->pm_enabled = false; | 514 | mvmvif->pm_enabled = false; |
515 | } | ||
516 | |||
517 | static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac, | ||
518 | struct ieee80211_vif *vif) | ||
519 | { | ||
520 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
521 | bool *disable_ps = _data; | ||
522 | |||
523 | if (mvmvif->phy_ctxt) | ||
524 | if (mvmvif->phy_ctxt->id < MAX_PHYS) | ||
525 | *disable_ps |= mvmvif->ps_disabled; | ||
526 | } | ||
527 | |||
528 | static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac, | ||
529 | struct ieee80211_vif *vif) | ||
530 | { | ||
531 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
532 | struct iwl_power_vifs *power_iterator = _data; | ||
533 | |||
507 | switch (ieee80211_vif_type_p2p(vif)) { | 534 | switch (ieee80211_vif_type_p2p(vif)) { |
508 | case NL80211_IFTYPE_P2P_DEVICE: | 535 | case NL80211_IFTYPE_P2P_DEVICE: |
509 | break; | 536 | break; |
@@ -559,9 +586,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac, | |||
559 | } | 586 | } |
560 | } | 587 | } |
561 | 588 | ||
562 | static void | 589 | static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm, |
563 | iwl_mvm_power_set_pm(struct iwl_mvm *mvm, | 590 | struct iwl_power_vifs *vifs) |
564 | struct iwl_power_vifs *vifs) | ||
565 | { | 591 | { |
566 | struct iwl_mvm_vif *bss_mvmvif = NULL; | 592 | struct iwl_mvm_vif *bss_mvmvif = NULL; |
567 | struct iwl_mvm_vif *p2p_mvmvif = NULL; | 593 | struct iwl_mvm_vif *p2p_mvmvif = NULL; |
@@ -571,10 +597,11 @@ iwl_mvm_power_set_pm(struct iwl_mvm *mvm, | |||
571 | 597 | ||
572 | lockdep_assert_held(&mvm->mutex); | 598 | lockdep_assert_held(&mvm->mutex); |
573 | 599 | ||
574 | /* get vifs info + set pm_enable to false */ | 600 | /* set pm_enable to false */ |
575 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | 601 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, |
576 | IEEE80211_IFACE_ITER_NORMAL, | 602 | IEEE80211_IFACE_ITER_NORMAL, |
577 | iwl_mvm_power_iterator, vifs); | 603 | iwl_mvm_power_disable_pm_iterator, |
604 | NULL); | ||
578 | 605 | ||
579 | if (vifs->bss_vif) | 606 | if (vifs->bss_vif) |
580 | bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif); | 607 | bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif); |
@@ -817,32 +844,92 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, | |||
817 | return ret; | 844 | return ret; |
818 | } | 845 | } |
819 | 846 | ||
820 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) | 847 | static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm) |
848 | { | ||
849 | bool disable_ps; | ||
850 | int ret; | ||
851 | |||
852 | /* disable PS if CAM */ | ||
853 | disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM); | ||
854 | /* ...or if any of the vifs require PS to be off */ | ||
855 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
856 | IEEE80211_IFACE_ITER_NORMAL, | ||
857 | iwl_mvm_power_ps_disabled_iterator, | ||
858 | &disable_ps); | ||
859 | |||
860 | /* update device power state if it has changed */ | ||
861 | if (mvm->ps_disabled != disable_ps) { | ||
862 | bool old_ps_disabled = mvm->ps_disabled; | ||
863 | |||
864 | mvm->ps_disabled = disable_ps; | ||
865 | ret = iwl_mvm_power_update_device(mvm); | ||
866 | if (ret) { | ||
867 | mvm->ps_disabled = old_ps_disabled; | ||
868 | return ret; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm, | ||
876 | struct iwl_power_vifs *vifs) | ||
821 | { | 877 | { |
822 | struct iwl_mvm_vif *mvmvif; | 878 | struct iwl_mvm_vif *mvmvif; |
879 | bool ba_enable; | ||
880 | |||
881 | if (!vifs->bf_vif) | ||
882 | return 0; | ||
883 | |||
884 | mvmvif = iwl_mvm_vif_from_mac80211(vifs->bf_vif); | ||
885 | |||
886 | ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled || | ||
887 | !vifs->bf_vif->bss_conf.ps || | ||
888 | iwl_mvm_vif_low_latency(mvmvif)); | ||
889 | |||
890 | return iwl_mvm_update_beacon_abort(mvm, vifs->bf_vif, ba_enable); | ||
891 | } | ||
892 | |||
893 | int iwl_mvm_power_update_ps(struct iwl_mvm *mvm) | ||
894 | { | ||
895 | struct iwl_power_vifs vifs = { | ||
896 | .mvm = mvm, | ||
897 | }; | ||
898 | int ret; | ||
899 | |||
900 | lockdep_assert_held(&mvm->mutex); | ||
901 | |||
902 | /* get vifs info */ | ||
903 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
904 | IEEE80211_IFACE_ITER_NORMAL, | ||
905 | iwl_mvm_power_get_vifs_iterator, &vifs); | ||
906 | |||
907 | ret = iwl_mvm_power_set_ps(mvm); | ||
908 | if (ret) | ||
909 | return ret; | ||
910 | |||
911 | return iwl_mvm_power_set_ba(mvm, &vifs); | ||
912 | } | ||
913 | |||
914 | int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) | ||
915 | { | ||
823 | struct iwl_power_vifs vifs = { | 916 | struct iwl_power_vifs vifs = { |
824 | .mvm = mvm, | 917 | .mvm = mvm, |
825 | }; | 918 | }; |
826 | bool ba_enable; | ||
827 | int ret; | 919 | int ret; |
828 | 920 | ||
829 | lockdep_assert_held(&mvm->mutex); | 921 | lockdep_assert_held(&mvm->mutex); |
830 | 922 | ||
923 | /* get vifs info */ | ||
924 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | ||
925 | IEEE80211_IFACE_ITER_NORMAL, | ||
926 | iwl_mvm_power_get_vifs_iterator, &vifs); | ||
927 | |||
831 | iwl_mvm_power_set_pm(mvm, &vifs); | 928 | iwl_mvm_power_set_pm(mvm, &vifs); |
832 | 929 | ||
833 | /* disable PS if CAM */ | 930 | ret = iwl_mvm_power_set_ps(mvm); |
834 | if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) { | 931 | if (ret) |
835 | mvm->ps_disabled = true; | 932 | return ret; |
836 | } else { | ||
837 | /* don't update device power state unless we add / remove monitor */ | ||
838 | if (vifs.monitor_vif) { | ||
839 | if (vifs.monitor_active) | ||
840 | mvm->ps_disabled = true; | ||
841 | ret = iwl_mvm_power_update_device(mvm); | ||
842 | if (ret) | ||
843 | return ret; | ||
844 | } | ||
845 | } | ||
846 | 933 | ||
847 | if (vifs.bss_vif) { | 934 | if (vifs.bss_vif) { |
848 | ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif); | 935 | ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif); |
@@ -856,16 +943,7 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) | |||
856 | return ret; | 943 | return ret; |
857 | } | 944 | } |
858 | 945 | ||
859 | if (!vifs.bf_vif) | 946 | return iwl_mvm_power_set_ba(mvm, &vifs); |
860 | return 0; | ||
861 | |||
862 | mvmvif = iwl_mvm_vif_from_mac80211(vifs.bf_vif); | ||
863 | |||
864 | ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled || | ||
865 | !vifs.bf_vif->bss_conf.ps || | ||
866 | iwl_mvm_vif_low_latency(mvmvif)); | ||
867 | |||
868 | return iwl_mvm_update_beacon_abort(mvm, vifs.bf_vif, ba_enable); | ||
869 | } | 947 | } |
870 | 948 | ||
871 | int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, | 949 | int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 4e20b3ce2b6a..5fd502db03d1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -161,6 +163,9 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm, | |||
161 | quota *= (beacon_int - mvm->noa_duration); | 163 | quota *= (beacon_int - mvm->noa_duration); |
162 | quota /= beacon_int; | 164 | quota /= beacon_int; |
163 | 165 | ||
166 | IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n", | ||
167 | le32_to_cpu(cmd->quotas[i].quota), quota); | ||
168 | |||
164 | cmd->quotas[i].quota = cpu_to_le32(quota); | 169 | cmd->quotas[i].quota = cpu_to_le32(quota); |
165 | } | 170 | } |
166 | #endif | 171 | #endif |
@@ -222,6 +227,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
222 | quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat; | 227 | quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat; |
223 | quota_rem = QUOTA_100 - n_non_lowlat * quota - | 228 | quota_rem = QUOTA_100 - n_non_lowlat * quota - |
224 | QUOTA_LOWLAT_MIN; | 229 | QUOTA_LOWLAT_MIN; |
230 | IWL_DEBUG_QUOTA(mvm, | ||
231 | "quota: low-latency binding active, remaining quota per other binding: %d\n", | ||
232 | quota); | ||
225 | } else if (num_active_macs) { | 233 | } else if (num_active_macs) { |
226 | /* | 234 | /* |
227 | * There are 0 or more than 1 low latency bindings, or all the | 235 | * There are 0 or more than 1 low latency bindings, or all the |
@@ -230,6 +238,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
230 | */ | 238 | */ |
231 | quota = QUOTA_100 / num_active_macs; | 239 | quota = QUOTA_100 / num_active_macs; |
232 | quota_rem = QUOTA_100 % num_active_macs; | 240 | quota_rem = QUOTA_100 % num_active_macs; |
241 | IWL_DEBUG_QUOTA(mvm, | ||
242 | "quota: splitting evenly per binding: %d\n", | ||
243 | quota); | ||
233 | } else { | 244 | } else { |
234 | /* values don't really matter - won't be used */ | 245 | /* values don't really matter - won't be used */ |
235 | quota = 0; | 246 | quota = 0; |
@@ -271,6 +282,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
271 | for (i = 0; i < MAX_BINDINGS; i++) { | 282 | for (i = 0; i < MAX_BINDINGS; i++) { |
272 | if (le32_to_cpu(cmd.quotas[i].quota) != 0) { | 283 | if (le32_to_cpu(cmd.quotas[i].quota) != 0) { |
273 | le32_add_cpu(&cmd.quotas[i].quota, quota_rem); | 284 | le32_add_cpu(&cmd.quotas[i].quota, quota_rem); |
285 | IWL_DEBUG_QUOTA(mvm, | ||
286 | "quota: giving remainder of %d to binding %d\n", | ||
287 | quota_rem, i); | ||
274 | break; | 288 | break; |
275 | } | 289 | } |
276 | } | 290 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index c70e959bf0e3..17002cf437db 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 7 | * under the terms of version 2 of the GNU General Public License as |
@@ -2678,6 +2679,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, | |||
2678 | int i; | 2679 | int i; |
2679 | int num_rates = ARRAY_SIZE(lq_cmd->rs_table); | 2680 | int num_rates = ARRAY_SIZE(lq_cmd->rs_table); |
2680 | __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate); | 2681 | __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate); |
2682 | u8 ant = (ucode_rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; | ||
2681 | 2683 | ||
2682 | for (i = 0; i < num_rates; i++) | 2684 | for (i = 0; i < num_rates; i++) |
2683 | lq_cmd->rs_table[i] = ucode_rate_le32; | 2685 | lq_cmd->rs_table[i] = ucode_rate_le32; |
@@ -2688,6 +2690,13 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, | |||
2688 | lq_cmd->mimo_delim = num_rates - 1; | 2690 | lq_cmd->mimo_delim = num_rates - 1; |
2689 | else | 2691 | else |
2690 | lq_cmd->mimo_delim = 0; | 2692 | lq_cmd->mimo_delim = 0; |
2693 | |||
2694 | lq_cmd->reduced_tpc = 0; | ||
2695 | |||
2696 | if (num_of_ant(ant) == 1) | ||
2697 | lq_cmd->single_stream_ant_msk = ant; | ||
2698 | |||
2699 | lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
2691 | } | 2700 | } |
2692 | #endif /* CONFIG_MAC80211_DEBUGFS */ | 2701 | #endif /* CONFIG_MAC80211_DEBUGFS */ |
2693 | 2702 | ||
@@ -2811,31 +2820,55 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm, | |||
2811 | const struct rs_rate *initial_rate) | 2820 | const struct rs_rate *initial_rate) |
2812 | { | 2821 | { |
2813 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; | 2822 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; |
2814 | u8 ant = initial_rate->ant; | 2823 | struct iwl_mvm_sta *mvmsta; |
2824 | struct iwl_mvm_vif *mvmvif; | ||
2825 | |||
2826 | lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; | ||
2827 | lq_cmd->agg_time_limit = | ||
2828 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | ||
2815 | 2829 | ||
2816 | #ifdef CONFIG_MAC80211_DEBUGFS | 2830 | #ifdef CONFIG_MAC80211_DEBUGFS |
2817 | if (lq_sta->pers.dbg_fixed_rate) { | 2831 | if (lq_sta->pers.dbg_fixed_rate) { |
2818 | rs_build_rates_table_from_fixed(mvm, lq_cmd, | 2832 | rs_build_rates_table_from_fixed(mvm, lq_cmd, |
2819 | lq_sta->band, | 2833 | lq_sta->band, |
2820 | lq_sta->pers.dbg_fixed_rate); | 2834 | lq_sta->pers.dbg_fixed_rate); |
2821 | lq_cmd->reduced_tpc = 0; | 2835 | return; |
2822 | ant = (lq_sta->pers.dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >> | 2836 | } |
2823 | RATE_MCS_ANT_POS; | ||
2824 | } else | ||
2825 | #endif | 2837 | #endif |
2826 | rs_build_rates_table(mvm, lq_sta, initial_rate); | 2838 | if (WARN_ON_ONCE(!sta || !initial_rate)) |
2839 | return; | ||
2827 | 2840 | ||
2828 | if (num_of_ant(ant) == 1) | 2841 | rs_build_rates_table(mvm, lq_sta, initial_rate); |
2829 | lq_cmd->single_stream_ant_msk = ant; | ||
2830 | 2842 | ||
2831 | lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | 2843 | if (num_of_ant(initial_rate->ant) == 1) |
2832 | lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; | 2844 | lq_cmd->single_stream_ant_msk = initial_rate->ant; |
2833 | 2845 | ||
2834 | lq_cmd->agg_time_limit = | 2846 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
2835 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | 2847 | mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); |
2848 | |||
2849 | if (num_of_ant(initial_rate->ant) == 1) | ||
2850 | lq_cmd->single_stream_ant_msk = initial_rate->ant; | ||
2851 | |||
2852 | lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; | ||
2836 | 2853 | ||
2837 | if (sta) | 2854 | /* |
2838 | lq_cmd->agg_time_limit = | 2855 | * In case of low latency, tell the firwmare to leave a frame in the |
2856 | * Tx Fifo so that it can start a transaction in the same TxOP. This | ||
2857 | * basically allows the firmware to send bursts. | ||
2858 | */ | ||
2859 | if (iwl_mvm_vif_low_latency(mvmvif)) { | ||
2860 | lq_cmd->agg_frame_cnt_limit--; | ||
2861 | |||
2862 | if (mvm->low_latency_agg_frame_limit) | ||
2863 | lq_cmd->agg_frame_cnt_limit = | ||
2864 | min(lq_cmd->agg_frame_cnt_limit, | ||
2865 | mvm->low_latency_agg_frame_limit); | ||
2866 | } | ||
2867 | |||
2868 | if (mvmsta->vif->p2p) | ||
2869 | lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK; | ||
2870 | |||
2871 | lq_cmd->agg_time_limit = | ||
2839 | cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); | 2872 | cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); |
2840 | } | 2873 | } |
2841 | 2874 | ||
@@ -2932,10 +2965,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm, | |||
2932 | lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); | 2965 | lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate); |
2933 | 2966 | ||
2934 | if (lq_sta->pers.dbg_fixed_rate) { | 2967 | if (lq_sta->pers.dbg_fixed_rate) { |
2935 | struct rs_rate rate; | 2968 | rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL); |
2936 | rs_rate_from_ucode_rate(lq_sta->pers.dbg_fixed_rate, | ||
2937 | lq_sta->band, &rate); | ||
2938 | rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate); | ||
2939 | iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false); | 2969 | iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false); |
2940 | } | 2970 | } |
2941 | } | 2971 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 4b98987fc413..48144e3ad527 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -491,10 +493,29 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, | |||
491 | .mvm = mvm, | 493 | .mvm = mvm, |
492 | }; | 494 | }; |
493 | 495 | ||
496 | /* | ||
497 | * set temperature debug enabled - ignore FW temperature updates | ||
498 | * and use the user set temperature. | ||
499 | */ | ||
500 | if (mvm->temperature_test) { | ||
501 | if (mvm->temperature < le32_to_cpu(common->temperature)) | ||
502 | IWL_DEBUG_TEMP(mvm, | ||
503 | "Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n", | ||
504 | mvm->temperature, | ||
505 | le32_to_cpu(common->temperature)); | ||
506 | /* | ||
507 | * skip iwl_mvm_tt_handler since we are in | ||
508 | * temperature debug mode and we are ignoring | ||
509 | * the new temperature value | ||
510 | */ | ||
511 | goto update; | ||
512 | } | ||
513 | |||
494 | if (mvm->temperature != le32_to_cpu(common->temperature)) { | 514 | if (mvm->temperature != le32_to_cpu(common->temperature)) { |
495 | mvm->temperature = le32_to_cpu(common->temperature); | 515 | mvm->temperature = le32_to_cpu(common->temperature); |
496 | iwl_mvm_tt_handler(mvm); | 516 | iwl_mvm_tt_handler(mvm); |
497 | } | 517 | } |
518 | update: | ||
498 | iwl_mvm_update_rx_statistics(mvm, stats); | 519 | iwl_mvm_update_rx_statistics(mvm, stats); |
499 | 520 | ||
500 | ieee80211_iterate_active_interfaces(mvm->hw, | 521 | ieee80211_iterate_active_interfaces(mvm->hw, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 004b1f5d0314..bf9c63dc4a7d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -279,6 +281,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
279 | { | 281 | { |
280 | bool global_bound = false; | 282 | bool global_bound = false; |
281 | enum ieee80211_band band; | 283 | enum ieee80211_band band; |
284 | u8 frag_passive_dwell = 0; | ||
282 | 285 | ||
283 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, | 286 | ieee80211_iterate_active_interfaces_atomic(mvm->hw, |
284 | IEEE80211_IFACE_ITER_NORMAL, | 287 | IEEE80211_IFACE_ITER_NORMAL, |
@@ -288,12 +291,36 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
288 | if (!global_bound) | 291 | if (!global_bound) |
289 | goto not_bound; | 292 | goto not_bound; |
290 | 293 | ||
291 | params->suspend_time = 100; | 294 | params->suspend_time = 30; |
292 | params->max_out_time = 600; | 295 | params->max_out_time = 170; |
293 | 296 | ||
294 | if (iwl_mvm_low_latency(mvm)) { | 297 | if (iwl_mvm_low_latency(mvm)) { |
295 | params->suspend_time = 250; | 298 | if (mvm->fw->ucode_capa.api[0] & |
296 | params->max_out_time = 250; | 299 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { |
300 | params->suspend_time = 105; | ||
301 | params->max_out_time = 70; | ||
302 | frag_passive_dwell = 20; | ||
303 | } else { | ||
304 | params->suspend_time = 120; | ||
305 | params->max_out_time = 120; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | if (frag_passive_dwell && (mvm->fw->ucode_capa.api[0] & | ||
310 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) { | ||
311 | /* | ||
312 | * P2P device scan should not be fragmented to avoid negative | ||
313 | * impact on P2P device discovery. Configure max_out_time to be | ||
314 | * equal to dwell time on passive channel. Take a longest | ||
315 | * possible value, one that corresponds to 2GHz band | ||
316 | */ | ||
317 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | ||
318 | u32 passive_dwell = | ||
319 | iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); | ||
320 | params->max_out_time = passive_dwell; | ||
321 | } else { | ||
322 | params->passive_fragmented = true; | ||
323 | } | ||
297 | } | 324 | } |
298 | 325 | ||
299 | if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY) | 326 | if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY) |
@@ -302,7 +329,11 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
302 | not_bound: | 329 | not_bound: |
303 | 330 | ||
304 | for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { | 331 | for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { |
305 | params->dwell[band].passive = iwl_mvm_get_passive_dwell(band); | 332 | if (params->passive_fragmented) |
333 | params->dwell[band].passive = frag_passive_dwell; | ||
334 | else | ||
335 | params->dwell[band].passive = | ||
336 | iwl_mvm_get_passive_dwell(band); | ||
306 | params->dwell[band].active = iwl_mvm_get_active_dwell(band, | 337 | params->dwell[band].active = iwl_mvm_get_active_dwell(band, |
307 | n_ssids); | 338 | n_ssids); |
308 | } | 339 | } |
@@ -1100,10 +1131,11 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, | |||
1100 | struct iwl_mvm_scan_params *params) | 1131 | struct iwl_mvm_scan_params *params) |
1101 | { | 1132 | { |
1102 | memset(cmd, 0, ksize(cmd)); | 1133 | memset(cmd, 0, ksize(cmd)); |
1103 | cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active; | 1134 | cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active; |
1104 | cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive; | 1135 | cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; |
1105 | /* TODO: Use params; now fragmented isn't used. */ | 1136 | if (params->passive_fragmented) |
1106 | cmd->fragmented_dwell = 0; | 1137 | cmd->fragmented_dwell = |
1138 | params->dwell[IEEE80211_BAND_2GHZ].passive; | ||
1107 | cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); | 1139 | cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); |
1108 | cmd->max_out_time = cpu_to_le32(params->max_out_time); | 1140 | cmd->max_out_time = cpu_to_le32(params->max_out_time); |
1109 | cmd->suspend_time = cpu_to_le32(params->suspend_time); | 1141 | cmd->suspend_time = cpu_to_le32(params->suspend_time); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c index 7edfd15efc9d..d1922afe06f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/iwlwifi/mvm/sf.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 763548880399..dd9f3a4347f6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -250,10 +252,14 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, | |||
250 | if (ret) | 252 | if (ret) |
251 | return ret; | 253 | return ret; |
252 | 254 | ||
253 | /* The first station added is the AP, the others are TDLS STAs */ | 255 | if (vif->type == NL80211_IFTYPE_STATION) { |
254 | if (vif->type == NL80211_IFTYPE_STATION && | 256 | if (!sta->tdls) { |
255 | mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) | 257 | WARN_ON(mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT); |
256 | mvmvif->ap_sta_id = sta_id; | 258 | mvmvif->ap_sta_id = sta_id; |
259 | } else { | ||
260 | WARN_ON(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT); | ||
261 | } | ||
262 | } | ||
257 | 263 | ||
258 | rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); | 264 | rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta); |
259 | 265 | ||
@@ -458,8 +464,9 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm, | |||
458 | return ret; | 464 | return ret; |
459 | } | 465 | } |
460 | 466 | ||
461 | int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | 467 | static int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, |
462 | u32 qmask, enum nl80211_iftype iftype) | 468 | struct iwl_mvm_int_sta *sta, |
469 | u32 qmask, enum nl80211_iftype iftype) | ||
463 | { | 470 | { |
464 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | 471 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { |
465 | sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); | 472 | sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype); |
@@ -474,7 +481,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | |||
474 | return 0; | 481 | return 0; |
475 | } | 482 | } |
476 | 483 | ||
477 | void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta) | 484 | static void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, |
485 | struct iwl_mvm_int_sta *sta) | ||
478 | { | 486 | { |
479 | RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL); | 487 | RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL); |
480 | memset(sta, 0, sizeof(struct iwl_mvm_int_sta)); | 488 | memset(sta, 0, sizeof(struct iwl_mvm_int_sta)); |
@@ -544,6 +552,13 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) | |||
544 | return ret; | 552 | return ret; |
545 | } | 553 | } |
546 | 554 | ||
555 | void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm) | ||
556 | { | ||
557 | lockdep_assert_held(&mvm->mutex); | ||
558 | |||
559 | iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); | ||
560 | } | ||
561 | |||
547 | /* | 562 | /* |
548 | * Send the add station command for the vif's broadcast station. | 563 | * Send the add station command for the vif's broadcast station. |
549 | * Assumes that the station was already allocated. | 564 | * Assumes that the station was already allocated. |
@@ -552,10 +567,10 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) | |||
552 | * @vif: the interface to which the broadcast station is added | 567 | * @vif: the interface to which the broadcast station is added |
553 | * @bsta: the broadcast station to add. | 568 | * @bsta: the broadcast station to add. |
554 | */ | 569 | */ |
555 | int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 570 | int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
556 | struct iwl_mvm_int_sta *bsta) | ||
557 | { | 571 | { |
558 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 572 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
573 | struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta; | ||
559 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 574 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
560 | const u8 *baddr = _baddr; | 575 | const u8 *baddr = _baddr; |
561 | 576 | ||
@@ -573,19 +588,40 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
573 | 588 | ||
574 | /* Send the FW a request to remove the station from it's internal data | 589 | /* Send the FW a request to remove the station from it's internal data |
575 | * structures, but DO NOT remove the entry from the local data structures. */ | 590 | * structures, but DO NOT remove the entry from the local data structures. */ |
576 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | 591 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
577 | struct iwl_mvm_int_sta *bsta) | ||
578 | { | 592 | { |
593 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
579 | int ret; | 594 | int ret; |
580 | 595 | ||
581 | lockdep_assert_held(&mvm->mutex); | 596 | lockdep_assert_held(&mvm->mutex); |
582 | 597 | ||
583 | ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); | 598 | ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id); |
584 | if (ret) | 599 | if (ret) |
585 | IWL_WARN(mvm, "Failed sending remove station\n"); | 600 | IWL_WARN(mvm, "Failed sending remove station\n"); |
586 | return ret; | 601 | return ret; |
587 | } | 602 | } |
588 | 603 | ||
604 | int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
605 | { | ||
606 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
607 | u32 qmask; | ||
608 | |||
609 | lockdep_assert_held(&mvm->mutex); | ||
610 | |||
611 | qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | ||
612 | |||
613 | /* | ||
614 | * The firmware defines the TFD queue mask to only be relevant | ||
615 | * for *unicast* queues, so the multicast (CAB) queue shouldn't | ||
616 | * be included. | ||
617 | */ | ||
618 | if (vif->type == NL80211_IFTYPE_AP) | ||
619 | qmask &= ~BIT(vif->cab_queue); | ||
620 | |||
621 | return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask, | ||
622 | ieee80211_vif_type_p2p(vif)); | ||
623 | } | ||
624 | |||
589 | /* Allocate a new station entry for the broadcast station to the given vif, | 625 | /* Allocate a new station entry for the broadcast station to the given vif, |
590 | * and send it to the FW. | 626 | * and send it to the FW. |
591 | * Note that each P2P mac should have its own broadcast station. | 627 | * Note that each P2P mac should have its own broadcast station. |
@@ -593,45 +629,47 @@ int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | |||
593 | * @mvm: the mvm component | 629 | * @mvm: the mvm component |
594 | * @vif: the interface to which the broadcast station is added | 630 | * @vif: the interface to which the broadcast station is added |
595 | * @bsta: the broadcast station to add. */ | 631 | * @bsta: the broadcast station to add. */ |
596 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 632 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
597 | struct iwl_mvm_int_sta *bsta) | ||
598 | { | 633 | { |
599 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 634 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
600 | static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 635 | struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta; |
601 | u32 qmask; | ||
602 | int ret; | 636 | int ret; |
603 | 637 | ||
604 | lockdep_assert_held(&mvm->mutex); | 638 | lockdep_assert_held(&mvm->mutex); |
605 | 639 | ||
606 | qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | 640 | ret = iwl_mvm_alloc_bcast_sta(mvm, vif); |
607 | ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask, | ||
608 | ieee80211_vif_type_p2p(vif)); | ||
609 | if (ret) | 641 | if (ret) |
610 | return ret; | 642 | return ret; |
611 | 643 | ||
612 | ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr, | 644 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
613 | mvmvif->id, mvmvif->color); | ||
614 | 645 | ||
615 | if (ret) | 646 | if (ret) |
616 | iwl_mvm_dealloc_int_sta(mvm, bsta); | 647 | iwl_mvm_dealloc_int_sta(mvm, bsta); |
648 | |||
617 | return ret; | 649 | return ret; |
618 | } | 650 | } |
619 | 651 | ||
652 | void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
653 | { | ||
654 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
655 | |||
656 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | ||
657 | } | ||
658 | |||
620 | /* | 659 | /* |
621 | * Send the FW a request to remove the station from it's internal data | 660 | * Send the FW a request to remove the station from it's internal data |
622 | * structures, and in addition remove it from the local data structure. | 661 | * structures, and in addition remove it from the local data structure. |
623 | */ | 662 | */ |
624 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) | 663 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
625 | { | 664 | { |
626 | int ret; | 665 | int ret; |
627 | 666 | ||
628 | lockdep_assert_held(&mvm->mutex); | 667 | lockdep_assert_held(&mvm->mutex); |
629 | 668 | ||
630 | ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); | 669 | ret = iwl_mvm_send_rm_bcast_sta(mvm, vif); |
631 | if (ret) | 670 | |
632 | return ret; | 671 | iwl_mvm_dealloc_bcast_sta(mvm, vif); |
633 | 672 | ||
634 | iwl_mvm_dealloc_int_sta(mvm, bsta); | ||
635 | return ret; | 673 | return ret; |
636 | } | 674 | } |
637 | 675 | ||
@@ -910,7 +948,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
910 | } | 948 | } |
911 | 949 | ||
912 | tid_data->ssn = 0xffff; | 950 | tid_data->ssn = 0xffff; |
913 | iwl_trans_txq_disable(mvm->trans, txq_id); | 951 | iwl_trans_txq_disable(mvm->trans, txq_id, true); |
914 | /* fall through */ | 952 | /* fall through */ |
915 | case IWL_AGG_STARTING: | 953 | case IWL_AGG_STARTING: |
916 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 954 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
@@ -965,7 +1003,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
965 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) | 1003 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) |
966 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | 1004 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); |
967 | 1005 | ||
968 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | 1006 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); |
969 | } | 1007 | } |
970 | 1008 | ||
971 | mvm->queue_to_mac80211[tid_data->txq_id] = | 1009 | mvm->queue_to_mac80211[tid_data->txq_id] = |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 3b1c8bd6cb54..aeb3a7f80ceb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -387,17 +389,15 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
387 | struct ieee80211_sta *sta, u16 tid); | 389 | struct ieee80211_sta *sta, u16 tid); |
388 | 390 | ||
389 | int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); | 391 | int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); |
390 | int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | 392 | void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm); |
391 | u32 qmask, enum nl80211_iftype iftype); | 393 | |
392 | void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, | 394 | int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
393 | struct iwl_mvm_int_sta *sta); | 395 | int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
394 | int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 396 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
395 | struct iwl_mvm_int_sta *bsta); | 397 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
396 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | 398 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
397 | struct iwl_mvm_int_sta *bsta); | 399 | void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
398 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 400 | |
399 | struct iwl_mvm_int_sta *bsta); | ||
400 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta); | ||
401 | void iwl_mvm_sta_drained_wk(struct work_struct *wk); | 401 | void iwl_mvm_sta_drained_wk(struct work_struct *wk); |
402 | void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, | 402 | void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, |
403 | struct ieee80211_sta *sta); | 403 | struct ieee80211_sta *sta); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h index 0241665925f7..79ab6beb6b26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/testmode.h +++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 33e5041f1efc..447d3b1003df 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -348,6 +350,38 @@ unlock: | |||
348 | return 0; | 350 | return 0; |
349 | } | 351 | } |
350 | 352 | ||
353 | static bool iwl_mvm_te_notif(struct iwl_notif_wait_data *notif_wait, | ||
354 | struct iwl_rx_packet *pkt, void *data) | ||
355 | { | ||
356 | struct iwl_mvm *mvm = | ||
357 | container_of(notif_wait, struct iwl_mvm, notif_wait); | ||
358 | struct iwl_mvm_time_event_data *te_data = data; | ||
359 | struct iwl_time_event_notif *resp; | ||
360 | int resp_len = iwl_rx_packet_payload_len(pkt); | ||
361 | |||
362 | if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_NOTIFICATION)) | ||
363 | return true; | ||
364 | |||
365 | if (WARN_ON_ONCE(resp_len != sizeof(*resp))) { | ||
366 | IWL_ERR(mvm, "Invalid TIME_EVENT_NOTIFICATION response\n"); | ||
367 | return true; | ||
368 | } | ||
369 | |||
370 | resp = (void *)pkt->data; | ||
371 | |||
372 | /* te_data->uid is already set in the TIME_EVENT_CMD response */ | ||
373 | if (le32_to_cpu(resp->unique_id) != te_data->uid) | ||
374 | return false; | ||
375 | |||
376 | IWL_DEBUG_TE(mvm, "TIME_EVENT_NOTIFICATION response - UID = 0x%x\n", | ||
377 | te_data->uid); | ||
378 | if (!resp->status) | ||
379 | IWL_ERR(mvm, | ||
380 | "TIME_EVENT_NOTIFICATION received but not executed\n"); | ||
381 | |||
382 | return true; | ||
383 | } | ||
384 | |||
351 | static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait, | 385 | static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait, |
352 | struct iwl_rx_packet *pkt, void *data) | 386 | struct iwl_rx_packet *pkt, void *data) |
353 | { | 387 | { |
@@ -441,10 +475,12 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm, | |||
441 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, | 475 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, |
442 | struct ieee80211_vif *vif, | 476 | struct ieee80211_vif *vif, |
443 | u32 duration, u32 min_duration, | 477 | u32 duration, u32 min_duration, |
444 | u32 max_delay) | 478 | u32 max_delay, bool wait_for_notif) |
445 | { | 479 | { |
446 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 480 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
447 | struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; | 481 | struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; |
482 | const u8 te_notif_response[] = { TIME_EVENT_NOTIFICATION }; | ||
483 | struct iwl_notification_wait wait_te_notif; | ||
448 | struct iwl_time_event_cmd time_cmd = {}; | 484 | struct iwl_time_event_cmd time_cmd = {}; |
449 | 485 | ||
450 | lockdep_assert_held(&mvm->mutex); | 486 | lockdep_assert_held(&mvm->mutex); |
@@ -489,7 +525,28 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, | |||
489 | TE_V2_NOTIF_HOST_EVENT_END | | 525 | TE_V2_NOTIF_HOST_EVENT_END | |
490 | T2_V2_START_IMMEDIATELY); | 526 | T2_V2_START_IMMEDIATELY); |
491 | 527 | ||
492 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | 528 | if (!wait_for_notif) { |
529 | iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); | ||
530 | return; | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * Create notification_wait for the TIME_EVENT_NOTIFICATION to use | ||
535 | * right after we send the time event | ||
536 | */ | ||
537 | iwl_init_notification_wait(&mvm->notif_wait, &wait_te_notif, | ||
538 | te_notif_response, | ||
539 | ARRAY_SIZE(te_notif_response), | ||
540 | iwl_mvm_te_notif, te_data); | ||
541 | |||
542 | /* If TE was sent OK - wait for the notification that started */ | ||
543 | if (iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd)) { | ||
544 | IWL_ERR(mvm, "Failed to add TE to protect session\n"); | ||
545 | iwl_remove_notification(&mvm->notif_wait, &wait_te_notif); | ||
546 | } else if (iwl_wait_notification(&mvm->notif_wait, &wait_te_notif, | ||
547 | TU_TO_JIFFIES(max_delay))) { | ||
548 | IWL_ERR(mvm, "Failed to protect session until TE\n"); | ||
549 | } | ||
493 | } | 550 | } |
494 | 551 | ||
495 | /* | 552 | /* |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 2f48a90d4ad3..bee3b2446b35 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -124,10 +126,12 @@ | |||
124 | * @min_duration: will start a new session if the current session will end | 126 | * @min_duration: will start a new session if the current session will end |
125 | * in less than min_duration. | 127 | * in less than min_duration. |
126 | * @max_delay: maximum delay before starting the time event (in TU) | 128 | * @max_delay: maximum delay before starting the time event (in TU) |
129 | * @wait_for_notif: true if it is required that a time event notification be | ||
130 | * waited for (that the time event has been scheduled before returning) | ||
127 | * | 131 | * |
128 | * This function can be used to start a session protection which means that the | 132 | * This function can be used to start a session protection which means that the |
129 | * fw will stay on the channel for %duration_ms milliseconds. This function | 133 | * fw will stay on the channel for %duration_ms milliseconds. This function |
130 | * will block (sleep) until the session starts. This function can also be used | 134 | * can block (sleep) until the session starts. This function can also be used |
131 | * to extend a currently running session. | 135 | * to extend a currently running session. |
132 | * This function is meant to be used for BSS association for example, where we | 136 | * This function is meant to be used for BSS association for example, where we |
133 | * want to make sure that the fw stays on the channel during the association. | 137 | * want to make sure that the fw stays on the channel during the association. |
@@ -135,7 +139,7 @@ | |||
135 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, | 139 | void iwl_mvm_protect_session(struct iwl_mvm *mvm, |
136 | struct ieee80211_vif *vif, | 140 | struct ieee80211_vif *vif, |
137 | u32 duration, u32 min_duration, | 141 | u32 duration, u32 min_duration, |
138 | u32 max_delay); | 142 | u32 max_delay, bool wait_for_notif); |
139 | 143 | ||
140 | /** | 144 | /** |
141 | * iwl_mvm_stop_session_protection - cancel the session protection. | 145 | * iwl_mvm_stop_session_protection - cancel the session protection. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index 0464599c111e..c3e1fe4282f1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -314,14 +316,26 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) | |||
314 | { | 316 | { |
315 | u32 duration = mvm->thermal_throttle.params->ct_kill_duration; | 317 | u32 duration = mvm->thermal_throttle.params->ct_kill_duration; |
316 | 318 | ||
319 | if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) | ||
320 | return; | ||
321 | |||
317 | IWL_ERR(mvm, "Enter CT Kill\n"); | 322 | IWL_ERR(mvm, "Enter CT Kill\n"); |
318 | iwl_mvm_set_hw_ctkill_state(mvm, true); | 323 | iwl_mvm_set_hw_ctkill_state(mvm, true); |
319 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | 324 | |
320 | round_jiffies_relative(duration * HZ)); | 325 | /* Don't schedule an exit work if we're in test mode, since |
326 | * the temperature will not change unless we manually set it | ||
327 | * again (or disable testing). | ||
328 | */ | ||
329 | if (!mvm->temperature_test) | ||
330 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | ||
331 | round_jiffies_relative(duration * HZ)); | ||
321 | } | 332 | } |
322 | 333 | ||
323 | static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) | 334 | static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) |
324 | { | 335 | { |
336 | if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) | ||
337 | return; | ||
338 | |||
325 | IWL_ERR(mvm, "Exit CT Kill\n"); | 339 | IWL_ERR(mvm, "Exit CT Kill\n"); |
326 | iwl_mvm_set_hw_ctkill_state(mvm, false); | 340 | iwl_mvm_set_hw_ctkill_state(mvm, false); |
327 | } | 341 | } |
@@ -444,6 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm) | |||
444 | return; | 458 | return; |
445 | } | 459 | } |
446 | 460 | ||
461 | if (params->support_ct_kill && | ||
462 | temperature <= tt->params->ct_kill_exit) { | ||
463 | iwl_mvm_exit_ctkill(mvm); | ||
464 | return; | ||
465 | } | ||
466 | |||
447 | if (params->support_dynamic_smps) { | 467 | if (params->support_dynamic_smps) { |
448 | if (!tt->dynamic_smps && | 468 | if (!tt->dynamic_smps && |
449 | temperature >= params->dynamic_smps_entry) { | 469 | temperature >= params->dynamic_smps_entry) { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index dbc870713882..963edb8656ad 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -482,7 +484,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, | |||
482 | IWL_DEBUG_TX_QUEUES(mvm, | 484 | IWL_DEBUG_TX_QUEUES(mvm, |
483 | "Can continue DELBA flow ssn = next_recl = %d\n", | 485 | "Can continue DELBA flow ssn = next_recl = %d\n", |
484 | tid_data->next_reclaimed); | 486 | tid_data->next_reclaimed); |
485 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); | 487 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); |
486 | tid_data->state = IWL_AGG_OFF; | 488 | tid_data->state = IWL_AGG_OFF; |
487 | /* | 489 | /* |
488 | * we can't hold the mutex - but since we are after a sequence | 490 | * we can't hold the mutex - but since we are after a sequence |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index ac249da8a22b..1958f298ac8b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
@@ -387,15 +389,19 @@ struct iwl_error_event_table { | |||
387 | struct iwl_umac_error_event_table { | 389 | struct iwl_umac_error_event_table { |
388 | u32 valid; /* (nonzero) valid, (0) log is empty */ | 390 | u32 valid; /* (nonzero) valid, (0) log is empty */ |
389 | u32 error_id; /* type of error */ | 391 | u32 error_id; /* type of error */ |
390 | u32 pc; /* program counter */ | ||
391 | u32 blink1; /* branch link */ | 392 | u32 blink1; /* branch link */ |
392 | u32 blink2; /* branch link */ | 393 | u32 blink2; /* branch link */ |
393 | u32 ilink1; /* interrupt link */ | 394 | u32 ilink1; /* interrupt link */ |
394 | u32 ilink2; /* interrupt link */ | 395 | u32 ilink2; /* interrupt link */ |
395 | u32 data1; /* error-specific data */ | 396 | u32 data1; /* error-specific data */ |
396 | u32 data2; /* error-specific data */ | 397 | u32 data2; /* error-specific data */ |
397 | u32 line; /* source code line of error */ | 398 | u32 data3; /* error-specific data */ |
398 | u32 umac_ver; /* umac version */ | 399 | u32 umac_fw_ver; /* UMAC version */ |
400 | u32 umac_fw_api_ver; /* UMAC FW API ver */ | ||
401 | u32 frame_pointer; /* core register 27*/ | ||
402 | u32 stack_pointer; /* core register 28 */ | ||
403 | u32 cmd_header; /* latest host cmd sent to UMAC */ | ||
404 | u32 nic_isr_pref; /* ISR status register */ | ||
399 | } __packed; | 405 | } __packed; |
400 | 406 | ||
401 | #define ERROR_START_OFFSET (1 * sizeof(u32)) | 407 | #define ERROR_START_OFFSET (1 * sizeof(u32)) |
@@ -409,7 +415,7 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm) | |||
409 | 415 | ||
410 | base = mvm->umac_error_event_table; | 416 | base = mvm->umac_error_event_table; |
411 | 417 | ||
412 | if (base < 0x800000 || base >= 0x80C000) { | 418 | if (base < 0x800000) { |
413 | IWL_ERR(mvm, | 419 | IWL_ERR(mvm, |
414 | "Not valid error log pointer 0x%08X for %s uCode\n", | 420 | "Not valid error log pointer 0x%08X for %s uCode\n", |
415 | base, | 421 | base, |
@@ -428,14 +434,19 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm) | |||
428 | 434 | ||
429 | IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, | 435 | IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, |
430 | desc_lookup(table.error_id)); | 436 | desc_lookup(table.error_id)); |
431 | IWL_ERR(mvm, "0x%08X | umac uPc\n", table.pc); | ||
432 | IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); | 437 | IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); |
433 | IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); | 438 | IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); |
434 | IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1); | 439 | IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1); |
435 | IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2); | 440 | IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2); |
436 | IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); | 441 | IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); |
437 | IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); | 442 | IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); |
438 | IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_ver); | 443 | IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3); |
444 | IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver); | ||
445 | IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver); | ||
446 | IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer); | ||
447 | IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer); | ||
448 | IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header); | ||
449 | IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref); | ||
439 | } | 450 | } |
440 | 451 | ||
441 | void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | 452 | void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index f0e722ced080..dbbbf23082a2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 78f72c34438a..a4fedc4a7448 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
@@ -364,9 +365,10 @@ int iwl_pcie_tx_init(struct iwl_trans *trans); | |||
364 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); | 365 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); |
365 | int iwl_pcie_tx_stop(struct iwl_trans *trans); | 366 | int iwl_pcie_tx_stop(struct iwl_trans *trans); |
366 | void iwl_pcie_tx_free(struct iwl_trans *trans); | 367 | void iwl_pcie_tx_free(struct iwl_trans *trans); |
367 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | 368 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, |
368 | int sta_id, int tid, int frame_limit, u16 ssn); | 369 | const struct iwl_trans_txq_scd_cfg *cfg); |
369 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); | 370 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue, |
371 | bool configure_scd); | ||
370 | int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 372 | int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
371 | struct iwl_device_cmd *dev_cmd, int txq_id); | 373 | struct iwl_device_cmd *dev_cmd, int txq_id); |
372 | void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); | 374 | void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index a2698e5e062c..702f47fb16fe 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 06e04aaf61ee..3076e0e9a490 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
9 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * 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 | * it under the terms of version 2 of the GNU General Public License as |
@@ -31,6 +32,7 @@ | |||
31 | * BSD LICENSE | 32 | * BSD LICENSE |
32 | * | 33 | * |
33 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 34 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
35 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | 36 | * All rights reserved. |
35 | * | 37 | * |
36 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 6acccb19c4f3..a6336b4aa3a4 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH | ||
4 | * | 5 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 6 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 7 | * as portions of the ieee80211 subsystem header files. |
@@ -34,6 +35,7 @@ | |||
34 | #include "iwl-csr.h" | 35 | #include "iwl-csr.h" |
35 | #include "iwl-prph.h" | 36 | #include "iwl-prph.h" |
36 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
38 | #include "iwl-scd.h" | ||
37 | #include "iwl-op-mode.h" | 39 | #include "iwl-op-mode.h" |
38 | #include "internal.h" | 40 | #include "internal.h" |
39 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 41 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
@@ -644,17 +646,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
644 | memset(txq, 0, sizeof(*txq)); | 646 | memset(txq, 0, sizeof(*txq)); |
645 | } | 647 | } |
646 | 648 | ||
647 | /* | ||
648 | * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask | ||
649 | */ | ||
650 | static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) | ||
651 | { | ||
652 | struct iwl_trans_pcie __maybe_unused *trans_pcie = | ||
653 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
654 | |||
655 | iwl_write_prph(trans, SCD_TXFACT, mask); | ||
656 | } | ||
657 | |||
658 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | 649 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) |
659 | { | 650 | { |
660 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 651 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -692,7 +683,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) | |||
692 | trans_pcie->cmd_fifo); | 683 | trans_pcie->cmd_fifo); |
693 | 684 | ||
694 | /* Activate all Tx DMA/FIFO channels */ | 685 | /* Activate all Tx DMA/FIFO channels */ |
695 | iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7)); | 686 | iwl_scd_activate_fifos(trans); |
696 | 687 | ||
697 | /* Enable DMA channel */ | 688 | /* Enable DMA channel */ |
698 | for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) | 689 | for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) |
@@ -745,7 +736,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) | |||
745 | /* Turn off all Tx DMA fifos */ | 736 | /* Turn off all Tx DMA fifos */ |
746 | spin_lock(&trans_pcie->irq_lock); | 737 | spin_lock(&trans_pcie->irq_lock); |
747 | 738 | ||
748 | iwl_pcie_txq_set_sched(trans, 0); | 739 | iwl_scd_deactivate_fifos(trans); |
749 | 740 | ||
750 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 741 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
751 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 742 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
@@ -886,7 +877,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) | |||
886 | spin_lock(&trans_pcie->irq_lock); | 877 | spin_lock(&trans_pcie->irq_lock); |
887 | 878 | ||
888 | /* Turn off all Tx DMA fifos */ | 879 | /* Turn off all Tx DMA fifos */ |
889 | iwl_write_prph(trans, SCD_TXFACT, 0); | 880 | iwl_scd_deactivate_fifos(trans); |
890 | 881 | ||
891 | /* Tell NIC where to find the "keep warm" buffer */ | 882 | /* Tell NIC where to find the "keep warm" buffer */ |
892 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | 883 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, |
@@ -1072,55 +1063,52 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | |||
1072 | return 0; | 1063 | return 0; |
1073 | } | 1064 | } |
1074 | 1065 | ||
1075 | static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans, | ||
1076 | u16 txq_id) | ||
1077 | { | ||
1078 | /* Simply stop the queue, but don't change any configuration; | ||
1079 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
1080 | iwl_write_prph(trans, | ||
1081 | SCD_QUEUE_STATUS_BITS(txq_id), | ||
1082 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
1083 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
1084 | } | ||
1085 | |||
1086 | /* Receiver address (actually, Rx station's index into station table), | 1066 | /* Receiver address (actually, Rx station's index into station table), |
1087 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ | 1067 | * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ |
1088 | #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) | 1068 | #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) |
1089 | 1069 | ||
1090 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | 1070 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, |
1091 | int sta_id, int tid, int frame_limit, u16 ssn) | 1071 | const struct iwl_trans_txq_scd_cfg *cfg) |
1092 | { | 1072 | { |
1093 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1073 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1074 | int fifo = -1; | ||
1094 | 1075 | ||
1095 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) | 1076 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) |
1096 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 1077 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
1097 | 1078 | ||
1098 | /* Stop this Tx queue before configuring it */ | 1079 | if (cfg) { |
1099 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1080 | fifo = cfg->fifo; |
1100 | 1081 | ||
1101 | /* Set this queue as a chain-building queue unless it is CMD queue */ | 1082 | /* Disable the scheduler prior configuring the cmd queue */ |
1102 | if (txq_id != trans_pcie->cmd_queue) | 1083 | if (txq_id == trans_pcie->cmd_queue) |
1103 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 1084 | iwl_scd_enable_set_active(trans, 0); |
1104 | 1085 | ||
1105 | /* If this queue is mapped to a certain station: it is an AGG queue */ | 1086 | /* Stop this Tx queue before configuring it */ |
1106 | if (sta_id >= 0) { | 1087 | iwl_scd_txq_set_inactive(trans, txq_id); |
1107 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | ||
1108 | 1088 | ||
1109 | /* Map receiver-address / traffic-ID to this queue */ | 1089 | /* Set this queue as a chain-building queue unless it is CMD */ |
1110 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); | 1090 | if (txq_id != trans_pcie->cmd_queue) |
1091 | iwl_scd_txq_set_chain(trans, txq_id); | ||
1111 | 1092 | ||
1112 | /* enable aggregations for the queue */ | 1093 | if (cfg->aggregate) { |
1113 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 1094 | u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); |
1114 | trans_pcie->txq[txq_id].ampdu = true; | 1095 | |
1115 | } else { | 1096 | /* Map receiver-address / traffic-ID to this queue */ |
1116 | /* | 1097 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); |
1117 | * disable aggregations for the queue, this will also make the | 1098 | |
1118 | * ra_tid mapping configuration irrelevant since it is now a | 1099 | /* enable aggregations for the queue */ |
1119 | * non-AGG queue. | 1100 | iwl_scd_txq_enable_agg(trans, txq_id); |
1120 | */ | 1101 | trans_pcie->txq[txq_id].ampdu = true; |
1121 | iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 1102 | } else { |
1103 | /* | ||
1104 | * disable aggregations for the queue, this will also | ||
1105 | * make the ra_tid mapping configuration irrelevant | ||
1106 | * since it is now a non-AGG queue. | ||
1107 | */ | ||
1108 | iwl_scd_txq_disable_agg(trans, txq_id); | ||
1122 | 1109 | ||
1123 | ssn = trans_pcie->txq[txq_id].q.read_ptr; | 1110 | ssn = trans_pcie->txq[txq_id].q.read_ptr; |
1111 | } | ||
1124 | } | 1112 | } |
1125 | 1113 | ||
1126 | /* Place first TFD at index corresponding to start sequence number. | 1114 | /* Place first TFD at index corresponding to start sequence number. |
@@ -1128,32 +1116,43 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
1128 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); | 1116 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); |
1129 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); | 1117 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); |
1130 | 1118 | ||
1131 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 1119 | if (cfg) { |
1132 | (ssn & 0xff) | (txq_id << 8)); | 1120 | u8 frame_limit = cfg->frame_limit; |
1133 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | 1121 | |
1122 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | ||
1123 | (ssn & 0xff) | (txq_id << 8)); | ||
1124 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); | ||
1134 | 1125 | ||
1135 | /* Set up Tx window size and frame limit for this queue */ | 1126 | /* Set up Tx window size and frame limit for this queue */ |
1136 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + | 1127 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + |
1137 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | 1128 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); |
1138 | iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + | 1129 | iwl_trans_write_mem32(trans, |
1130 | trans_pcie->scd_base_addr + | ||
1139 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 1131 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
1140 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 1132 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
1141 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 1133 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
1142 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 1134 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
1143 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 1135 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
1144 | 1136 | ||
1145 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 1137 | /* Set up status area in SRAM, map to Tx DMA/FIFO, activate */ |
1146 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), | 1138 | iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), |
1147 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 1139 | (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
1148 | (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | | 1140 | (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | |
1149 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | | 1141 | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | |
1150 | SCD_QUEUE_STTS_REG_MSK); | 1142 | SCD_QUEUE_STTS_REG_MSK); |
1143 | |||
1144 | /* enable the scheduler for this queue (only) */ | ||
1145 | if (txq_id == trans_pcie->cmd_queue) | ||
1146 | iwl_scd_enable_set_active(trans, BIT(txq_id)); | ||
1147 | } | ||
1148 | |||
1151 | trans_pcie->txq[txq_id].active = true; | 1149 | trans_pcie->txq[txq_id].active = true; |
1152 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", | 1150 | IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", |
1153 | txq_id, fifo, ssn & 0xff); | 1151 | txq_id, fifo, ssn & 0xff); |
1154 | } | 1152 | } |
1155 | 1153 | ||
1156 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 1154 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, |
1155 | bool configure_scd) | ||
1157 | { | 1156 | { |
1158 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1157 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1159 | u32 stts_addr = trans_pcie->scd_base_addr + | 1158 | u32 stts_addr = trans_pcie->scd_base_addr + |
@@ -1172,10 +1171,12 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
1172 | return; | 1171 | return; |
1173 | } | 1172 | } |
1174 | 1173 | ||
1175 | iwl_pcie_txq_set_inactive(trans, txq_id); | 1174 | if (configure_scd) { |
1175 | iwl_scd_txq_set_inactive(trans, txq_id); | ||
1176 | 1176 | ||
1177 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, | 1177 | iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, |
1178 | ARRAY_SIZE(zero_val)); | 1178 | ARRAY_SIZE(zero_val)); |
1179 | } | ||
1179 | 1180 | ||
1180 | iwl_pcie_txq_unmap(trans, txq_id); | 1181 | iwl_pcie_txq_unmap(trans, txq_id); |
1181 | trans_pcie->txq[txq_id].ampdu = false; | 1182 | trans_pcie->txq[txq_id].ampdu = false; |