aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-08 13:15:39 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-08 13:15:39 -0500
commit74ecd3d1dd26f54ff36a0392f10e50fa8e256bd3 (patch)
tree878833c714ddcb35f1574f2b11e1f69d1130d206 /drivers
parentdcd607718385d02ce3741de225927a57f528f93b (diff)
parentc1f3bb6bd317994beb3af7bbec4bf54ed0035509 (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== Here is one more pull request for the 3.13 window. This is primarily composed of downstream pull requests that were posted while I was traveling during the last part of the 3.12 release. For the mac80211 bits, Johannes says: "I have two DFS fixes (ath9k already supports DFS) and a fix for a pointer race." And... "In this round for mac80211-next I have: * mesh channel switch support * a CCM rewrite, using potential hardware offloads * SMPS for AP mode * RF-kill GPIO driver updates to make it usable as an ACPI driver * regulatory improvements * documentation fixes * DFS for IBSS mode * and a few small other fixes/improvements" For the TI driver bits, Luca says: "Some patches intended for 3.13. Eliad continues upstreaming pending patches from the internal tree." For the iwlwifi bits, Emmanuel says: "There are a few fixes from Johannes mostly clean up patches. We have also a few other fixes that are relevant for the new firmware that has not been released yet." For the Bluetooth bits, Gustavo says: "A last fix to the 3.12. I ended forgetting to send it before, I hope we can still make the way to 3.12. It is a revert and it fixes an issue with bluetooth suspend/hibernate that had many bug reports. Please pull or let me know of any problems. Thanks!" (Obviously, that one didn't make 3.12...) Also... "One more big pull request for 3.13. These are the patches we queued during last week. Here you will find a lot of improvements to the HCI and L2CAP and MGMT layers with the main ones being a better debugfs support and end of work of splitting L2CAP into Core and Socket parts." Additionally, there is one ath9k patch to enable DFS in IBSS mode for that driver. I appreciate your consideration for taking this extra pull request this cycle. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c9
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c27
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c16
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c32
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c10
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c12
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h5
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c18
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c1
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c74
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c24
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h2
32 files changed, 244 insertions, 87 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 30868fa870f6..c0ff34f2d2df 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1629,7 +1629,6 @@ static struct usb_driver btusb_driver = {
1629#ifdef CONFIG_PM 1629#ifdef CONFIG_PM
1630 .suspend = btusb_suspend, 1630 .suspend = btusb_suspend,
1631 .resume = btusb_resume, 1631 .resume = btusb_resume,
1632 .reset_resume = btusb_resume,
1633#endif 1632#endif
1634 .id_table = btusb_table, 1633 .id_table = btusb_table,
1635 .supports_autosuspend = 1, 1634 .supports_autosuspend = 1,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index e89db64532f5..d8643ebabd30 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -845,7 +845,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
845}; 845};
846 846
847static const struct ieee80211_iface_limit if_dfs_limits[] = { 847static const struct ieee80211_iface_limit if_dfs_limits[] = {
848 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) }, 848 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) |
849 BIT(NL80211_IFTYPE_ADHOC) },
849}; 850};
850 851
851static const struct ieee80211_iface_combination if_comb[] = { 852static const struct ieee80211_iface_combination if_comb[] = {
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 86270b69cd02..63637949a146 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -330,15 +330,14 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
330 enum iwl_ucode_type old_type; 330 enum iwl_ucode_type old_type;
331 static const u8 alive_cmd[] = { REPLY_ALIVE }; 331 static const u8 alive_cmd[] = { REPLY_ALIVE };
332 332
333 old_type = priv->cur_ucode;
334 priv->cur_ucode = ucode_type;
335 fw = iwl_get_ucode_image(priv, ucode_type); 333 fw = iwl_get_ucode_image(priv, ucode_type);
334 if (WARN_ON(!fw))
335 return -EINVAL;
336 336
337 old_type = priv->cur_ucode;
338 priv->cur_ucode = ucode_type;
337 priv->ucode_loaded = false; 339 priv->ucode_loaded = false;
338 340
339 if (!fw)
340 return -EINVAL;
341
342 iwl_init_notification_wait(&priv->notif_wait, &alive_wait, 341 iwl_init_notification_wait(&priv->notif_wait, &alive_wait,
343 alive_cmd, ARRAY_SIZE(alive_cmd), 342 alive_cmd, ARRAY_SIZE(alive_cmd),
344 iwl_alive_fn, &alive_data); 343 iwl_alive_fn, &alive_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 87b66a821ec8..75db087120c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -100,7 +100,7 @@ enum iwl_ucode_tlv_flag {
100 IWL_UCODE_TLV_FLAGS_P2P = BIT(3), 100 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
101 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), 101 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
102 IWL_UCODE_TLV_FLAGS_NEWBT_COEX = BIT(5), 102 IWL_UCODE_TLV_FLAGS_NEWBT_COEX = BIT(5),
103 IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6), 103 IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT = BIT(6),
104 IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7), 104 IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
105 IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8), 105 IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8),
106 IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9), 106 IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9),
@@ -113,6 +113,7 @@ enum iwl_ucode_tlv_flag {
113 IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17), 113 IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
114 IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), 114 IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
115 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20), 115 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
116 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
116}; 117};
117 118
118/* The default calibrate table size if not specified by firmware file */ 119/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index dfa4d2e3aaa2..ad8e19a56eca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -34,7 +34,6 @@
34#include "iwl-csr.h" 34#include "iwl-csr.h"
35#include "iwl-debug.h" 35#include "iwl-debug.h"
36#include "iwl-fh.h" 36#include "iwl-fh.h"
37#include "iwl-csr.h"
38 37
39#define IWL_POLL_INTERVAL 10 /* microseconds */ 38#define IWL_POLL_INTERVAL 10 /* microseconds */
40 39
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index c6bac7c90b00..143292b4dbbf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -344,7 +344,7 @@ struct iwl_trans_config {
344 u8 cmd_queue; 344 u8 cmd_queue;
345 u8 cmd_fifo; 345 u8 cmd_fifo;
346 const u8 *no_reclaim_cmds; 346 const u8 *no_reclaim_cmds;
347 int n_no_reclaim_cmds; 347 unsigned int n_no_reclaim_cmds;
348 348
349 bool rx_buf_size_8k; 349 bool rx_buf_size_8k;
350 bool bc_table_dword; 350 bool bc_table_dword;
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 5b630f12bbff..5d066cbc5ac7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -505,12 +505,16 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
505 struct iwl_mvm_sta *mvmsta; 505 struct iwl_mvm_sta *mvmsta;
506 int ret; 506 int ret;
507 507
508 /* This can happen if the station has been removed right now */
509 if (sta_id == IWL_MVM_STATION_COUNT) 508 if (sta_id == IWL_MVM_STATION_COUNT)
510 return 0; 509 return 0;
511 510
512 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], 511 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
513 lockdep_is_held(&mvm->mutex)); 512 lockdep_is_held(&mvm->mutex));
513
514 /* This can happen if the station has been removed right now */
515 if (IS_ERR_OR_NULL(sta))
516 return 0;
517
514 mvmsta = (void *)sta->drv_priv; 518 mvmsta = (void *)sta->drv_priv;
515 519
516 /* nothing to do */ 520 /* nothing to do */
@@ -751,7 +755,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
751 755
752 cmd.bt_secondary_ci = 756 cmd.bt_secondary_ci =
753 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; 757 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
754 cmd.secondary_ch_phy_id = *((u16 *)data.primary->drv_priv); 758 cmd.secondary_ch_phy_id = *((u16 *)data.secondary->drv_priv);
755 } 759 }
756 760
757 rcu_read_unlock(); 761 rcu_read_unlock();
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 0675f0c8ef93..9864d713eb2c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -342,6 +342,7 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
342 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: 342 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
343 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); 343 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
344 dbgfs_pm->disable_power_off = val; 344 dbgfs_pm->disable_power_off = val;
345 break;
345 case MVM_DEBUGFS_PM_LPRX_ENA: 346 case MVM_DEBUGFS_PM_LPRX_ENA:
346 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled"); 347 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
347 dbgfs_pm->lprx_ena = val; 348 dbgfs_pm->lprx_ena = val;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 83fc5ca04433..70e5297646b2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -151,13 +151,11 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
151 enum iwl_ucode_type old_type = mvm->cur_ucode; 151 enum iwl_ucode_type old_type = mvm->cur_ucode;
152 static const u8 alive_cmd[] = { MVM_ALIVE }; 152 static const u8 alive_cmd[] = { MVM_ALIVE };
153 153
154 mvm->cur_ucode = ucode_type;
155 fw = iwl_get_ucode_image(mvm, ucode_type); 154 fw = iwl_get_ucode_image(mvm, ucode_type);
156 155 if (WARN_ON(!fw))
157 mvm->ucode_loaded = false;
158
159 if (!fw)
160 return -EINVAL; 156 return -EINVAL;
157 mvm->cur_ucode = ucode_type;
158 mvm->ucode_loaded = false;
161 159
162 iwl_init_notification_wait(&mvm->notif_wait, &alive_wait, 160 iwl_init_notification_wait(&mvm->notif_wait, &alive_wait,
163 alive_cmd, ARRAY_SIZE(alive_cmd), 161 alive_cmd, ARRAY_SIZE(alive_cmd),
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index ab5a7ac90dcd..f41f9b079831 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -719,7 +719,9 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
719 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | 719 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
720 MAC_FILTER_IN_CONTROL_AND_MGMT | 720 MAC_FILTER_IN_CONTROL_AND_MGMT |
721 MAC_FILTER_IN_BEACON | 721 MAC_FILTER_IN_BEACON |
722 MAC_FILTER_IN_PROBE_REQUEST); 722 MAC_FILTER_IN_PROBE_REQUEST |
723 MAC_FILTER_IN_CRC32);
724 mvm->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS;
723 725
724 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 726 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
725} 727}
@@ -1122,6 +1124,10 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1122 } 1124 }
1123 1125
1124 mvmvif->uploaded = false; 1126 mvmvif->uploaded = false;
1127
1128 if (vif->type == NL80211_IFTYPE_MONITOR)
1129 mvm->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
1130
1125 return 0; 1131 return 0;
1126} 1132}
1127 1133
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index f40685c3764e..74bc2c8af06d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -164,8 +164,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
164 IEEE80211_HW_TIMING_BEACON_ONLY | 164 IEEE80211_HW_TIMING_BEACON_ONLY |
165 IEEE80211_HW_CONNECTION_MONITOR | 165 IEEE80211_HW_CONNECTION_MONITOR |
166 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 166 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
167 IEEE80211_HW_SUPPORTS_STATIC_SMPS | 167 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
168 IEEE80211_HW_SUPPORTS_UAPSD;
169 168
170 hw->queues = mvm->first_agg_queue; 169 hw->queues = mvm->first_agg_queue;
171 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 170 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -180,6 +179,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
180 !iwlwifi_mod_params.sw_crypto) 179 !iwlwifi_mod_params.sw_crypto)
181 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 180 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
182 181
182 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT) {
183 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
184 hw->uapsd_queues = IWL_UAPSD_AC_INFO;
185 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
186 }
187
183 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 188 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
184 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 189 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
185 hw->chanctx_data_size = sizeof(u16); 190 hw->chanctx_data_size = sizeof(u16);
@@ -204,8 +209,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
204 209
205 hw->wiphy->max_remain_on_channel_duration = 10000; 210 hw->wiphy->max_remain_on_channel_duration = 10000;
206 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 211 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
207 hw->uapsd_queues = IWL_UAPSD_AC_INFO;
208 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
209 212
210 /* Extract MAC address */ 213 /* Extract MAC address */
211 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 214 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
@@ -861,7 +864,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
861 /* reset rssi values */ 864 /* reset rssi values */
862 mvmvif->bf_data.ave_beacon_signal = 0; 865 mvmvif->bf_data.ave_beacon_signal = 0;
863 866
864 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)) { 867 if (!(mvm->fw->ucode_capa.flags &
868 IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
865 /* Workaround for FW bug, otherwise FW disables device 869 /* Workaround for FW bug, otherwise FW disables device
866 * power save upon disassociation 870 * power save upon disassociation
867 */ 871 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 6235cb729f5c..fed21ef4162d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -73,7 +73,6 @@
73#include "iwl-trans.h" 73#include "iwl-trans.h"
74#include "iwl-notif-wait.h" 74#include "iwl-notif-wait.h"
75#include "iwl-eeprom-parse.h" 75#include "iwl-eeprom-parse.h"
76#include "iwl-trans.h"
77#include "sta.h" 76#include "sta.h"
78#include "fw-api.h" 77#include "fw-api.h"
79#include "constants.h" 78#include "constants.h"
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 59b7cb3c6134..d86083c6f445 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -459,7 +459,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
459 if (err) 459 if (err)
460 goto out_unregister; 460 goto out_unregister;
461 461
462 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD) 462 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)
463 mvm->pm_ops = &pm_mac_ops; 463 mvm->pm_ops = &pm_mac_ops;
464 else 464 else
465 mvm->pm_ops = &pm_legacy_ops; 465 mvm->pm_ops = &pm_legacy_ops;
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index a4af5019a496..3a1f3982109d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -300,10 +300,14 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
300 return 0; 300 return 0;
301 } 301 }
302 302
303 /*
304 * Keep packets with CRC errors (and with overrun) for monitor mode
305 * (otherwise the firmware discards them) but mark them as bad.
306 */
303 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_CRC_OK) || 307 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_CRC_OK) ||
304 !(rx_pkt_status & RX_MPDU_RES_STATUS_OVERRUN_OK)) { 308 !(rx_pkt_status & RX_MPDU_RES_STATUS_OVERRUN_OK)) {
305 IWL_DEBUG_RX(mvm, "Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status); 309 IWL_DEBUG_RX(mvm, "Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status);
306 return 0; 310 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
307 } 311 }
308 312
309 /* This will be used in several places later */ 313 /* This will be used in several places later */
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index f644fcf861a8..059c5acad3a0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1499,12 +1499,11 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1499 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", 1499 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
1500 get_cmd_string(trans_pcie, cmd->id)); 1500 get_cmd_string(trans_pcie, cmd->id));
1501 1501
1502 if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, 1502 if (WARN(test_and_set_bit(STATUS_HCMD_ACTIVE,
1503 &trans_pcie->status))) { 1503 &trans_pcie->status),
1504 IWL_ERR(trans, "Command %s: a command is already active!\n", 1504 "Command %s: a command is already active!\n",
1505 get_cmd_string(trans_pcie, cmd->id)); 1505 get_cmd_string(trans_pcie, cmd->id)))
1506 return -EIO; 1506 return -EIO;
1507 }
1508 1507
1509 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", 1508 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
1510 get_cmd_string(trans_pcie, cmd->id)); 1509 get_cmd_string(trans_pcie, cmd->id));
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 2cd3f54e1efa..de0df86704e7 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -167,6 +167,7 @@ struct hwsim_vif_priv {
167 u32 magic; 167 u32 magic;
168 u8 bssid[ETH_ALEN]; 168 u8 bssid[ETH_ALEN];
169 bool assoc; 169 bool assoc;
170 bool bcn_en;
170 u16 aid; 171 u16 aid;
171}; 172};
172 173
@@ -1170,6 +1171,16 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
1170 *total_flags = data->rx_filter; 1171 *total_flags = data->rx_filter;
1171} 1172}
1172 1173
1174static void mac80211_hwsim_bcn_en_iter(void *data, u8 *mac,
1175 struct ieee80211_vif *vif)
1176{
1177 unsigned int *count = data;
1178 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
1179
1180 if (vp->bcn_en)
1181 (*count)++;
1182}
1183
1173static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, 1184static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
1174 struct ieee80211_vif *vif, 1185 struct ieee80211_vif *vif,
1175 struct ieee80211_bss_conf *info, 1186 struct ieee80211_bss_conf *info,
@@ -1180,7 +1191,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
1180 1191
1181 hwsim_check_magic(vif); 1192 hwsim_check_magic(vif);
1182 1193
1183 wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed); 1194 wiphy_debug(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n",
1195 __func__, changed, vif->addr);
1184 1196
1185 if (changed & BSS_CHANGED_BSSID) { 1197 if (changed & BSS_CHANGED_BSSID) {
1186 wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n", 1198 wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n",
@@ -1202,6 +1214,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
1202 1214
1203 if (changed & BSS_CHANGED_BEACON_ENABLED) { 1215 if (changed & BSS_CHANGED_BEACON_ENABLED) {
1204 wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon); 1216 wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon);
1217 vp->bcn_en = info->enable_beacon;
1205 if (data->started && 1218 if (data->started &&
1206 !hrtimer_is_queued(&data->beacon_timer.timer) && 1219 !hrtimer_is_queued(&data->beacon_timer.timer) &&
1207 info->enable_beacon) { 1220 info->enable_beacon) {
@@ -1215,8 +1228,16 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
1215 tasklet_hrtimer_start(&data->beacon_timer, 1228 tasklet_hrtimer_start(&data->beacon_timer,
1216 ns_to_ktime(until_tbtt * 1000), 1229 ns_to_ktime(until_tbtt * 1000),
1217 HRTIMER_MODE_REL); 1230 HRTIMER_MODE_REL);
1218 } else if (!info->enable_beacon) 1231 } else if (!info->enable_beacon) {
1219 tasklet_hrtimer_cancel(&data->beacon_timer); 1232 unsigned int count = 0;
1233 ieee80211_iterate_active_interfaces(
1234 data->hw, IEEE80211_IFACE_ITER_NORMAL,
1235 mac80211_hwsim_bcn_en_iter, &count);
1236 wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u",
1237 count);
1238 if (count == 0)
1239 tasklet_hrtimer_cancel(&data->beacon_timer);
1240 }
1220 } 1241 }
1221 1242
1222 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 1243 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 591526b99154..be7129ba16ad 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -333,11 +333,11 @@ static struct wlcore_conf wl12xx_conf = {
333 .always = 0, 333 .always = 0,
334 }, 334 },
335 .fwlog = { 335 .fwlog = {
336 .mode = WL12XX_FWLOG_ON_DEMAND, 336 .mode = WL12XX_FWLOG_CONTINUOUS,
337 .mem_blocks = 2, 337 .mem_blocks = 2,
338 .severity = 0, 338 .severity = 0,
339 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, 339 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
340 .output = WL12XX_FWLOG_OUTPUT_HOST, 340 .output = WL12XX_FWLOG_OUTPUT_DBG_PINS,
341 .threshold = 0, 341 .threshold = 0,
342 }, 342 },
343 .rate = { 343 .rate = {
@@ -717,6 +717,9 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
717 goto out; 717 goto out;
718 } 718 }
719 719
720 wl->fw_mem_block_size = 256;
721 wl->fwlog_end = 0x2000000;
722
720 /* common settings */ 723 /* common settings */
721 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY; 724 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY;
722 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY; 725 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY;
@@ -1262,9 +1265,10 @@ static int wl12xx_boot(struct wl1271 *wl)
1262 BA_SESSION_RX_CONSTRAINT_EVENT_ID | 1265 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
1263 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | 1266 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
1264 INACTIVE_STA_EVENT_ID | 1267 INACTIVE_STA_EVENT_ID |
1265 MAX_TX_RETRY_EVENT_ID |
1266 CHANNEL_SWITCH_COMPLETE_EVENT_ID; 1268 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
1267 1269
1270 wl->ap_event_mask = MAX_TX_RETRY_EVENT_ID;
1271
1268 ret = wlcore_boot_run_firmware(wl); 1272 ret = wlcore_boot_run_firmware(wl);
1269 if (ret < 0) 1273 if (ret < 0)
1270 goto out; 1274 goto out;
@@ -1648,6 +1652,11 @@ static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1648 return true; 1652 return true;
1649} 1653}
1650 1654
1655static u32 wl12xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1656{
1657 return hwaddr << 5;
1658}
1659
1651static int wl12xx_setup(struct wl1271 *wl); 1660static int wl12xx_setup(struct wl1271 *wl);
1652 1661
1653static struct wlcore_ops wl12xx_ops = { 1662static struct wlcore_ops wl12xx_ops = {
@@ -1684,6 +1693,7 @@ static struct wlcore_ops wl12xx_ops = {
1684 .channel_switch = wl12xx_cmd_channel_switch, 1693 .channel_switch = wl12xx_cmd_channel_switch,
1685 .pre_pkt_send = NULL, 1694 .pre_pkt_send = NULL,
1686 .set_peer_cap = wl12xx_set_peer_cap, 1695 .set_peer_cap = wl12xx_set_peer_cap,
1696 .convert_hwaddr = wl12xx_convert_hwaddr,
1687 .lnk_high_prio = wl12xx_lnk_high_prio, 1697 .lnk_high_prio = wl12xx_lnk_high_prio,
1688 .lnk_low_prio = wl12xx_lnk_low_prio, 1698 .lnk_low_prio = wl12xx_lnk_low_prio,
1689}; 1699};
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index d0daca1d23bc..ec37b16585df 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -456,11 +456,11 @@ static struct wlcore_conf wl18xx_conf = {
456 .always = 0, 456 .always = 0,
457 }, 457 },
458 .fwlog = { 458 .fwlog = {
459 .mode = WL12XX_FWLOG_ON_DEMAND, 459 .mode = WL12XX_FWLOG_CONTINUOUS,
460 .mem_blocks = 2, 460 .mem_blocks = 2,
461 .severity = 0, 461 .severity = 0,
462 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, 462 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
463 .output = WL12XX_FWLOG_OUTPUT_HOST, 463 .output = WL12XX_FWLOG_OUTPUT_DBG_PINS,
464 .threshold = 0, 464 .threshold = 0,
465 }, 465 },
466 .rate = { 466 .rate = {
@@ -505,7 +505,7 @@ static struct wlcore_conf wl18xx_conf = {
505 505
506static struct wl18xx_priv_conf wl18xx_default_priv_conf = { 506static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
507 .ht = { 507 .ht = {
508 .mode = HT_MODE_DEFAULT, 508 .mode = HT_MODE_WIDE,
509 }, 509 },
510 .phy = { 510 .phy = {
511 .phy_standalone = 0x00, 511 .phy_standalone = 0x00,
@@ -516,7 +516,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
516 .auto_detect = 0x00, 516 .auto_detect = 0x00,
517 .dedicated_fem = FEM_NONE, 517 .dedicated_fem = FEM_NONE,
518 .low_band_component = COMPONENT_3_WAY_SWITCH, 518 .low_band_component = COMPONENT_3_WAY_SWITCH,
519 .low_band_component_type = 0x04, 519 .low_band_component_type = 0x05,
520 .high_band_component = COMPONENT_2_WAY_SWITCH, 520 .high_band_component = COMPONENT_2_WAY_SWITCH,
521 .high_band_component_type = 0x09, 521 .high_band_component_type = 0x09,
522 .tcxo_ldo_voltage = 0x00, 522 .tcxo_ldo_voltage = 0x00,
@@ -556,15 +556,15 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
556 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff, 556 .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff,
557 0xff, 0xff, 0xff }, 557 0xff, 0xff, 0xff },
558 .psat = 0, 558 .psat = 0,
559 .low_power_val = 0x08,
560 .med_power_val = 0x12,
561 .high_power_val = 0x18,
562 .low_power_val_2nd = 0x05,
563 .med_power_val_2nd = 0x0a,
564 .high_power_val_2nd = 0x14,
565 .external_pa_dc2dc = 0, 559 .external_pa_dc2dc = 0,
566 .number_of_assembled_ant2_4 = 2, 560 .number_of_assembled_ant2_4 = 2,
567 .number_of_assembled_ant5 = 1, 561 .number_of_assembled_ant5 = 1,
562 .low_power_val = 0xff,
563 .med_power_val = 0xff,
564 .high_power_val = 0xff,
565 .low_power_val_2nd = 0xff,
566 .med_power_val_2nd = 0xff,
567 .high_power_val_2nd = 0xff,
568 .tx_rf_margin = 1, 568 .tx_rf_margin = 1,
569 }, 569 },
570}; 570};
@@ -686,6 +686,9 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
686 goto out; 686 goto out;
687 } 687 }
688 688
689 wl->fw_mem_block_size = 272;
690 wl->fwlog_end = 0x40000000;
691
689 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 692 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
690 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 693 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
691 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC; 694 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
@@ -988,10 +991,11 @@ static int wl18xx_boot(struct wl1271 *wl)
988 BA_SESSION_RX_CONSTRAINT_EVENT_ID | 991 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
989 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | 992 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
990 INACTIVE_STA_EVENT_ID | 993 INACTIVE_STA_EVENT_ID |
991 MAX_TX_FAILURE_EVENT_ID |
992 CHANNEL_SWITCH_COMPLETE_EVENT_ID | 994 CHANNEL_SWITCH_COMPLETE_EVENT_ID |
993 DFS_CHANNELS_CONFIG_COMPLETE_EVENT; 995 DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
994 996
997 wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
998
995 ret = wlcore_boot_run_firmware(wl); 999 ret = wlcore_boot_run_firmware(wl);
996 if (ret < 0) 1000 if (ret < 0)
997 goto out; 1001 goto out;
@@ -1604,6 +1608,11 @@ static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1604 return lnk->allocated_pkts < thold; 1608 return lnk->allocated_pkts < thold;
1605} 1609}
1606 1610
1611static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1612{
1613 return hwaddr & ~0x80000000;
1614}
1615
1607static int wl18xx_setup(struct wl1271 *wl); 1616static int wl18xx_setup(struct wl1271 *wl);
1608 1617
1609static struct wlcore_ops wl18xx_ops = { 1618static struct wlcore_ops wl18xx_ops = {
@@ -1641,6 +1650,7 @@ static struct wlcore_ops wl18xx_ops = {
1641 .pre_pkt_send = wl18xx_pre_pkt_send, 1650 .pre_pkt_send = wl18xx_pre_pkt_send,
1642 .sta_rc_update = wl18xx_sta_rc_update, 1651 .sta_rc_update = wl18xx_sta_rc_update,
1643 .set_peer_cap = wl18xx_set_peer_cap, 1652 .set_peer_cap = wl18xx_set_peer_cap,
1653 .convert_hwaddr = wl18xx_convert_hwaddr,
1644 .lnk_high_prio = wl18xx_lnk_high_prio, 1654 .lnk_high_prio = wl18xx_lnk_high_prio,
1645 .lnk_low_prio = wl18xx_lnk_low_prio, 1655 .lnk_low_prio = wl18xx_lnk_low_prio,
1646}; 1656};
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index 7a970cd9c555..ec83675a2446 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -162,7 +162,8 @@ int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
162 162
163 wl1271_debug(DEBUG_ACX, "acx mem map"); 163 wl1271_debug(DEBUG_ACX, "acx mem map");
164 164
165 ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); 165 ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map,
166 sizeof(struct acx_header), len);
166 if (ret < 0) 167 if (ret < 0)
167 return ret; 168 return ret;
168 169
@@ -722,6 +723,7 @@ int wl1271_acx_statistics(struct wl1271 *wl, void *stats)
722 wl1271_debug(DEBUG_ACX, "acx statistics"); 723 wl1271_debug(DEBUG_ACX, "acx statistics");
723 724
724 ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, 725 ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
726 sizeof(struct acx_header),
725 wl->stats.fw_stats_len); 727 wl->stats.fw_stats_len);
726 if (ret < 0) { 728 if (ret < 0) {
727 wl1271_warning("acx statistics failed: %d", ret); 729 wl1271_warning("acx statistics failed: %d", ret);
@@ -1470,8 +1472,8 @@ int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1470 1472
1471 tsf_info->role_id = wlvif->role_id; 1473 tsf_info->role_id = wlvif->role_id;
1472 1474
1473 ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, 1475 ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, tsf_info,
1474 tsf_info, sizeof(*tsf_info)); 1476 sizeof(struct acx_header), sizeof(*tsf_info));
1475 if (ret < 0) { 1477 if (ret < 0) {
1476 wl1271_warning("acx tsf info interrogate failed"); 1478 wl1271_warning("acx tsf info interrogate failed");
1477 goto out; 1479 goto out;
@@ -1752,7 +1754,7 @@ int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1752 1754
1753 acx->role_id = wlvif->role_id; 1755 acx->role_id = wlvif->role_id;
1754 ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL, 1756 ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL,
1755 acx, sizeof(*acx)); 1757 acx, sizeof(*acx), sizeof(*acx));
1756 if (ret < 0) { 1758 if (ret < 0) {
1757 wl1271_warning("acx roaming statistics failed: %d", ret); 1759 wl1271_warning("acx roaming statistics failed: %d", ret);
1758 ret = -ENOMEM; 1760 ret = -ENOMEM;
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 9e5416f8764d..34d9dfff2ad3 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -60,7 +60,8 @@ static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf,
60 u16 status; 60 u16 status;
61 u16 poll_count = 0; 61 u16 poll_count = 0;
62 62
63 if (WARN_ON(unlikely(wl->state == WLCORE_STATE_RESTARTING))) 63 if (WARN_ON(wl->state == WLCORE_STATE_RESTARTING &&
64 id != CMD_STOP_FWLOGGER))
64 return -EIO; 65 return -EIO;
65 66
66 cmd = buf; 67 cmd = buf;
@@ -845,7 +846,8 @@ EXPORT_SYMBOL_GPL(wl1271_cmd_test);
845 * @buf: buffer for the response, including all headers, must work with dma 846 * @buf: buffer for the response, including all headers, must work with dma
846 * @len: length of buf 847 * @len: length of buf
847 */ 848 */
848int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) 849int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf,
850 size_t cmd_len, size_t res_len)
849{ 851{
850 struct acx_header *acx = buf; 852 struct acx_header *acx = buf;
851 int ret; 853 int ret;
@@ -854,10 +856,10 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
854 856
855 acx->id = cpu_to_le16(id); 857 acx->id = cpu_to_le16(id);
856 858
857 /* payload length, does not include any headers */ 859 /* response payload length, does not include any headers */
858 acx->len = cpu_to_le16(len - sizeof(*acx)); 860 acx->len = cpu_to_le16(res_len - sizeof(*acx));
859 861
860 ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len); 862 ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, cmd_len, res_len);
861 if (ret < 0) 863 if (ret < 0)
862 wl1271_error("INTERROGATE command failed"); 864 wl1271_error("INTERROGATE command failed");
863 865
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index fd34123047cd..323d4a856e4b 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -45,7 +45,8 @@ int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif,
45 enum ieee80211_band band, int channel); 45 enum ieee80211_band band, int channel);
46int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); 46int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif);
47int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); 47int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
48int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 48int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf,
49 size_t cmd_len, size_t res_len);
49int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 50int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
50int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf, 51int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf,
51 size_t len, unsigned long valid_rets); 52 size_t len, unsigned long valid_rets);
diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index 2b96ff821341..40995c42bef8 100644
--- a/drivers/net/wireless/ti/wlcore/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -1274,6 +1274,9 @@ struct conf_rx_streaming_settings {
1274 u8 always; 1274 u8 always;
1275} __packed; 1275} __packed;
1276 1276
1277#define CONF_FWLOG_MIN_MEM_BLOCKS 2
1278#define CONF_FWLOG_MAX_MEM_BLOCKS 16
1279
1277struct conf_fwlog { 1280struct conf_fwlog {
1278 /* Continuous or on-demand */ 1281 /* Continuous or on-demand */
1279 u8 mode; 1282 u8 mode;
@@ -1281,7 +1284,7 @@ struct conf_fwlog {
1281 /* 1284 /*
1282 * Number of memory blocks dedicated for the FW logger 1285 * Number of memory blocks dedicated for the FW logger
1283 * 1286 *
1284 * Range: 1-3, or 0 to disable the FW logger 1287 * Range: 2-16, or 0 to disable the FW logger
1285 */ 1288 */
1286 u8 mem_blocks; 1289 u8 mem_blocks;
1287 1290
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index e17630c2a849..89893c717025 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -437,6 +437,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
437 int res = 0; 437 int res = 0;
438 ssize_t ret; 438 ssize_t ret;
439 char *buf; 439 char *buf;
440 struct wl12xx_vif *wlvif;
440 441
441#define DRIVER_STATE_BUF_LEN 1024 442#define DRIVER_STATE_BUF_LEN 1024
442 443
@@ -450,12 +451,28 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
450 (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\ 451 (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\
451 #x " = " fmt "\n", wl->x)) 452 #x " = " fmt "\n", wl->x))
452 453
454#define DRIVER_STATE_PRINT_GENERIC(x, fmt, args...) \
455 (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\
456 #x " = " fmt "\n", args))
457
453#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld") 458#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
454#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d") 459#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d")
455#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s") 460#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s")
456#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx") 461#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
457#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x") 462#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")
458 463
464 wl12xx_for_each_wlvif_sta(wl, wlvif) {
465 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
466 continue;
467
468 DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel,
469 wlvif->p2p ? "P2P-CL" : "STA");
470 }
471
472 wl12xx_for_each_wlvif_ap(wl, wlvif)
473 DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel,
474 wlvif->p2p ? "P2P-GO" : "AP");
475
459 DRIVER_STATE_PRINT_INT(tx_blocks_available); 476 DRIVER_STATE_PRINT_INT(tx_blocks_available);
460 DRIVER_STATE_PRINT_INT(tx_allocated_blocks); 477 DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
461 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]); 478 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]);
@@ -474,7 +491,6 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
474 DRIVER_STATE_PRINT_INT(tx_blocks_freed); 491 DRIVER_STATE_PRINT_INT(tx_blocks_freed);
475 DRIVER_STATE_PRINT_INT(rx_counter); 492 DRIVER_STATE_PRINT_INT(rx_counter);
476 DRIVER_STATE_PRINT_INT(state); 493 DRIVER_STATE_PRINT_INT(state);
477 DRIVER_STATE_PRINT_INT(channel);
478 DRIVER_STATE_PRINT_INT(band); 494 DRIVER_STATE_PRINT_INT(band);
479 DRIVER_STATE_PRINT_INT(power_level); 495 DRIVER_STATE_PRINT_INT(power_level);
480 DRIVER_STATE_PRINT_INT(sg_enabled); 496 DRIVER_STATE_PRINT_INT(sg_enabled);
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 67f61689b49e..8d3b34965db3 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -266,6 +266,7 @@ int wl1271_event_unmask(struct wl1271 *wl)
266{ 266{
267 int ret; 267 int ret;
268 268
269 wl1271_debug(DEBUG_EVENT, "unmasking event_mask 0x%x", wl->event_mask);
269 ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask)); 270 ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask));
270 if (ret < 0) 271 if (ret < 0)
271 return ret; 272 return ret;
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 7fd260c02a0a..51f8d634d32f 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -222,6 +222,15 @@ wlcore_hw_set_peer_cap(struct wl1271 *wl,
222 return 0; 222 return 0;
223} 223}
224 224
225static inline u32
226wlcore_hw_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
227{
228 if (!wl->ops->convert_hwaddr)
229 BUG_ON(1);
230
231 return wl->ops->convert_hwaddr(wl, hwaddr);
232}
233
225static inline bool 234static inline bool
226wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid, 235wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid,
227 struct wl1271_link *lnk) 236 struct wl1271_link *lnk)
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c
index 5c6f11e157d9..7699f9d07e26 100644
--- a/drivers/net/wireless/ti/wlcore/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -571,6 +571,12 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
571 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); 571 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
572 if (ret < 0) 572 if (ret < 0)
573 return ret; 573 return ret;
574
575 /* unmask ap events */
576 wl->event_mask |= wl->ap_event_mask;
577 ret = wl1271_event_unmask(wl);
578 if (ret < 0)
579 return ret;
574 /* first STA, no APs */ 580 /* first STA, no APs */
575 } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { 581 } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) {
576 u8 sta_auth = wl->conf.conn.sta_sleep_auth; 582 u8 sta_auth = wl->conf.conn.sta_sleep_auth;
diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h
index af7d9f9b3b4d..07e3d6a049ad 100644
--- a/drivers/net/wireless/ti/wlcore/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -165,8 +165,8 @@ static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr,
165 int physical; 165 int physical;
166 int addr; 166 int addr;
167 167
168 /* Addresses are stored internally as addresses to 32 bytes blocks */ 168 /* Convert from FW internal address which is chip arch dependent */
169 addr = hwaddr << 5; 169 addr = wl->ops->convert_hwaddr(wl, hwaddr);
170 170
171 physical = wlcore_translate_addr(wl, addr); 171 physical = wlcore_translate_addr(wl, addr);
172 172
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index bbdd10632373..0368b9cbfb89 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -44,6 +44,7 @@
44#define WL1271_BOOT_RETRIES 3 44#define WL1271_BOOT_RETRIES 3
45 45
46static char *fwlog_param; 46static char *fwlog_param;
47static int fwlog_mem_blocks = -1;
47static int bug_on_recovery = -1; 48static int bug_on_recovery = -1;
48static int no_recovery = -1; 49static int no_recovery = -1;
49 50
@@ -291,6 +292,18 @@ static void wlcore_adjust_conf(struct wl1271 *wl)
291{ 292{
292 /* Adjust settings according to optional module parameters */ 293 /* Adjust settings according to optional module parameters */
293 294
295 /* Firmware Logger params */
296 if (fwlog_mem_blocks != -1) {
297 if (fwlog_mem_blocks >= CONF_FWLOG_MIN_MEM_BLOCKS &&
298 fwlog_mem_blocks <= CONF_FWLOG_MAX_MEM_BLOCKS) {
299 wl->conf.fwlog.mem_blocks = fwlog_mem_blocks;
300 } else {
301 wl1271_error(
302 "Illegal fwlog_mem_blocks=%d using default %d",
303 fwlog_mem_blocks, wl->conf.fwlog.mem_blocks);
304 }
305 }
306
294 if (fwlog_param) { 307 if (fwlog_param) {
295 if (!strcmp(fwlog_param, "continuous")) { 308 if (!strcmp(fwlog_param, "continuous")) {
296 wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS; 309 wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
@@ -780,6 +793,7 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl)
780 if (wl->state == WLCORE_STATE_ON) { 793 if (wl->state == WLCORE_STATE_ON) {
781 wl->state = WLCORE_STATE_RESTARTING; 794 wl->state = WLCORE_STATE_RESTARTING;
782 set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); 795 set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
796 wl1271_ps_elp_wakeup(wl);
783 wlcore_disable_interrupts_nosync(wl); 797 wlcore_disable_interrupts_nosync(wl);
784 ieee80211_queue_work(wl->hw, &wl->recovery_work); 798 ieee80211_queue_work(wl->hw, &wl->recovery_work);
785 } 799 }
@@ -787,19 +801,10 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl)
787 801
788size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) 802size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
789{ 803{
790 size_t len = 0; 804 size_t len;
791
792 /* The FW log is a length-value list, find where the log end */
793 while (len < maxlen) {
794 if (memblock[len] == 0)
795 break;
796 if (len + memblock[len] + 1 > maxlen)
797 break;
798 len += memblock[len] + 1;
799 }
800 805
801 /* Make sure we have enough room */ 806 /* Make sure we have enough room */
802 len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size)); 807 len = min(maxlen, (size_t)(PAGE_SIZE - wl->fwlog_size));
803 808
804 /* Fill the FW log file, consumed by the sysfs fwlog entry */ 809 /* Fill the FW log file, consumed by the sysfs fwlog entry */
805 memcpy(wl->fwlog + wl->fwlog_size, memblock, len); 810 memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
@@ -808,10 +813,9 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
808 return len; 813 return len;
809} 814}
810 815
811#define WLCORE_FW_LOG_END 0x2000000
812
813static void wl12xx_read_fwlog_panic(struct wl1271 *wl) 816static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
814{ 817{
818 struct wlcore_partition_set part, old_part;
815 u32 addr; 819 u32 addr;
816 u32 offset; 820 u32 offset;
817 u32 end_of_log; 821 u32 end_of_log;
@@ -824,7 +828,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
824 828
825 wl1271_info("Reading FW panic log"); 829 wl1271_info("Reading FW panic log");
826 830
827 block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL); 831 block = kmalloc(wl->fw_mem_block_size, GFP_KERNEL);
828 if (!block) 832 if (!block)
829 return; 833 return;
830 834
@@ -850,17 +854,31 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
850 854
851 if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) { 855 if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) {
852 offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor); 856 offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor);
853 end_of_log = WLCORE_FW_LOG_END; 857 end_of_log = wl->fwlog_end;
854 } else { 858 } else {
855 offset = sizeof(addr); 859 offset = sizeof(addr);
856 end_of_log = addr; 860 end_of_log = addr;
857 } 861 }
858 862
863 old_part = wl->curr_part;
864 memset(&part, 0, sizeof(part));
865
859 /* Traverse the memory blocks linked list */ 866 /* Traverse the memory blocks linked list */
860 do { 867 do {
861 memset(block, 0, WL12XX_HW_BLOCK_SIZE); 868 part.mem.start = wlcore_hw_convert_hwaddr(wl, addr);
862 ret = wlcore_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, 869 part.mem.size = PAGE_SIZE;
863 false); 870
871 ret = wlcore_set_partition(wl, &part);
872 if (ret < 0) {
873 wl1271_error("%s: set_partition start=0x%X size=%d",
874 __func__, part.mem.start, part.mem.size);
875 goto out;
876 }
877
878 memset(block, 0, wl->fw_mem_block_size);
879 ret = wlcore_read_hwaddr(wl, addr, block,
880 wl->fw_mem_block_size, false);
881
864 if (ret < 0) 882 if (ret < 0)
865 goto out; 883 goto out;
866 884
@@ -871,8 +889,9 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
871 * on demand mode and is equal to 0x2000000 in continuous mode. 889 * on demand mode and is equal to 0x2000000 in continuous mode.
872 */ 890 */
873 addr = le32_to_cpup((__le32 *)block); 891 addr = le32_to_cpup((__le32 *)block);
892
874 if (!wl12xx_copy_fwlog(wl, block + offset, 893 if (!wl12xx_copy_fwlog(wl, block + offset,
875 WL12XX_HW_BLOCK_SIZE - offset)) 894 wl->fw_mem_block_size - offset))
876 break; 895 break;
877 } while (addr && (addr != end_of_log)); 896 } while (addr && (addr != end_of_log));
878 897
@@ -880,6 +899,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
880 899
881out: 900out:
882 kfree(block); 901 kfree(block);
902 wlcore_set_partition(wl, &old_part);
883} 903}
884 904
885static void wlcore_print_recovery(struct wl1271 *wl) 905static void wlcore_print_recovery(struct wl1271 *wl)
@@ -924,7 +944,8 @@ static void wl1271_recovery_work(struct work_struct *work)
924 goto out_unlock; 944 goto out_unlock;
925 945
926 if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) { 946 if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
927 wl12xx_read_fwlog_panic(wl); 947 if (wl->conf.fwlog.output == WL12XX_FWLOG_OUTPUT_HOST)
948 wl12xx_read_fwlog_panic(wl);
928 wlcore_print_recovery(wl); 949 wlcore_print_recovery(wl);
929 } 950 }
930 951
@@ -1928,8 +1949,10 @@ static void wlcore_op_stop_locked(struct wl1271 *wl)
1928 1949
1929 /* 1950 /*
1930 * FW channels must be re-calibrated after recovery, 1951 * FW channels must be re-calibrated after recovery,
1931 * clear the last Reg-Domain channel configuration. 1952 * save current Reg-Domain channel configuration and clear it.
1932 */ 1953 */
1954 memcpy(wl->reg_ch_conf_pending, wl->reg_ch_conf_last,
1955 sizeof(wl->reg_ch_conf_pending));
1933 memset(wl->reg_ch_conf_last, 0, sizeof(wl->reg_ch_conf_last)); 1956 memset(wl->reg_ch_conf_last, 0, sizeof(wl->reg_ch_conf_last));
1934} 1957}
1935 1958
@@ -2623,6 +2646,12 @@ deinit:
2623 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) 2646 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags))
2624 goto unlock; 2647 goto unlock;
2625 2648
2649 if (wl->ap_count == 0 && is_ap) {
2650 /* mask ap events */
2651 wl->event_mask &= ~wl->ap_event_mask;
2652 wl1271_event_unmask(wl);
2653 }
2654
2626 if (wl->ap_count == 0 && is_ap && wl->sta_count) { 2655 if (wl->ap_count == 0 && is_ap && wl->sta_count) {
2627 u8 sta_auth = wl->conf.conn.sta_sleep_auth; 2656 u8 sta_auth = wl->conf.conn.sta_sleep_auth;
2628 /* Configure for power according to debugfs */ 2657 /* Configure for power according to debugfs */
@@ -6152,6 +6181,9 @@ module_param_named(fwlog, fwlog_param, charp, 0);
6152MODULE_PARM_DESC(fwlog, 6181MODULE_PARM_DESC(fwlog,
6153 "FW logger options: continuous, ondemand, dbgpins or disable"); 6182 "FW logger options: continuous, ondemand, dbgpins or disable");
6154 6183
6184module_param(fwlog_mem_blocks, int, S_IRUSR | S_IWUSR);
6185MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks");
6186
6155module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR); 6187module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR);
6156MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); 6188MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
6157 6189
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index 13e743df2e31..7ed86203304b 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -92,9 +92,31 @@ out:
92static void wlcore_started_vifs_iter(void *data, u8 *mac, 92static void wlcore_started_vifs_iter(void *data, u8 *mac,
93 struct ieee80211_vif *vif) 93 struct ieee80211_vif *vif)
94{ 94{
95 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
96 bool active = false;
95 int *count = (int *)data; 97 int *count = (int *)data;
96 98
97 if (!vif->bss_conf.idle) 99 /*
100 * count active interfaces according to interface type.
101 * checking only bss_conf.idle is bad for some cases, e.g.
102 * we don't want to count sta in p2p_find as active interface.
103 */
104 switch (wlvif->bss_type) {
105 case BSS_TYPE_STA_BSS:
106 if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
107 active = true;
108 break;
109
110 case BSS_TYPE_AP_BSS:
111 if (wlvif->wl->active_sta_count > 0)
112 active = true;
113 break;
114
115 default:
116 break;
117 }
118
119 if (active)
98 (*count)++; 120 (*count)++;
99} 121}
100 122
diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
index a3b7d950d8e9..ddad58f614da 100644
--- a/drivers/net/wireless/ti/wlcore/testmode.c
+++ b/drivers/net/wireless/ti/wlcore/testmode.c
@@ -179,7 +179,8 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
179 goto out_sleep; 179 goto out_sleep;
180 } 180 }
181 181
182 ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); 182 ret = wl1271_cmd_interrogate(wl, ie_id, cmd,
183 sizeof(struct acx_header), sizeof(*cmd));
183 if (ret < 0) { 184 if (ret < 0) {
184 wl1271_warning("testmode cmd interrogate failed: %d", ret); 185 wl1271_warning("testmode cmd interrogate failed: %d", ret);
185 goto out_free; 186 goto out_free;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 54ce5d5e84db..06efc12a39e5 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -110,6 +110,7 @@ struct wlcore_ops {
110 struct ieee80211_sta_ht_cap *ht_cap, 110 struct ieee80211_sta_ht_cap *ht_cap,
111 bool allow_ht_operation, 111 bool allow_ht_operation,
112 u32 rate_set, u8 hlid); 112 u32 rate_set, u8 hlid);
113 u32 (*convert_hwaddr)(struct wl1271 *wl, u32 hwaddr);
113 bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid, 114 bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid,
114 struct wl1271_link *lnk); 115 struct wl1271_link *lnk);
115 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid, 116 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid,
@@ -290,6 +291,12 @@ struct wl1271 {
290 /* Number of valid bytes in the FW log buffer */ 291 /* Number of valid bytes in the FW log buffer */
291 ssize_t fwlog_size; 292 ssize_t fwlog_size;
292 293
294 /* FW log end marker */
295 u32 fwlog_end;
296
297 /* FW memory block size */
298 u32 fw_mem_block_size;
299
293 /* Sysfs FW log entry readers wait queue */ 300 /* Sysfs FW log entry readers wait queue */
294 wait_queue_head_t fwlog_waitq; 301 wait_queue_head_t fwlog_waitq;
295 302
@@ -307,6 +314,8 @@ struct wl1271 {
307 314
308 /* The mbox event mask */ 315 /* The mbox event mask */
309 u32 event_mask; 316 u32 event_mask;
317 /* events to unmask only when ap interface is up */
318 u32 ap_event_mask;
310 319
311 /* Mailbox pointers */ 320 /* Mailbox pointers */
312 u32 mbox_size; 321 u32 mbox_size;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 2a50e089b0e7..ce7261ce8b59 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -550,6 +550,4 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
550#define HW_HT_RATES_OFFSET 16 550#define HW_HT_RATES_OFFSET 16
551#define HW_MIMO_RATES_OFFSET 24 551#define HW_MIMO_RATES_OFFSET 24
552 552
553#define WL12XX_HW_BLOCK_SIZE 256
554
555#endif /* __WLCORE_I_H__ */ 553#endif /* __WLCORE_I_H__ */