return mvm->tcm.result.band_load[band];
}
+struct iwl_is_dcm_with_go_iterator_data {
+ struct ieee80211_vif *current_vif;
+ bool is_dcm_with_p2p_go;
+};
+
+static void iwl_mvm_is_dcm_with_go_iterator(void *_data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_is_dcm_with_go_iterator_data *data = _data;
+ struct iwl_mvm_vif *other_mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_vif *curr_mvmvif =
+ iwl_mvm_vif_from_mac80211(data->current_vif);
+
+ /* exclude the given vif */
+ if (vif == data->current_vif)
+ return;
+
+ if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
+ other_mvmvif->phy_ctxt && curr_mvmvif->phy_ctxt &&
+ other_mvmvif->phy_ctxt->id != curr_mvmvif->phy_ctxt->id)
+ data->is_dcm_with_p2p_go = true;
+}
+
static enum
-iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device,
+iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
enum iwl_mvm_traffic_load load,
bool low_latency)
{
if (!global_cnt)
return IWL_SCAN_TYPE_UNASSOC;
- if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) && !p2p_device &&
- fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAGMENTED_SCAN))
- return IWL_SCAN_TYPE_FRAGMENTED;
+ if (fw_has_api(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
+ if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) &&
+ (!vif || vif->type != NL80211_IFTYPE_P2P_DEVICE))
+ return IWL_SCAN_TYPE_FRAGMENTED;
+
+ /* in case of DCM with GO where BSS DTIM interval < 220msec
+ * set all scan requests as fast-balance scan
+ * */
+ if (vif && vif->type == NL80211_IFTYPE_STATION &&
+ vif->bss_conf.dtim_period < 220) {
+ struct iwl_is_dcm_with_go_iterator_data data = {
+ .current_vif = vif,
+ .is_dcm_with_p2p_go = false,
+ };
+
+ ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+ IEEE80211_IFACE_ITER_NORMAL,
+ iwl_mvm_is_dcm_with_go_iterator,
+ &data);
+ if (data.is_dcm_with_p2p_go)
+ return IWL_SCAN_TYPE_FAST_BALANCE;
+ }
+ }
if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency)
return IWL_SCAN_TYPE_MILD;
}
static enum
-iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device)
+iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif)
{
enum iwl_mvm_traffic_load load;
bool low_latency;
load = iwl_mvm_get_traffic_load(mvm);
low_latency = iwl_mvm_low_latency(mvm);
- return _iwl_mvm_get_scan_type(mvm, p2p_device, load, low_latency);
+ return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
}
static enum
iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
- bool p2p_device,
+ struct ieee80211_vif *vif,
enum nl80211_band band)
{
enum iwl_mvm_traffic_load load;
load = iwl_mvm_get_traffic_load_band(mvm, band);
low_latency = iwl_mvm_low_latency_band(mvm, band);
- return _iwl_mvm_get_scan_type(mvm, p2p_device, load, low_latency);
+ return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
}
static int
static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
u32 flags, u8 channel_flags)
{
- enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, false);
+ enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL);
struct iwl_scan_config_v1 *cfg = config;
cfg->flags = cpu_to_le32(flags);
if (iwl_mvm_is_cdb_supported(mvm)) {
enum iwl_mvm_scan_type lb_type, hb_type;
- lb_type = iwl_mvm_get_scan_type_band(mvm, false,
+ lb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
NL80211_BAND_2GHZ);
- hb_type = iwl_mvm_get_scan_type_band(mvm, false,
+ hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
NL80211_BAND_5GHZ);
cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
cpu_to_le32(scan_timing[hb_type].suspend_time);
} else {
enum iwl_mvm_scan_type type =
- iwl_mvm_get_scan_type(mvm, false);
+ iwl_mvm_get_scan_type(mvm, NULL);
cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
cpu_to_le32(scan_timing[type].max_out_time);
return -ENOBUFS;
if (iwl_mvm_is_cdb_supported(mvm)) {
- type = iwl_mvm_get_scan_type_band(mvm, false,
+ type = iwl_mvm_get_scan_type_band(mvm, NULL,
NL80211_BAND_2GHZ);
- hb_type = iwl_mvm_get_scan_type_band(mvm, false,
+ hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
NL80211_BAND_5GHZ);
if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
return 0;
} else {
- type = iwl_mvm_get_scan_type(mvm, false);
+ type = iwl_mvm_get_scan_type(mvm, NULL);
if (type == mvm->scan_type)
return 0;
}
static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
struct iwl_mvm_scan_params *params,
- bool p2p)
+ struct ieee80211_vif *vif)
{
if (iwl_mvm_is_cdb_supported(mvm)) {
params->type =
- iwl_mvm_get_scan_type_band(mvm, p2p,
+ iwl_mvm_get_scan_type_band(mvm, vif,
NL80211_BAND_2GHZ);
params->hb_type =
- iwl_mvm_get_scan_type_band(mvm, p2p,
+ iwl_mvm_get_scan_type_band(mvm, vif,
NL80211_BAND_5GHZ);
} else {
- params->type = iwl_mvm_get_scan_type(mvm, p2p);
+ params->type = iwl_mvm_get_scan_type(mvm, vif);
}
}
+
int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req,
struct ieee80211_scan_ies *ies)
params.scan_plans = &scan_plan;
params.n_scan_plans = 1;
- iwl_mvm_fill_scan_type(mvm, ¶ms,
- vif->type == NL80211_IFTYPE_P2P_DEVICE);
+ iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
ret = iwl_mvm_get_measurement_dwell(mvm, req, ¶ms);
if (ret < 0)
params.n_scan_plans = req->n_scan_plans;
params.scan_plans = req->scan_plans;
- iwl_mvm_fill_scan_type(mvm, ¶ms,
- vif->type == NL80211_IFTYPE_P2P_DEVICE);
+ iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
/* In theory, LMAC scans can handle a 32-bit delay, but since
* waiting for over 18 hours to start the scan is a bit silly