diff --git a/src/drivers/driver_zephyr.c b/src/drivers/driver_zephyr.c index 882561f49a..540bc8c19a 100644 --- a/src/drivers/driver_zephyr.c +++ b/src/drivers/driver_zephyr.c @@ -2519,6 +2519,7 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d #ifdef CONFIG_WIFI_NM_HOSTAPD_AP struct zep_drv_if_ctx *if_ctx = priv; struct hostapd_data *hapd = NULL; + const struct zep_wpa_supp_dev_ops *dev_ops = NULL; int ret = -1; /* TODO: Unused for now, but might need for rekeying */ @@ -2532,6 +2533,19 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d wpa_printf(MSG_DEBUG, "hostapd: Send EAPOL frame (encrypt=%d)", encrypt); + /* Try to use driver operation for high-priority transmission */ + dev_ops = get_dev_ops(if_ctx->dev_ctx); +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT + if (dev_ops && dev_ops->send_l2_packet) { + ret = dev_ops->send_l2_packet(if_ctx->dev_priv, addr, ETH_P_EAPOL, data, data_len); + if (ret >= 0) { + return ret; + } + wpa_printf(MSG_DEBUG, "Driver L2 transmission failed, falling back to socket"); + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */ + + /* Fallback to socket-based transmission */ ret = l2_packet_send(hapd->l2, addr, ETH_P_EAPOL, data, data_len); if (ret < 0) { wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret); @@ -2539,7 +2553,7 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d } #else struct zep_drv_if_ctx *if_ctx = priv; - const struct zep_wpa_supp_dev_ops *dev_ops; + const struct zep_wpa_supp_dev_ops *dev_ops = NULL; int ret = -1; struct wpa_supplicant *wpa_s = NULL; @@ -2549,10 +2563,22 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d (void)encrypt; wpa_s = if_ctx->supp_if_ctx; - dev_ops = if_ctx->dev_ctx->config; + dev_ops = get_dev_ops(if_ctx->dev_ctx); wpa_printf(MSG_DEBUG, "wpa_supp: Send EAPOL frame (encrypt=%d)", encrypt); + /* Try to use driver operation for high-priority transmission */ + if (dev_ops && dev_ops->send_l2_packet) { +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT + ret = dev_ops->send_l2_packet(if_ctx->dev_priv, addr, ETH_P_EAPOL, data, data_len); + if (ret >= 0) { + return ret; + } + wpa_printf(MSG_DEBUG, "Driver L2 transmission failed, falling back to socket"); +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */ + } + + /* Fallback to socket-based transmission */ ret = l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data, data_len); if (ret < 0) { wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret); diff --git a/src/drivers/driver_zephyr.h b/src/drivers/driver_zephyr.h index 102d6a8cb5..45f2dd4144 100644 --- a/src/drivers/driver_zephyr.h +++ b/src/drivers/driver_zephyr.h @@ -351,6 +351,15 @@ struct zep_wpa_supp_dev_ops { int (*cancel_remain_on_channel)(void *priv); int (*get_inact_sec)(void *if_priv, const u8 *addr); void (*send_action_cancel_wait)(void *priv); + +#ifdef CONFIG_NRF70_L2_PACKET + /* L2 packet transmission with high priority (VO) */ + int (*send_l2_packet)(void *if_priv, const u8 *dst_addr, u16 proto, + const u8 *data, size_t data_len); +#endif }; +/* Function to get driver operations from device */ +const struct zep_wpa_supp_dev_ops *get_dev_ops(const struct device *dev); + #endif /* DRIVER_ZEPHYR_H */ diff --git a/src/l2_packet/l2_packet_zephyr.c b/src/l2_packet/l2_packet_zephyr.c index 3a20428b08..eb571fe63e 100644 --- a/src/l2_packet/l2_packet_zephyr.c +++ b/src/l2_packet/l2_packet_zephyr.c @@ -11,12 +11,14 @@ #include #include #include +#include #include "includes.h" #include "common.h" #include "eloop.h" #include "l2_packet.h" #include "common/eapol_common.h" +#include "drivers/driver_zephyr.h" struct l2_packet_data { char ifname[17]; @@ -30,6 +32,7 @@ struct l2_packet_data { * buffers */ int fd; unsigned short protocol; + void *dev_priv; /* Device private data for driver operations */ }; int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) @@ -41,35 +44,63 @@ int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, const u8 *buf, size_t len) { - int ret; + int ret = -1; + const struct device *device = NULL; + const struct zep_wpa_supp_dev_ops *dev_ops = NULL; if (l2 == NULL) { return -1; } + /* Get the device from the interface */ + device = net_if_get_device(l2->iface); + if (!device) { + wpa_printf(MSG_ERROR, "l2_packet_send: Failed to get device"); + return -1; + } + + /* Get driver operations */ + dev_ops = get_dev_ops(device); + if (!dev_ops) { + wpa_printf(MSG_ERROR, "l2_packet_send: Failed to get driver ops"); + return -1; + } + +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT + /* Try to use driver operation for high-priority transmission */ + if (dev_ops && dev_ops->send_l2_packet) { + ret = dev_ops->send_l2_packet(l2->dev_priv, dst_addr, proto, buf, len); + if (ret >= 0) { + wpa_printf(MSG_DEBUG, "l2_packet_send: Used high-priority driver transmission"); + return ret; + } + wpa_printf(MSG_DEBUG, "l2_packet_send: Driver L2 transmission failed, falling back to socket"); + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */ + + /* Fallback to socket-based transmission */ if (l2->l2_hdr) { ret = send(l2->fd, buf, len, 0); if (ret < 0) { - wpa_printf(MSG_ERROR, "l2_packet_send - send: %s", - strerror(errno)); + wpa_printf(MSG_ERROR, "l2_packet_send: send failed: %d", ret); } } else { struct sockaddr_ll ll; - os_memset(&ll, 0, sizeof(ll)); + memset(&ll, 0, sizeof(ll)); ll.sll_family = AF_PACKET; - ll.sll_ifindex = l2->ifindex; ll.sll_protocol = htons(proto); + ll.sll_ifindex = l2->ifindex; ll.sll_halen = ETH_ALEN; - os_memcpy(ll.sll_addr, dst_addr, ETH_ALEN); - // TODO: This takes up too much stack, call wifi driver TX directly? + memcpy(ll.sll_addr, dst_addr, ETH_ALEN); + ret = sendto(l2->fd, buf, len, 0, (struct sockaddr *) &ll, sizeof(ll)); if (ret < 0) { - wpa_printf(MSG_ERROR, "l2_packet_send - sendto: %s", - strerror(errno)); + wpa_printf(MSG_ERROR, "l2_packet_send: sendto failed: %d", ret); } } + return ret; } @@ -114,6 +145,8 @@ l2_packet_init(const char *ifname, const u8 *own_addr, unsigned short protocol, int ret = 0; struct net_linkaddr *link_addr = NULL; struct net_if *iface; + const struct device *device = NULL; + const struct zep_wpa_supp_dev_ops *dev_ops = NULL; iface = net_if_get_by_index(net_if_get_by_name(ifname)); if (!iface) { @@ -143,6 +176,21 @@ l2_packet_init(const char *ifname, const u8 *own_addr, unsigned short protocol, link_addr = &iface->if_dev->link_addr; os_memcpy(l2->own_addr, link_addr->addr, link_addr->len); + /* Get device and driver operations for high-priority transmission */ + device = net_if_get_device(l2->iface); + if (device) { + dev_ops = get_dev_ops(device); +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT + if (dev_ops && dev_ops->send_l2_packet) { + /* Get device private data from the interface context */ + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = device->data; + if (vif_ctx_zep) { + l2->dev_priv = vif_ctx_zep; + } + } +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */ + } + l2->fd = socket(AF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM, htons(protocol)); if (l2->fd < 0) {