diff options
| author | David S. Miller <davem@davemloft.net> | 2013-11-08 13:15:39 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-11-08 13:15:39 -0500 |
| commit | 74ecd3d1dd26f54ff36a0392f10e50fa8e256bd3 (patch) | |
| tree | 878833c714ddcb35f1574f2b11e1f69d1130d206 /drivers | |
| parent | dcd607718385d02ce3741de225927a57f528f93b (diff) | |
| parent | c1f3bb6bd317994beb3af7bbec4bf54ed0035509 (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')
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 | ||
| 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__ */ |
