diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-11-08 09:03:10 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-11-08 09:03:10 -0500 |
commit | c1f3bb6bd317994beb3af7bbec4bf54ed0035509 (patch) | |
tree | 878833c714ddcb35f1574f2b11e1f69d1130d206 /drivers/net | |
parent | dcd607718385d02ce3741de225927a57f528f93b (diff) | |
parent | 3c57e865cfb2dcbb48fdfa08e7d4e3479e9b40f0 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers/net')
31 files changed, 244 insertions, 86 deletions
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 | ||
847 | static const struct ieee80211_iface_limit if_dfs_limits[] = { | 847 | static 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 | ||
851 | static const struct ieee80211_iface_combination if_comb[] = { | 852 | static 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 | ||
1174 | static 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 | |||
1173 | static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | 1184 | static 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 | ||
1655 | static u32 wl12xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr) | ||
1656 | { | ||
1657 | return hwaddr << 5; | ||
1658 | } | ||
1659 | |||
1651 | static int wl12xx_setup(struct wl1271 *wl); | 1660 | static int wl12xx_setup(struct wl1271 *wl); |
1652 | 1661 | ||
1653 | static struct wlcore_ops wl12xx_ops = { | 1662 | static 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 | ||
506 | static struct wl18xx_priv_conf wl18xx_default_priv_conf = { | 506 | static 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 | ||
1611 | static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr) | ||
1612 | { | ||
1613 | return hwaddr & ~0x80000000; | ||
1614 | } | ||
1615 | |||
1607 | static int wl18xx_setup(struct wl1271 *wl); | 1616 | static int wl18xx_setup(struct wl1271 *wl); |
1608 | 1617 | ||
1609 | static struct wlcore_ops wl18xx_ops = { | 1618 | static 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 | */ |
848 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) | 849 | int 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); |
46 | int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 46 | int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
47 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); | 47 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); |
48 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); | 48 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, |
49 | size_t cmd_len, size_t res_len); | ||
49 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); | 50 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); |
50 | int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf, | 51 | int 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 | |||
1277 | struct conf_fwlog { | 1280 | struct 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 | ||
225 | static inline u32 | ||
226 | wlcore_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 | |||
225 | static inline bool | 234 | static inline bool |
226 | wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid, | 235 | wlcore_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 | ||
46 | static char *fwlog_param; | 46 | static char *fwlog_param; |
47 | static int fwlog_mem_blocks = -1; | ||
47 | static int bug_on_recovery = -1; | 48 | static int bug_on_recovery = -1; |
48 | static int no_recovery = -1; | 49 | static 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 | ||
788 | size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) | 802 | size_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 | |||
813 | static void wl12xx_read_fwlog_panic(struct wl1271 *wl) | 816 | static 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 | ||
881 | out: | 900 | out: |
882 | kfree(block); | 901 | kfree(block); |
902 | wlcore_set_partition(wl, &old_part); | ||
883 | } | 903 | } |
884 | 904 | ||
885 | static void wlcore_print_recovery(struct wl1271 *wl) | 905 | static 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); | |||
6152 | MODULE_PARM_DESC(fwlog, | 6181 | MODULE_PARM_DESC(fwlog, |
6153 | "FW logger options: continuous, ondemand, dbgpins or disable"); | 6182 | "FW logger options: continuous, ondemand, dbgpins or disable"); |
6154 | 6183 | ||
6184 | module_param(fwlog_mem_blocks, int, S_IRUSR | S_IWUSR); | ||
6185 | MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks"); | ||
6186 | |||
6155 | module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR); | 6187 | module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR); |
6156 | MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); | 6188 | MODULE_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: | |||
92 | static void wlcore_started_vifs_iter(void *data, u8 *mac, | 92 | static 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__ */ |