Commit 5119f9c3 authored by Chaitanya Tata's avatar Chaitanya Tata Committed by Benjamin Cabé
Browse files

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: default avatarChaitanya Tata <Chaitanya.Tata@nordicsemi.no>
parent 5cbae7f2
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -828,4 +828,25 @@ config NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN
	help
	  Enable this configuration to disable priority window for scan
	  in the case of coexistence with Short Range radio.

if NETWORKING
config NRF_WIFI_ZERO_COPY_TX
	bool "Zero copy Transmit path [EXPERIMENTAL]"
	select NET_L2_ETHERNET_RESERVE_HEADER
	select EXPERIMENTAL
	# 54L has lower RAM
	default y if SOC_SERIES_NRF54LX
	help
	  Enable this configuration to use zero copy Transmit path.
	  The driver will use the network buffer directly for transmission
	  without copying the data to the driver's buffer. This reduces the
	  driver heap memory usage without much impact on the performance.

	  The application should configure the network buffers to ensure that
	  the whole packet fits in a single buffer, else the driver will fallback
	  to the normal copy path, but the memory requirements would still match
	  to the zero copy path and may be sub-optimal for the normal copy path.

endif # NETWORKING

endif # WIFI_NRF70
+5 −0
Original line number Diff line number Diff line
@@ -1002,6 +1002,11 @@ int nrf_wifi_if_get_config_zep(const struct device *dev,
					 ETHERNET_CHECKSUM_SUPPORT_TCP |
					 ETHERNET_CHECKSUM_SUPPORT_UDP;
	}
#endif
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
	if (type == ETHERNET_CONFIG_TYPE_EXTRA_TX_PKT_HEADROOM) {
		config->extra_tx_pkt_headroom = NRF_WIFI_EXTRA_TX_HEADROOM;
	}
#endif
	ret = 0;
unlock:
+59 −0
Original line number Diff line number Diff line
@@ -268,6 +268,9 @@ struct nwb {
	void (*cleanup_cb)();
	unsigned char priority;
	bool chksum_done;
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
	struct net_pkt *pkt;
#endif
};

static void *zep_shim_nbuf_alloc(unsigned int size)
@@ -301,6 +304,12 @@ static void zep_shim_nbuf_free(void *nbuf)
	if (!nbuf) {
		return;
	}
#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
	if (((struct nwb *)nbuf)->pkt) {
		net_pkt_unref(((struct nwb *)nbuf)->pkt);
		((struct nwb *)nbuf)->pkt = NULL;
	}
#endif /* CONFIG_NRF_WIFI_ZERO_COPY_TX */

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

#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
void *net_pkt_to_nbuf_zc(struct net_pkt *pkt)
{
	struct nwb *nbuff;

	if (!pkt || !pkt->buffer) {
		LOG_DBG("Invalid packet, dropping");
		return NULL;
	}

	/* Check if packet has more than one fragment */
	if (pkt->buffer->frags) {
		LOG_ERR("Zero-copy only supports single buffer packets");
		return NULL;
	}

	nbuff = zep_shim_nbuf_alloc(NRF_WIFI_EXTRA_TX_HEADROOM); /* Just for headers */
	if (!nbuff) {
		return NULL;
	}

	zep_shim_nbuf_headroom_res(nbuff, NRF_WIFI_EXTRA_TX_HEADROOM);

	/* Zero-copy: point to the single data buffer */
	/* TODO: Use API for proper cursor access? */
	nbuff->data = pkt->buffer->data;
	nbuff->len = pkt->buffer->len;

	nbuff->priority = net_pkt_priority(pkt);
	nbuff->chksum_done = (bool)net_pkt_is_chksum_done(pkt);

	nbuff->pkt = pkt;
	/* Ref the packet so that it is not freed */
	net_pkt_ref(pkt);

	return nbuff;
}
#endif /* CONFIG_NRF_WIFI_ZERO_COPY_TX */

void *net_pkt_to_nbuf(struct net_pkt *pkt)
{
	struct nwb *nbuff;
	unsigned char *data;
	unsigned int len;

	if (!pkt) {
		return NULL;
	}

#ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX
	/* For zero-copy, check if packet has single buffer */
	if (pkt->buffer && !pkt->buffer->frags) {
		return net_pkt_to_nbuf_zc(pkt);
	}
#endif /* CONFIG_NRF_WIFI_ZERO_COPY_TX */

	len = net_pkt_get_len(pkt);

	nbuff = zep_shim_nbuf_alloc(len + 100);
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include <zephyr/drivers/gpio.h>
#include <zephyr/net/net_pkt.h>

#define NRF_WIFI_EXTRA_TX_HEADROOM 100

/**
 * struct zep_shim_bus_qspi_priv - Structure to hold context information for the Linux OS
 *                        shim.