xref: /linux/drivers/net/wireless/intel/iwlwifi/mld/tests/chan_load_thresh.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * KUnit tests for channel helper functions
4  *
5  * Copyright (C) 2026 Intel Corporation
6  */
7 #include <kunit/static_stub.h>
8 #include "mld.h"
9 #include "link.h"
10 #include "iface.h"
11 #include "utils.h"
12 
13 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
14 
15 struct test_chan_load_case {
16 	const char *desc;
17 	u32 load;
18 	enum iwl_mld_link_chan_load_level old_lvl;
19 	enum iwl_mld_link_chan_load_level expected_lvl;
20 	bool expected_scan_trig;
21 };
22 
23 static const struct test_chan_load_case test_chan_load_thresh_cases[] = {
24 	/* Level-up transitions */
25 	{
26 		.desc = "Transition NONE->NONE",
27 		.load = 20,
28 		.old_lvl = LINK_CHAN_LOAD_LVL_NONE,
29 		.expected_lvl = LINK_CHAN_LOAD_LVL_NONE,
30 		.expected_scan_trig = false,
31 	},
32 	{
33 		.desc = "Transition NONE->LVL1",
34 		.load = 50,
35 		.old_lvl = LINK_CHAN_LOAD_LVL_NONE,
36 		.expected_lvl = LINK_CHAN_LOAD_LVL1,
37 		.expected_scan_trig = true,
38 	},
39 	{
40 		.desc = "Transition LVL1->LVL2",
41 		.load = 75,
42 		.old_lvl = LINK_CHAN_LOAD_LVL1,
43 		.expected_lvl = LINK_CHAN_LOAD_LVL2,
44 		.expected_scan_trig = true,
45 	},
46 	{
47 		.desc = "Transition LVL2->LVL3",
48 		.load = 90,
49 		.old_lvl = LINK_CHAN_LOAD_LVL2,
50 		.expected_lvl = LINK_CHAN_LOAD_LVL3,
51 		.expected_scan_trig = true,
52 	},
53 
54 	/* Level-down transitions */
55 	{
56 		.desc = "Transition LVL1->NONE",
57 		.load = 30,
58 		.old_lvl = LINK_CHAN_LOAD_LVL1,
59 		.expected_lvl = LINK_CHAN_LOAD_LVL_NONE,
60 		.expected_scan_trig = false,
61 	},
62 	{
63 		.desc = "Transition LVL2->LVL1",
64 		.load = 60,
65 		.old_lvl = LINK_CHAN_LOAD_LVL2,
66 		.expected_lvl = LINK_CHAN_LOAD_LVL1,
67 		.expected_scan_trig = false,
68 	},
69 	{
70 		.desc = "Transition LVL3->LVL2",
71 		.load = 70,
72 		.old_lvl = LINK_CHAN_LOAD_LVL3,
73 		.expected_lvl = LINK_CHAN_LOAD_LVL2,
74 		.expected_scan_trig = false,
75 	},
76 
77 	/* No change */
78 	{
79 		.desc = "Transition LVL2->LVL2",
80 		.load = 72,
81 		.old_lvl = LINK_CHAN_LOAD_LVL2,
82 		.expected_lvl = LINK_CHAN_LOAD_LVL2,
83 		.expected_scan_trig = false,
84 	},
85 };
86 
87 KUNIT_ARRAY_PARAM_DESC(test_chan_load_thresh_cases,
88 		       test_chan_load_thresh_cases, desc);
89 
90 static void test_chan_load_thresholds(struct kunit *test)
91 {
92 	const struct test_chan_load_case *tc = test->param_value;
93 	struct iwl_mld *mld = test->priv;
94 	struct ieee80211_vif *vif;
95 	struct iwl_mld_vif *mld_vif;
96 	struct ieee80211_bss_conf *link_conf;
97 	struct iwl_mld_link *mld_link;
98 	struct iwl_mld_kunit_link assoc_link = {
99 		.id = 0,
100 		.chandef = &chandef_6ghz_160mhz,
101 	};
102 	bool scan_trig;
103 	u32 chan_load;
104 
105 	/* Setup associated non-MLO station */
106 	vif = iwlmld_kunit_setup_non_mlo_assoc(&assoc_link);
107 	mld_vif = iwl_mld_vif_from_mac80211(vif);
108 
109 	link_conf = &vif->bss_conf;
110 	mld_link = &mld_vif->deflink;
111 
112 	chan_load = tc->load;
113 	mld_link->chan_load_lvl = tc->old_lvl;
114 
115 	/* Execute function under test */
116 	wiphy_lock(mld->wiphy);
117 	scan_trig = iwl_mld_chan_load_requires_scan(mld, link_conf, chan_load);
118 	wiphy_unlock(mld->wiphy);
119 
120 	/* Check return value */
121 	KUNIT_EXPECT_EQ(test, tc->expected_scan_trig, scan_trig);
122 
123 	/* Check updated channel-load level */
124 	KUNIT_EXPECT_EQ(test, tc->expected_lvl, mld_link->chan_load_lvl);
125 }
126 
127 static struct kunit_case chan_load_thresh_test_cases[] = {
128 	KUNIT_CASE_PARAM(test_chan_load_thresholds,
129 			 test_chan_load_thresh_cases_gen_params),
130 	{}
131 };
132 
133 static struct kunit_suite chan_load_thresh_test_suite = {
134 	.name = "iwl_mld_chan_load_threshold_tests",
135 	.init = iwlmld_kunit_test_init,
136 	.test_cases = chan_load_thresh_test_cases,
137 };
138 
139 kunit_test_suite(chan_load_thresh_test_suite);
140