]> Git Repo - linux.git/blob - drivers/net/wireless/intel/iwlwifi/mvm/tests/links.c
Linux 6.14-rc3
[linux.git] / drivers / net / wireless / intel / iwlwifi / mvm / tests / links.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * KUnit tests for channel helper functions
4  *
5  * Copyright (C) 2024 Intel Corporation
6  */
7 #include <net/mac80211.h>
8 #include "../mvm.h"
9 #include <kunit/test.h>
10
11 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
12
13 static struct wiphy wiphy = {
14         .mtx = __MUTEX_INITIALIZER(wiphy.mtx),
15 };
16
17 static struct ieee80211_hw hw = {
18         .wiphy = &wiphy,
19 };
20
21 static struct ieee80211_channel chan_5ghz = {
22         .band = NL80211_BAND_5GHZ,
23 };
24
25 static struct ieee80211_channel chan_6ghz = {
26         .band = NL80211_BAND_6GHZ,
27 };
28
29 static struct ieee80211_channel chan_2ghz = {
30         .band = NL80211_BAND_2GHZ,
31 };
32
33 static struct cfg80211_chan_def chandef_a = {};
34
35 static struct cfg80211_chan_def chandef_b = {};
36
37 static struct iwl_mvm_phy_ctxt ctx = {};
38
39 static struct iwl_mvm_vif_link_info mvm_link = {
40         .phy_ctxt = &ctx,
41         .active = true
42 };
43
44 static struct cfg80211_bss bss = {};
45
46 static struct ieee80211_bss_conf link_conf = {.bss = &bss};
47
48 static const struct iwl_fw_cmd_version entry = {
49         .group = LEGACY_GROUP,
50         .cmd = BT_PROFILE_NOTIFICATION,
51         .notif_ver = 4
52 };
53
54 static struct iwl_fw fw = {
55         .ucode_capa = {
56                 .n_cmd_versions = 1,
57                 .cmd_versions = &entry,
58         },
59 };
60
61 static struct iwl_mvm mvm = {
62         .hw = &hw,
63         .fw = &fw,
64 };
65
66 static const struct link_grading_case {
67         const char *desc;
68         const struct cfg80211_chan_def chandef;
69         s32 signal;
70         s16 channel_util;
71         int chan_load_by_us;
72         unsigned int grade;
73 } link_grading_cases[] = {
74         {
75                 .desc = "UHB, RSSI below range, no factors",
76                 .chandef = {
77                         .chan = &chan_6ghz,
78                         .width = NL80211_CHAN_WIDTH_20,
79                 },
80                 .signal = -100,
81                 .grade = 177,
82         },
83         {
84                 .desc = "LB, RSSI in range, no factors",
85                 .chandef = {
86                         .chan = &chan_2ghz,
87                         .width = NL80211_CHAN_WIDTH_20,
88                 },
89                 .signal = -84,
90                 .grade = 344,
91         },
92         {
93                 .desc = "HB, RSSI above range, no factors",
94                 .chandef = {
95                         .chan = &chan_5ghz,
96                         .width = NL80211_CHAN_WIDTH_20,
97                 },
98                 .signal = -50,
99                 .grade = 3442,
100         },
101         {
102                 .desc = "HB, BSS Load IE (20 percent), inactive link, no puncturing factor",
103                 .chandef = {
104                         .chan = &chan_5ghz,
105                         .width = NL80211_CHAN_WIDTH_20,
106                 },
107                 .signal = -66,
108                 .channel_util = 51,
109                 .grade = 1836,
110         },
111         {
112                 .desc = "LB, BSS Load IE (20 percent), active link, chan_load_by_us=10 percent. No puncturing factor",
113                 .chandef = {
114                         .chan = &chan_2ghz,
115                         .width = NL80211_CHAN_WIDTH_20,
116                 },
117                 .signal = -61,
118                 .channel_util = 51,
119                 .chan_load_by_us = 10,
120                 .grade = 2061,
121         },
122         {
123                 .desc = "UHB, BSS Load IE (40 percent), active link, chan_load_by_us=50 (invalid) percent. No puncturing factor",
124                 .chandef = {
125                         .chan = &chan_6ghz,
126                         .width = NL80211_CHAN_WIDTH_20,
127                 },
128                 .signal = -66,
129                 .channel_util = 102,
130                 .chan_load_by_us = 50,
131                 .grade = 1552,
132         },
133         {       .desc = "HB, 80 MHz, no channel load factor, punctured percentage 0",
134                 .chandef = {
135                         .chan = &chan_5ghz,
136                         .width = NL80211_CHAN_WIDTH_80,
137                         .punctured = 0x0000
138                 },
139                 .signal = -72,
140                 .grade = 1750,
141         },
142         {       .desc = "HB, 160 MHz, no channel load factor, punctured percentage 25",
143                 .chandef = {
144                         .chan = &chan_5ghz,
145                         .width = NL80211_CHAN_WIDTH_160,
146                         .punctured = 0x3
147                 },
148                 .signal = -72,
149                 .grade = 1312,
150         },
151         {       .desc = "UHB, 320 MHz, no channel load factor, punctured percentage 12.5 (2/16)",
152                 .chandef = {
153                         .chan = &chan_6ghz,
154                         .width = NL80211_CHAN_WIDTH_320,
155                         .punctured = 0x3
156                 },
157                 .signal = -72,
158                 .grade = 1806,
159         },
160         {       .desc = "HB, 160 MHz, channel load 20, channel load by us 10, punctured percentage 25",
161                 .chandef = {
162                         .chan = &chan_5ghz,
163                         .width = NL80211_CHAN_WIDTH_160,
164                         .punctured = 0x3
165                 },
166                 .channel_util = 51,
167                 .chan_load_by_us = 10,
168                 .signal = -72,
169                 .grade = 1179,
170         },
171 };
172
173 KUNIT_ARRAY_PARAM_DESC(link_grading, link_grading_cases, desc)
174
175 static void setup_link_conf(struct kunit *test)
176 {
177         const struct link_grading_case *params = test->param_value;
178         size_t vif_size = sizeof(struct ieee80211_vif) +
179                 sizeof(struct iwl_mvm_vif);
180         struct ieee80211_vif *vif = kunit_kzalloc(test, vif_size, GFP_KERNEL);
181         struct ieee80211_bss_load_elem *bss_load;
182         struct element *element;
183         size_t ies_size = sizeof(struct cfg80211_bss_ies) + sizeof(*bss_load) + sizeof(element);
184         struct cfg80211_bss_ies *ies;
185         struct iwl_mvm_vif *mvmvif;
186
187         KUNIT_ASSERT_NOT_NULL(test, vif);
188
189         mvmvif = iwl_mvm_vif_from_mac80211(vif);
190         if (params->chan_load_by_us > 0) {
191                 ctx.channel_load_by_us = params->chan_load_by_us;
192                 mvmvif->link[0] = &mvm_link;
193         }
194
195         link_conf.vif = vif;
196         link_conf.chanreq.oper = params->chandef;
197         bss.signal = DBM_TO_MBM(params->signal);
198
199         ies = kunit_kzalloc(test, ies_size, GFP_KERNEL);
200         KUNIT_ASSERT_NOT_NULL(test, ies);
201         ies->len = sizeof(*bss_load) + sizeof(struct element);
202
203         element = (void *)ies->data;
204         element->datalen = sizeof(*bss_load);
205         element->id = 11;
206
207         bss_load = (void *)element->data;
208         bss_load->channel_util = params->channel_util;
209
210         rcu_assign_pointer(bss.ies, ies);
211         rcu_assign_pointer(bss.beacon_ies, ies);
212 }
213
214 static void test_link_grading(struct kunit *test)
215 {
216         const struct link_grading_case *params = test->param_value;
217         unsigned int ret;
218
219         setup_link_conf(test);
220
221         rcu_read_lock();
222         ret = iwl_mvm_get_link_grade(&link_conf);
223         rcu_read_unlock();
224
225         KUNIT_EXPECT_EQ(test, ret, params->grade);
226
227         kunit_kfree(test, link_conf.vif);
228         RCU_INIT_POINTER(bss.ies, NULL);
229 }
230
231 static struct kunit_case link_grading_test_cases[] = {
232         KUNIT_CASE_PARAM(test_link_grading, link_grading_gen_params),
233         {}
234 };
235
236 static struct kunit_suite link_grading = {
237         .name = "iwlmvm-link-grading",
238         .test_cases = link_grading_test_cases,
239 };
240
241 kunit_test_suite(link_grading);
242
243 static const struct valid_link_pair_case {
244         const char *desc;
245         bool bt;
246         struct ieee80211_channel *chan_a;
247         struct ieee80211_channel *chan_b;
248         enum nl80211_chan_width cw_a;
249         enum nl80211_chan_width cw_b;
250         s32 sig_a;
251         s32 sig_b;
252         bool csa_a;
253         bool valid;
254 } valid_link_pair_cases[] = {
255         {
256                 .desc = "HB + UHB, valid.",
257                 .chan_a = &chan_6ghz,
258                 .chan_b = &chan_5ghz,
259                 .valid = true,
260         },
261         {
262                 .desc = "LB + HB, no BT.",
263                 .chan_a = &chan_2ghz,
264                 .chan_b = &chan_5ghz,
265                 .valid = true,
266         },
267         {
268                 .desc = "LB + HB, with BT.",
269                 .bt = true,
270                 .chan_a = &chan_2ghz,
271                 .chan_b = &chan_5ghz,
272                 .valid = false,
273         },
274         {
275                 .desc = "Same band",
276                 .chan_a = &chan_2ghz,
277                 .chan_b = &chan_2ghz,
278                 .valid = false,
279         },
280         {
281                 .desc = "RSSI: LB, 20 MHz, low",
282                 .chan_a = &chan_2ghz,
283                 .cw_a = NL80211_CHAN_WIDTH_20,
284                 .sig_a = -68,
285                 .chan_b = &chan_5ghz,
286                 .valid = false,
287         },
288         {
289                 .desc = "RSSI: UHB, 20 MHz, high",
290                 .chan_a = &chan_6ghz,
291                 .cw_a = NL80211_CHAN_WIDTH_20,
292                 .sig_a = -66,
293                 .chan_b = &chan_5ghz,
294                 .cw_b = NL80211_CHAN_WIDTH_20,
295                 .valid = true,
296         },
297         {
298                 .desc = "RSSI: UHB, 40 MHz, low",
299                 .chan_a = &chan_6ghz,
300                 .cw_a = NL80211_CHAN_WIDTH_40,
301                 .sig_a = -65,
302                 .chan_b = &chan_5ghz,
303                 .cw_b = NL80211_CHAN_WIDTH_40,
304                 .valid = false,
305         },
306         {
307                 .desc = "RSSI: UHB, 40 MHz, high",
308                 .chan_a = &chan_6ghz,
309                 .cw_a = NL80211_CHAN_WIDTH_40,
310                 .sig_a = -63,
311                 .chan_b = &chan_5ghz,
312                 .cw_b = NL80211_CHAN_WIDTH_40,
313                 .valid = true,
314         },
315         {
316                 .desc = "RSSI: UHB, 80 MHz, low",
317                 .chan_a = &chan_6ghz,
318                 .cw_a = NL80211_CHAN_WIDTH_80,
319                 .sig_a = -62,
320                 .chan_b = &chan_5ghz,
321                 .cw_b = NL80211_CHAN_WIDTH_80,
322                 .valid = false,
323         },
324         {
325                 .desc = "RSSI: UHB, 80 MHz, high",
326                 .chan_a = &chan_6ghz,
327                 .cw_a = NL80211_CHAN_WIDTH_80,
328                 .sig_a = -60,
329                 .chan_b = &chan_5ghz,
330                 .cw_b = NL80211_CHAN_WIDTH_80,
331                 .valid = true,
332         },
333         {
334                 .desc = "RSSI: UHB, 160 MHz, low",
335                 .chan_a = &chan_6ghz,
336                 .cw_a = NL80211_CHAN_WIDTH_160,
337                 .sig_a = -59,
338                 .chan_b = &chan_5ghz,
339                 .cw_b = NL80211_CHAN_WIDTH_160,
340                 .valid = false,
341         },
342         {
343                 .desc = "RSSI: HB, 160 MHz, high",
344                 .chan_a = &chan_6ghz,
345                 .cw_a = NL80211_CHAN_WIDTH_160,
346                 .sig_a = -5,
347                 .chan_b = &chan_5ghz,
348                 .cw_b = NL80211_CHAN_WIDTH_160,
349                 .valid = true,
350         },
351         {
352                 .desc = "CSA active",
353                 .chan_a = &chan_6ghz,
354                 .cw_a = NL80211_CHAN_WIDTH_160,
355                 .sig_a = -5,
356                 .chan_b = &chan_5ghz,
357                 .cw_b = NL80211_CHAN_WIDTH_160,
358                 .valid = false,
359                 /* same as previous entry with valid=true except for CSA */
360                 .csa_a = true,
361         },
362 };
363
364 KUNIT_ARRAY_PARAM_DESC(valid_link_pair, valid_link_pair_cases, desc)
365
366 static void test_valid_link_pair(struct kunit *test)
367 {
368         const struct valid_link_pair_case *params = test->param_value;
369         size_t vif_size = sizeof(struct ieee80211_vif) +
370                 sizeof(struct iwl_mvm_vif);
371         struct ieee80211_vif *vif = kunit_kzalloc(test, vif_size, GFP_KERNEL);
372         struct iwl_trans *trans = kunit_kzalloc(test, sizeof(struct iwl_trans),
373                                                 GFP_KERNEL);
374         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
375         struct iwl_mvm_link_sel_data link_a = {
376                 .chandef = &chandef_a,
377                 .link_id = 1,
378                 .signal = params->sig_a,
379         };
380         struct iwl_mvm_link_sel_data link_b = {
381                 .chandef = &chandef_b,
382                 .link_id = 5,
383                 .signal = params->sig_b,
384         };
385         struct ieee80211_bss_conf *conf;
386         bool result;
387
388         KUNIT_ASSERT_NOT_NULL(test, vif);
389         KUNIT_ASSERT_NOT_NULL(test, trans);
390
391         chandef_a.chan = params->chan_a;
392         chandef_b.chan = params->chan_b;
393
394         chandef_a.width = params->cw_a ?: NL80211_CHAN_WIDTH_20;
395         chandef_b.width = params->cw_b ?: NL80211_CHAN_WIDTH_20;
396
397         mvm.trans = trans;
398
399         mvm.last_bt_notif.wifi_loss_low_rssi = params->bt;
400         mvmvif->mvm = &mvm;
401
402         conf = kunit_kzalloc(test, sizeof(*vif->link_conf[0]), GFP_KERNEL);
403         KUNIT_ASSERT_NOT_NULL(test, conf);
404         conf->chanreq.oper = chandef_a;
405         conf->csa_active = params->csa_a;
406         vif->link_conf[link_a.link_id] = (void __rcu *)conf;
407
408         conf = kunit_kzalloc(test, sizeof(*vif->link_conf[0]), GFP_KERNEL);
409         KUNIT_ASSERT_NOT_NULL(test, conf);
410         conf->chanreq.oper = chandef_b;
411         vif->link_conf[link_b.link_id] = (void __rcu *)conf;
412
413         wiphy_lock(&wiphy);
414         result = iwl_mvm_mld_valid_link_pair(vif, &link_a, &link_b);
415         wiphy_unlock(&wiphy);
416
417         KUNIT_EXPECT_EQ(test, result, params->valid);
418
419         kunit_kfree(test, vif);
420         kunit_kfree(test, trans);
421 }
422
423 static struct kunit_case valid_link_pair_test_cases[] = {
424         KUNIT_CASE_PARAM(test_valid_link_pair, valid_link_pair_gen_params),
425         {},
426 };
427
428 static struct kunit_suite valid_link_pair = {
429         .name = "iwlmvm-valid-link-pair",
430         .test_cases = valid_link_pair_test_cases,
431 };
432
433 kunit_test_suite(valid_link_pair);
This page took 0.05539 seconds and 4 git commands to generate.