Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48849a41 authored by Andrei Otcheretianski's avatar Andrei Otcheretianski Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: Refactor and fix max probe len computation



Move iwl_mvm_max_scan_ie_len function to scan.c and fix the
implementation to conform with the LMAC scan API.
Since the correct implementation would leave us with unacceptably
tiny probes, add a workaround which returns a larger value.
In current implementation it's possible that unified_scan_lmac and
unified_sched_scan_lmac would return -ENOBUFS.

Signed-off-by: default avatarAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 9b60bb6d
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -279,14 +279,6 @@ 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)
{
	struct ieee80211_hw *hw = mvm->hw;
@@ -379,7 +371,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)

	iwl_mvm_reset_phy_ctxts(mvm);

	hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
	hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm, false);

	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;

+1 −0
Original line number Diff line number Diff line
@@ -935,6 +935,7 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
			     struct iwl_device_cmd *cmd);
int iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);

/* Scheduled scan */
int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
+53 −11
Original line number Diff line number Diff line
@@ -346,6 +346,48 @@ static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm)
	       IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT;
}

static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm,
					   bool is_sched_scan)
{
	int max_probe_len;

	if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
		max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
	else
		max_probe_len = mvm->fw->ucode_capa.max_probe_length;

	/* we create the 802.11 header and SSID element */
	max_probe_len -= 24 + 2;

	/* basic ssid is added only for hw_scan with and old api */
	if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) &&
	    !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) &&
	    !is_sched_scan)
		max_probe_len -= 32;

	return max_probe_len;
}

int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
{
	int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan);

	if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN))
		return max_ie_len;

	/* TODO: [BUG] This function should return the maximum allowed size of
	 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
	 * in the same command. So the correct implementation of this function
	 * is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan
	 * command has only 512 bytes and it would leave us with about 240
	 * bytes for scan IEs, which is clearly not enough. So meanwhile
	 * we will report an incorrect value. This may result in a failure to
	 * issue a scan in unified_scan_lmac and unified_sched_scan_lmac
	 * functions with -ENOBUFS, if a large enough probe will be provided.
	 */
	return max_ie_len;
}

int iwl_mvm_scan_request(struct iwl_mvm *mvm,
			 struct ieee80211_vif *vif,
			 struct cfg80211_scan_request *req)
@@ -1191,13 +1233,12 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
	if (WARN_ON(mvm->scan_cmd == NULL))
		return -ENOMEM;

	if (WARN_ON_ONCE(req->req.n_ssids > PROBE_OPTION_MAX ||
			 req->ies.common_ie_len + req->ies.len[0] +
				req->ies.len[1] + 24 + 2 >
					SCAN_OFFLOAD_PROBE_REQ_SIZE ||
			 req->req.n_channels >
				mvm->fw->ucode_capa.n_scan_channels))
		return -1;
	if (req->req.n_ssids > PROBE_OPTION_MAX ||
	    req->ies.common_ie_len + req->ies.len[NL80211_BAND_2GHZ] +
	    req->ies.len[NL80211_BAND_5GHZ] >
		iwl_mvm_max_scan_ie_fw_cmd_room(mvm, false) ||
	    req->req.n_channels > mvm->fw->ucode_capa.n_scan_channels)
		return -ENOBUFS;

	mvm->scan_status = IWL_MVM_SCAN_OS;

@@ -1285,10 +1326,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
	if (WARN_ON(mvm->scan_cmd == NULL))
		return -ENOMEM;

	if (WARN_ON_ONCE(req->n_ssids > PROBE_OPTION_MAX ||
			 ies->common_ie_len + ies->len[0] + ies->len[1] + 24 + 2
				> SCAN_OFFLOAD_PROBE_REQ_SIZE ||
			 req->n_channels > mvm->fw->ucode_capa.n_scan_channels))
	if (req->n_ssids > PROBE_OPTION_MAX ||
	    ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] +
	    ies->len[NL80211_BAND_5GHZ] >
		iwl_mvm_max_scan_ie_fw_cmd_room(mvm, true) ||
	    req->n_channels > mvm->fw->ucode_capa.n_scan_channels)
		return -ENOBUFS;

	iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);