xref: /linux/drivers/net/wireless/intel/iwlwifi/mld/tests/rx.c (revision 1a9239bb4253f9076b5b4b2a1a4e8d7defd77a95)
1*d1e879ecSMiri Korenblit // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*d1e879ecSMiri Korenblit /*
3*d1e879ecSMiri Korenblit  * KUnit tests for channel helper functions
4*d1e879ecSMiri Korenblit  *
5*d1e879ecSMiri Korenblit  * Copyright (C) 2024 Intel Corporation
6*d1e879ecSMiri Korenblit  */
7*d1e879ecSMiri Korenblit #include <kunit/test.h>
8*d1e879ecSMiri Korenblit #include "utils.h"
9*d1e879ecSMiri Korenblit #include "iwl-trans.h"
10*d1e879ecSMiri Korenblit #include "mld.h"
11*d1e879ecSMiri Korenblit #include "sta.h"
12*d1e879ecSMiri Korenblit 
13*d1e879ecSMiri Korenblit static const struct is_dup_case {
14*d1e879ecSMiri Korenblit 	const char *desc;
15*d1e879ecSMiri Korenblit 	struct {
16*d1e879ecSMiri Korenblit 		/* ieee80211_hdr fields */
17*d1e879ecSMiri Korenblit 		__le16 fc;
18*d1e879ecSMiri Korenblit 		__le16 seq;
19*d1e879ecSMiri Korenblit 		u8 tid;
20*d1e879ecSMiri Korenblit 		bool multicast;
21*d1e879ecSMiri Korenblit 		/* iwl_rx_mpdu_desc fields */
22*d1e879ecSMiri Korenblit 		bool is_amsdu;
23*d1e879ecSMiri Korenblit 		u8 sub_frame_idx;
24*d1e879ecSMiri Korenblit 	} rx_pkt;
25*d1e879ecSMiri Korenblit 	struct {
26*d1e879ecSMiri Korenblit 		__le16 last_seq;
27*d1e879ecSMiri Korenblit 		u8 last_sub_frame_idx;
28*d1e879ecSMiri Korenblit 		u8 tid;
29*d1e879ecSMiri Korenblit 	} dup_data_state;
30*d1e879ecSMiri Korenblit 	struct {
31*d1e879ecSMiri Korenblit 		bool is_dup;
32*d1e879ecSMiri Korenblit 		u32 rx_status_flag;
33*d1e879ecSMiri Korenblit 	} result;
34*d1e879ecSMiri Korenblit } is_dup_cases[] = {
35*d1e879ecSMiri Korenblit 	{
36*d1e879ecSMiri Korenblit 		.desc = "Control frame",
37*d1e879ecSMiri Korenblit 		.rx_pkt = {
38*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_CTL),
39*d1e879ecSMiri Korenblit 		},
40*d1e879ecSMiri Korenblit 		.result = {
41*d1e879ecSMiri Korenblit 			.is_dup = false,
42*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
43*d1e879ecSMiri Korenblit 		}
44*d1e879ecSMiri Korenblit 	},
45*d1e879ecSMiri Korenblit 	{
46*d1e879ecSMiri Korenblit 		.desc = "Null func frame",
47*d1e879ecSMiri Korenblit 		.rx_pkt = {
48*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
49*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_NULLFUNC),
50*d1e879ecSMiri Korenblit 		},
51*d1e879ecSMiri Korenblit 		.result = {
52*d1e879ecSMiri Korenblit 			.is_dup = false,
53*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
54*d1e879ecSMiri Korenblit 		}
55*d1e879ecSMiri Korenblit 	},
56*d1e879ecSMiri Korenblit 	{
57*d1e879ecSMiri Korenblit 		.desc = "Multicast data",
58*d1e879ecSMiri Korenblit 		.rx_pkt = {
59*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA),
60*d1e879ecSMiri Korenblit 			.multicast = true,
61*d1e879ecSMiri Korenblit 		},
62*d1e879ecSMiri Korenblit 		.result = {
63*d1e879ecSMiri Korenblit 			.is_dup = false,
64*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
65*d1e879ecSMiri Korenblit 		}
66*d1e879ecSMiri Korenblit 	},
67*d1e879ecSMiri Korenblit 	{
68*d1e879ecSMiri Korenblit 		.desc = "QoS null func frame",
69*d1e879ecSMiri Korenblit 		.rx_pkt = {
70*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
71*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_NULLFUNC),
72*d1e879ecSMiri Korenblit 		},
73*d1e879ecSMiri Korenblit 		.result = {
74*d1e879ecSMiri Korenblit 			.is_dup = false,
75*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
76*d1e879ecSMiri Korenblit 		}
77*d1e879ecSMiri Korenblit 	},
78*d1e879ecSMiri Korenblit 	{
79*d1e879ecSMiri Korenblit 		.desc = "QoS data new sequence",
80*d1e879ecSMiri Korenblit 		.rx_pkt = {
81*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
82*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA),
83*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x101),
84*d1e879ecSMiri Korenblit 		},
85*d1e879ecSMiri Korenblit 		.dup_data_state = {
86*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
87*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
88*d1e879ecSMiri Korenblit 		},
89*d1e879ecSMiri Korenblit 		.result = {
90*d1e879ecSMiri Korenblit 			.is_dup = false,
91*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_DUP_VALIDATED,
92*d1e879ecSMiri Korenblit 		},
93*d1e879ecSMiri Korenblit 	},
94*d1e879ecSMiri Korenblit 	{
95*d1e879ecSMiri Korenblit 		.desc = "QoS data same sequence, no retry",
96*d1e879ecSMiri Korenblit 		.rx_pkt = {
97*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
98*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA),
99*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
100*d1e879ecSMiri Korenblit 		},
101*d1e879ecSMiri Korenblit 		.dup_data_state = {
102*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
103*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
104*d1e879ecSMiri Korenblit 		},
105*d1e879ecSMiri Korenblit 		.result = {
106*d1e879ecSMiri Korenblit 			.is_dup = false,
107*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_DUP_VALIDATED,
108*d1e879ecSMiri Korenblit 		},
109*d1e879ecSMiri Korenblit 	},
110*d1e879ecSMiri Korenblit 	{
111*d1e879ecSMiri Korenblit 		.desc = "QoS data same sequence, has retry",
112*d1e879ecSMiri Korenblit 		.rx_pkt = {
113*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
114*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA |
115*d1e879ecSMiri Korenblit 					    IEEE80211_FCTL_RETRY),
116*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
117*d1e879ecSMiri Korenblit 		},
118*d1e879ecSMiri Korenblit 		.dup_data_state = {
119*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
120*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
121*d1e879ecSMiri Korenblit 		},
122*d1e879ecSMiri Korenblit 		.result = {
123*d1e879ecSMiri Korenblit 			.is_dup = true,
124*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
125*d1e879ecSMiri Korenblit 		},
126*d1e879ecSMiri Korenblit 	},
127*d1e879ecSMiri Korenblit 	{
128*d1e879ecSMiri Korenblit 		.desc = "QoS data invalid tid",
129*d1e879ecSMiri Korenblit 		.rx_pkt = {
130*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
131*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA),
132*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
133*d1e879ecSMiri Korenblit 			.tid = IWL_MAX_TID_COUNT + 1,
134*d1e879ecSMiri Korenblit 		},
135*d1e879ecSMiri Korenblit 		.result = {
136*d1e879ecSMiri Korenblit 			.is_dup = true,
137*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
138*d1e879ecSMiri Korenblit 		},
139*d1e879ecSMiri Korenblit 	},
140*d1e879ecSMiri Korenblit 	{
141*d1e879ecSMiri Korenblit 		.desc = "non-QoS data, same sequence, same tid, no retry",
142*d1e879ecSMiri Korenblit 		.rx_pkt = {
143*d1e879ecSMiri Korenblit 			/* Driver will use tid = IWL_MAX_TID_COUNT */
144*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA),
145*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
146*d1e879ecSMiri Korenblit 		},
147*d1e879ecSMiri Korenblit 		.dup_data_state = {
148*d1e879ecSMiri Korenblit 			.tid = IWL_MAX_TID_COUNT,
149*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
150*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
151*d1e879ecSMiri Korenblit 		},
152*d1e879ecSMiri Korenblit 		.result = {
153*d1e879ecSMiri Korenblit 			.is_dup = false,
154*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_DUP_VALIDATED,
155*d1e879ecSMiri Korenblit 		},
156*d1e879ecSMiri Korenblit 	},
157*d1e879ecSMiri Korenblit 	{
158*d1e879ecSMiri Korenblit 		.desc = "non-QoS data, same sequence, same tid, has retry",
159*d1e879ecSMiri Korenblit 		.rx_pkt = {
160*d1e879ecSMiri Korenblit 			/* Driver will use tid = IWL_MAX_TID_COUNT */
161*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
162*d1e879ecSMiri Korenblit 					    IEEE80211_FCTL_RETRY),
163*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
164*d1e879ecSMiri Korenblit 		},
165*d1e879ecSMiri Korenblit 		.dup_data_state = {
166*d1e879ecSMiri Korenblit 			.tid = IWL_MAX_TID_COUNT,
167*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
168*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
169*d1e879ecSMiri Korenblit 		},
170*d1e879ecSMiri Korenblit 		.result = {
171*d1e879ecSMiri Korenblit 			.is_dup = true,
172*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
173*d1e879ecSMiri Korenblit 		},
174*d1e879ecSMiri Korenblit 	},
175*d1e879ecSMiri Korenblit 	{
176*d1e879ecSMiri Korenblit 		.desc = "non-QoS data, same sequence on different tid's",
177*d1e879ecSMiri Korenblit 		.rx_pkt = {
178*d1e879ecSMiri Korenblit 			/* Driver will use tid = IWL_MAX_TID_COUNT */
179*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA),
180*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
181*d1e879ecSMiri Korenblit 		},
182*d1e879ecSMiri Korenblit 		.dup_data_state = {
183*d1e879ecSMiri Korenblit 			.tid = 7,
184*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
185*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
186*d1e879ecSMiri Korenblit 		},
187*d1e879ecSMiri Korenblit 		.result = {
188*d1e879ecSMiri Korenblit 			.is_dup = false,
189*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_DUP_VALIDATED,
190*d1e879ecSMiri Korenblit 		},
191*d1e879ecSMiri Korenblit 	},
192*d1e879ecSMiri Korenblit 	{
193*d1e879ecSMiri Korenblit 		.desc = "A-MSDU new subframe, allow same PN",
194*d1e879ecSMiri Korenblit 		.rx_pkt = {
195*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
196*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA),
197*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
198*d1e879ecSMiri Korenblit 			.is_amsdu = true,
199*d1e879ecSMiri Korenblit 			.sub_frame_idx = 1,
200*d1e879ecSMiri Korenblit 		},
201*d1e879ecSMiri Korenblit 		.dup_data_state = {
202*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
203*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
204*d1e879ecSMiri Korenblit 		},
205*d1e879ecSMiri Korenblit 		.result = {
206*d1e879ecSMiri Korenblit 			.is_dup = false,
207*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_ALLOW_SAME_PN |
208*d1e879ecSMiri Korenblit 					  RX_FLAG_DUP_VALIDATED,
209*d1e879ecSMiri Korenblit 		},
210*d1e879ecSMiri Korenblit 	},
211*d1e879ecSMiri Korenblit 	{
212*d1e879ecSMiri Korenblit 		.desc = "A-MSDU subframe with smaller idx, disallow same PN",
213*d1e879ecSMiri Korenblit 		.rx_pkt = {
214*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
215*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA),
216*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
217*d1e879ecSMiri Korenblit 			.is_amsdu = true,
218*d1e879ecSMiri Korenblit 			.sub_frame_idx = 1,
219*d1e879ecSMiri Korenblit 		},
220*d1e879ecSMiri Korenblit 		.dup_data_state = {
221*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
222*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 2,
223*d1e879ecSMiri Korenblit 		},
224*d1e879ecSMiri Korenblit 		.result = {
225*d1e879ecSMiri Korenblit 			.is_dup = false,
226*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_DUP_VALIDATED,
227*d1e879ecSMiri Korenblit 		},
228*d1e879ecSMiri Korenblit 	},
229*d1e879ecSMiri Korenblit 	{
230*d1e879ecSMiri Korenblit 		.desc = "A-MSDU same subframe, no retry, disallow same PN",
231*d1e879ecSMiri Korenblit 		.rx_pkt = {
232*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
233*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA),
234*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
235*d1e879ecSMiri Korenblit 			.is_amsdu = true,
236*d1e879ecSMiri Korenblit 			.sub_frame_idx = 0,
237*d1e879ecSMiri Korenblit 		},
238*d1e879ecSMiri Korenblit 		.dup_data_state = {
239*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
240*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
241*d1e879ecSMiri Korenblit 		},
242*d1e879ecSMiri Korenblit 		.result = {
243*d1e879ecSMiri Korenblit 			.is_dup = false,
244*d1e879ecSMiri Korenblit 			.rx_status_flag = RX_FLAG_DUP_VALIDATED,
245*d1e879ecSMiri Korenblit 		},
246*d1e879ecSMiri Korenblit 	},
247*d1e879ecSMiri Korenblit 	{
248*d1e879ecSMiri Korenblit 		.desc = "A-MSDU same subframe, has retry",
249*d1e879ecSMiri Korenblit 		.rx_pkt = {
250*d1e879ecSMiri Korenblit 			.fc = __cpu_to_le16(IEEE80211_FTYPE_DATA |
251*d1e879ecSMiri Korenblit 					    IEEE80211_STYPE_QOS_DATA |
252*d1e879ecSMiri Korenblit 					    IEEE80211_FCTL_RETRY),
253*d1e879ecSMiri Korenblit 			.seq = __cpu_to_le16(0x100),
254*d1e879ecSMiri Korenblit 			.is_amsdu = true,
255*d1e879ecSMiri Korenblit 			.sub_frame_idx = 0,
256*d1e879ecSMiri Korenblit 		},
257*d1e879ecSMiri Korenblit 		.dup_data_state = {
258*d1e879ecSMiri Korenblit 			.last_seq = __cpu_to_le16(0x100),
259*d1e879ecSMiri Korenblit 			.last_sub_frame_idx = 0,
260*d1e879ecSMiri Korenblit 		},
261*d1e879ecSMiri Korenblit 		.result = {
262*d1e879ecSMiri Korenblit 			.is_dup = true,
263*d1e879ecSMiri Korenblit 			.rx_status_flag = 0,
264*d1e879ecSMiri Korenblit 		},
265*d1e879ecSMiri Korenblit 	},
266*d1e879ecSMiri Korenblit };
267*d1e879ecSMiri Korenblit 
268*d1e879ecSMiri Korenblit KUNIT_ARRAY_PARAM_DESC(test_is_dup, is_dup_cases, desc);
269*d1e879ecSMiri Korenblit 
270*d1e879ecSMiri Korenblit static void
setup_dup_data_state(struct ieee80211_sta * sta)271*d1e879ecSMiri Korenblit setup_dup_data_state(struct ieee80211_sta *sta)
272*d1e879ecSMiri Korenblit {
273*d1e879ecSMiri Korenblit 	struct kunit *test = kunit_get_current_test();
274*d1e879ecSMiri Korenblit 	const struct is_dup_case *param = (const void *)(test->param_value);
275*d1e879ecSMiri Korenblit 	struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
276*d1e879ecSMiri Korenblit 	u8 tid = param->dup_data_state.tid;
277*d1e879ecSMiri Korenblit 	struct iwl_mld_rxq_dup_data *dup_data;
278*d1e879ecSMiri Korenblit 
279*d1e879ecSMiri Korenblit 	/* Allocate dup_data only for 1 queue */
280*d1e879ecSMiri Korenblit 	KUNIT_ALLOC_AND_ASSERT(test, dup_data);
281*d1e879ecSMiri Korenblit 
282*d1e879ecSMiri Korenblit 	/* Initialize dup data, see iwl_mld_alloc_dup_data */
283*d1e879ecSMiri Korenblit 	memset(dup_data->last_seq, 0xff, sizeof(dup_data->last_seq));
284*d1e879ecSMiri Korenblit 
285*d1e879ecSMiri Korenblit 	dup_data->last_seq[tid] = param->dup_data_state.last_seq;
286*d1e879ecSMiri Korenblit 	dup_data->last_sub_frame_idx[tid] =
287*d1e879ecSMiri Korenblit 		param->dup_data_state.last_sub_frame_idx;
288*d1e879ecSMiri Korenblit 
289*d1e879ecSMiri Korenblit 	mld_sta->dup_data = dup_data;
290*d1e879ecSMiri Korenblit }
291*d1e879ecSMiri Korenblit 
setup_rx_pkt(const struct is_dup_case * param,struct ieee80211_hdr * hdr,struct iwl_rx_mpdu_desc * mpdu_desc)292*d1e879ecSMiri Korenblit static void setup_rx_pkt(const struct is_dup_case *param,
293*d1e879ecSMiri Korenblit 			 struct ieee80211_hdr *hdr,
294*d1e879ecSMiri Korenblit 			 struct iwl_rx_mpdu_desc *mpdu_desc)
295*d1e879ecSMiri Korenblit {
296*d1e879ecSMiri Korenblit 	u8 tid = param->rx_pkt.tid;
297*d1e879ecSMiri Korenblit 
298*d1e879ecSMiri Korenblit 	/* Set "new rx packet" header */
299*d1e879ecSMiri Korenblit 	hdr->frame_control = param->rx_pkt.fc;
300*d1e879ecSMiri Korenblit 	hdr->seq_ctrl = param->rx_pkt.seq;
301*d1e879ecSMiri Korenblit 
302*d1e879ecSMiri Korenblit 	if (ieee80211_is_data_qos(hdr->frame_control)) {
303*d1e879ecSMiri Korenblit 		u8 *qc = ieee80211_get_qos_ctl(hdr);
304*d1e879ecSMiri Korenblit 
305*d1e879ecSMiri Korenblit 		qc[0] = tid & IEEE80211_QOS_CTL_TID_MASK;
306*d1e879ecSMiri Korenblit 	}
307*d1e879ecSMiri Korenblit 
308*d1e879ecSMiri Korenblit 	if (param->rx_pkt.multicast)
309*d1e879ecSMiri Korenblit 		hdr->addr1[0] = 0x1;
310*d1e879ecSMiri Korenblit 
311*d1e879ecSMiri Korenblit 	/* Set mpdu_desc */
312*d1e879ecSMiri Korenblit 	mpdu_desc->amsdu_info = param->rx_pkt.sub_frame_idx &
313*d1e879ecSMiri Korenblit 				IWL_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK;
314*d1e879ecSMiri Korenblit 	if (param->rx_pkt.is_amsdu)
315*d1e879ecSMiri Korenblit 		mpdu_desc->mac_flags2 |= IWL_RX_MPDU_MFLG2_AMSDU;
316*d1e879ecSMiri Korenblit }
317*d1e879ecSMiri Korenblit 
test_is_dup(struct kunit * test)318*d1e879ecSMiri Korenblit static void test_is_dup(struct kunit *test)
319*d1e879ecSMiri Korenblit {
320*d1e879ecSMiri Korenblit 	const struct is_dup_case *param = (const void *)(test->param_value);
321*d1e879ecSMiri Korenblit 	struct iwl_mld *mld = test->priv;
322*d1e879ecSMiri Korenblit 	struct iwl_rx_mpdu_desc mpdu_desc = { };
323*d1e879ecSMiri Korenblit 	struct ieee80211_rx_status rx_status = { };
324*d1e879ecSMiri Korenblit 	struct ieee80211_vif *vif;
325*d1e879ecSMiri Korenblit 	struct ieee80211_sta *sta;
326*d1e879ecSMiri Korenblit 	struct ieee80211_hdr hdr;
327*d1e879ecSMiri Korenblit 
328*d1e879ecSMiri Korenblit 	vif = iwlmld_kunit_add_vif(false, NL80211_IFTYPE_STATION);
329*d1e879ecSMiri Korenblit 	sta = iwlmld_kunit_setup_sta(vif, IEEE80211_STA_AUTHORIZED, -1);
330*d1e879ecSMiri Korenblit 
331*d1e879ecSMiri Korenblit 	/* Prepare test case state */
332*d1e879ecSMiri Korenblit 	setup_dup_data_state(sta);
333*d1e879ecSMiri Korenblit 	setup_rx_pkt(param, &hdr, &mpdu_desc);
334*d1e879ecSMiri Korenblit 
335*d1e879ecSMiri Korenblit 	KUNIT_EXPECT_EQ(test,
336*d1e879ecSMiri Korenblit 			iwl_mld_is_dup(mld, sta, &hdr, &mpdu_desc, &rx_status,
337*d1e879ecSMiri Korenblit 				       0), /* assuming only 1 queue */
338*d1e879ecSMiri Korenblit 			param->result.is_dup);
339*d1e879ecSMiri Korenblit 	KUNIT_EXPECT_EQ(test, rx_status.flag, param->result.rx_status_flag);
340*d1e879ecSMiri Korenblit }
341*d1e879ecSMiri Korenblit 
342*d1e879ecSMiri Korenblit static struct kunit_case is_dup_test_cases[] = {
343*d1e879ecSMiri Korenblit 	KUNIT_CASE_PARAM(test_is_dup, test_is_dup_gen_params),
344*d1e879ecSMiri Korenblit 	{},
345*d1e879ecSMiri Korenblit };
346*d1e879ecSMiri Korenblit 
347*d1e879ecSMiri Korenblit static struct kunit_suite is_dup = {
348*d1e879ecSMiri Korenblit 	.name = "iwlmld-rx-is-dup",
349*d1e879ecSMiri Korenblit 	.test_cases = is_dup_test_cases,
350*d1e879ecSMiri Korenblit 	.init = iwlmld_kunit_test_init,
351*d1e879ecSMiri Korenblit };
352*d1e879ecSMiri Korenblit 
353*d1e879ecSMiri Korenblit kunit_test_suite(is_dup);
354