@@ -732,7 +732,7 @@ iwl_mld_get_min_chan_load_thresh(struct ieee80211_chanctx_conf *chanctx)
return 10;
}
-VISIBLE_IF_IWLWIFI_KUNIT bool
+static bool
iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld,
struct ieee80211_vif *vif,
const struct iwl_mld_link_sel_data *a,
@@ -789,10 +789,9 @@ iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld,
return false;
}
-EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_channel_load_allows_emlsr);
-static bool
-iwl_mld_valid_emlsr_pair(struct ieee80211_vif *vif,
+VISIBLE_IF_KUNIT u32
+iwl_mld_emlsr_pair_state(struct ieee80211_vif *vif,
struct iwl_mld_link_sel_data *a,
struct iwl_mld_link_sel_data *b)
{
@@ -801,9 +800,13 @@ iwl_mld_valid_emlsr_pair(struct ieee80211_vif *vif,
u32 reason_mask = 0;
/* Per-link considerations */
- if (iwl_mld_emlsr_disallowed_with_link(mld, vif, a, true) ||
- iwl_mld_emlsr_disallowed_with_link(mld, vif, b, false))
- return false;
+ reason_mask = iwl_mld_emlsr_disallowed_with_link(mld, vif, a, true);
+ if (reason_mask)
+ return reason_mask;
+
+ reason_mask = iwl_mld_emlsr_disallowed_with_link(mld, vif, b, false);
+ if (reason_mask)
+ return reason_mask;
if (a->chandef->chan->band == b->chandef->chan->band) {
const struct cfg80211_chan_def *c_low = a->chandef;
@@ -839,11 +842,11 @@ iwl_mld_valid_emlsr_pair(struct ieee80211_vif *vif,
nl80211_chan_width_to_mhz(a->chandef->width),
nl80211_chan_width_to_mhz(b->chandef->width));
iwl_mld_print_emlsr_exit(mld, reason_mask);
- return false;
}
- return true;
+ return reason_mask;
}
+EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_mld_emlsr_pair_state);
/* Calculation is done with fixed-point with a scaling factor of 1/256 */
#define SCALE_FACTOR 256
@@ -871,7 +874,7 @@ unsigned int iwl_mld_get_emlsr_grade(struct iwl_mld *mld,
*primary_id = a->link_id;
- if (!iwl_mld_valid_emlsr_pair(vif, a, b))
+ if (iwl_mld_emlsr_pair_state(vif, a, b))
return 0;
primary_conf = wiphy_dereference(wiphy, vif->link_conf[*primary_id]);
@@ -158,10 +158,9 @@ struct iwl_mld_link_sel_data {
};
#if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS)
-bool iwl_mld_channel_load_allows_emlsr(struct iwl_mld *mld,
- struct ieee80211_vif *vif,
- const struct iwl_mld_link_sel_data *a,
- const struct iwl_mld_link_sel_data *b);
+u32 iwl_mld_emlsr_pair_state(struct ieee80211_vif *vif,
+ struct iwl_mld_link_sel_data *a,
+ struct iwl_mld_link_sel_data *b);
#endif
#endif /* __iwl_mld_mlo_h__ */
@@ -172,21 +172,21 @@ static struct kunit_suite link_selection = {
kunit_test_suite(link_selection);
-static const struct channel_load_case {
+static const struct link_pair_case {
const char *desc;
const struct cfg80211_chan_def *chandef_a, *chandef_b;
bool low_latency_vif;
u32 chan_load_not_by_us;
bool primary_link_active;
- bool expected_result;
-} channel_load_cases[] = {
+ u32 expected_result;
+} link_pair_cases[] = {
{
.desc = "Unequal bandwidth, primary link inactive, EMLSR not allowed",
.low_latency_vif = false,
.primary_link_active = false,
.chandef_a = &chandef_5ghz_40mhz,
.chandef_b = &chandef_6ghz_20mhz,
- .expected_result = false,
+ .expected_result = IWL_MLD_EMLSR_EXIT_CHAN_LOAD,
},
{
.desc = "Equal bandwidths, sufficient channel load, EMLSR allowed",
@@ -195,7 +195,7 @@ static const struct channel_load_case {
.chan_load_not_by_us = 11,
.chandef_a = &chandef_5ghz_40mhz,
.chandef_b = &chandef_6ghz_40mhz,
- .expected_result = true,
+ .expected_result = 0,
},
{
.desc = "Equal bandwidths, insufficient channel load, EMLSR not allowed",
@@ -204,7 +204,7 @@ static const struct channel_load_case {
.chan_load_not_by_us = 6,
.chandef_a = &chandef_5ghz_80mhz,
.chandef_b = &chandef_6ghz_80mhz,
- .expected_result = false,
+ .expected_result = IWL_MLD_EMLSR_EXIT_CHAN_LOAD,
},
{
.desc = "Low latency VIF, sufficient channel load, EMLSR allowed",
@@ -213,7 +213,7 @@ static const struct channel_load_case {
.chan_load_not_by_us = 6,
.chandef_a = &chandef_5ghz_160mhz,
.chandef_b = &chandef_6ghz_160mhz,
- .expected_result = true,
+ .expected_result = 0,
},
{
.desc = "Different bandwidths (2x ratio), primary link load permits EMLSR",
@@ -222,7 +222,7 @@ static const struct channel_load_case {
.chan_load_not_by_us = 30,
.chandef_a = &chandef_5ghz_40mhz,
.chandef_b = &chandef_6ghz_20mhz,
- .expected_result = true,
+ .expected_result = 0,
},
{
.desc = "Different bandwidths (4x ratio), primary link load permits EMLSR",
@@ -231,7 +231,7 @@ static const struct channel_load_case {
.chan_load_not_by_us = 45,
.chandef_a = &chandef_5ghz_80mhz,
.chandef_b = &chandef_6ghz_20mhz,
- .expected_result = true,
+ .expected_result = 0,
},
{
.desc = "Different bandwidths (16x ratio), primary link load insufficient",
@@ -240,15 +240,51 @@ static const struct channel_load_case {
.chan_load_not_by_us = 45,
.chandef_a = &chandef_6ghz_320mhz,
.chandef_b = &chandef_5ghz_20mhz,
- .expected_result = false,
+ .expected_result = IWL_MLD_EMLSR_EXIT_CHAN_LOAD,
+ },
+ {
+ .desc = "Same band not allowed (2.4 GHz)",
+ .low_latency_vif = false,
+ .primary_link_active = true,
+ .chan_load_not_by_us = 30,
+ .chandef_a = &chandef_2ghz_20mhz,
+ .chandef_b = &chandef_2ghz_11_20mhz,
+ .expected_result = IWL_MLD_EMLSR_EXIT_EQUAL_BAND,
+ },
+ {
+ .desc = "Same band not allowed (5 GHz)",
+ .low_latency_vif = false,
+ .primary_link_active = true,
+ .chan_load_not_by_us = 30,
+ .chandef_a = &chandef_5ghz_40mhz,
+ .chandef_b = &chandef_5ghz_40mhz,
+ .expected_result = IWL_MLD_EMLSR_EXIT_EQUAL_BAND,
+ },
+ {
+ .desc = "Same band allowed (5 GHz separated)",
+ .low_latency_vif = false,
+ .primary_link_active = true,
+ .chan_load_not_by_us = 30,
+ .chandef_a = &chandef_5ghz_40mhz,
+ .chandef_b = &chandef_5ghz_120_40mhz,
+ .expected_result = 0,
+ },
+ {
+ .desc = "Same band not allowed (6 GHz)",
+ .low_latency_vif = false,
+ .primary_link_active = true,
+ .chan_load_not_by_us = 30,
+ .chandef_a = &chandef_6ghz_160mhz,
+ .chandef_b = &chandef_6ghz_221_160mhz,
+ .expected_result = IWL_MLD_EMLSR_EXIT_EQUAL_BAND,
},
};
-KUNIT_ARRAY_PARAM_DESC(channel_load, channel_load_cases, desc);
+KUNIT_ARRAY_PARAM_DESC(link_pair, link_pair_cases, desc);
-static void test_iwl_mld_channel_load_allows_emlsr(struct kunit *test)
+static void test_iwl_mld_link_pair_allows_emlsr(struct kunit *test)
{
- const struct channel_load_case *params = test->param_value;
+ const struct link_pair_case *params = test->param_value;
struct iwl_mld *mld = test->priv;
struct ieee80211_vif *vif;
/* link A is the primary and link B is the secondary */
@@ -264,7 +300,7 @@ static void test_iwl_mld_channel_load_allows_emlsr(struct kunit *test)
.chandef = params->primary_link_active ? a.chandef : b.chandef,
.id = params->primary_link_active ? a.link_id : b.link_id,
};
- bool result;
+ u32 result;
vif = iwlmld_kunit_setup_mlo_assoc(BIT(a.link_id) | BIT(b.link_id),
&assoc_link);
@@ -282,22 +318,22 @@ static void test_iwl_mld_channel_load_allows_emlsr(struct kunit *test)
phy->avg_channel_load_not_by_us = params->chan_load_not_by_us;
}
- result = iwl_mld_channel_load_allows_emlsr(mld, vif, &a, &b);
+ result = iwl_mld_emlsr_pair_state(vif, &a, &b);
wiphy_unlock(mld->wiphy);
KUNIT_EXPECT_EQ(test, result, params->expected_result);
}
-static struct kunit_case channel_load_criteria_test_cases[] = {
- KUNIT_CASE_PARAM(test_iwl_mld_channel_load_allows_emlsr, channel_load_gen_params),
+static struct kunit_case link_pair_criteria_test_cases[] = {
+ KUNIT_CASE_PARAM(test_iwl_mld_link_pair_allows_emlsr, link_pair_gen_params),
{}
};
-static struct kunit_suite channel_load_criteria_tests = {
- .name = "iwlmld_channel_load_allows_emlsr",
- .test_cases = channel_load_criteria_test_cases,
+static struct kunit_suite link_pair_criteria_tests = {
+ .name = "iwlmld_link_pair_allows_emlsr",
+ .test_cases = link_pair_criteria_test_cases,
.init = iwlmld_kunit_test_init,
};
-kunit_test_suite(channel_load_criteria_tests);
+kunit_test_suite(link_pair_criteria_tests);