aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Spinadel <david.spinadel@intel.com>2013-08-21 02:14:27 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-10-02 12:00:39 -0400
commit20f1a5deb67f00cef89d63fb957a940c7f976cf3 (patch)
tree65073a059256415cff46cc9efacba8946a2ab7de /drivers
parent3394817f833f13958320ae6e0dccf347c1ce5200 (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.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c13
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c32
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 */
85enum iwl_ucode_tlv_flag { 87enum 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
142static 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
142int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 150int 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 */
139static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, 139static 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 */
164static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 165static 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
176static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, 177static 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) +