mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
iwlwifi: mvm: use fast balance scan in case of DCM mode with P2P GO
Currently in case of DCM with P2P GO where BSS DTIM interval < 220 msec the fw fails to allocate events for the P2P GO dtim due to long passive scan events. Fix this by requesting all scans in this scenario to be fragmented with fast balance scan time settings. The only exception is in case fragmented scan was planned to be set due to low latency or high throughput reason, set the scan timing as planned. Signed-off-by: Ayala Beker <ayala.beker@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
6ff80f18d5
commit
2ec3ef4614
@ -239,8 +239,32 @@ iwl_mvm_get_traffic_load_band(struct iwl_mvm *mvm, enum nl80211_band band)
|
|||||||
return mvm->tcm.result.band_load[band];
|
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
|
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,
|
enum iwl_mvm_traffic_load load,
|
||||||
bool low_latency)
|
bool low_latency)
|
||||||
{
|
{
|
||||||
@ -253,9 +277,30 @@ iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device,
|
|||||||
if (!global_cnt)
|
if (!global_cnt)
|
||||||
return IWL_SCAN_TYPE_UNASSOC;
|
return IWL_SCAN_TYPE_UNASSOC;
|
||||||
|
|
||||||
if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) && !p2p_device &&
|
if (fw_has_api(&mvm->fw->ucode_capa,
|
||||||
fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAGMENTED_SCAN))
|
IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
|
||||||
return IWL_SCAN_TYPE_FRAGMENTED;
|
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)
|
if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency)
|
||||||
return IWL_SCAN_TYPE_MILD;
|
return IWL_SCAN_TYPE_MILD;
|
||||||
@ -264,7 +309,8 @@ iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum
|
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;
|
enum iwl_mvm_traffic_load load;
|
||||||
bool low_latency;
|
bool low_latency;
|
||||||
@ -272,12 +318,12 @@ iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device)
|
|||||||
load = iwl_mvm_get_traffic_load(mvm);
|
load = iwl_mvm_get_traffic_load(mvm);
|
||||||
low_latency = iwl_mvm_low_latency(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
|
static enum
|
||||||
iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
|
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 nl80211_band band)
|
||||||
{
|
{
|
||||||
enum iwl_mvm_traffic_load load;
|
enum iwl_mvm_traffic_load load;
|
||||||
@ -286,7 +332,7 @@ iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
|
|||||||
load = iwl_mvm_get_traffic_load_band(mvm, band);
|
load = iwl_mvm_get_traffic_load_band(mvm, band);
|
||||||
low_latency = iwl_mvm_low_latency_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 int
|
||||||
@ -1054,7 +1100,7 @@ static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels)
|
|||||||
static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
|
static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
|
||||||
u32 flags, u8 channel_flags)
|
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;
|
struct iwl_scan_config_v1 *cfg = config;
|
||||||
|
|
||||||
cfg->flags = cpu_to_le32(flags);
|
cfg->flags = cpu_to_le32(flags);
|
||||||
@ -1087,9 +1133,9 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
|
|||||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||||
enum iwl_mvm_scan_type lb_type, hb_type;
|
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);
|
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);
|
NL80211_BAND_5GHZ);
|
||||||
|
|
||||||
cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
|
cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
|
||||||
@ -1103,7 +1149,7 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
|
|||||||
cpu_to_le32(scan_timing[hb_type].suspend_time);
|
cpu_to_le32(scan_timing[hb_type].suspend_time);
|
||||||
} else {
|
} else {
|
||||||
enum iwl_mvm_scan_type type =
|
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] =
|
cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
|
||||||
cpu_to_le32(scan_timing[type].max_out_time);
|
cpu_to_le32(scan_timing[type].max_out_time);
|
||||||
@ -1140,14 +1186,14 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
|||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
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);
|
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);
|
NL80211_BAND_5GHZ);
|
||||||
if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
|
if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
type = iwl_mvm_get_scan_type(mvm, false);
|
type = iwl_mvm_get_scan_type(mvm, NULL);
|
||||||
if (type == mvm->scan_type)
|
if (type == mvm->scan_type)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1599,19 +1645,20 @@ void iwl_mvm_scan_timeout_wk(struct work_struct *work)
|
|||||||
|
|
||||||
static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
|
static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
|
||||||
struct iwl_mvm_scan_params *params,
|
struct iwl_mvm_scan_params *params,
|
||||||
bool p2p)
|
struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||||
params->type =
|
params->type =
|
||||||
iwl_mvm_get_scan_type_band(mvm, p2p,
|
iwl_mvm_get_scan_type_band(mvm, vif,
|
||||||
NL80211_BAND_2GHZ);
|
NL80211_BAND_2GHZ);
|
||||||
params->hb_type =
|
params->hb_type =
|
||||||
iwl_mvm_get_scan_type_band(mvm, p2p,
|
iwl_mvm_get_scan_type_band(mvm, vif,
|
||||||
NL80211_BAND_5GHZ);
|
NL80211_BAND_5GHZ);
|
||||||
} else {
|
} 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,
|
int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||||
struct cfg80211_scan_request *req,
|
struct cfg80211_scan_request *req,
|
||||||
struct ieee80211_scan_ies *ies)
|
struct ieee80211_scan_ies *ies)
|
||||||
@ -1659,8 +1706,7 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||||||
params.scan_plans = &scan_plan;
|
params.scan_plans = &scan_plan;
|
||||||
params.n_scan_plans = 1;
|
params.n_scan_plans = 1;
|
||||||
|
|
||||||
iwl_mvm_fill_scan_type(mvm, ¶ms,
|
iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
|
||||||
vif->type == NL80211_IFTYPE_P2P_DEVICE);
|
|
||||||
|
|
||||||
ret = iwl_mvm_get_measurement_dwell(mvm, req, ¶ms);
|
ret = iwl_mvm_get_measurement_dwell(mvm, req, ¶ms);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1755,8 +1801,7 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
|
|||||||
params.n_scan_plans = req->n_scan_plans;
|
params.n_scan_plans = req->n_scan_plans;
|
||||||
params.scan_plans = req->scan_plans;
|
params.scan_plans = req->scan_plans;
|
||||||
|
|
||||||
iwl_mvm_fill_scan_type(mvm, ¶ms,
|
iwl_mvm_fill_scan_type(mvm, ¶ms, vif);
|
||||||
vif->type == NL80211_IFTYPE_P2P_DEVICE);
|
|
||||||
|
|
||||||
/* In theory, LMAC scans can handle a 32-bit delay, but since
|
/* 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
|
* waiting for over 18 hours to start the scan is a bit silly
|
||||||
|
Loading…
Reference in New Issue
Block a user