1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief File containing TX data path specific function definitions for the
9  * FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "list.h"
13 #include "queue.h"
14 #include "system/hal_api.h"
15 #include "system/fmac_tx.h"
16 #include "system/fmac_api.h"
17 #include "system/fmac_peer.h"
18 #include "common/hal_structs_common.h"
19 #include "common/hal_mem.h"
20 #include "common/fmac_util.h"
21 
is_twt_emergency_pkt(void * nwb)22 static bool is_twt_emergency_pkt(void *nwb)
23 {
24 	unsigned char priority = nrf_wifi_osal_nbuf_get_priority(nwb);
25 
26 	return  priority == NRF_WIFI_AC_TWT_PRIORITY_EMERGENCY;
27 }
28 
29 /* Can be extended for other cases as well */
can_xmit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * nwb)30 static bool can_xmit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
31 			       void *nwb)
32 {
33 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
34 
35 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
36 
37 	return is_twt_emergency_pkt(nwb) ||
38 	    sys_dev_ctx->twt_sleep_status == NRF_WIFI_FMAC_TWT_STATE_AWAKE;
39 }
40 
41 /* Set the coresponding bit of access category.
42  * First 4 bits(0 to 3) represenst first spare desc access cateogories
43  * Second 4 bits(4 to 7) represenst second spare desc access cateogories and so on
44  */
set_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc,int tx_done_q)45 static void set_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
46 				 unsigned int desc,
47 				 int tx_done_q)
48 {
49 	unsigned short spare_desc_indx = 0;
50 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
51 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
52 
53 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
54 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
55 
56 	nrf_wifi_osal_assert(sys_fpriv->num_tx_tokens_per_ac,
57 			     0,
58 			     NRF_WIFI_ASSERT_NOT_EQUAL_TO,
59 			     "num_tx_tokens_per_ac is zero");
60 
61 	spare_desc_indx = (desc % (sys_fpriv->num_tx_tokens_per_ac *
62 				   NRF_WIFI_FMAC_AC_MAX));
63 
64 	sys_dev_ctx->tx_config.spare_desc_queue_map |=
65 		(1 << ((spare_desc_indx * SPARE_DESC_Q_MAP_SIZE) + tx_done_q));
66 }
67 
68 
69 /* Clear the coresponding bit of access category.
70  * First 4 bits(0 to 3) represenst first spare desc access cateogories
71  * Second 4 bits(4 to 7) represenst second spare desc access cateogories and so on
72  */
clear_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc,int tx_done_q)73 static void clear_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
74 				   unsigned int desc,
75 				   int tx_done_q)
76 {
77 	unsigned short spare_desc_indx = 0;
78 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
79 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
80 
81 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
82 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
83 
84 	nrf_wifi_osal_assert(sys_fpriv->num_tx_tokens_per_ac,
85 			     0,
86 			     NRF_WIFI_ASSERT_NOT_EQUAL_TO,
87 			     "num_tx_tokens_per_ac is zero");
88 
89 	spare_desc_indx = (desc % (sys_fpriv->num_tx_tokens_per_ac *
90 				   NRF_WIFI_FMAC_AC_MAX));
91 
92 	sys_dev_ctx->tx_config.spare_desc_queue_map &=
93 		~(1 << ((spare_desc_indx * SPARE_DESC_Q_MAP_SIZE) + tx_done_q));
94 }
95 
96 /*Get the spare descriptor queue map */
get_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc)97 static unsigned short get_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
98 					   unsigned int desc)
99 {
100 	unsigned short spare_desc_indx = 0;
101 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
102 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
103 
104 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
105 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
106 
107 	spare_desc_indx = (desc % (sys_fpriv->num_tx_tokens_per_ac *
108 				   NRF_WIFI_FMAC_AC_MAX));
109 
110 	return	(sys_dev_ctx->tx_config.spare_desc_queue_map >> (spare_desc_indx *
111 			SPARE_DESC_Q_MAP_SIZE)) & 0x000F;
112 }
113 
114 
nrf_wifi_get_dest(void * nwb)115 static unsigned char *nrf_wifi_get_dest(void *nwb)
116 {
117 	return nrf_wifi_osal_nbuf_data_get(nwb);
118 }
119 
120 
nrf_wifi_get_src(void * nwb)121 static unsigned char *nrf_wifi_get_src(void *nwb)
122 {
123 	return (unsigned char *)nrf_wifi_osal_nbuf_data_get(nwb) + NRF_WIFI_FMAC_ETH_ADDR_LEN;
124 }
125 
nrf_wifi_get_tid(void * nwb)126 static int nrf_wifi_get_tid(void *nwb)
127 {
128 	unsigned short ether_type = 0;
129 	int priority = 0;
130 	unsigned short vlan_tci = 0;
131 	unsigned char vlan_priority = 0;
132 	unsigned int mpls_hdr = 0;
133 	unsigned char mpls_tc_qos = 0;
134 	unsigned char tos = 0;
135 	unsigned char dscp = 0;
136 	unsigned short ipv6_hdr = 0;
137 	void *nwb_data = NULL;
138 
139 	nwb_data = nrf_wifi_osal_nbuf_data_get(nwb);
140 
141 	ether_type = nrf_wifi_util_tx_get_eth_type(nwb_data);
142 
143 	nwb_data = (unsigned char *)nrf_wifi_osal_nbuf_data_get(nwb) + NRF_WIFI_FMAC_ETH_HDR_LEN;
144 
145 	switch (ether_type & NRF_WIFI_FMAC_ETH_TYPE_MASK) {
146 	/* If VLAN 802.1Q (0x8100) ||
147 	 * 802.1AD(0x88A8) FRAME calculate priority accordingly
148 	 */
149 	case NRF_WIFI_FMAC_ETH_P_8021Q:
150 	case NRF_WIFI_FMAC_ETH_P_8021AD:
151 		vlan_tci = (((unsigned char *)nwb_data)[4] << 8) |
152 			(((unsigned char *)nwb_data)[5]);
153 		vlan_priority = ((vlan_tci & NRF_WIFI_FMAC_VLAN_PRIO_MASK)
154 				 >> NRF_WIFI_FMAC_VLAN_PRIO_SHIFT);
155 		priority = vlan_priority;
156 		break;
157 	/* If MPLS MC(0x8840) / UC(0x8847) frame calculate priority
158 	 * accordingly
159 	 */
160 	case NRF_WIFI_FMAC_ETH_P_MPLS_UC:
161 	case NRF_WIFI_FMAC_ETH_P_MPLS_MC:
162 		mpls_hdr = (((unsigned char *)nwb_data)[0] << 24) |
163 			(((unsigned char *)nwb_data)[1] << 16) |
164 			(((unsigned char *)nwb_data)[2] << 8)  |
165 			(((unsigned char *)nwb_data)[3]);
166 		mpls_tc_qos = (mpls_hdr & (NRF_WIFI_FMAC_MPLS_LS_TC_MASK)
167 			       >> NRF_WIFI_FMAC_MPLS_LS_TC_SHIFT);
168 		priority = mpls_tc_qos;
169 		break;
170 	/* If IP (0x0800) frame calculate priority accordingly */
171 	case NRF_WIFI_FMAC_ETH_P_IP:
172 		/*get the tos filed*//*DA+SA+ETH+(VER+IHL)*/
173 		tos = (((unsigned char *)nwb_data)[1]);
174 		/*get the dscp value */
175 		dscp = (tos & 0xfc);
176 		priority = dscp >> 5;
177 		break;
178 	case NRF_WIFI_FMAC_ETH_P_IPV6:
179 		/* Get the TOS filled DA+SA+ETH */
180 		ipv6_hdr = (((unsigned char *)nwb_data)[0] << 8) |
181 			((unsigned char *)nwb_data)[1];
182 		dscp = (((ipv6_hdr & NRF_WIFI_FMAC_IPV6_TOS_MASK)
183 			 >> NRF_WIFI_FMAC_IPV6_TOS_SHIFT) & 0xfc);
184 		priority = dscp >> 5;
185 		break;
186 	/* If Media Independent (0x8917)
187 	 * frame calculate priority accordingly.
188 	 */
189 	case NRF_WIFI_FMAC_ETH_P_80221:
190 		/* 802.21 is always network control traffic */
191 		priority = 0x07;
192 		break;
193 	default:
194 		priority = 0;
195 	}
196 
197 	return priority;
198 }
199 
200 
pending_frames_count(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,int peer_id)201 int pending_frames_count(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
202 			 int peer_id)
203 {
204 	int count = 0;
205 	int ac = 0;
206 	void *queue = NULL;
207 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
208 
209 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
210 
211 	for (ac = NRF_WIFI_FMAC_AC_VO; ac >= 0; --ac) {
212 		queue = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
213 		count += nrf_wifi_utils_q_len(queue);
214 	}
215 
216 	return count;
217 }
218 
219 
update_pend_q_bmp(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int ac,int peer_id)220 static enum nrf_wifi_status update_pend_q_bmp(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
221 				       unsigned int ac,
222 				       int peer_id)
223 {
224 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
225 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
226 	void *pend_pkt_q = NULL;
227 	int len = 0;
228 	unsigned char vif_id = 0;
229 	unsigned char *bmp = NULL;
230 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
231 
232 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
233 
234 	if (!fmac_dev_ctx) {
235 		goto out;
236 	}
237 
238 	vif_id = sys_dev_ctx->tx_config.peers[peer_id].if_idx;
239 	vif_ctx = sys_dev_ctx->vif_ctx[vif_id];
240 
241 	if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP &&
242 	    peer_id < MAX_PEERS) {
243 		const unsigned int bitmap_offset = offsetof(struct sap_client_pend_frames_bitmap,
244 						      pend_frames_bitmap);
245 		const unsigned char *rpu_addr = (unsigned char *)RPU_MEM_UMAC_PEND_Q_BMP +
246 			(sizeof(struct sap_client_pend_frames_bitmap) * peer_id) +
247 			bitmap_offset;
248 
249 		bmp = &sys_dev_ctx->tx_config.peers[peer_id].pend_q_bmp;
250 		pend_pkt_q = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
251 
252 		len = nrf_wifi_utils_q_len(pend_pkt_q);
253 
254 		if (len == 0) {
255 			*bmp = *bmp & ~(1 << ac);
256 		} else {
257 			*bmp = *bmp | (1 << ac);
258 		}
259 
260 		status = hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx,
261 					   (unsigned long)rpu_addr,
262 					   bmp,
263 					   4); /* For alignment */
264 	} else {
265 		status = NRF_WIFI_STATUS_SUCCESS;
266 	}
267 out:
268 	return status;
269 }
270 
271 
tx_desc_free(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc,int queue)272 static void tx_desc_free(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
273 		  unsigned int desc,
274 		  int queue)
275 {
276 	struct nrf_wifi_fmac_priv *fpriv = NULL;
277 	int bit = -1;
278 	int pool_id = -1;
279 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
280 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
281 
282 	fpriv = fmac_dev_ctx->fpriv;
283 
284 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
285 	sys_fpriv = wifi_fmac_priv(fpriv);
286 
287 	bit = (desc % TX_DESC_BUCKET_BOUND);
288 	pool_id = (desc / TX_DESC_BUCKET_BOUND);
289 
290 	if (!(sys_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] & (1 << bit))) {
291 		return;
292 	}
293 
294 	sys_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] &= (~(1 << bit));
295 
296 	sys_dev_ctx->tx_config.outstanding_descs[queue]--;
297 
298 	if (desc >= (sys_fpriv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX)) {
299 		clear_spare_desc_q_map(fmac_dev_ctx, desc, queue);
300 	}
301 
302 }
303 
304 
tx_desc_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,int queue)305 unsigned int tx_desc_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
306 			 int queue)
307 {
308 	struct nrf_wifi_fmac_priv *fpriv = NULL;
309 	unsigned int cnt = 0;
310 	int curr_bit = 0;
311 	unsigned int desc = 0;
312 	int pool_id = 0;
313 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
314 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
315 
316 	fpriv = fmac_dev_ctx->fpriv;
317 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
318 	sys_fpriv = wifi_fmac_priv(fpriv);
319 
320 	desc = sys_fpriv->num_tx_tokens;
321 
322 	/* First search for a reserved desc */
323 
324 	for (cnt = 0; cnt < sys_fpriv->num_tx_tokens_per_ac; cnt++) {
325 		curr_bit = ((queue + (NRF_WIFI_FMAC_AC_MAX * cnt)));
326 		curr_bit = ((queue + (NRF_WIFI_FMAC_AC_MAX * cnt)) % TX_DESC_BUCKET_BOUND);
327 		pool_id = ((queue + (NRF_WIFI_FMAC_AC_MAX * cnt)) / TX_DESC_BUCKET_BOUND);
328 
329 		if ((((sys_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] >>
330 		       curr_bit)) & 1)) {
331 			continue;
332 		} else {
333 			sys_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] |=
334 				(1 << curr_bit);
335 			desc = queue + (NRF_WIFI_FMAC_AC_MAX * cnt);
336 			sys_dev_ctx->tx_config.outstanding_descs[queue]++;
337 			break;
338 		}
339 	}
340 
341 	/* If reserved desc is not found search for a spare desc
342 	 * (only for non beacon queues)
343 	 */
344 	if (cnt == sys_fpriv->num_tx_tokens_per_ac) {
345 		for (desc = sys_fpriv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX;
346 		     desc < sys_fpriv->num_tx_tokens;
347 		     desc++) {
348 			curr_bit = (desc % TX_DESC_BUCKET_BOUND);
349 			pool_id = (desc / TX_DESC_BUCKET_BOUND);
350 
351 			if ((sys_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] >> curr_bit) & 1) {
352 				continue;
353 			} else {
354 				sys_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] |=
355 					(1 << curr_bit);
356 				sys_dev_ctx->tx_config.outstanding_descs[queue]++;
357 				/* Keep a note which queue has been assigned the
358 				 * spare desc. Need for processing of TX_DONE
359 				 * event as queue number is not being provided
360 				 * by UMAC.
361 				 * First nibble epresent first spare desc
362 				 * (B3B2B1B0: VO-VI-BE-BK)
363 				 * Second nibble represent second spare desc
364 				 * (B7B6B5B4 : V0-VI-BE-BK)
365 				 * Third nibble represent second spare desc
366 				 * (B11B10B9B8 : V0-VI-BE-BK)
367 				 * Fourth nibble represent second spare desc
368 				 * (B15B14B13B12 : V0-VI-BE-BK)
369 				 */
370 				set_spare_desc_q_map(fmac_dev_ctx, desc, queue);
371 				break;
372 			}
373 		}
374 	}
375 
376 
377 	return desc;
378 }
379 
380 
tx_aggr_check(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * first_nwb,int ac,int peer)381 static int tx_aggr_check(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
382 		  void *first_nwb,
383 		  int ac,
384 		  int peer)
385 {
386 	void *nwb = NULL;
387 	void *pending_pkt_queue = NULL;
388 	bool aggr = true;
389 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
390 
391 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
392 
393 	if (sys_dev_ctx->tx_config.peers[peer].is_legacy) {
394 		return false;
395 	}
396 
397 #ifdef NRF70_RAW_DATA_TX
398 	if (sys_dev_ctx->raw_tx_config.raw_tx_flag) {
399 		return false;
400 	}
401 #endif /* NRF70_RAW_DATA_TX */
402 
403 	pending_pkt_queue = sys_dev_ctx->tx_config.data_pending_txq[peer][ac];
404 
405 	if (nrf_wifi_utils_q_len(pending_pkt_queue) == 0) {
406 		return false;
407 	}
408 
409 	nwb = nrf_wifi_utils_q_peek(pending_pkt_queue);
410 
411 	if (nwb) {
412 		if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_get_dest(nwb),
413 						    nrf_wifi_get_dest(first_nwb))) {
414 			aggr = false;
415 		}
416 
417 		if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_get_src(nwb),
418 						    nrf_wifi_get_src(first_nwb))) {
419 			aggr = false;
420 		}
421 	}
422 
423 
424 	return aggr;
425 }
426 
427 
get_peer_from_wakeup_q(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int ac)428 static int get_peer_from_wakeup_q(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
429 			   unsigned int ac)
430 {
431 	int peer_id = -1;
432 	struct peers_info *peer = NULL;
433 	void *pend_q = NULL;
434 	unsigned int pend_q_len;
435 	void *client_q = NULL;
436 	void *list_node = NULL;
437 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
438 
439 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
440 
441 	client_q = sys_dev_ctx->tx_config.wakeup_client_q;
442 
443 	list_node = nrf_wifi_osal_llist_get_node_head(client_q);
444 
445 	while (list_node) {
446 		peer = nrf_wifi_osal_llist_node_data_get(list_node);
447 
448 		if (peer != NULL && peer->ps_token_count) {
449 
450 			pend_q = sys_dev_ctx->tx_config.data_pending_txq[peer->peer_id][ac];
451 			pend_q_len = nrf_wifi_utils_q_len(pend_q);
452 
453 			if (pend_q_len) {
454 				peer->ps_token_count--;
455 				return peer->peer_id;
456 			}
457 		}
458 
459 		list_node = nrf_wifi_osal_llist_get_node_nxt(client_q,
460 							     list_node);
461 	}
462 
463 	return peer_id;
464 }
465 
466 
tx_curr_peer_opp_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int ac)467 static int tx_curr_peer_opp_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
468 			 unsigned int ac)
469 {
470 	unsigned int i = 0;
471 	unsigned int curr_peer_opp = 0;
472 	unsigned int init_peer_opp = 0;
473 	unsigned int pend_q_len;
474 	void *pend_q = NULL;
475 	int peer_id = -1;
476 	unsigned char ps_state = 0;
477 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
478 
479 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
480 
481 	if (ac == NRF_WIFI_FMAC_AC_MC) {
482 		return MAX_PEERS;
483 	}
484 
485 #ifdef NRF70_RAW_DATA_TX
486 	if (sys_dev_ctx->raw_tx_config.raw_tx_flag) {
487 		return MAX_PEERS;
488 	}
489 #endif /* NRF70_RAW_DATA_TX */
490 
491 	peer_id = get_peer_from_wakeup_q(fmac_dev_ctx, ac);
492 
493 	if (peer_id != -1) {
494 		return peer_id;
495 	}
496 
497 	init_peer_opp = sys_dev_ctx->tx_config.curr_peer_opp[ac];
498 
499 	for (i = 0; i < MAX_PEERS; i++) {
500 		curr_peer_opp = (init_peer_opp + i) % MAX_PEERS;
501 
502 		ps_state = sys_dev_ctx->tx_config.peers[curr_peer_opp].ps_state;
503 
504 		if (ps_state == NRF_WIFI_CLIENT_PS_MODE) {
505 			continue;
506 		}
507 
508 		pend_q = sys_dev_ctx->tx_config.data_pending_txq[curr_peer_opp][ac];
509 		pend_q_len = nrf_wifi_utils_q_len(pend_q);
510 
511 		if (pend_q_len) {
512 			sys_dev_ctx->tx_config.curr_peer_opp[ac] =
513 				(curr_peer_opp + 1) % MAX_PEERS;
514 			break;
515 		}
516 	}
517 
518 	if (i != MAX_PEERS) {
519 		peer_id = curr_peer_opp;
520 	}
521 
522 	return peer_id;
523 }
524 
_tx_pending_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc,unsigned int ac)525 static size_t _tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
526 			unsigned int desc,
527 			unsigned int ac)
528 {
529 	int len = 0;
530 	void *pend_pkt_q = NULL;
531 	void *txq = NULL;
532 	struct tx_pkt_info *pkt_info = NULL;
533 	int peer_id = -1;
534 	void *nwb = NULL;
535 	void *first_nwb = NULL;
536 
537 	int max_txq_len, avail_ampdu_len_per_token;
538 	int ampdu_len = 0;
539 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
540 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
541 
542 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
543 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
544 
545 	max_txq_len = sys_fpriv->data_config.max_tx_aggregation;
546 	avail_ampdu_len_per_token = sys_fpriv->avail_ampdu_len_per_token;
547 
548 	peer_id = tx_curr_peer_opp_get(fmac_dev_ctx, ac);
549 
550 	/* No pending frames for any peer in that AC. */
551 	if (peer_id == -1) {
552 		return 0;
553 	}
554 
555 	pend_pkt_q = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
556 
557 	if (nrf_wifi_utils_q_len(pend_pkt_q) == 0) {
558 		return 0;
559 	}
560 
561 	pkt_info = &sys_dev_ctx->tx_config.pkt_info_p[desc];
562 	txq = pkt_info->pkt;
563 
564 	/* Aggregate Only MPDU's with same RA, same Rate,
565 	 * same Rate flags, same Tx Info flags
566 	 */
567 	if (nrf_wifi_utils_q_len(pend_pkt_q)) {
568 		first_nwb = nrf_wifi_utils_q_peek(pend_pkt_q);
569 	}
570 
571 	while (nrf_wifi_utils_q_len(pend_pkt_q)) {
572 		nwb = nrf_wifi_utils_q_peek(pend_pkt_q);
573 
574 		ampdu_len += TX_BUF_HEADROOM +
575 			nrf_wifi_osal_nbuf_data_size((void *)nwb);
576 
577 		if (ampdu_len >= avail_ampdu_len_per_token) {
578 			break;
579 		}
580 
581 		if (!can_xmit(fmac_dev_ctx, nwb) ||
582 			(!tx_aggr_check(fmac_dev_ctx, first_nwb, ac, peer_id)) ||
583 			(nrf_wifi_utils_q_len(txq) >= max_txq_len)) {
584 			break;
585 		}
586 
587 		nwb = nrf_wifi_utils_q_dequeue(pend_pkt_q);
588 
589 		nrf_wifi_utils_list_add_tail(txq,
590 					     nwb);
591 	}
592 
593 	/* If our criterion rejects all pending frames, or
594 	 * pend_q is empty, send only 1
595 	 */
596 	if (!nrf_wifi_utils_q_len(txq)) {
597 		nwb = nrf_wifi_utils_q_peek(pend_pkt_q);
598 
599 		if (!nwb || !can_xmit(fmac_dev_ctx, nwb)) {
600 			return 0;
601 		}
602 
603 		nwb = nrf_wifi_utils_q_dequeue(pend_pkt_q);
604 
605 		nrf_wifi_utils_list_add_tail(txq,
606 					     nwb);
607 	}
608 
609 	len = nrf_wifi_utils_q_len(txq);
610 
611 	if (len > 0) {
612 		sys_dev_ctx->tx_config.pkt_info_p[desc].peer_id = peer_id;
613 	}
614 
615 	update_pend_q_bmp(fmac_dev_ctx, ac, peer_id);
616 
617 	return len;
618 }
619 
620 #ifdef NRF70_RAW_DATA_TX
rawtx_cmd_prep_callbk_fn(void * callbk_data,void * nbuf)621 enum nrf_wifi_status rawtx_cmd_prep_callbk_fn(void *callbk_data,
622 					      void *nbuf)
623 {
624 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
625 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
626 	struct nrf_wifi_fmac_buf_map_info *tx_buf_info = NULL;
627 	unsigned long nwb = 0;
628 	unsigned long nwb_data = 0;
629 	unsigned long phy_addr = 0;
630 	struct tx_cmd_prep_raw_info *info = NULL;
631 	struct nrf_wifi_cmd_raw_tx *config = NULL;
632 	unsigned int desc_id = 0;
633 	unsigned int buf_len = 0;
634 	unsigned char frame_indx = 0;
635 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
636 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
637 
638 	info = (struct tx_cmd_prep_raw_info *)callbk_data;
639 	fmac_dev_ctx = info->fmac_dev_ctx;
640 	config = info->raw_config;
641 	frame_indx = info->num_tx_pkts;
642 
643 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
644 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
645 	nwb = (unsigned long)nbuf;
646 	desc_id = (config->raw_tx_info.desc_num *
647 		   sys_fpriv->data_config.max_tx_aggregation) + frame_indx;
648 
649 	tx_buf_info = &sys_dev_ctx->tx_buf_info[desc_id];
650 	if (tx_buf_info->mapped) {
651 		nrf_wifi_osal_log_err("%s: Raw init_TX cmd called for already mapped TX buffer(%d)",
652 				      __func__,
653 				      desc_id);
654 
655 		status = NRF_WIFI_STATUS_FAIL;
656 		goto out;
657 	}
658 
659 	nwb_data = (unsigned long)nrf_wifi_osal_nbuf_data_get((void *)nwb);
660 	buf_len = nrf_wifi_osal_nbuf_data_size((void *)nwb);
661 
662 	phy_addr = nrf_wifi_sys_hal_buf_map_tx(fmac_dev_ctx->hal_dev_ctx,
663 					       nwb_data,
664 					       buf_len,
665 					       desc_id,
666 					       config->raw_tx_info.desc_num,
667 					       frame_indx);
668 	if (!phy_addr) {
669 		nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_buf_map_tx failed",
670 				      __func__);
671 		status = NRF_WIFI_STATUS_FAIL;
672 		goto out;
673 	}
674 
675 	tx_buf_info->nwb = nwb;
676 	tx_buf_info->mapped = true;
677 	config->raw_tx_info.frame_ddr_pointer = (unsigned long long)phy_addr;
678 	config->raw_tx_info.pkt_length = buf_len;
679 	info->num_tx_pkts++;
680 
681 	status = NRF_WIFI_STATUS_SUCCESS;
682 out:
683 	return status;
684 }
685 #endif /* NRF70_RAW_DATA_TX */
686 
tx_cmd_prep_callbk_fn(void * callbk_data,void * nbuf)687 static enum nrf_wifi_status tx_cmd_prep_callbk_fn(void *callbk_data,
688 					   void *nbuf)
689 {
690 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
691 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
692 	struct nrf_wifi_fmac_buf_map_info *tx_buf_info = NULL;
693 	unsigned long nwb = 0;
694 	unsigned long nwb_data = 0;
695 	unsigned long phy_addr = 0;
696 	struct tx_cmd_prep_info *info = NULL;
697 	struct nrf_wifi_tx_buff *config = NULL;
698 	unsigned int desc_id = 0;
699 	unsigned int buf_len = 0;
700 	unsigned char frame_indx = 0;
701 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
702 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
703 
704 	info = (struct tx_cmd_prep_info *)callbk_data;
705 	fmac_dev_ctx = info->fmac_dev_ctx;
706 
707 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
708 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
709 
710 	config = info->config;
711 	frame_indx = config->num_tx_pkts;
712 
713 	nwb = (unsigned long)nbuf;
714 
715 	desc_id = (config->tx_desc_num *
716 		   sys_fpriv->data_config.max_tx_aggregation) + frame_indx;
717 
718 	tx_buf_info = &sys_dev_ctx->tx_buf_info[desc_id];
719 
720 	if (tx_buf_info->mapped) {
721 		nrf_wifi_osal_log_err("%s: Init_TX cmd called for already mapped TX buffer(%d)",
722 				      __func__,
723 				      desc_id);
724 
725 		status = NRF_WIFI_STATUS_FAIL;
726 		goto out;
727 	}
728 
729 	nwb_data = (unsigned long)nrf_wifi_osal_nbuf_data_get((void *)nwb);
730 
731 	buf_len = nrf_wifi_osal_nbuf_data_size((void *)nwb);
732 
733 	phy_addr = nrf_wifi_sys_hal_buf_map_tx(fmac_dev_ctx->hal_dev_ctx,
734 					       nwb_data,
735 					       buf_len,
736 					       desc_id,
737 					       config->tx_desc_num,
738 					       frame_indx);
739 
740 	if (!phy_addr) {
741 		nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_buf_map_tx failed",
742 				      __func__);
743 		status = NRF_WIFI_STATUS_FAIL;
744 		goto out;
745 	}
746 
747 	tx_buf_info->nwb = nwb;
748 	tx_buf_info->mapped = true;
749 
750 	config->tx_buff_info[frame_indx].ddr_ptr =
751 		(unsigned long long)phy_addr;
752 
753 	config->tx_buff_info[frame_indx].pkt_length = buf_len;
754 	config->num_tx_pkts++;
755 
756 	status = NRF_WIFI_STATUS_SUCCESS;
757 out:
758 	return status;
759 }
760 
761 #ifdef NRF70_RAW_DATA_TX
rawtx_cmd_prepare(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct host_rpu_msg * umac_cmd,int desc,void * txq,int peer_id)762 enum nrf_wifi_status rawtx_cmd_prepare(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
763 				       struct host_rpu_msg *umac_cmd,
764 				       int desc,
765 				       void *txq,
766 				       int peer_id)
767 {
768 	struct nrf_wifi_cmd_raw_tx *config = NULL;
769 	int len = 0;
770 	void *nwb = NULL;
771 	unsigned int txq_len = 0;
772 	struct tx_cmd_prep_raw_info info;
773 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
774 	unsigned char vif_id;
775 	struct nrf_wifi_fmac_vif_ctx *vif_ctx;
776 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
777 
778 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
779 	vif_id = sys_dev_ctx->tx_config.peers[peer_id].if_idx;
780 	vif_ctx = sys_dev_ctx->vif_ctx[vif_id];
781 
782 	txq_len = nrf_wifi_utils_list_len(txq);
783 	if (txq_len == 0) {
784 		nrf_wifi_osal_log_err("%s: txq_len = %d\n",
785 				      __func__,
786 				      txq_len);
787 		goto err;
788 	}
789 
790 	nwb = nrf_wifi_utils_list_peek(txq);
791 	/**
792 	 * Pull the Raw packet header and only send the buffer to the UMAC
793 	 * with the parameters configured to the UMAC
794 	 */
795 	nrf_wifi_osal_nbuf_data_pull(nwb,
796 				     sizeof(struct raw_tx_pkt_header));
797 
798 	sys_dev_ctx->tx_config.send_pkt_coalesce_count_p[desc] = txq_len;
799 	config = (struct nrf_wifi_cmd_raw_tx *)(umac_cmd->msg);
800 	len = nrf_wifi_osal_nbuf_data_size(nwb);
801 
802 	config->sys_head.cmd_event = NRF_WIFI_CMD_RAW_TX_PKT;
803 	config->sys_head.len = sizeof(*config);
804 	config->if_index = vif_id;
805 	config->raw_tx_info.desc_num = desc;
806 	config->raw_tx_info.queue_num = sys_dev_ctx->raw_tx_config.queue;
807 	if (len != sys_dev_ctx->raw_tx_config.packet_length) {
808 		goto err;
809 	}
810 	config->raw_tx_info.pkt_length = len;
811 	config->raw_tx_info.rate = sys_dev_ctx->raw_tx_config.data_rate;
812 	config->raw_tx_info.rate_flags = sys_dev_ctx->raw_tx_config.tx_mode;
813 
814 	info.fmac_dev_ctx = fmac_dev_ctx;
815 	info.raw_config = config;
816 	info.num_tx_pkts = 0;
817 
818 	status = nrf_wifi_utils_list_traverse(txq,
819 					      &info,
820 					      rawtx_cmd_prep_callbk_fn);
821 	if (status != NRF_WIFI_STATUS_SUCCESS) {
822 		nrf_wifi_osal_log_err("%s: failed",
823 				      __func__);
824 		goto err;
825 	}
826 	sys_dev_ctx->host_stats.total_tx_pkts += info.num_tx_pkts;
827 
828 	return NRF_WIFI_STATUS_SUCCESS;
829 err:
830 	return NRF_WIFI_STATUS_FAIL;
831 }
832 #endif /* NRF70_RAW_DATA_TX */
833 
tx_cmd_prepare(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct host_rpu_msg * umac_cmd,int desc,void * txq,int peer_id)834 static enum nrf_wifi_status tx_cmd_prepare(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
835 		   struct host_rpu_msg *umac_cmd,
836 		   int desc,
837 		   void *txq,
838 		   int peer_id)
839 {
840 	struct nrf_wifi_tx_buff *config = NULL;
841 	int len = 0;
842 	void *nwb = NULL;
843 	void *nwb_data = NULL;
844 	unsigned int txq_len = 0;
845 	unsigned char *data = NULL;
846 	struct tx_cmd_prep_info info;
847 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
848 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
849 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
850 	unsigned char vif_id;
851 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
852 
853 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
854 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
855 
856 	vif_id = sys_dev_ctx->tx_config.peers[peer_id].if_idx;
857 	vif_ctx = sys_dev_ctx->vif_ctx[vif_id];
858 
859 	txq_len = nrf_wifi_utils_list_len(txq);
860 
861 	if (txq_len == 0) {
862 		nrf_wifi_osal_log_err("%s: txq_len = %d",
863 				      __func__,
864 				      txq_len);
865 		goto err;
866 	}
867 
868 	nwb = nrf_wifi_utils_list_peek(txq);
869 
870 	sys_dev_ctx->tx_config.send_pkt_coalesce_count_p[desc] = txq_len;
871 
872 	config = (struct nrf_wifi_tx_buff *)(umac_cmd->msg);
873 
874 	data = nrf_wifi_osal_nbuf_data_get(nwb);
875 
876 	len = nrf_wifi_osal_nbuf_data_size(nwb);
877 
878 	config->umac_head.cmd = NRF_WIFI_CMD_TX_BUFF;
879 
880 	config->umac_head.len += sizeof(struct nrf_wifi_tx_buff);
881 	config->umac_head.len += sizeof(struct nrf_wifi_tx_buff_info) * txq_len;
882 
883 	config->tx_desc_num = desc;
884 
885 	nrf_wifi_osal_mem_cpy(config->mac_hdr_info.dest,
886 			      nrf_wifi_get_dest(nwb),
887 			      NRF_WIFI_ETH_ADDR_LEN);
888 
889 	nrf_wifi_osal_mem_cpy(config->mac_hdr_info.src,
890 			      nrf_wifi_get_src(nwb),
891 			      NRF_WIFI_ETH_ADDR_LEN);
892 
893 	nwb_data = nrf_wifi_osal_nbuf_data_get(nwb);
894 	config->mac_hdr_info.etype =
895 		nrf_wifi_util_tx_get_eth_type(nwb_data);
896 
897 	config->mac_hdr_info.tx_flags =
898 		nrf_wifi_get_tid(nwb) & NRF_WIFI_TX_FLAGS_DSCP_TOS_MASK;
899 
900 	if (is_twt_emergency_pkt(nwb)) {
901 		config->mac_hdr_info.tx_flags |= NRF_WIFI_TX_FLAG_TWT_EMERGENCY_TX;
902 	}
903 
904 	if (nrf_wifi_osal_nbuf_get_chksum_done(nwb)) {
905 		config->mac_hdr_info.tx_flags |= NRF_WIFI_TX_FLAG_CHKSUM_AVAILABLE;
906 	}
907 
908 	config->num_tx_pkts = 0;
909 
910 	info.fmac_dev_ctx = fmac_dev_ctx;
911 	info.config = config;
912 
913 	status = nrf_wifi_utils_list_traverse(txq,
914 					      &info,
915 					      tx_cmd_prep_callbk_fn);
916 
917 	if (status != NRF_WIFI_STATUS_SUCCESS) {
918 		nrf_wifi_osal_log_err("%s: build_mac80211_hdr failed",
919 				      __func__);
920 		goto err;
921 	}
922 
923 	sys_dev_ctx->host_stats.total_tx_pkts += config->num_tx_pkts;
924 	config->wdev_id = sys_dev_ctx->tx_config.peers[peer_id].if_idx;
925 
926 	if ((vif_ctx->if_type == NRF_WIFI_IFTYPE_AP ||
927 	    vif_ctx->if_type == NRF_WIFI_IFTYPE_AP_VLAN ||
928 	    vif_ctx->if_type == NRF_WIFI_IFTYPE_MESH_POINT) &&
929 		pending_frames_count(fmac_dev_ctx, peer_id) != 0) {
930 		config->mac_hdr_info.more_data = 1;
931 	}
932 
933 	if (sys_dev_ctx->tx_config.peers[peer_id].ps_token_count == 0) {
934 		nrf_wifi_utils_list_del_node(sys_dev_ctx->tx_config.wakeup_client_q,
935 					     &sys_dev_ctx->tx_config.peers[peer_id]);
936 
937 		config->mac_hdr_info.eosp = 1;
938 
939 	} else {
940 		config->mac_hdr_info.eosp = 0;
941 	}
942 
943 	return NRF_WIFI_STATUS_SUCCESS;
944 err:
945 	return NRF_WIFI_STATUS_FAIL;
946 }
947 
948 #ifdef NRF70_RAW_DATA_TX
rawtx_cmd_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * txq,int desc,int peer_id)949 enum nrf_wifi_status rawtx_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
950 				    void *txq,
951 				    int desc,
952 				    int peer_id)
953 {
954 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
955 	struct host_rpu_msg *umac_cmd = NULL;
956 	unsigned int len = 0;
957 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
958 
959 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
960 
961 	len += sizeof(struct nrf_wifi_cmd_raw_tx);
962 	len *= nrf_wifi_utils_list_len(txq);
963 
964 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
965 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
966 				  len);
967 
968 	status = rawtx_cmd_prepare(fmac_dev_ctx,
969 				   umac_cmd,
970 				   desc,
971 				   txq,
972 				   peer_id);
973 	if (status != NRF_WIFI_STATUS_SUCCESS) {
974 		nrf_wifi_osal_log_err("%s: rawtx_cmd_prepare failed",
975 				      __func__);
976 
977 		goto out;
978 	}
979 
980 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
981 					    umac_cmd,
982 					    (sizeof(*umac_cmd) + len));
983 
984 	/* clear the raw tx config data */
985 	nrf_wifi_osal_mem_set(&sys_dev_ctx->raw_tx_config,
986 			      0, sizeof(struct raw_tx_pkt_header));
987 out:
988 	return status;
989 }
990 #endif /* NRF70_RAW_DATA_TX */
991 
tx_cmd_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * txq,int desc,int peer_id)992 enum nrf_wifi_status tx_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
993 				 void *txq,
994 				 int desc,
995 				 int peer_id)
996 {
997 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
998 	struct host_rpu_msg *umac_cmd = NULL;
999 	unsigned int len = 0;
1000 
1001 	len += sizeof(struct nrf_wifi_tx_buff_info);
1002 	len *= nrf_wifi_utils_list_len(txq);
1003 
1004 	len += sizeof(struct nrf_wifi_tx_buff);
1005 
1006 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
1007 				  NRF_WIFI_HOST_RPU_MSG_TYPE_DATA,
1008 				  len);
1009 
1010 	status = tx_cmd_prepare(fmac_dev_ctx,
1011 				umac_cmd,
1012 				desc,
1013 				txq,
1014 				peer_id);
1015 
1016 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1017 		nrf_wifi_osal_log_err("%s: tx_cmd_prepare failed",
1018 				      __func__);
1019 
1020 		goto out;
1021 	}
1022 
1023 	status = nrf_wifi_sys_hal_data_cmd_send(fmac_dev_ctx->hal_dev_ctx,
1024 						NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX,
1025 						umac_cmd,
1026 						sizeof(*umac_cmd) + len,
1027 						desc,
1028 						0);
1029 
1030 	nrf_wifi_osal_mem_free(umac_cmd);
1031 out:
1032 	return status;
1033 }
1034 
1035 
tx_pending_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc,unsigned int ac)1036 enum nrf_wifi_status tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1037 					unsigned int desc,
1038 					unsigned int ac)
1039 {
1040 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1041 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1042 
1043 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1044 
1045 	if (!fmac_dev_ctx) {
1046 		nrf_wifi_osal_log_err("%s: Invalid params",
1047 				      __func__);
1048 		goto out;
1049 	}
1050 
1051 	if (_tx_pending_process(fmac_dev_ctx, desc, ac)) {
1052 #ifdef NRF70_RAW_DATA_TX
1053 		if (!sys_dev_ctx->raw_tx_config.raw_tx_flag) {
1054 #endif
1055 			status = tx_cmd_init(fmac_dev_ctx,
1056 					     sys_dev_ctx->tx_config.pkt_info_p[desc].pkt,
1057 					     desc,
1058 					     sys_dev_ctx->tx_config.pkt_info_p[desc].peer_id);
1059 #ifdef NRF70_RAW_DATA_TX
1060 		} else {
1061 			status = rawtx_cmd_init(fmac_dev_ctx,
1062 						sys_dev_ctx->tx_config.pkt_info_p[desc].pkt,
1063 						desc,
1064 						sys_dev_ctx->tx_config.pkt_info_p[desc].peer_id);
1065 		}
1066 #endif
1067 	} else {
1068 		tx_desc_free(fmac_dev_ctx,
1069 			     desc,
1070 			     ac);
1071 
1072 		status = NRF_WIFI_STATUS_SUCCESS;
1073 	}
1074 
1075 out:
1076 	return status;
1077 }
1078 
1079 
tx_enqueue(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * nwb,unsigned int ac,unsigned int peer_id)1080 static enum nrf_wifi_status tx_enqueue(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1081 				void *nwb,
1082 				unsigned int ac,
1083 				unsigned int peer_id)
1084 {
1085 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1086 	void *queue = NULL;
1087 	int qlen = 0;
1088 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1089 
1090 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1091 
1092 	if (!fmac_dev_ctx || !nwb) {
1093 		nrf_wifi_osal_log_err("%s: Invalid params",
1094 				      __func__);
1095 		goto out;
1096 	}
1097 
1098 	queue = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
1099 
1100 	qlen = nrf_wifi_utils_q_len(queue);
1101 
1102 	if (qlen >= NRF70_MAX_TX_PENDING_QLEN) {
1103 		goto out;
1104 	}
1105 
1106 	if (is_twt_emergency_pkt(nwb)) {
1107 		nrf_wifi_utils_q_enqueue_head(queue,
1108 					      nwb);
1109 	} else {
1110 		nrf_wifi_utils_q_enqueue(queue,
1111 					 nwb);
1112 	}
1113 
1114 	status = update_pend_q_bmp(fmac_dev_ctx, ac, peer_id);
1115 
1116 out:
1117 	return status;
1118 }
1119 
1120 
tx_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char if_idx,void * nbuf,unsigned int ac,unsigned int peer_id)1121 static enum nrf_wifi_fmac_tx_status tx_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1122 				unsigned char if_idx,
1123 				void *nbuf,
1124 				unsigned int ac,
1125 				unsigned int peer_id)
1126 {
1127 	enum nrf_wifi_fmac_tx_status status;
1128 	struct nrf_wifi_fmac_priv *fpriv = NULL;
1129 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1130 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
1131 	void *pend_pkt_q = NULL;
1132 	void *first_nwb = NULL;
1133 	unsigned char ps_state = 0;
1134 	bool aggr_status = false;
1135 	int max_cmds = 0;
1136 
1137 	fpriv = fmac_dev_ctx->fpriv;
1138 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1139 	sys_fpriv = wifi_fmac_priv(fpriv);
1140 
1141 	status = (enum nrf_wifi_fmac_tx_status)tx_enqueue(fmac_dev_ctx,
1142 						  nbuf,
1143 						  ac,
1144 						  peer_id);
1145 
1146 	if (status != NRF_WIFI_FMAC_TX_STATUS_SUCCESS) {
1147 		goto err;
1148 	}
1149 
1150 	ps_state = sys_dev_ctx->tx_config.peers[peer_id].ps_state;
1151 
1152 	if (ps_state == NRF_WIFI_CLIENT_PS_MODE) {
1153 		goto out;
1154 	}
1155 
1156 	pend_pkt_q = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
1157 
1158 	/* If outstanding_descs for a particular
1159 	 * access category >= NUM_TX_DESCS_PER_AC means there are already
1160 	 * pending packets for that access category. So now see if frames
1161 	 * can be aggregated depending upon access category depending
1162 	 * upon SA, RA & AC
1163 	 */
1164 
1165 	if ((sys_dev_ctx->tx_config.outstanding_descs[ac]) >= sys_fpriv->num_tx_tokens_per_ac) {
1166 		if (nrf_wifi_utils_q_len(pend_pkt_q)) {
1167 			first_nwb = nrf_wifi_utils_q_peek(pend_pkt_q);
1168 
1169 			aggr_status = true;
1170 
1171 			if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_get_dest(nbuf),
1172 							    nrf_wifi_get_dest(first_nwb))) {
1173 				aggr_status = false;
1174 			}
1175 
1176 			if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_get_src(nbuf),
1177 							    nrf_wifi_get_src(first_nwb))) {
1178 				aggr_status = false;
1179 			}
1180 		}
1181 
1182 		if (aggr_status) {
1183 			max_cmds = sys_fpriv->data_config.max_tx_aggregation;
1184 
1185 			if (nrf_wifi_utils_q_len(pend_pkt_q) < max_cmds) {
1186 				goto out;
1187 			}
1188 		}
1189 	}
1190 	return NRF_WIFI_FMAC_TX_STATUS_SUCCESS;
1191 out:
1192 	return NRF_WIFI_FMAC_TX_STATUS_QUEUED;
1193 err:
1194 	return NRF_WIFI_FMAC_TX_STATUS_FAIL;
1195 }
1196 
1197 
tx_buff_req_free(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int tx_desc_num,unsigned char * ac)1198 unsigned int tx_buff_req_free(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1199 			      unsigned int tx_desc_num,
1200 			      unsigned char *ac)
1201 {
1202 	unsigned int pkts_pend = 0;
1203 	unsigned int desc = tx_desc_num;
1204 	int tx_done_q = 0, start_ac, end_ac, cnt = 0;
1205 	unsigned short tx_done_spare_desc_q_map = 0;
1206 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1207 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
1208 
1209 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1210 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
1211 
1212 	/* Determine the Queue from the descriptor */
1213 	/* Reserved desc */
1214 	if (desc < (sys_fpriv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX)) {
1215 		tx_done_q = (desc % NRF_WIFI_FMAC_AC_MAX);
1216 		start_ac = end_ac = tx_done_q;
1217 	} else {
1218 		/* Derive the queue here as it is not given by UMAC. */
1219 		if (desc >= (sys_fpriv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX)) {
1220 			tx_done_spare_desc_q_map = get_spare_desc_q_map(fmac_dev_ctx, desc);
1221 
1222 			if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_BK))
1223 				tx_done_q = NRF_WIFI_FMAC_AC_BK;
1224 			else if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_BE))
1225 				tx_done_q = NRF_WIFI_FMAC_AC_BE;
1226 			else if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_VI))
1227 				tx_done_q = NRF_WIFI_FMAC_AC_VI;
1228 			else if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_VO))
1229 				tx_done_q = NRF_WIFI_FMAC_AC_VO;
1230 		}
1231 
1232 		/* Spare desc:
1233 		 * Loop through all AC's
1234 		 */
1235 		start_ac = NRF_WIFI_FMAC_AC_VO;
1236 		end_ac = NRF_WIFI_FMAC_AC_BK;
1237 	}
1238 
1239 	for (cnt = start_ac; cnt >= end_ac; cnt--) {
1240 		pkts_pend = _tx_pending_process(fmac_dev_ctx, desc, cnt);
1241 
1242 		if (pkts_pend) {
1243 			*ac = (unsigned char)cnt;
1244 
1245 			/* Spare Token Case*/
1246 			if (tx_done_q != *ac) {
1247 				/* Adjust the counters */
1248 				sys_dev_ctx->tx_config.outstanding_descs[tx_done_q]--;
1249 				sys_dev_ctx->tx_config.outstanding_descs[*ac]++;
1250 
1251 				/* Update the queue_map */
1252 				/* Clear the last access category. */
1253 				clear_spare_desc_q_map(fmac_dev_ctx, desc, tx_done_q);
1254 				/* Set the new access category. */
1255 				set_spare_desc_q_map(fmac_dev_ctx, desc, *ac);
1256 			}
1257 			break;
1258 		}
1259 	}
1260 
1261 	if (!pkts_pend) {
1262 		/* Mark the desc as available */
1263 		tx_desc_free(fmac_dev_ctx,
1264 			     desc,
1265 			     tx_done_q);
1266 	}
1267 
1268 	return pkts_pend;
1269 }
1270 
1271 
tx_done_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char tx_desc_num)1272 static enum nrf_wifi_status tx_done_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1273 				     unsigned char tx_desc_num)
1274 {
1275 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1276 	struct nrf_wifi_fmac_priv *fpriv = NULL;
1277 	void *nwb = NULL;
1278 	void *nwb_list = NULL;
1279 	unsigned int desc = 0;
1280 	unsigned int frame = 0;
1281 	unsigned int desc_id = 0;
1282 	unsigned long virt_addr = 0;
1283 	struct nrf_wifi_fmac_buf_map_info *tx_buf_info = NULL;
1284 	struct tx_pkt_info *pkt_info = NULL;
1285 	unsigned int pkt = 0;
1286 	unsigned int pkts_pending = 0;
1287 	unsigned char queue = 0;
1288 	void *txq = NULL;
1289 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1290 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
1291 
1292 	fpriv = fmac_dev_ctx->fpriv;
1293 
1294 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1295 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
1296 
1297 	desc = tx_desc_num;
1298 
1299 	if (desc > sys_fpriv->num_tx_tokens) {
1300 		nrf_wifi_osal_log_err("Invalid desc");
1301 		goto out;
1302 	}
1303 
1304 	pkt_info = &sys_dev_ctx->tx_config.pkt_info_p[desc];
1305 	nwb_list = pkt_info->pkt;
1306 
1307 	for (frame = 0;
1308 	     frame < sys_dev_ctx->tx_config.send_pkt_coalesce_count_p[desc];
1309 	     frame++) {
1310 		desc_id = (desc * sys_fpriv->data_config.max_tx_aggregation) + frame;
1311 
1312 		tx_buf_info = &sys_dev_ctx->tx_buf_info[desc_id];
1313 
1314 		if (!tx_buf_info->mapped) {
1315 			nrf_wifi_osal_log_err("%s: Deinit_TX cmd called for unmapped TX buf(%d)",
1316 					      __func__,
1317 					      desc_id);
1318 			status = NRF_WIFI_STATUS_FAIL;
1319 			goto out;
1320 		}
1321 
1322 		virt_addr = nrf_wifi_sys_hal_buf_unmap_tx(fmac_dev_ctx->hal_dev_ctx,
1323 							  desc_id);
1324 
1325 		if (!virt_addr) {
1326 			nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_buf_unmap_tx failed",
1327 					      __func__);
1328 			status = NRF_WIFI_STATUS_FAIL;
1329 			goto out;
1330 		}
1331 
1332 		/* TODO: See why we can't free the nwb here itself instead of
1333 		 * later as is being done now
1334 		 */
1335 		tx_buf_info->nwb = 0;
1336 		tx_buf_info->mapped = false;
1337 	}
1338 
1339 	pkt = 0;
1340 
1341 	while (nrf_wifi_utils_q_len(nwb_list)) {
1342 		nwb = nrf_wifi_utils_q_dequeue(nwb_list);
1343 
1344 		if (!nwb) {
1345 			continue;
1346 		}
1347 
1348 		nrf_wifi_osal_nbuf_free(nwb);
1349 		pkt++;
1350 	}
1351 
1352 	sys_dev_ctx->host_stats.total_tx_done_pkts += pkt;
1353 
1354 	pkts_pending = tx_buff_req_free(fmac_dev_ctx, tx_desc_num, &queue);
1355 
1356 	if (pkts_pending) {
1357 #ifdef NRF70_RAW_DATA_TX
1358 		unsigned char *data = NULL;
1359 		struct nrf_wifi_fmac_vif_ctx *vif_ctx;
1360 		unsigned char if_idx;
1361 
1362 		pkt_info = &sys_dev_ctx->tx_config.pkt_info_p[desc];
1363 		txq = pkt_info->pkt;
1364 
1365 		/**
1366 		 * we need to peek into the pending buffer to determine if
1367 		 * packet is a raw packet or not
1368 		 */
1369 		nwb = nrf_wifi_utils_list_peek(txq);
1370 		data = nrf_wifi_osal_nbuf_data_get(nwb);
1371 
1372 		if (*(unsigned int *)data != NRF_WIFI_MAGIC_NUM_RAWTX) {
1373 #endif /* NRF70_RAW_DATA_TX */
1374 			if (sys_dev_ctx->twt_sleep_status ==
1375 			    NRF_WIFI_FMAC_TWT_STATE_AWAKE) {
1376 				pkt_info = &sys_dev_ctx->tx_config.pkt_info_p[desc];
1377 				txq = pkt_info->pkt;
1378 				status = tx_cmd_init(fmac_dev_ctx,
1379 						     txq,
1380 						     desc,
1381 						     pkt_info->peer_id);
1382 			} else {
1383 				status = NRF_WIFI_STATUS_SUCCESS;
1384 			}
1385 #ifdef NRF70_RAW_DATA_TX
1386 		} else {
1387 			nrf_wifi_osal_mem_cpy(&sys_dev_ctx->raw_tx_config,
1388 					      data,
1389 					      sizeof(struct raw_tx_pkt_header));
1390 
1391 			/**
1392 			 * check if the if_type is STA_TX_INJECTOR
1393 			 * if so, we need to check for TWT_SLEEP.
1394 			 * for RAW TX, we use MAX-PEERS queue presently
1395 			 */
1396 			if_idx = sys_dev_ctx->tx_config.peers[MAX_PEERS].if_idx;
1397 			vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
1398 			if ((vif_ctx->if_type == NRF_WIFI_STA_TX_INJECTOR) &&
1399 			    (sys_dev_ctx->twt_sleep_status == NRF_WIFI_FMAC_TWT_STATE_SLEEP)) {
1400 				status = NRF_WIFI_STATUS_SUCCESS;
1401 			} else {
1402 				status = rawtx_cmd_init(fmac_dev_ctx,
1403 							txq,
1404 							desc,
1405 							pkt_info->peer_id);
1406 			}
1407 		}
1408 #endif /* NRF70_RAW_DATA_TX */
1409 	} else {
1410 		status = NRF_WIFI_STATUS_SUCCESS;
1411 	}
1412 out:
1413 	return status;
1414 }
1415 
1416 #ifdef NRF70_TX_DONE_WQ_ENABLED
tx_done_tasklet_fn(unsigned long data)1417 static void tx_done_tasklet_fn(unsigned long data)
1418 {
1419 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)data;
1420 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx;
1421 	void *tx_done_tasklet_event_q;
1422 	enum NRF_WIFI_HAL_STATUS hal_status;
1423 
1424 	nrf_wifi_sys_hal_lock_rx(fmac_dev_ctx->hal_dev_ctx);
1425 	hal_status = nrf_wifi_hal_status_unlocked(fmac_dev_ctx->hal_dev_ctx);
1426 	if (hal_status != NRF_WIFI_HAL_STATUS_ENABLED) {
1427 		goto out;
1428 	}
1429 
1430 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1431 	tx_done_tasklet_event_q = sys_dev_ctx->tx_done_tasklet_event_q;
1432 
1433 	struct nrf_wifi_tx_buff_done *config = nrf_wifi_utils_q_dequeue(
1434 		tx_done_tasklet_event_q);
1435 
1436 	if (!config) {
1437 		nrf_wifi_osal_log_err("%s: TX done event Q is empty",
1438 				      __func__);
1439 		return;
1440 	}
1441 
1442 	(void) nrf_wifi_fmac_tx_done_event_process(fmac_dev_ctx, config);
1443 
1444 	nrf_wifi_osal_mem_free(config);
1445 out:
1446 	nrf_wifi_sys_hal_unlock_rx(fmac_dev_ctx->hal_dev_ctx);
1447 }
1448 #endif /* NRF70_TX_DONE_WQ_ENABLED */
1449 
1450 #ifdef NRF70_RAW_DATA_TX
nrf_wifi_fmac_rawtx_done_event_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_event_raw_tx_done * config)1451 enum nrf_wifi_status nrf_wifi_fmac_rawtx_done_event_process(
1452 		     struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1453 		     struct nrf_wifi_event_raw_tx_done *config)
1454 {
1455 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1456 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1457 
1458 	if (!fmac_dev_ctx || !config) {
1459 		nrf_wifi_osal_log_err("%s: Invalid parameters",
1460 				      __func__);
1461 		goto out;
1462 	}
1463 
1464 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1465 	if (!sys_dev_ctx || !sys_dev_ctx->tx_config.tx_lock) {
1466 		/* This is a valid case when the TX_DONE event is received
1467 		 * during the driver deinit, so, silently ignore the failure.
1468 		 */
1469 		return NRF_WIFI_STATUS_SUCCESS;
1470 	}
1471 
1472 	nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock);
1473 
1474 	if (config->status == NRF_WIFI_STATUS_FAIL) {
1475 		/**
1476 		 * If the status indicates failure,
1477 		 * increment raw TX failure count. The TX buffers
1478 		 * still need to be freed. */
1479 		sys_dev_ctx->raw_pkt_stats.raw_pkt_send_failure += 1;
1480 	}
1481 
1482 	status = tx_done_process(fmac_dev_ctx,
1483 				 config->desc_num);
1484 
1485 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1486 		nrf_wifi_osal_log_err("%s: Process raw tx done failed",
1487 				      __func__);
1488 		goto unlock;
1489 	}
1490 unlock:
1491 	nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
1492 out:
1493 	return status;
1494 }
1495 #endif
1496 
nrf_wifi_status(nrf_wifi_fmac_tx_done_event_process)1497 enum nrf_wifi_status (nrf_wifi_fmac_tx_done_event_process)(
1498 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1499 	struct nrf_wifi_tx_buff_done *config)
1500 {
1501 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1502 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1503 
1504 	if (!fmac_dev_ctx || !config) {
1505 		nrf_wifi_osal_log_err("%s: Invalid parameters",
1506 				      __func__);
1507 		goto out;
1508 	}
1509 
1510 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1511 	if (!sys_dev_ctx || !sys_dev_ctx->tx_config.tx_lock) {
1512 		/* This is a valid case when the TX_DONE event is received
1513 		 * during the driver deinit, so, silently ignore the failure.
1514 		 */
1515 		return NRF_WIFI_STATUS_SUCCESS;
1516 	}
1517 
1518 
1519 	nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock);
1520 
1521 	status = tx_done_process(fmac_dev_ctx,
1522 				 config->tx_desc_num);
1523 
1524 	nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
1525 
1526 out:
1527 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1528 		nrf_wifi_osal_log_err("%s: Failed",
1529 				      __func__);
1530 	}
1531 
1532 	return status;
1533 }
1534 
1535 
nrf_wifi_fmac_tx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,int if_id,void * nbuf,unsigned int ac,unsigned int peer_id)1536 static enum nrf_wifi_fmac_tx_status nrf_wifi_fmac_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1537 				      int if_id,
1538 				      void *nbuf,
1539 				      unsigned int ac,
1540 				      unsigned int peer_id)
1541 {
1542 	enum nrf_wifi_fmac_tx_status status = NRF_WIFI_FMAC_TX_STATUS_FAIL;
1543 	unsigned int desc = 0;
1544 	struct nrf_wifi_fmac_priv *fpriv = NULL;
1545 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1546 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
1547 
1548 	fpriv = fmac_dev_ctx->fpriv;
1549 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1550 	sys_fpriv = wifi_fmac_priv(fpriv);
1551 
1552 	nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock);
1553 
1554 
1555 	if (sys_fpriv->num_tx_tokens == 0) {
1556 		goto out;
1557 	}
1558 
1559 	status = tx_process(fmac_dev_ctx,
1560 			    if_id,
1561 			    nbuf,
1562 			    ac,
1563 			    peer_id);
1564 
1565 	if (status != NRF_WIFI_FMAC_TX_STATUS_SUCCESS) {
1566 		goto out;
1567 	}
1568 
1569 	status = NRF_WIFI_FMAC_TX_STATUS_QUEUED;
1570 
1571 	if (!can_xmit(fmac_dev_ctx, nbuf)) {
1572 		goto out;
1573 	}
1574 
1575 	desc = tx_desc_get(fmac_dev_ctx, ac);
1576 
1577 	if (desc == sys_fpriv->num_tx_tokens) {
1578 		goto out;
1579 	}
1580 
1581 	status = (enum nrf_wifi_fmac_tx_status)tx_pending_process(fmac_dev_ctx,
1582 					desc,
1583 					ac);
1584 out:
1585 	nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
1586 
1587 	return status;
1588 }
1589 
1590 
tx_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)1591 enum nrf_wifi_status tx_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
1592 {
1593 	struct nrf_wifi_fmac_priv *fpriv = NULL;
1594 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
1595 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1596 	void *q_ptr = NULL;
1597 	unsigned int i = 0;
1598 	unsigned int j = 0;
1599 
1600 	if (!fmac_dev_ctx) {
1601 		goto out;
1602 	}
1603 
1604 	fpriv = fmac_dev_ctx->fpriv;
1605 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1606 	sys_fpriv = wifi_fmac_priv(fpriv);
1607 
1608 	sys_dev_ctx->tx_config.send_pkt_coalesce_count_p =
1609 		nrf_wifi_osal_mem_zalloc((sizeof(unsigned int) *
1610 					  sys_fpriv->num_tx_tokens));
1611 
1612 	if (!sys_dev_ctx->tx_config.send_pkt_coalesce_count_p) {
1613 		nrf_wifi_osal_log_err("%s: Unable to allocate send_pkt_coalesce_count_p",
1614 				      __func__);
1615 		goto out;
1616 	}
1617 
1618 	for (i = 0; i < NRF_WIFI_FMAC_AC_MAX; i++) {
1619 		for (j = 0; j < MAX_SW_PEERS; j++) {
1620 			sys_dev_ctx->tx_config.data_pending_txq[j][i] =
1621 				nrf_wifi_utils_q_alloc();
1622 
1623 			if (!sys_dev_ctx->tx_config.data_pending_txq[j][i]) {
1624 				nrf_wifi_osal_log_err("%s: Unable to allocate data_pending_txq",
1625 						      __func__);
1626 				goto coal_q_free;
1627 			}
1628 		}
1629 
1630 		sys_dev_ctx->tx_config.outstanding_descs[i] = 0;
1631 	}
1632 
1633 	/* Used to store the address of tx'ed skb and len of 802.11 hdr
1634 	 * it will be used in tx complete.
1635 	 */
1636 	sys_dev_ctx->tx_config.pkt_info_p = nrf_wifi_osal_mem_zalloc((sizeof(struct tx_pkt_info) *
1637 								     sys_fpriv->num_tx_tokens));
1638 
1639 	if (!sys_dev_ctx->tx_config.pkt_info_p) {
1640 		nrf_wifi_osal_log_err("%s: Unable to allocate pkt_info_p",
1641 				      __func__);
1642 		goto tx_q_free;
1643 	}
1644 
1645 	for (i = 0; i < sys_fpriv->num_tx_tokens; i++) {
1646 		sys_dev_ctx->tx_config.pkt_info_p[i].pkt = nrf_wifi_utils_list_alloc();
1647 
1648 		if (!sys_dev_ctx->tx_config.pkt_info_p[i].pkt) {
1649 			nrf_wifi_osal_log_err("%s: Unable to allocate pkt list",
1650 					      __func__);
1651 			goto tx_q_setup_free;
1652 		}
1653 	}
1654 
1655 	for (j = 0; j < NRF_WIFI_FMAC_AC_MAX; j++) {
1656 		sys_dev_ctx->tx_config.curr_peer_opp[j] = 0;
1657 	}
1658 
1659 	sys_dev_ctx->tx_config.buf_pool_bmp_p =
1660 		nrf_wifi_osal_mem_zalloc((sizeof(unsigned long) *
1661 					 (sys_fpriv->num_tx_tokens/TX_DESC_BUCKET_BOUND) + 1));
1662 
1663 	if (!sys_dev_ctx->tx_config.buf_pool_bmp_p) {
1664 		nrf_wifi_osal_log_err("%s: Unable to allocate buf_pool_bmp_p",
1665 				      __func__);
1666 		goto tx_pkt_info_free;
1667 	}
1668 
1669 	nrf_wifi_osal_mem_set(sys_dev_ctx->tx_config.buf_pool_bmp_p,
1670 			      0,
1671 			      sizeof(long)*((sys_fpriv->num_tx_tokens/TX_DESC_BUCKET_BOUND) + 1));
1672 
1673 	for (i = 0; i < MAX_PEERS; i++) {
1674 		sys_dev_ctx->tx_config.peers[i].peer_id = -1;
1675 	}
1676 
1677 	sys_dev_ctx->tx_config.tx_lock = nrf_wifi_osal_spinlock_alloc();
1678 
1679 	if (!sys_dev_ctx->tx_config.tx_lock) {
1680 		nrf_wifi_osal_log_err("%s: Unable to allocate TX lock",
1681 				      __func__);
1682 		goto tx_buff_map_free;
1683 	}
1684 
1685 	nrf_wifi_osal_spinlock_init(sys_dev_ctx->tx_config.tx_lock);
1686 
1687 	sys_dev_ctx->tx_config.wakeup_client_q = nrf_wifi_utils_q_alloc();
1688 
1689 	if (!sys_dev_ctx->tx_config.wakeup_client_q) {
1690 		nrf_wifi_osal_log_err("%s: Unable to allocate Wakeup Client List",
1691 				      __func__);
1692 		goto tx_spin_lock_free;
1693 	}
1694 
1695 	sys_dev_ctx->twt_sleep_status = NRF_WIFI_FMAC_TWT_STATE_AWAKE;
1696 
1697 #ifdef NRF70_TX_DONE_WQ_ENABLED
1698 	sys_dev_ctx->tx_done_tasklet = nrf_wifi_osal_tasklet_alloc(NRF_WIFI_TASKLET_TYPE_TX_DONE);
1699 	if (!sys_dev_ctx->tx_done_tasklet) {
1700 		nrf_wifi_osal_log_err("%s: Unable to allocate tx_done_tasklet",
1701 				      __func__);
1702 		goto wakeup_client_q_free;
1703 	}
1704 	sys_dev_ctx->tx_config.tx_done_tasklet_event_q = nrf_wifi_utils_q_alloc();
1705 	if (!sys_dev_ctx->tx_config.tx_done_tasklet_event_q) {
1706 		nrf_wifi_osal_log_err("%s: Unable to allocate tx_done_tasklet_event_q",
1707 				      __func__);
1708 		goto tx_done_tasklet_free;
1709 	}
1710 
1711 	nrf_wifi_osal_tasklet_init(sys_dev_ctx->tx_done_tasklet,
1712 				   tx_done_tasklet_fn,
1713 				   (unsigned long)fmac_dev_ctx);
1714 #endif /* NRF70_TX_DONE_WQ_ENABLED */
1715 	return NRF_WIFI_STATUS_SUCCESS;
1716 #ifdef NRF70_TX_DONE_WQ_ENABLED
1717 tx_done_tasklet_free:
1718 	nrf_wifi_osal_tasklet_free(sys_dev_ctx->tx_done_tasklet);
1719 wakeup_client_q_free:
1720 	nrf_wifi_utils_q_free(sys_dev_ctx->tx_config.wakeup_client_q);
1721 #endif /* NRF70_TX_DONE_WQ_ENABLED */
1722 tx_spin_lock_free:
1723 	nrf_wifi_osal_spinlock_free(sys_dev_ctx->tx_config.tx_lock);
1724 tx_buff_map_free:
1725 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_config.buf_pool_bmp_p);
1726 tx_pkt_info_free:
1727 	for (i = 0; i < sys_fpriv->num_tx_tokens; i++) {
1728 		nrf_wifi_utils_list_free(sys_dev_ctx->tx_config.pkt_info_p[i].pkt);
1729 	}
1730 tx_q_setup_free:
1731 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_config.pkt_info_p);
1732 tx_q_free:
1733 	for (i = 0; i < NRF_WIFI_FMAC_AC_MAX; i++) {
1734 		for (j = 0; j < MAX_SW_PEERS; j++) {
1735 			q_ptr = sys_dev_ctx->tx_config.data_pending_txq[j][i];
1736 
1737 			nrf_wifi_utils_q_free(q_ptr);
1738 		}
1739 	}
1740 coal_q_free:
1741 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_config.send_pkt_coalesce_count_p);
1742 out:
1743 	return NRF_WIFI_STATUS_FAIL;
1744 }
1745 
1746 
tx_deinit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)1747 void tx_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
1748 {
1749 	struct nrf_wifi_fmac_priv *fpriv = NULL;
1750 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1751 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
1752 	unsigned int i = 0;
1753 	unsigned int j = 0;
1754 
1755 	fpriv = fmac_dev_ctx->fpriv;
1756 
1757 	sys_fpriv = wifi_fmac_priv(fpriv);
1758 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1759 
1760 #ifdef NRF70_TX_DONE_WQ_ENABLED
1761 	/* TODO: Need to deinit network buffers? */
1762 	nrf_wifi_osal_tasklet_free(sys_dev_ctx->tx_done_tasklet);
1763 	nrf_wifi_utils_q_free(sys_dev_ctx->tx_config.tx_done_tasklet_event_q);
1764 #endif /* NRF70_TX_DONE_WQ_ENABLED */
1765 	nrf_wifi_utils_q_free(sys_dev_ctx->tx_config.wakeup_client_q);
1766 
1767 	nrf_wifi_osal_spinlock_free(sys_dev_ctx->tx_config.tx_lock);
1768 
1769 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_config.buf_pool_bmp_p);
1770 
1771 	for (i = 0; i < sys_fpriv->num_tx_tokens; i++) {
1772 		if (sys_dev_ctx->tx_config.pkt_info_p) {
1773 			while (nrf_wifi_utils_q_len(sys_dev_ctx->tx_config.pkt_info_p[i].pkt)) {
1774 				nrf_wifi_osal_nbuf_free(
1775 					nrf_wifi_utils_q_dequeue(sys_dev_ctx->tx_config.pkt_info_p[i].pkt));
1776 			}
1777 			nrf_wifi_utils_list_free(
1778 						 sys_dev_ctx->tx_config.pkt_info_p[i].pkt);
1779 		}
1780 	}
1781 
1782 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_config.pkt_info_p);
1783 
1784 	for (i = 0; i < NRF_WIFI_FMAC_AC_MAX; i++) {
1785 		for (j = 0; j < MAX_SW_PEERS; j++) {
1786 			while (nrf_wifi_utils_q_len(sys_dev_ctx->tx_config.data_pending_txq[j][i])) {
1787 				nrf_wifi_osal_nbuf_free(
1788 					nrf_wifi_utils_q_dequeue(sys_dev_ctx->tx_config.data_pending_txq[j][i]));
1789 			}
1790 			nrf_wifi_utils_q_free(
1791 					      sys_dev_ctx->tx_config.data_pending_txq[j][i]);
1792 		}
1793 	}
1794 
1795 	nrf_wifi_osal_mem_free(sys_dev_ctx->tx_config.send_pkt_coalesce_count_p);
1796 
1797 	nrf_wifi_osal_mem_set(&sys_dev_ctx->tx_config,
1798 			      0,
1799 			      sizeof(struct tx_config));
1800 }
1801 
1802 
map_ac_from_tid(int tid)1803 static int map_ac_from_tid(int tid)
1804 {
1805 	const int map_1d_to_ac[8] = {
1806 		NRF_WIFI_FMAC_AC_BE, /*UP 0, 802.1D(BE), AC(BE) */
1807 		NRF_WIFI_FMAC_AC_BK, /*UP 1, 802.1D(BK), AC(BK) */
1808 		NRF_WIFI_FMAC_AC_BK, /*UP 2, 802.1D(BK), AC(BK) */
1809 		NRF_WIFI_FMAC_AC_BE, /*UP 3, 802.1D(EE), AC(BE) */
1810 		NRF_WIFI_FMAC_AC_VI, /*UP 4, 802.1D(CL), AC(VI) */
1811 		NRF_WIFI_FMAC_AC_VI, /*UP 5, 802.1D(VI), AC(VI) */
1812 		NRF_WIFI_FMAC_AC_VO, /*UP 6, 802.1D(VO), AC(VO) */
1813 		NRF_WIFI_FMAC_AC_VO  /*UP 7, 802.1D(NC), AC(VO) */
1814 	};
1815 
1816 	return map_1d_to_ac[tid & 7];
1817 }
1818 
1819 
get_ac(unsigned int tid,unsigned char * ra)1820 static int get_ac(unsigned int tid,
1821 		  unsigned char *ra)
1822 {
1823 	if (nrf_wifi_util_is_multicast_addr(ra)) {
1824 		return NRF_WIFI_FMAC_AC_MC;
1825 	}
1826 
1827 	return map_ac_from_tid(tid);
1828 }
1829 
1830 
nrf_wifi_util_get_ra(struct nrf_wifi_fmac_vif_ctx * vif,void * nwb)1831 unsigned char *nrf_wifi_util_get_ra(struct nrf_wifi_fmac_vif_ctx *vif,
1832 				    void *nwb)
1833 {
1834 	if ((vif->if_type == NRF_WIFI_IFTYPE_STATION)
1835 #ifdef NRF70_RAW_DATA_TX
1836 	    || (vif->if_type == NRF_WIFI_STA_TX_INJECTOR)
1837 #endif /* NRF70_RAW_DATA_TX */
1838 #ifdef NRF70_PROMISC_DATA_RX
1839 	    || (vif->if_type == NRF_WIFI_STA_PROMISC)
1840 	    || (vif->if_type == NRF_WIFI_STA_PROMISC_TX_INJECTOR)
1841 #endif
1842 	    ) {
1843 		return vif->bssid;
1844 	}
1845 
1846 	return nrf_wifi_osal_nbuf_data_get(nwb);
1847 }
1848 
1849 
1850 #ifdef NRF70_RAW_DATA_TX
nrf_wifi_raw_pkt_mode_enabled(struct nrf_wifi_fmac_vif_ctx * vif)1851 static bool nrf_wifi_raw_pkt_mode_enabled(struct nrf_wifi_fmac_vif_ctx *vif)
1852 {
1853 	if ((vif->if_type == NRF_WIFI_STA_TX_INJECTOR) ||
1854 	    (vif->if_type == NRF_WIFI_MONITOR_TX_INJECTOR) ||
1855 	    (vif->if_type == NRF_WIFI_STA_PROMISC_TX_INJECTOR)) {
1856 		return true;
1857 	}
1858 	return false;
1859 }
1860 
nrf_wifi_fmac_start_rawpkt_xmit(void * dev_ctx,unsigned char if_idx,void * nwb)1861 enum nrf_wifi_status nrf_wifi_fmac_start_rawpkt_xmit(void *dev_ctx,
1862 						     unsigned char if_idx,
1863 						     void *nwb)
1864 {
1865 	enum nrf_wifi_fmac_tx_status tx_status = NRF_WIFI_FMAC_TX_STATUS_FAIL;
1866 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1867 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1868 	void *nwb_data = NULL;
1869 	int ac;
1870 	int peer_id;
1871 
1872 	if (!nwb || !dev_ctx) {
1873 		/**
1874 		 * Handling an abnormal case.
1875 		 * return failure as network buffer and device
1876 		 * context are NULL
1877 		 */
1878 		goto fail;
1879 	}
1880 
1881 	fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)dev_ctx;
1882 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1883 
1884 	/**
1885 	 * only allow raw packet to be transmitted if interface type allows it
1886 	 * do not queue the packet if interface type does not allow raw tx
1887 	 */
1888 	if (!nrf_wifi_raw_pkt_mode_enabled(sys_dev_ctx->vif_ctx[if_idx])) {
1889 		nrf_wifi_osal_log_err("%s: raw_packet mode is not enabled",
1890 				      __func__);
1891 		goto out;
1892 	}
1893 
1894 	nwb_data = nrf_wifi_osal_nbuf_data_get(nwb);
1895 	nrf_wifi_osal_mem_cpy(&sys_dev_ctx->raw_tx_config,
1896 			      nwb_data,
1897 			      sizeof(struct raw_tx_pkt_header));
1898 
1899 	sys_dev_ctx->raw_tx_config.raw_tx_flag = 1;
1900 	peer_id = MAX_PEERS;
1901 	ac = sys_dev_ctx->raw_tx_config.queue;
1902 
1903 	tx_status = nrf_wifi_fmac_tx(fmac_dev_ctx,
1904 				     if_idx,
1905 				     nwb,
1906 				     ac,
1907 				     peer_id);
1908 	if (tx_status == NRF_WIFI_FMAC_TX_STATUS_FAIL) {
1909 		nrf_wifi_osal_log_dbg("%s: Failed to send packet\n",
1910 				      __func__);
1911 		/** Increment failure count */
1912 		sys_dev_ctx->raw_pkt_stats.raw_pkt_send_failure += 1;
1913 	} else {
1914 		/**
1915 		 * Increment success count.
1916 		 * can be added to shell command to obtain statistics
1917 		 */
1918 		sys_dev_ctx->raw_pkt_stats.raw_pkt_send_success += 1;
1919 	}
1920 
1921 	/**
1922 	 * Always silently drop the RAW packet and not send Failure.
1923 	 * The network stack might think interface is down
1924 	 */
1925 out:
1926 	sys_dev_ctx->raw_pkt_stats.raw_pkts_sent += 1;
1927 	return NRF_WIFI_STATUS_SUCCESS;
1928 fail:
1929 	return NRF_WIFI_STATUS_FAIL;
1930 }
1931 #endif /* NRF70_RAW_DATA_TX */
1932 
nrf_wifi_fmac_start_xmit(void * dev_ctx,unsigned char if_idx,void * nbuf)1933 enum nrf_wifi_status nrf_wifi_fmac_start_xmit(void *dev_ctx,
1934 					      unsigned char if_idx,
1935 					      void *nbuf)
1936 {
1937 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1938 	enum nrf_wifi_fmac_tx_status tx_status = NRF_WIFI_FMAC_TX_STATUS_FAIL;
1939 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1940 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1941 	unsigned char *ra = NULL;
1942 	int tid = 0;
1943 	int ac = 0;
1944 	int peer_id = -1;
1945 
1946 	if (!nbuf) {
1947 		goto out;
1948 	}
1949 
1950 	fmac_dev_ctx = dev_ctx;
1951 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1952 
1953 	if (nrf_wifi_osal_nbuf_data_size(nbuf) < NRF_WIFI_FMAC_ETH_HDR_LEN) {
1954 		goto out;
1955 	}
1956 
1957 	ra = nrf_wifi_util_get_ra(sys_dev_ctx->vif_ctx[if_idx], nbuf);
1958 
1959 	peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, ra);
1960 
1961 	if (peer_id == -1) {
1962 		nrf_wifi_osal_log_err("%s: Got packet for unknown PEER",
1963 				      __func__);
1964 
1965 		goto out;
1966 	} else if (peer_id == MAX_PEERS) {
1967 		ac = NRF_WIFI_FMAC_AC_MC;
1968 	} else {
1969 		if (sys_dev_ctx->tx_config.peers[peer_id].qos_supported) {
1970 			tid = nrf_wifi_get_tid(nbuf);
1971 			ac = get_ac(tid, ra);
1972 		} else {
1973 			ac = NRF_WIFI_FMAC_AC_BE;
1974 		}
1975 	}
1976 
1977 	tx_status = nrf_wifi_fmac_tx(fmac_dev_ctx,
1978 				  if_idx,
1979 				  nbuf,
1980 				  ac,
1981 				  peer_id);
1982 
1983 	if (tx_status == NRF_WIFI_FMAC_TX_STATUS_FAIL) {
1984 		nrf_wifi_osal_log_dbg("%s: Failed to send packet",
1985 				      __func__);
1986 		goto out;
1987 	}
1988 
1989 	return NRF_WIFI_STATUS_SUCCESS;
1990 out:
1991 	if (nbuf) {
1992 		nrf_wifi_osal_nbuf_free(nbuf);
1993 	}
1994 	return status;
1995 }
1996