mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
wifi: iwlwifi: mld: add KUnit tests for PSD/EIRP RSSI adjustment
Add tests for PSD/EIRP RSSI adjustment which compensates measurements when APs use PSD-based power scaling with bandwidth. Tests cover all power types, bandwidths, and limiting scenarios. Signed-off-by: Avinash Bhatt <avinash.bhatt@intel.com> Link: https://patch.msgid.link/20260531135036.a18b8d0acd62.I68dfcc17359ab8a5abdc84e1e21db4ad1671af41@changeid Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
This commit is contained in:
parent
18bf30892c
commit
7d390ff7f2
|
|
@ -1098,7 +1098,8 @@ static s8 iwl_mld_get_primary_psd(const struct ieee80211_parsed_tpe_psd *psd,
|
|||
return psd->power[primary_idx] / 2;
|
||||
}
|
||||
|
||||
static s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
||||
VISIBLE_IF_IWLWIFI_KUNIT s8
|
||||
iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
const struct ieee80211_parsed_tpe *tpe = &link_conf->tpe;
|
||||
s8 psd_20mhz, psd_oper, psd_local, psd_reg, psd_boost;
|
||||
|
|
@ -1217,6 +1218,7 @@ static s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf)
|
|||
|
||||
return adjustment;
|
||||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_get_psd_eirp_rssi_adjust);
|
||||
|
||||
/* This function calculates the grade of a link. Returns 0 in error case */
|
||||
unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
|
|||
#if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS)
|
||||
s8 iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
|
||||
struct ieee80211_bss_conf *link_conf);
|
||||
s8 iwl_mld_get_psd_eirp_rssi_adjust(struct ieee80211_bss_conf *link_conf);
|
||||
#endif
|
||||
|
||||
unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld,
|
||||
|
|
|
|||
|
|
@ -158,6 +158,354 @@ static const struct dup_beacon_test_case dup_beacon_cases[] = {
|
|||
|
||||
KUNIT_ARRAY_PARAM_DESC(test_dup_beacon_rssi_adjust, dup_beacon_cases, desc);
|
||||
|
||||
struct psd_eirp_test_case {
|
||||
const char *desc;
|
||||
const struct cfg80211_chan_def *chandef;
|
||||
enum ieee80211_ap_reg_power power_type;
|
||||
struct {
|
||||
s8 psd_20;
|
||||
s8 psd_oper;
|
||||
s8 eirp_20;
|
||||
s8 eirp_oper;
|
||||
} local, reg;
|
||||
s8 expected_adj;
|
||||
struct {
|
||||
bool no_psd_data;
|
||||
bool no_eirp_data;
|
||||
bool no_reg_psd_data;
|
||||
bool has_partial_psd;
|
||||
u8 psd_partial_count;
|
||||
bool non_uniform_psd;
|
||||
bool has_unusable_channels;
|
||||
} flags;
|
||||
};
|
||||
|
||||
static const struct psd_eirp_test_case psd_eirp_cases[] = {
|
||||
{
|
||||
.desc = "20 MHz VLP baseline - no boost expected",
|
||||
.chandef = &chandef_6ghz_20mhz,
|
||||
.power_type = IEEE80211_REG_VLP_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 40,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 40,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz VLP - power limit prevents boost",
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.power_type = IEEE80211_REG_VLP_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 46,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 46,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz LPI - power limit caps the boost",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz LPI - power limit caps the boost",
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "320 MHz SP - power limit caps the boost",
|
||||
.chandef = &chandef_6ghz_320mhz_pri0,
|
||||
.power_type = IEEE80211_REG_SP_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 63,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 63,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - EIRP prevents boost",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 20,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 20,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz - regulatory TPE sets lower limits",
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 30, .psd_oper = 30,
|
||||
.eirp_20 = 50, .eirp_oper = 56,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 46,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - PSD missing, use EIRP only",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = S8_MAX, .psd_oper = S8_MAX,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = S8_MAX, .psd_oper = S8_MAX,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
.flags.no_psd_data = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - single PSD source available",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
.flags.no_reg_psd_data = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - partial PSD data present",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 24, .psd_oper = 24,
|
||||
.eirp_20 = 40, .eirp_oper = 56,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 24, .psd_oper = 24,
|
||||
.eirp_20 = 40, .eirp_oper = 56,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
.flags.has_partial_psd = true,
|
||||
.flags.psd_partial_count = 2,
|
||||
},
|
||||
{
|
||||
.desc = "160 MHz - different PSD per sub-channel",
|
||||
.chandef = &chandef_6ghz_160mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 8, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 8, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 58,
|
||||
},
|
||||
.expected_adj = 11,
|
||||
.flags.non_uniform_psd = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - EIRP missing, use PSD only",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = S8_MAX, .eirp_oper = S8_MAX,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = S8_MAX, .eirp_oper = S8_MAX,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
.flags.no_eirp_data = true,
|
||||
},
|
||||
{
|
||||
.desc = "80 MHz - skip unusable channels in average",
|
||||
.chandef = &chandef_6ghz_80mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 52,
|
||||
},
|
||||
.expected_adj = 3,
|
||||
.flags.has_unusable_channels = true,
|
||||
},
|
||||
{
|
||||
.desc = "40 MHz - no negative adjustment",
|
||||
.chandef = &chandef_6ghz_40mhz,
|
||||
.power_type = IEEE80211_REG_LPI_AP,
|
||||
.local = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 18,
|
||||
},
|
||||
.reg = {
|
||||
.psd_20 = 20, .psd_oper = 20,
|
||||
.eirp_20 = 40, .eirp_oper = 18,
|
||||
},
|
||||
.expected_adj = 0,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM_DESC(test_psd_eirp_rssi_adjust, psd_eirp_cases, desc);
|
||||
|
||||
static void setup_psd(struct ieee80211_bss_conf *link_conf,
|
||||
const struct psd_eirp_test_case *params,
|
||||
int num_subchannels)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (params->flags.no_psd_data) {
|
||||
link_conf->tpe.psd_local[0].valid = false;
|
||||
link_conf->tpe.psd_reg_client[0].valid = false;
|
||||
link_conf->tpe.psd_local[0].count = 0;
|
||||
link_conf->tpe.psd_reg_client[0].count = 0;
|
||||
} else if (params->flags.no_reg_psd_data) {
|
||||
link_conf->tpe.psd_local[0].valid = true;
|
||||
link_conf->tpe.psd_local[0].count = num_subchannels;
|
||||
link_conf->tpe.psd_reg_client[0].valid = false;
|
||||
link_conf->tpe.psd_reg_client[0].count = 0;
|
||||
} else if (params->flags.has_partial_psd) {
|
||||
link_conf->tpe.psd_local[0].valid = true;
|
||||
link_conf->tpe.psd_local[0].count =
|
||||
params->flags.psd_partial_count;
|
||||
link_conf->tpe.psd_reg_client[0].valid = true;
|
||||
link_conf->tpe.psd_reg_client[0].count =
|
||||
params->flags.psd_partial_count;
|
||||
} else {
|
||||
link_conf->tpe.psd_local[0].valid = true;
|
||||
link_conf->tpe.psd_local[0].count = num_subchannels;
|
||||
link_conf->tpe.psd_reg_client[0].valid = true;
|
||||
link_conf->tpe.psd_reg_client[0].count = num_subchannels;
|
||||
}
|
||||
|
||||
/* TPE element stores PSD limit as value * 2 */
|
||||
if (params->flags.non_uniform_psd) {
|
||||
/* PSD varies per sub-channel: 10/12/10/8 dBm pattern */
|
||||
static const s8 psd_values[] = {20, 24, 20, 16, 20, 24, 20, 16,
|
||||
20, 24, 20, 16, 20, 24, 20};
|
||||
/* Set primary channel (index 0) explicitly */
|
||||
link_conf->tpe.psd_local[0].power[0] =
|
||||
params->local.psd_20 * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[0] =
|
||||
params->reg.psd_20 * 2;
|
||||
/* Set remaining subchannels with pattern */
|
||||
for (i = 1; i < num_subchannels; i++) {
|
||||
link_conf->tpe.psd_local[0].power[i] =
|
||||
psd_values[i - 1];
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
psd_values[i - 1];
|
||||
}
|
||||
} else if (params->flags.no_psd_data) {
|
||||
for (i = 0; i < num_subchannels; i++) {
|
||||
link_conf->tpe.psd_local[0].power[i] = S8_MAX;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] = S8_MAX;
|
||||
}
|
||||
} else if (params->flags.has_unusable_channels) {
|
||||
/* Alternate usable/unusable channels for S8_MIN test */
|
||||
/* Set primary channel (index 0) explicitly */
|
||||
link_conf->tpe.psd_local[0].power[0] =
|
||||
params->local.psd_20 * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[0] =
|
||||
params->reg.psd_20 * 2;
|
||||
/* Alternate usable/unusable for remaining subchannels */
|
||||
for (i = 1; i < num_subchannels; i++) {
|
||||
if (i % 2 == 0) {
|
||||
link_conf->tpe.psd_local[0].power[i] =
|
||||
params->local.psd_oper * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
params->reg.psd_oper * 2;
|
||||
} else {
|
||||
link_conf->tpe.psd_local[0].power[i] = S8_MIN;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
S8_MIN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set primary channel (index 0) separately */
|
||||
link_conf->tpe.psd_local[0].power[0] =
|
||||
params->local.psd_20 * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[0] =
|
||||
params->reg.psd_20 * 2;
|
||||
/* Set remaining subchannels */
|
||||
for (i = 1; i < num_subchannels; i++) {
|
||||
link_conf->tpe.psd_local[0].power[i] =
|
||||
params->local.psd_oper * 2;
|
||||
link_conf->tpe.psd_reg_client[0].power[i] =
|
||||
params->reg.psd_oper * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_eirp(struct ieee80211_bss_conf *link_conf,
|
||||
const struct psd_eirp_test_case *params,
|
||||
int num_subchannels)
|
||||
{
|
||||
int i;
|
||||
int count = ilog2(num_subchannels) + 1;
|
||||
|
||||
link_conf->tpe.max_local[0].valid = !params->flags.no_eirp_data;
|
||||
link_conf->tpe.max_reg_client[0].valid = !params->flags.no_eirp_data;
|
||||
|
||||
if (params->flags.no_eirp_data) {
|
||||
link_conf->tpe.max_local[0].count = 0;
|
||||
link_conf->tpe.max_reg_client[0].count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
link_conf->tpe.max_local[0].count = count;
|
||||
link_conf->tpe.max_reg_client[0].count = count;
|
||||
|
||||
/* TPE element stores EIRP limit as value * 2 */
|
||||
link_conf->tpe.max_local[0].power[0] = params->local.eirp_20 * 2;
|
||||
link_conf->tpe.max_reg_client[0].power[0] = params->reg.eirp_20 * 2;
|
||||
for (i = 1; i < count; i++) {
|
||||
link_conf->tpe.max_local[0].power[i] =
|
||||
params->local.eirp_oper * 2;
|
||||
link_conf->tpe.max_reg_client[0].power[i] =
|
||||
params->reg.eirp_oper * 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_dup_beacon_rssi_adjust(struct kunit *test)
|
||||
{
|
||||
const struct dup_beacon_test_case *params = test->param_value;
|
||||
|
|
@ -192,10 +540,34 @@ static void test_dup_beacon_rssi_adjust(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, result, params->expected_adj);
|
||||
}
|
||||
|
||||
static void test_psd_eirp_rssi_adjust(struct kunit *test)
|
||||
{
|
||||
const struct psd_eirp_test_case *params = test->param_value;
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
int num_subchannels;
|
||||
s8 result;
|
||||
|
||||
KUNIT_ALLOC_AND_ASSERT(test, link_conf);
|
||||
|
||||
link_conf->power_type = params->power_type;
|
||||
link_conf->chanreq.oper = *params->chandef;
|
||||
num_subchannels =
|
||||
nl80211_chan_width_to_mhz(params->chandef->width) / 20;
|
||||
|
||||
setup_psd(link_conf, params, num_subchannels);
|
||||
setup_eirp(link_conf, params, num_subchannels);
|
||||
|
||||
result = iwl_mld_get_psd_eirp_rssi_adjust(link_conf);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, result, params->expected_adj);
|
||||
}
|
||||
|
||||
static struct kunit_case link_cases[] = {
|
||||
KUNIT_CASE_PARAM(test_missed_beacon, test_missed_beacon_gen_params),
|
||||
KUNIT_CASE_PARAM(test_dup_beacon_rssi_adjust,
|
||||
test_dup_beacon_rssi_adjust_gen_params),
|
||||
KUNIT_CASE_PARAM(test_psd_eirp_rssi_adjust,
|
||||
test_psd_eirp_rssi_adjust_gen_params),
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ CHANNEL(chan_6ghz_221, NL80211_BAND_6GHZ, 7055);
|
|||
NL80211_CHAN_WIDTH_160) \
|
||||
CHANDEF(chandef_6ghz_320mhz, chan_6ghz, 6105, \
|
||||
NL80211_CHAN_WIDTH_320) \
|
||||
CHANDEF(chandef_6ghz_320mhz_pri0, chan_6ghz, 6265, \
|
||||
NL80211_CHAN_WIDTH_320) \
|
||||
CHANDEF(chandef_6ghz_221_160mhz, chan_6ghz_221, 6985, \
|
||||
NL80211_CHAN_WIDTH_160) \
|
||||
/* Feel free to add more */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user