Commit b66b5817 authored by Sara Sharon's avatar Sara Sharon Committed by Luca Coelho

iwlwifi: mvm: detect low latency and traffic load per band

Detect low latency and traffic load per band.  Add support for
deciding on scan type and timings per band.
Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent b0ffe455
...@@ -1093,6 +1093,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) ...@@ -1093,6 +1093,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
mvm->scan_type = IWL_SCAN_TYPE_NOT_SET; mvm->scan_type = IWL_SCAN_TYPE_NOT_SET;
mvm->hb_scan_type = IWL_SCAN_TYPE_NOT_SET;
ret = iwl_mvm_config_scan(mvm); ret = iwl_mvm_config_scan(mvm);
if (ret) if (ret)
goto error; goto error;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -638,6 +640,7 @@ struct iwl_mvm_tcm { ...@@ -638,6 +640,7 @@ struct iwl_mvm_tcm {
u32 elapsed; /* milliseconds for this TCM period */ u32 elapsed; /* milliseconds for this TCM period */
u32 airtime[NUM_MAC_INDEX_DRIVER]; u32 airtime[NUM_MAC_INDEX_DRIVER];
enum iwl_mvm_traffic_load load[NUM_MAC_INDEX_DRIVER]; enum iwl_mvm_traffic_load load[NUM_MAC_INDEX_DRIVER];
enum iwl_mvm_traffic_load band_load[NUM_NL80211_BANDS];
enum iwl_mvm_traffic_load global_load; enum iwl_mvm_traffic_load global_load;
bool low_latency[NUM_MAC_INDEX_DRIVER]; bool low_latency[NUM_MAC_INDEX_DRIVER];
bool change[NUM_MAC_INDEX_DRIVER]; bool change[NUM_MAC_INDEX_DRIVER];
...@@ -879,7 +882,10 @@ struct iwl_mvm { ...@@ -879,7 +882,10 @@ struct iwl_mvm {
unsigned int scan_status; unsigned int scan_status;
void *scan_cmd; void *scan_cmd;
struct iwl_mcast_filter_cmd *mcast_filter_cmd; struct iwl_mcast_filter_cmd *mcast_filter_cmd;
/* For CDB this is low band scan type, for non-CDB - type. */
enum iwl_mvm_scan_type scan_type; enum iwl_mvm_scan_type scan_type;
enum iwl_mvm_scan_type hb_scan_type;
enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all; enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
struct delayed_work scan_timeout_dwork; struct delayed_work scan_timeout_dwork;
...@@ -1828,6 +1834,8 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1828,6 +1834,8 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum iwl_mvm_low_latency_cause cause); enum iwl_mvm_low_latency_cause cause);
/* get SystemLowLatencyMode - only needed for beacon threshold? */ /* get SystemLowLatencyMode - only needed for beacon threshold? */
bool iwl_mvm_low_latency(struct iwl_mvm *mvm); bool iwl_mvm_low_latency(struct iwl_mvm *mvm);
bool iwl_mvm_low_latency_band(struct iwl_mvm *mvm, enum nl80211_band band);
/* get VMACLowLatencyMode */ /* get VMACLowLatencyMode */
static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif) static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
{ {
......
...@@ -1074,23 +1074,48 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1074,23 +1074,48 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return iwl_mvm_power_update_mac(mvm); return iwl_mvm_power_update_mac(mvm);
} }
struct iwl_mvm_low_latency_iter {
bool result;
bool result_per_band[NUM_NL80211_BANDS];
};
static void iwl_mvm_ll_iter(void *_data, u8 *mac, struct ieee80211_vif *vif) static void iwl_mvm_ll_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
{ {
bool *result = _data; struct iwl_mvm_low_latency_iter *result = _data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
enum nl80211_band band;
if (iwl_mvm_vif_low_latency(mvmvif)) {
result->result = true;
if (!mvmvif->phy_ctxt)
return;
if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(vif))) band = mvmvif->phy_ctxt->channel->band;
*result = true; result->result_per_band[band] = true;
}
} }
bool iwl_mvm_low_latency(struct iwl_mvm *mvm) bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
{ {
bool result = false; struct iwl_mvm_low_latency_iter data = {};
ieee80211_iterate_active_interfaces_atomic( ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL, mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_ll_iter, &result); iwl_mvm_ll_iter, &data);
return result; return data.result;
}
bool iwl_mvm_low_latency_band(struct iwl_mvm *mvm, enum nl80211_band band)
{
struct iwl_mvm_low_latency_iter data = {};
ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_ll_iter, &data);
return data.result_per_band[band];
} }
struct iwl_bss_iter_data { struct iwl_bss_iter_data {
...@@ -1599,6 +1624,18 @@ static void iwl_mvm_check_uapsd_agg_expected_tpt(struct iwl_mvm *mvm, ...@@ -1599,6 +1624,18 @@ static void iwl_mvm_check_uapsd_agg_expected_tpt(struct iwl_mvm *mvm,
iwl_mvm_uapsd_agg_disconnect_iter, &mac); iwl_mvm_uapsd_agg_disconnect_iter, &mac);
} }
static void iwl_mvm_tcm_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u32 *band = _data;
if (!mvmvif->phy_ctxt)
return;
band[mvmvif->id] = mvmvif->phy_ctxt->channel->band;
}
static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm, static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
unsigned long ts, unsigned long ts,
bool handle_uapsd) bool handle_uapsd)
...@@ -1607,9 +1644,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm, ...@@ -1607,9 +1644,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
unsigned int uapsd_elapsed = unsigned int uapsd_elapsed =
jiffies_to_msecs(ts - mvm->tcm.uapsd_nonagg_ts); jiffies_to_msecs(ts - mvm->tcm.uapsd_nonagg_ts);
u32 total_airtime = 0; u32 total_airtime = 0;
int ac, mac; u32 band_airtime[NUM_NL80211_BANDS] = {0};
u32 band[NUM_MAC_INDEX_DRIVER] = {0};
int ac, mac, i;
bool low_latency = false; bool low_latency = false;
enum iwl_mvm_traffic_load load; enum iwl_mvm_traffic_load load, band_load;
bool handle_ll = time_after(ts, mvm->tcm.ll_ts + MVM_LL_PERIOD); bool handle_ll = time_after(ts, mvm->tcm.ll_ts + MVM_LL_PERIOD);
if (handle_ll) if (handle_ll)
...@@ -1619,12 +1658,18 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm, ...@@ -1619,12 +1658,18 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
mvm->tcm.result.elapsed = elapsed; mvm->tcm.result.elapsed = elapsed;
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_tcm_iterator,
&band);
for (mac = 0; mac < NUM_MAC_INDEX_DRIVER; mac++) { for (mac = 0; mac < NUM_MAC_INDEX_DRIVER; mac++) {
struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac]; struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac];
u32 vo_vi_pkts = 0; u32 vo_vi_pkts = 0;
u32 airtime = mdata->rx.airtime + mdata->tx.airtime; u32 airtime = mdata->rx.airtime + mdata->tx.airtime;
total_airtime += airtime; total_airtime += airtime;
band_airtime[band[mac]] += airtime;
load = iwl_mvm_tcm_load(mvm, airtime, elapsed); load = iwl_mvm_tcm_load(mvm, airtime, elapsed);
mvm->tcm.result.change[mac] = load != mvm->tcm.result.load[mac]; mvm->tcm.result.change[mac] = load != mvm->tcm.result.load[mac];
...@@ -1662,6 +1707,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm, ...@@ -1662,6 +1707,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
mvm->tcm.result.global_change = load != mvm->tcm.result.global_load; mvm->tcm.result.global_change = load != mvm->tcm.result.global_load;
mvm->tcm.result.global_load = load; mvm->tcm.result.global_load = load;
for (i = 0; i < NUM_NL80211_BANDS; i++) {
band_load = iwl_mvm_tcm_load(mvm, band_airtime[i], elapsed);
mvm->tcm.result.band_load[i] = band_load;
}
/* /*
* If the current load isn't low we need to force re-evaluation * If the current load isn't low we need to force re-evaluation
* in the TCM period, so that we can return to low load if there * in the TCM period, so that we can return to low load if there
......
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