Commit 20f1a5de authored by David Spinadel's avatar David Spinadel Committed by Johannes Berg

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: default avatarDavid Spinadel <david.spinadel@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 3394817f
...@@ -80,6 +80,8 @@ ...@@ -80,6 +80,8 @@
* @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
* (rather than two) IPv6 addresses * (rather than two) IPv6 addresses
* @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
* @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
* from the probe request template.
* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
*/ */
enum iwl_ucode_tlv_flag { enum iwl_ucode_tlv_flag {
...@@ -93,6 +95,7 @@ enum iwl_ucode_tlv_flag { ...@@ -93,6 +95,7 @@ enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9), IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9),
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11), IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11),
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
}; };
......
...@@ -139,6 +139,14 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm) ...@@ -139,6 +139,14 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
} }
} }
static int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
{
/* we create the 802.11 header and SSID element */
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID)
return mvm->fw->ucode_capa.max_probe_length - 24 - 2;
return mvm->fw->ucode_capa.max_probe_length - 24 - 34;
}
int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
{ {
struct ieee80211_hw *hw = mvm->hw; struct ieee80211_hw *hw = mvm->hw;
...@@ -213,9 +221,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ...@@ -213,9 +221,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
iwl_mvm_reset_phy_ctxts(mvm); iwl_mvm_reset_phy_ctxts(mvm);
/* we create the 802.11 header and a max-length SSID element */ hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
hw->wiphy->max_scan_ie_len =
mvm->fw->ucode_capa.max_probe_length - 24 - 34;
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
......
...@@ -137,11 +137,12 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band, ...@@ -137,11 +137,12 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
* request. * request.
*/ */
static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
struct cfg80211_scan_request *req) struct cfg80211_scan_request *req,
int first)
{ {
int fw_idx, req_idx; int fw_idx, req_idx;
for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0; for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx >= first;
req_idx--, fw_idx++) { req_idx--, fw_idx++) {
cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; 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,9 +158,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
* just to notify that this scan is active and not passive. * just to notify that this scan is active and not passive.
* In order to notify the FW of the number of SSIDs we wish to scan (including * In order to notify the FW of the number of SSIDs we wish to scan (including
* the zero-length one), we need to set the corresponding bits in chan->type, * the zero-length one), we need to set the corresponding bits in chan->type,
* one for each SSID, and set the active bit (first). The first SSID is already * one for each SSID, and set the active bit (first). If the first SSID is
* included in the probe template, so we need to set only req->n_ssids - 1 bits * already included in the probe template, so we need to set only
* in addition to the first bit. * req->n_ssids - 1 bits in addition to the first bit.
*/ */
static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
{ {
...@@ -174,7 +175,8 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) ...@@ -174,7 +175,8 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
} }
static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
struct cfg80211_scan_request *req) struct cfg80211_scan_request *req,
bool basic_ssid)
{ {
u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band); u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band);
u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band, 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,10 +184,14 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
struct iwl_scan_channel *chan = (struct iwl_scan_channel *) struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
(cmd->data + le16_to_cpu(cmd->tx_cmd.len)); (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
int i; int i;
int type = BIT(req->n_ssids) - 1;
if (!basic_ssid)
type |= BIT(req->n_ssids);
for (i = 0; i < cmd->channel_count; i++) { for (i = 0; i < cmd->channel_count; i++) {
chan->channel = cpu_to_le16(req->channels[i]->hw_value); chan->channel = cpu_to_le16(req->channels[i]->hw_value);
chan->type = cpu_to_le32(BIT(req->n_ssids) - 1); chan->type = cpu_to_le32(type);
if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
chan->active_dwell = cpu_to_le16(active_dwell); chan->active_dwell = cpu_to_le16(active_dwell);
...@@ -272,6 +278,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, ...@@ -272,6 +278,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
u32 status; u32 status;
int ssid_len = 0; int ssid_len = 0;
u8 *ssid = NULL; u8 *ssid = NULL;
bool basic_ssid = !(mvm->fw->ucode_capa.flags &
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
BUG_ON(mvm->scan_cmd == NULL); BUG_ON(mvm->scan_cmd == NULL);
...@@ -306,14 +314,16 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, ...@@ -306,14 +314,16 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
if (req->n_ssids > 0) { if (req->n_ssids > 0) {
cmd->passive2active = cpu_to_le16(1); cmd->passive2active = cpu_to_le16(1);
cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE; cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE;
if (basic_ssid) {
ssid = req->ssids[0].ssid; ssid = req->ssids[0].ssid;
ssid_len = req->ssids[0].ssid_len; ssid_len = req->ssids[0].ssid_len;
}
} else { } else {
cmd->passive2active = 0; cmd->passive2active = 0;
cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
} }
iwl_mvm_scan_fill_ssids(cmd, req); iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0);
cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
...@@ -330,7 +340,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, ...@@ -330,7 +340,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
req->ie, req->ie_len, req->ie, req->ie_len,
mvm->fw->ucode_capa.max_probe_length)); mvm->fw->ucode_capa.max_probe_length));
iwl_mvm_scan_fill_channels(cmd, req); iwl_mvm_scan_fill_channels(cmd, req, basic_ssid);
cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
le16_to_cpu(cmd->tx_cmd.len) + le16_to_cpu(cmd->tx_cmd.len) +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment