Skip to content

Commit 52286f1

Browse files
committed
Fix Raw TX handling
Using a flag for per-packet handling is not ideal, esp. that flash is cleared after TX, but in case of pending raw TX packets that will be processed through TX done flag is unset and they won't be processed. Move the check to per-packet and add APIs to set/get/check, this way it's a clean implementation and handles sending from both TX and TX_DONE paths. This is a breaking change as the raw TX header is modified. Signed-off-by: Chaitanya Tata <[email protected]>
1 parent 7cb2f44 commit 52286f1

File tree

5 files changed

+137
-45
lines changed

5 files changed

+137
-45
lines changed

fw_if/umac_if/inc/system/fmac_structs.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,6 @@ struct raw_tx_pkt_header {
426426
unsigned char tx_mode;
427427
/** Wi-Fi access category mapping for packet @ref nrf_wifi_fmac_ac. */
428428
unsigned char queue;
429-
/** Flag indicating raw packet transmission. */
430-
unsigned char raw_tx_flag;
431429
};
432430

433431
/**

fw_if/umac_if/src/system/tx.c

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ static int tx_aggr_check(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
399399
}
400400

401401
#ifdef NRF70_RAW_DATA_TX
402-
if (sys_dev_ctx->raw_tx_config.raw_tx_flag) {
402+
if (nrf_wifi_osal_nbuf_is_raw_tx(first_nwb)) {
403403
return false;
404404
}
405405
#endif /* NRF70_RAW_DATA_TX */
@@ -486,12 +486,6 @@ static int tx_curr_peer_opp_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
486486
return MAX_PEERS;
487487
}
488488

489-
#ifdef NRF70_RAW_DATA_TX
490-
if (sys_dev_ctx->raw_tx_config.raw_tx_flag) {
491-
return MAX_PEERS;
492-
}
493-
#endif /* NRF70_RAW_DATA_TX */
494-
495489
peer_id = get_peer_from_wakeup_q(fmac_dev_ctx, ac);
496490

