wifi: iwlwifi: mld: add KUnit tests for duplicated beacon RSSI adjustment

Add KUnit tests to verify RSSI adjustment for 6 GHz duplicated
beacons across different operational bandwidths and validate
detection of the duplicated beacon bit.

Signed-off-by: Avinash Bhatt <avinash.bhatt@intel.com>
Link: https://patch.msgid.link/20260527230313.a3500c44f5e8.Icba6ee1158e9f563a91b482b8cdd3f51ddace468@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
This commit is contained in:
Avinash Bhatt 2026-05-27 23:05:10 +03:00 committed by Miri Korenblit
parent 301b0dfa9d
commit fa6758a86e
5 changed files with 173 additions and 4 deletions

View File

@ -1024,7 +1024,7 @@ iwl_mld_get_avail_chan_load(struct iwl_mld *mld,
return MAX_CHAN_LOAD - iwl_mld_get_chan_load(mld, link_conf);
}
static s8
VISIBLE_IF_IWLWIFI_KUNIT s8
iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf)
{
@ -1077,6 +1077,7 @@ iwl_mld_get_dup_beacon_rssi_adjust(struct iwl_mld *mld,
return 0;
}
}
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_get_dup_beacon_rssi_adjust);
static s8 iwl_mld_get_primary_psd(const struct ieee80211_parsed_tpe_psd *psd,
const struct cfg80211_chan_def *chandef,

View File

@ -142,6 +142,11 @@ int iwl_mld_link_set_associated(struct iwl_mld *mld, struct ieee80211_vif *vif,
unsigned int iwl_mld_get_link_grade(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf);
#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);
#endif
unsigned int iwl_mld_get_chan_load(struct iwl_mld *mld,
struct ieee80211_bss_conf *link_conf);

View File

@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* KUnit tests for channel helper functions
* KUnit tests for link helper functions
*
* Copyright (C) 2024-2025 Intel Corporation
* Copyright (C) 2024-2026 Intel Corporation
*/
#include <kunit/static_stub.h>
@ -96,8 +96,106 @@ static void test_missed_beacon(struct kunit *test)
/* TODO: add test cases for esr and check */
}
struct dup_beacon_test_case {
const char *desc;
enum nl80211_chan_width bandwidth;
bool has_he_oper;
bool dup_beacon_bit;
s8 expected_adj;
};
static const struct dup_beacon_test_case dup_beacon_cases[] = {
{
.desc = "20 MHz - no duplication",
.bandwidth = NL80211_CHAN_WIDTH_20,
.has_he_oper = true,
.dup_beacon_bit = true,
.expected_adj = 0,
},
{
.desc = "40 MHz with duplication - 3 dB",
.bandwidth = NL80211_CHAN_WIDTH_40,
.has_he_oper = true,
.dup_beacon_bit = true,
.expected_adj = 3,
},
{
.desc = "80 MHz with duplication - 6 dB",
.bandwidth = NL80211_CHAN_WIDTH_80,
.has_he_oper = true,
.dup_beacon_bit = true,
.expected_adj = 6,
},
{
.desc = "160 MHz with duplication - 9 dB",
.bandwidth = NL80211_CHAN_WIDTH_160,
.has_he_oper = true,
.dup_beacon_bit = true,
.expected_adj = 9,
},
{
.desc = "320 MHz with duplication - 12 dB",
.bandwidth = NL80211_CHAN_WIDTH_320,
.has_he_oper = true,
.dup_beacon_bit = true,
.expected_adj = 12,
},
{
.desc = "80 MHz without dup bit - no adjustment",
.bandwidth = NL80211_CHAN_WIDTH_80,
.has_he_oper = true,
.dup_beacon_bit = false,
.expected_adj = 0,
},
{
.desc = "80 MHz without HE oper - no adjustment",
.bandwidth = NL80211_CHAN_WIDTH_80,
.has_he_oper = false,
.dup_beacon_bit = true,
.expected_adj = 0,
},
};
KUNIT_ARRAY_PARAM_DESC(test_dup_beacon_rssi_adjust, dup_beacon_cases, desc);
static void test_dup_beacon_rssi_adjust(struct kunit *test)
{
const struct dup_beacon_test_case *params = test->param_value;
struct iwl_mld *mld = test->priv;
struct ieee80211_bss_conf *link_conf;
struct cfg80211_bss *bss;
struct element *he_elem = NULL;
s8 result;
KUNIT_ALLOC_AND_ASSERT(test, link_conf);
KUNIT_ALLOC_AND_ASSERT(test, bss);
link_conf->bss = bss;
link_conf->chanreq.oper.chan = &chan_6ghz;
link_conf->chanreq.oper.width = params->bandwidth;
if (params->has_he_oper) {
struct ieee80211_he_6ghz_oper he_6ghz = {};
if (params->dup_beacon_bit)
he_6ghz.control =
IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON;
he_elem = iwlmld_kunit_create_he_6ghz_oper(he_6ghz);
}
rcu_assign_pointer(bss->beacon_ies,
iwlmld_kunit_create_bss_ies(he_elem));
guard(wiphy)(mld->wiphy);
result = iwl_mld_get_dup_beacon_rssi_adjust(mld, 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),
{},
};

View File

@ -439,6 +439,66 @@ struct ieee80211_vif *iwlmld_kunit_assoc_emlsr(struct iwl_mld_kunit_link *link1,
return vif;
}
struct element *
iwlmld_kunit_create_he_6ghz_oper(struct ieee80211_he_6ghz_oper he_6ghz)
{
struct kunit *test = kunit_get_current_test();
u8 *data;
size_t data_len;
size_t offset = 0;
__le32 he_oper_params;
__le16 he_mcs_nss_set = 0;
/* Build HE Operation IE with 6 GHz info using raw buffer.
* Cannot use struct embedding because ieee80211_he_operation
* has a flexible array member (optional[]).
*
* Layout:
* 1 byte: ext_id (WLAN_EID_EXT_HE_OPERATION)
* he_oper_params: he_oper_params (from ieee80211_he_operation)
* he_mcs_nss_set: he_mcs_nss_set (from ieee80211_he_operation)
* he_6ghz: ieee80211_he_6ghz_oper (goes into optional[])
*/
data_len = 1 + sizeof(he_oper_params) + sizeof(he_mcs_nss_set) +
sizeof(struct ieee80211_he_6ghz_oper);
data = kunit_kzalloc(test, data_len, GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, data);
data[offset++] = WLAN_EID_EXT_HE_OPERATION;
he_oper_params = cpu_to_le32(IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
memcpy(&data[offset], &he_oper_params, sizeof(he_oper_params));
offset += sizeof(he_oper_params);
memcpy(&data[offset], &he_mcs_nss_set, sizeof(he_mcs_nss_set));
offset += sizeof(he_mcs_nss_set);
memcpy(&data[offset], &he_6ghz, sizeof(he_6ghz));
return iwlmld_kunit_gen_element(WLAN_EID_EXTENSION, data, data_len);
}
struct cfg80211_bss_ies *iwlmld_kunit_create_bss_ies(struct element *elem)
{
struct kunit *test = kunit_get_current_test();
struct cfg80211_bss_ies *ies;
size_t ies_len = 0;
if (elem)
ies_len = sizeof(*elem) + elem->datalen;
ies = kunit_kzalloc(test, sizeof(*ies) + ies_len, GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, ies);
ies->len = ies_len;
if (elem)
memcpy(ies->data, elem, ies_len);
return ies;
}
struct element *iwlmld_kunit_gen_element(u8 id, const void *data, size_t len)
{
struct kunit *test = kunit_get_current_test();

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2024-2025 Intel Corporation
* Copyright (C) 2024-2026 Intel Corporation
*/
#ifndef __iwl_mld_kunit_utils_h__
@ -121,6 +121,11 @@ iwlmld_kunit_assoc_emlsr(struct iwl_mld_kunit_link *link1,
struct element *iwlmld_kunit_gen_element(u8 id, const void *data, size_t len);
struct element *
iwlmld_kunit_create_he_6ghz_oper(struct ieee80211_he_6ghz_oper he_6ghz);
struct cfg80211_bss_ies *iwlmld_kunit_create_bss_ies(struct element *elem);
/**
* iwlmld_kunit_get_phy_of_link - Get the phy of a link
*