diff options
author | David Spinadel <david.spinadel@intel.com> | 2013-08-21 02:14:27 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-10-02 12:00:39 -0400 |
commit | 20f1a5deb67f00cef89d63fb957a940c7f976cf3 (patch) | |
tree | 65073a059256415cff46cc9efacba8946a2ab7de /drivers | |
parent | 3394817f833f13958320ae6e0dccf347c1ce5200 (diff) |
iwlwifi: mvm: add no_basic_ssid option
New FW doesn't use the SSID from scan request template. Adding
a TLV flag to indicate the change, and fixing the flows to send
the first SSID in SSID list if the flag is on.
Signed-off-by: David Spinadel <david.spinadel@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/scan.c | 32 |
3 files changed, 34 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 3ddbc1bda74e..d2f0381d2abd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -80,6 +80,8 @@ | |||
80 | * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six | 80 | * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six |
81 | * (rather than two) IPv6 addresses | 81 | * (rather than two) IPv6 addresses |
82 | * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API | 82 | * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API |
83 | * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element | ||
84 | * from the probe request template. | ||
83 | * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API | 85 | * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API |
84 | */ | 86 | */ |
85 | enum iwl_ucode_tlv_flag { | 87 | enum iwl_ucode_tlv_flag { |
@@ -93,6 +95,7 @@ enum iwl_ucode_tlv_flag { | |||
93 | IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9), | 95 | IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9), |
94 | IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), | 96 | IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), |
95 | IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11), | 97 | IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11), |
98 | IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12), | ||
96 | IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), | 99 | IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), |
97 | }; | 100 | }; |
98 | 101 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 141fc547dc2d..0340299b4b63 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -139,6 +139,14 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm) | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | static int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm) | ||
143 | { | ||
144 | /* we create the 802.11 header and SSID element */ | ||
145 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) | ||
146 | return mvm->fw->ucode_capa.max_probe_length - 24 - 2; | ||
147 | return mvm->fw->ucode_capa.max_probe_length - 24 - 34; | ||
148 | } | ||
149 | |||
142 | int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | 150 | int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) |
143 | { | 151 | { |
144 | struct ieee80211_hw *hw = mvm->hw; | 152 | struct ieee80211_hw *hw = mvm->hw; |
@@ -213,9 +221,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
213 | 221 | ||
214 | iwl_mvm_reset_phy_ctxts(mvm); | 222 | iwl_mvm_reset_phy_ctxts(mvm); |
215 | 223 | ||
216 | /* we create the 802.11 header and a max-length SSID element */ | 224 | hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm); |
217 | hw->wiphy->max_scan_ie_len = | 225 | |
218 | mvm->fw->ucode_capa.max_probe_length - 24 - 34; | ||
219 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | 226 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; |
220 | 227 | ||
221 | if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) | 228 | if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 71170fcc8f14..0dc626f34927 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -137,11 +137,12 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band, | |||
137 | * request. | 137 | * request. |
138 | */ | 138 | */ |
139 | static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, | 139 | static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, |
140 | struct cfg80211_scan_request *req) | 140 | struct cfg80211_scan_request *req, |
141 | int first) | ||
141 | { | 142 | { |
142 | int fw_idx, req_idx; | 143 | int fw_idx, req_idx; |
143 | 144 | ||
144 | for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0; | 145 | for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx >= first; |
145 | req_idx--, fw_idx++) { | 146 | req_idx--, fw_idx++) { |
146 | cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; | 147 | cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; |
147 | cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; | 148 | cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; |
@@ -157,9 +158,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, | |||
157 | * just to notify that this scan is active and not passive. | 158 | * just to notify that this scan is active and not passive. |
158 | * In order to notify the FW of the number of SSIDs we wish to scan (including | 159 | * In order to notify the FW of the number of SSIDs we wish to scan (including |
159 | * the zero-length one), we need to set the corresponding bits in chan->type, | 160 | * the zero-length one), we need to set the corresponding bits in chan->type, |
160 | * one for each SSID, and set the active bit (first). The first SSID is already | 161 | * one for each SSID, and set the active bit (first). If the first SSID is |
161 | * included in the probe template, so we need to set only req->n_ssids - 1 bits | 162 | * already included in the probe template, so we need to set only |
162 | * in addition to the first bit. | 163 | * req->n_ssids - 1 bits in addition to the first bit. |
163 | */ | 164 | */ |
164 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) | 165 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) |
165 | { | 166 | { |
@@ -174,7 +175,8 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) | |||
174 | } | 175 | } |
175 | 176 | ||
176 | static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, | 177 | static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, |
177 | struct cfg80211_scan_request *req) | 178 | struct cfg80211_scan_request *req, |
179 | bool basic_ssid) | ||
178 | { | 180 | { |
179 | u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band); | 181 | u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band); |
180 | u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band, | 182 | u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band, |
@@ -182,10 +184,14 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, | |||
182 | struct iwl_scan_channel *chan = (struct iwl_scan_channel *) | 184 | struct iwl_scan_channel *chan = (struct iwl_scan_channel *) |
183 | (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); | 185 | (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); |
184 | int i; | 186 | int i; |
187 | int type = BIT(req->n_ssids) - 1; | ||
188 | |||
189 | if (!basic_ssid) | ||
190 | type |= BIT(req->n_ssids); | ||
185 | 191 | ||
186 | for (i = 0; i < cmd->channel_count; i++) { | 192 | for (i = 0; i < cmd->channel_count; i++) { |
187 | chan->channel = cpu_to_le16(req->channels[i]->hw_value); | 193 | chan->channel = cpu_to_le16(req->channels[i]->hw_value); |
188 | chan->type = cpu_to_le32(BIT(req->n_ssids) - 1); | 194 | chan->type = cpu_to_le32(type); |
189 | if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 195 | if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
190 | chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); | 196 | chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); |
191 | chan->active_dwell = cpu_to_le16(active_dwell); | 197 | chan->active_dwell = cpu_to_le16(active_dwell); |
@@ -272,6 +278,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
272 | u32 status; | 278 | u32 status; |
273 | int ssid_len = 0; | 279 | int ssid_len = 0; |
274 | u8 *ssid = NULL; | 280 | u8 *ssid = NULL; |
281 | bool basic_ssid = !(mvm->fw->ucode_capa.flags & | ||
282 | IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID); | ||
275 | 283 | ||
276 | lockdep_assert_held(&mvm->mutex); | 284 | lockdep_assert_held(&mvm->mutex); |
277 | BUG_ON(mvm->scan_cmd == NULL); | 285 | BUG_ON(mvm->scan_cmd == NULL); |
@@ -306,14 +314,16 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
306 | if (req->n_ssids > 0) { | 314 | if (req->n_ssids > 0) { |
307 | cmd->passive2active = cpu_to_le16(1); | 315 | cmd->passive2active = cpu_to_le16(1); |
308 | cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE; | 316 | cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE; |
309 | ssid = req->ssids[0].ssid; | 317 | if (basic_ssid) { |
310 | ssid_len = req->ssids[0].ssid_len; | 318 | ssid = req->ssids[0].ssid; |
319 | ssid_len = req->ssids[0].ssid_len; | ||
320 | } | ||
311 | } else { | 321 | } else { |
312 | cmd->passive2active = 0; | 322 | cmd->passive2active = 0; |
313 | cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; | 323 | cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; |
314 | } | 324 | } |
315 | 325 | ||
316 | iwl_mvm_scan_fill_ssids(cmd, req); | 326 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); |
317 | 327 | ||
318 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); | 328 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); |
319 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; | 329 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; |
@@ -330,7 +340,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
330 | req->ie, req->ie_len, | 340 | req->ie, req->ie_len, |
331 | mvm->fw->ucode_capa.max_probe_length)); | 341 | mvm->fw->ucode_capa.max_probe_length)); |
332 | 342 | ||
333 | iwl_mvm_scan_fill_channels(cmd, req); | 343 | iwl_mvm_scan_fill_channels(cmd, req, basic_ssid); |
334 | 344 | ||
335 | cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + | 345 | cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + |
336 | le16_to_cpu(cmd->tx_cmd.len) + | 346 | le16_to_cpu(cmd->tx_cmd.len) + |