Skip to content

Commit 7f6ce42

Browse files
krish2718kapbh
authored andcommitted
[nrf fromtree] drivers: nrf_wifi: Implement TX zero-copy feature
This uses the network packet as is without the need for a copy all the way till the packet is handed over to RPU. Signed-off-by: Chaitanya Tata <[email protected]> (cherry picked from commit 5119f9c)
1 parent 6c26cf4 commit 7f6ce42

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

drivers/wifi/nrf_wifi/Kconfig.nrfwifi

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,4 +817,25 @@ config NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN
817817
help
818818
Enable this configuration to disable priority window for scan
819819
in the case of coexistence with Short Range radio.
820+
821+
if NETWORKING
822+
config NRF_WIFI_ZERO_COPY_TX
823+
bool "Zero copy Transmit path [EXPERIMENTAL]"
824+
select NET_L2_ETHERNET_RESERVE_HEADER
825+
select EXPERIMENTAL
826+
# 54L has lower RAM
827+
default y if SOC_SERIES_NRF54LX
828+
help
829+
Enable this configuration to use zero copy Transmit path.
830+
The driver will use the network buffer directly for transmission
831+
without copying the data to the driver's buffer. This reduces the
832+
driver heap memory usage without much impact on the performance.
833+
834+
The application should configure the network buffers to ensure that
835+
the whole packet fits in a single buffer, else the driver will fallback
836+
to the normal copy path, but the memory requirements would still match
837+
to the zero copy path and may be sub-optimal for the normal copy path.
838+
839+
endif # NETWORKING
840+
820841
endif # WIFI_NRF70

drivers/wifi/nrf_wifi/src/net_if.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,11 @@ int nrf_wifi_if_get_config_zep(const struct device *dev,
10011001
ETHERNET_CHECKSUM_SUPPORT_TCP |
10021002
ETHERNET_CHECKSUM_SUPPORT_UDP;
10031003
}
1004+
#endif
1005+
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
1006+
if (type == ETHERNET_CONFIG_TYPE_EXTRA_TX_PKT_HEADROOM) {
1007+
config->extra_tx_pkt_headroom = NRF_WIFI_EXTRA_TX_HEADROOM;
1008+
}
10041009
#endif
10051010
ret = 0;
10061011
unlock:

modules/nrf_wifi/os/shim.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ struct nwb {
268268
void (*cleanup_cb)();
269269
unsigned char priority;
270270
bool chksum_done;
271+
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
272+
struct net_pkt *pkt;
273+
#endif
271274
};
272275

273276
static void *zep_shim_nbuf_alloc(unsigned int size)
@@ -301,6 +304,12 @@ static void zep_shim_nbuf_free(void *nbuf)
301304
if (!nbuf) {
302305
return;
303306
}
307+
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
308+
if (((struct nwb *)nbuf)->pkt) {
309+
net_pkt_unref(((struct nwb *)nbuf)->pkt);
310+
((struct nwb *)nbuf)->pkt = NULL;
311+
}
312+
#endif /* CONFIG_NRF_WIFI_ZERO_COPY_TX */
304313

305314
zep_shim_data_mem_free(((struct nwb *)nbuf)->priv);
306315
zep_shim_data_mem_free(nbuf);
@@ -387,12 +396,62 @@ static void zep_shim_nbuf_set_chksum_done(void *nbuf, unsigned char chksum_done)
387396
#include <zephyr/net/ethernet.h>
388397
#include <zephyr/net/net_core.h>
389398

399+
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
400+
void *net_pkt_to_nbuf_zc(struct net_pkt *pkt)
401+
{
402+
struct nwb *nbuff;
403+
404+
if (!pkt || !pkt->buffer) {
405+
LOG_DBG("Invalid packet, dropping");
406+
return NULL;
407+
}
408+
409+
/* Check if packet has more than one fragment */
410+
if (pkt->buffer->frags) {
411+
LOG_ERR("Zero-copy only supports single buffer packets");
412+
return NULL;
413+
}
414+
415+
nbuff = zep_shim_nbuf_alloc(NRF_WIFI_EXTRA_TX_HEADROOM); /* Just for headers */
416+
if (!nbuff) {
417+
return NULL;
418+
}
419+
420+
zep_shim_nbuf_headroom_res(nbuff, NRF_WIFI_EXTRA_TX_HEADROOM);
421+
422+
/* Zero-copy: point to the single data buffer */
423+
/* TODO: Use API for proper cursor access? */
424+
nbuff->data = pkt->buffer->data;
425+
nbuff->len = pkt->buffer->len;
426+
427+
nbuff->priority = net_pkt_priority(pkt);
428+
nbuff->chksum_done = (bool)net_pkt_is_chksum_done(pkt);
429+
430+
nbuff->pkt = pkt;
431+
/* Ref the packet so that it is not freed */
432+
net_pkt_ref(pkt);
433+
434+
return nbuff;
435+
}
436+
#endif /* CONFIG_NRF_WIFI_ZERO_COPY_TX */
437+
390438
void *net_pkt_to_nbuf(struct net_pkt *pkt)
391439
{
392440
struct nwb *nbuff;
393441
unsigned char *data;
394442
unsigned int len;
395443

444+
if (!pkt) {
445+
return NULL;
446+
}
447+
448+
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
449+
/* For zero-copy, check if packet has single buffer */
450+
if (pkt->buffer && !pkt->buffer->frags) {
451+
return net_pkt_to_nbuf_zc(pkt);
452+
}
453+
#endif /* CONFIG_NRF_WIFI_ZERO_COPY_TX */
454+
396455
len = net_pkt_get_len(pkt);
397456

398457
nbuff = zep_shim_nbuf_alloc(len + 100);

modules/nrf_wifi/os/shim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <zephyr/drivers/gpio.h>
1717
#include <zephyr/net/net_pkt.h>
1818

19+
#define NRF_WIFI_EXTRA_TX_HEADROOM 100
20+
1921
/**
2022
* struct zep_shim_bus_qspi_priv - Structure to hold context information for the Linux OS
2123
* shim.

0 commit comments

Comments
 (0)