497491
if (peer_id != -1) {
@@ -549,14 +543,24 @@ static size_t _tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
549543
max_txq_len = sys_fpriv->data_config.max_tx_aggregation;
550544
avail_ampdu_len_per_token = sys_fpriv->avail_ampdu_len_per_token;
551545

552-
peer_id = tx_curr_peer_opp_get(fmac_dev_ctx, ac);
546+
#ifdef NRF70_RAW_DATA_TX
547+
/* Check for Raw packets first, if not found, then check for
548+
* regular packets.
549+
*/
550+
pend_pkt_q = sys_dev_ctx->tx_config.data_pending_txq[MAX_PEERS][ac];
551+
if (!(nrf_wifi_utils_q_len(pend_pkt_q) > 0 &&
552+
nrf_wifi_osal_nbuf_is_raw_tx(nrf_wifi_utils_q_peek(pend_pkt_q))))
553+
#endif
554+
{
555+
peer_id = tx_curr_peer_opp_get(fmac_dev_ctx, ac);
553556

554-
/* No pending frames for any peer in that AC. */
555-
if (peer_id == -1) {
556-
return 0;
557-
}
557+
/* No pending frames for any peer in that AC. */
558+
if (peer_id == -1) {
559+
return 0;
560+
}
558561

559-
pend_pkt_q = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
562+
pend_pkt_q = sys_dev_ctx->tx_config.data_pending_txq[peer_id][ac];
563+
}
560564

561565
if (nrf_wifi_utils_q_len(pend_pkt_q) == 0) {
562566
return 0;
@@ -821,13 +825,20 @@ enum nrf_wifi_status rawtx_cmd_prepare(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ct
821825
config->sys_head.len = sizeof(*config);
822826
config->if_index = vif_id;
823827
config->raw_tx_info.desc_num = desc;
824-
config->raw_tx_info.queue_num = sys_dev_ctx->raw_tx_config.queue;
825-
if (len != sys_dev_ctx->raw_tx_config.packet_length) {
826-
goto err;
827-
}
828828
config->raw_tx_info.pkt_length = len;
829-
config->raw_tx_info.rate = sys_dev_ctx->raw_tx_config.data_rate;
830-
config->raw_tx_info.rate_flags = sys_dev_ctx->raw_tx_config.tx_mode;
829+
830+
/* Check first packet in queue for per-packet raw TX config */
831+
void *first_nwb = nrf_wifi_utils_list_peek(txq);
832+
struct raw_tx_pkt_header *raw_tx_hdr = NULL;
833+
834+
if (first_nwb && nrf_wifi_osal_nbuf_is_raw_tx(first_nwb)) {
835+
raw_tx_hdr = nrf_wifi_osal_nbuf_get_raw_tx_hdr(first_nwb);
836+
if (raw_tx_hdr) {
837+
config->raw_tx_info.queue_num = raw_tx_hdr->queue;
838+
config->raw_tx_info.rate = raw_tx_hdr->data_rate;
839+
config->raw_tx_info.rate_flags = raw_tx_hdr->tx_mode;
840+
}
841+
}
831842

832843
info.fmac_dev_ctx = fmac_dev_ctx;
833844
info.raw_config = config;
@@ -998,10 +1009,6 @@ enum nrf_wifi_status rawtx_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
9981009
status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
9991010
umac_cmd,
10001011
(sizeof(*umac_cmd) + len));
1001-
1002-
/* clear the raw tx config data */
1003-
nrf_wifi_osal_mem_set(&sys_dev_ctx->raw_tx_config,
1004-
0, sizeof(struct raw_tx_pkt_header));
10051012
out:
10061013
return status;
10071014
}
@@ -1068,6 +1075,7 @@ enum nrf_wifi_status tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_c
10681075
{
10691076
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
10701077
struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1078+
void *first_nwb = NULL;
10711079

10721080
sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
10731081

@@ -1078,21 +1086,27 @@ enum nrf_wifi_status tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_c
10781086
}
10791087

10801088
if (_tx_pending_process(fmac_dev_ctx, desc, ac)) {
1089+
first_nwb = nrf_wifi_utils_list_peek(sys_dev_ctx->tx_config.pkt_info_p[desc].pkt);
1090+
/* Should never happen, but just in case */
1091+
if (!first_nwb) {
1092+
nrf_wifi_osal_log_err("%s: No pending packets in txq",
1093+
__func__);
1094+
goto out;
1095+
}
10811096
#ifdef NRF70_RAW_DATA_TX
1082-
if (!sys_dev_ctx->raw_tx_config.raw_tx_flag) {
1083-
#endif
1084-
status = tx_cmd_init(fmac_dev_ctx,
1085-
sys_dev_ctx->tx_config.pkt_info_p[desc].pkt,
1086-
desc,
1087-
sys_dev_ctx->tx_config.pkt_info_p[desc].peer_id);
1088-
#ifdef NRF70_RAW_DATA_TX
1089-
} else {
1097+
if (nrf_wifi_osal_nbuf_is_raw_tx(first_nwb)) {
10901098
status = rawtx_cmd_init(fmac_dev_ctx,
10911099
sys_dev_ctx->tx_config.pkt_info_p[desc].pkt,
10921100
desc,
10931101
sys_dev_ctx->tx_config.pkt_info_p[desc].peer_id);
1094-
}
1102+
} else
10951103
#endif
1104+
{
1105+
status = tx_cmd_init(fmac_dev_ctx,
1106+
sys_dev_ctx->tx_config.pkt_info_p[desc].pkt,
1107+
desc,
1108+
sys_dev_ctx->tx_config.pkt_info_p[desc].peer_id);
1109+
}
10961110
} else {
10971111
tx_desc_free(fmac_dev_ctx,
10981112
desc,
@@ -1403,10 +1417,6 @@ static enum nrf_wifi_status tx_done_process(struct nrf_wifi_fmac_dev_ctx *fmac_d
14031417
}
14041418
#ifdef NRF70_RAW_DATA_TX
14051419
} else {
1406-
nrf_wifi_osal_mem_cpy(&sys_dev_ctx->raw_tx_config,
1407-
data,
1408-
sizeof(struct raw_tx_pkt_header));
1409-
14101420
/**
14111421
* check if the if_type is STA_TX_INJECTOR
14121422
* if so, we need to check for TWT_SLEEP.
@@ -1884,7 +1894,7 @@ enum nrf_wifi_status nrf_wifi_fmac_start_rawpkt_xmit(void *dev_ctx,
18841894
enum nrf_wifi_fmac_tx_status tx_status = NRF_WIFI_FMAC_TX_STATUS_FAIL;
18851895
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
18861896
struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1887-
void *nwb_data = NULL;
1897+
struct raw_tx_pkt_header *raw_tx_hdr = NULL;
18881898
int ac;
18891899
int peer_id;
18901900

@@ -1910,14 +1920,21 @@ enum nrf_wifi_status nrf_wifi_fmac_start_rawpkt_xmit(void *dev_ctx,
19101920
goto out;
19111921
}
19121922

1913-
nwb_data = nrf_wifi_osal_nbuf_data_get(nwb);
1914-
nrf_wifi_osal_mem_cpy(&sys_dev_ctx->raw_tx_config,
1915-
nwb_data,
1916-
sizeof(struct raw_tx_pkt_header));
1923+
raw_tx_hdr = nrf_wifi_osal_nbuf_set_raw_tx_hdr(nwb, sizeof(struct raw_tx_pkt_header));
1924+
if (!raw_tx_hdr) {
1925+
nrf_wifi_osal_log_err("%s: Failed to get raw tx header",
1926+
__func__);
1927+
goto fail;
1928+
}
19171929

1918-
sys_dev_ctx->raw_tx_config.raw_tx_flag = 1;
19191930
peer_id = MAX_PEERS;
1920-
ac = sys_dev_ctx->raw_tx_config.queue;
1931+
ac = raw_tx_hdr->queue;
1932+
if (ac >= NRF_WIFI_FMAC_AC_MAX) {
1933+
nrf_wifi_osal_log_err("%s: Invalid access category %d",
1934+
__func__,
1935+
ac);
1936+
goto fail;
1937+
}
19211938

19221939
tx_status = nrf_wifi_fmac_tx(fmac_dev_ctx,
19231940
if_idx,

os_if/inc/osal_api.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,40 @@ unsigned char nrf_wifi_osal_nbuf_get_chksum_done(void *nbuf);
621621
void nrf_wifi_osal_nbuf_set_chksum_done(void *nbuf,
622622
unsigned char chksum_done);
623623

624+
#if defined(CONFIG_NRF70_RAW_DATA_TX) || defined(__DOXYGEN__)
625+
/**
626+
* @brief Set the raw Tx header in a network buffer.
627+
* @param nbuf Pointer to a network buffer.
628+
* @param raw_hdr_len Length of the raw Tx header to be set.
629+
*
630+
* Sets the raw Tx header in a network buffer.
631+
*
632+
* * @return Pointer to the raw Tx header if successful, NULL otherwise.
633+
*/
634+
void *nrf_wifi_osal_nbuf_set_raw_tx_hdr(void *nbuf,
635+
unsigned short raw_hdr_len);
636+
637+
/**
638+
* @brief Get the raw Tx header from a network buffer.
639+
* @param nbuf Pointer to a network buffer.
640+
*
641+
* Gets the raw Tx header from a network buffer.
642+
*
643+
* @return Pointer to the raw Tx header if successful, NULL otherwise.
644+
*/
645+
void *nrf_wifi_osal_nbuf_get_raw_tx_hdr(void *nbuf);
646+
647+
/**
648+
* @brief Check if a network buffer is a raw Tx buffer.
649+
* @param nbuf Pointer to a network buffer.
650+
*
651+
* Checks if a network buffer is a raw Tx buffer.
652+
*
653+
* @return true if the network buffer is a raw Tx buffer, false otherwise.
654+
*/
655+
bool nrf_wifi_osal_nbuf_is_raw_tx(void *nbuf);
656+
#endif /* CONFIG_NRF70_RAW_DATA_TX || __DOXYGEN__ */
657+
624658
/**
625659
* @brief Allocate a tasklet.
626660
* @param type Type of tasklet.

os_if/inc/osal_ops.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,31 @@ struct nrf_wifi_osal_ops {
524524
* @param chksum_done The checksum status to set.
525525
*/
526526
void (*nbuf_set_chksum_done)(void *nbuf, unsigned char chksum_done);
527+
#if defined(NRF70_RAW_DATA_TX) || defined(__DOXYGEN__)
528+
/**
529+
* @brief Set the raw Tx header in a network buffer.
530+
*
531+
* @param nbuf A pointer to the network buffer.
532+
* @param raw_hdr_len The length of the raw header to set.
533+
*/
534+
void *(*nbuf_set_raw_tx_hdr)(void *nbuf, unsigned short raw_hdr_len);
535+
/**
536+
* @brief Get the raw Tx header from a network buffer.
537+
*
538+
* @param nbuf A pointer to the network buffer.
539+
* @return A pointer to the raw Tx header.
540+
*/
541+
void *(*nbuf_get_raw_tx_hdr)(void *nbuf);
527542

543+
/**
544+
* @brief Check if the network buffer is a raw Tx buffer.
545+
*
546+
* @param nbuf A pointer to the network buffer.
547+
*
548+
* @return true if it is a raw Tx buffer, false otherwise.
549+
*/
550+
bool (*nbuf_is_raw_tx)(void *nbuf);
551+
#endif /* NRF70_RAW_DATA_TX || __DOXYGEN__ */
528552
/**
529553
* @brief Allocate a tasklet structure.
530554
*

os_if/src/osal.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,25 @@ void nrf_wifi_osal_nbuf_set_chksum_done(void *nbuf,
416416
return os_ops->nbuf_set_chksum_done(nbuf, chksum_done);
417417
}
418418

419+
#ifdef CONFIG_NRF70_RAW_DATA_TX
420+
void *nrf_wifi_osal_nbuf_set_raw_tx_hdr(void *nbuf,
421+
unsigned short raw_hdr_len)
422+
{
423+
return os_ops->nbuf_set_raw_tx_hdr(nbuf,
424+
raw_hdr_len);
425+
}
426+
427+
void *nrf_wifi_osal_nbuf_get_raw_tx_hdr(void *nbuf)
428+
{
429+
return os_ops->nbuf_get_raw_tx_hdr(nbuf);
430+
}
431+
432+
bool nrf_wifi_osal_nbuf_is_raw_tx(void *nbuf)
433+
{
434+
return os_ops->nbuf_is_raw_tx(nbuf);
435+
}
436+
#endif /* CONFIG_NRF70_RAW_DATA_TX */
437+
419438

420439
void *nrf_wifi_osal_tasklet_alloc(int type)
421440
{

0 commit comments

Comments
 (0)