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)
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
mvm->scan_type = IWL_SCAN_TYPE_NOT_SET;
mvm->hb_scan_type = IWL_SCAN_TYPE_NOT_SET;
ret = iwl_mvm_config_scan(mvm);
if (ret)
goto error;
......
......@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications 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
* it under the terms of version 2 of the GNU General Public License as
......@@ -35,6 +36,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -638,6 +640,7 @@ struct iwl_mvm_tcm {
u32 elapsed; /* milliseconds for this TCM period */
u32 airtime[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;
bool low_latency[NUM_MAC_INDEX_DRIVER];
bool change[NUM_MAC_INDEX_DRIVER];
......@@ -879,7 +882,10 @@ struct iwl_mvm {
unsigned int scan_status;
void *scan_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 hb_scan_type;
enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
struct delayed_work scan_timeout_dwork;
......@@ -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);
/* get SystemLowLatencyMode - only needed for beacon threshold? */
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 */
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,
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)
{
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)))
*result = true;
band = mvmvif->phy_ctxt->channel->band;
result->result_per_band[band] = true;
}
}
bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
{
bool result = false;
struct iwl_mvm_low_latency_iter data = {};
ieee80211_iterate_active_interfaces_atomic(
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 {
......@@ -1599,6 +1624,18 @@ static void iwl_mvm_check_uapsd_agg_expected_tpt(struct iwl_mvm *mvm,
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,
unsigned long ts,
bool handle_uapsd)
......@@ -1607,9 +1644,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
unsigned int uapsd_elapsed =
jiffies_to_msecs(ts - mvm->tcm.uapsd_nonagg_ts);
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;
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);
if (handle_ll)
......@@ -1619,12 +1658,18 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm,
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++) {
struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[mac];
u32 vo_vi_pkts = 0;
u32 airtime = mdata->rx.airtime + mdata->tx.airtime;
total_airtime += airtime;
band_airtime[band[mac]] += airtime;
load = iwl_mvm_tcm_load(mvm, airtime, elapsed);
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,
mvm->tcm.result.global_change = load != mvm->tcm.result.global_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
* 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