From 683a56db90a57844fef7ebd6bf951d3c6abc9d34 Mon Sep 17 00:00:00 2001 From: Vivekananda Uppunda Date: Tue, 8 Oct 2024 09:53:04 +0530 Subject: [PATCH 1/2] nrf_wifi: Add promiscuous mode support functions and structures The changes introduces support functions and structures for promiscuous mode operation. Signed-off-by: Vivekananda Uppunda --- .../nrf_wifi/fw_if/umac_if/inc/fmac_promisc.h | 42 ++++++++++ .../nrf_wifi/fw_if/umac_if/src/fmac_promisc.c | 80 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 drivers/nrf_wifi/fw_if/umac_if/inc/fmac_promisc.h create mode 100644 drivers/nrf_wifi/fw_if/umac_if/src/fmac_promisc.c diff --git a/drivers/nrf_wifi/fw_if/umac_if/inc/fmac_promisc.h b/drivers/nrf_wifi/fw_if/umac_if/inc/fmac_promisc.h new file mode 100644 index 00000000..210862a5 --- /dev/null +++ b/drivers/nrf_wifi/fw_if/umac_if/inc/fmac_promisc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing code to support promiscuous mode + * for the FMAC IF Layer of the Wi-Fi driver. + */ +#ifndef __FMAC_PROMISC_H__ +#define __FMAC_PROMISC_H__ +#include "fmac_structs.h" +#include "pack_def.h" + +enum nrf_wifi_fmac_frame_type { + /** 802.11 management packet type */ + NRF_WIFI_MGMT_PKT_TYPE = 0x0, + /** 802.11 control packet type */ + NRF_WIFI_CTRL_PKT_TYPE, + /** 802.11 data packet type */ + NRF_WIFI_DATA_PKT_TYPE, +}; + +/* Frame Control structure */ +struct nrf_wifi_fmac_frame_ctrl { + unsigned short protocolVersion : 2; + unsigned short type : 2; + unsigned short subtype : 4; + unsigned short toDS : 1; + unsigned short fromDS : 1; + unsigned short moreFragments : 1; + unsigned short retry : 1; + unsigned short powerManagement : 1; + unsigned short moreData : 1; + unsigned short protectedFrame : 1; + unsigned short order : 1; +} __NRF_WIFI_PKD; + +bool nrf_wifi_util_check_filt_setting(struct nrf_wifi_fmac_vif_ctx *vif, + unsigned short *frame_control); +#endif /* __FMAC_PROMISC_H__ */ diff --git a/drivers/nrf_wifi/fw_if/umac_if/src/fmac_promisc.c b/drivers/nrf_wifi/fw_if/umac_if/src/fmac_promisc.c new file mode 100644 index 00000000..7deb81ba --- /dev/null +++ b/drivers/nrf_wifi/fw_if/umac_if/src/fmac_promisc.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing promiscuous mode + * support functions for the FMAC IF Layer + * of the Wi-Fi driver. + */ + +#include "osal_api.h" +#include "fmac_structs.h" +#include "fmac_promisc.h" + +bool nrf_wifi_util_check_filt_setting(struct nrf_wifi_fmac_vif_ctx *vif, + unsigned short *frame_control) +{ + bool filter_check = false; + struct nrf_wifi_fmac_frame_ctrl *frm_ctrl = + (struct nrf_wifi_fmac_frame_ctrl *)frame_control; + + /** + * The different filter settings for 802.11 packets within the driver + * is a bit map. The description of the different valid values for + * the case statements are as follows: + * 0x2 - Enable management packets only + * 0x4 - Enable data packets only + * 0x8 - Enable control packets only + * 0x6 - Enable data and management packets + * 0xa - Enable control and management packets + * 0xc - Enable data and control packets + * The bit map setting is checked against the packet type field and + * the relevant filtered packet is sent up the stack. if bit 0 is set + * in the driver bitmap, all packet types are allowed to be sent upstack. + **/ + switch (vif->packet_filter) { + case 0x2: + if (frm_ctrl->type == NRF_WIFI_MGMT_PKT_TYPE) { + filter_check = true; + } + break; + case 0x4: + if (frm_ctrl->type == NRF_WIFI_DATA_PKT_TYPE) { + filter_check = true; + } + break; + case 0x6: + if ((frm_ctrl->type == NRF_WIFI_DATA_PKT_TYPE) || + (frm_ctrl->type == NRF_WIFI_MGMT_PKT_TYPE)) { + filter_check = true; + } + break; + case 0x8: + if (frm_ctrl->type == NRF_WIFI_CTRL_PKT_TYPE) { + filter_check = true; + } + break; + case 0xa: + if ((frm_ctrl->type == NRF_WIFI_CTRL_PKT_TYPE) || + (frm_ctrl->type == NRF_WIFI_MGMT_PKT_TYPE)) { + filter_check = true; + } + break; + case 0xc: + if ((frm_ctrl->type == NRF_WIFI_DATA_PKT_TYPE) || + (frm_ctrl->type == NRF_WIFI_CTRL_PKT_TYPE)) { + filter_check = true; + } + break; + /* all other packet_filter cases - bit 0 is set and hence all + * packet types are allowed or in the case of 0xE - all packet + * type bits are enabled */ + default: + filter_check = true; + break; + } + return filter_check; +} From ac5562f5501db00e8446a5fb59a0d02cb9fde44d Mon Sep 17 00:00:00 2001 From: Vivekananda Uppunda Date: Mon, 7 Oct 2024 09:08:50 +0530 Subject: [PATCH 2/2] nrf_wifi: Bring in Promiscuous mode filtering support in driver This set of changes brings in promiscuous mode filtering support in the driver. Since, firmware would be unable to filter packets in the case of promiscuous mode as it would lead to connection issues, filtering support is moved to the driver for promiscuous mode. Signed-off-by: Vivekananda Uppunda --- .../fw_if/umac_if/inc/default/fmac_structs.h | 8 ++-- drivers/nrf_wifi/fw_if/umac_if/src/rx.c | 47 ++++++++++++++----- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/drivers/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h b/drivers/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h index c58d7b84..e1f565c5 100644 --- a/drivers/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h +++ b/drivers/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h @@ -270,10 +270,10 @@ struct nrf_wifi_fmac_callbk_fns { signed short signal); #endif /* NRF70_STA_MODE */ #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX) - void (*rx_sniffer_frm_callbk_fn)(void *os_vif_ctx, - void *frm, - struct raw_rx_pkt_header *, - bool pkt_free); + void (*sniffer_callbk_fn)(void *os_vif_ctx, + void *frm, + struct raw_rx_pkt_header *, + bool pkt_free); #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */ void (*reg_change_callbk_fn)(void *os_vif_ctx, struct nrf_wifi_event_regulatory_change *reg_change, diff --git a/drivers/nrf_wifi/fw_if/umac_if/src/rx.c b/drivers/nrf_wifi/fw_if/umac_if/src/rx.c index f7f1325c..50ddbbe7 100644 --- a/drivers/nrf_wifi/fw_if/umac_if/src/rx.c +++ b/drivers/nrf_wifi/fw_if/umac_if/src/rx.c @@ -12,7 +12,7 @@ #include "hal_api.h" #include "fmac_rx.h" #include "fmac_util.h" - +#include "fmac_promisc.h" static enum nrf_wifi_status nrf_wifi_fmac_map_desc_to_pool(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, @@ -211,6 +211,9 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx struct nrf_wifi_fmac_rx_pool_map_info pool_info; #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX) struct raw_rx_pkt_header raw_rx_hdr; +#if defined(NRF70_PROMISC_DATA_RX) + unsigned short frame_control; +#endif #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */ void *nwb = NULL; void *nwb_data = NULL; @@ -282,6 +285,12 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx rx_buf_info->nwb = 0; rx_buf_info->mapped = false; +#ifdef NRF70_PROMISC_DATA_RX + nrf_wifi_osal_mem_cpy(&frame_control, + nwb_data, + sizeof(unsigned short)); +#endif + if (config->rx_pkt_type == NRF_WIFI_RX_PKT_DATA) { #ifdef NRF70_PROMISC_DATA_RX if (vif_ctx->promisc_mode) { @@ -289,11 +298,12 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx raw_rx_hdr.signal = config->signal; raw_rx_hdr.rate_flags = config->rate_flags; raw_rx_hdr.rate = config->rate; - - def_priv->callbk_fns.rx_sniffer_frm_callbk_fn(vif_ctx->os_vif_ctx, - nwb, - &raw_rx_hdr, - false); + if (nrf_wifi_util_check_filt_setting(vif_ctx, &frame_control)) { + def_priv->callbk_fns.sniffer_callbk_fn(vif_ctx->os_vif_ctx, + nwb, + &raw_rx_hdr, + false); + } } #endif #ifdef NRF70_STA_MODE @@ -356,11 +366,26 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx raw_rx_hdr.signal = config->signal; raw_rx_hdr.rate_flags = config->rate_flags; raw_rx_hdr.rate = config->rate; - - def_priv->callbk_fns.rx_sniffer_frm_callbk_fn(vif_ctx->os_vif_ctx, - nwb, - &raw_rx_hdr, - true); +#if defined(NRF70_PROMISC_DATA_RX) + if (nrf_wifi_util_check_filt_setting(vif_ctx, &frame_control)) +#endif + { + def_priv->callbk_fns.sniffer_callbk_fn(vif_ctx->os_vif_ctx, + nwb, + &raw_rx_hdr, + true); + } +#if defined(NRF70_PROMISC_DATA_RX) + /** + * In the case of Monitor mode, the sniffer callback function + * will free the packet. For promiscuous mode, if the packet + * is not meant to be sent up the stack, the packet needs + * to be freed here. + */ + else { + nrf_wifi_osal_nbuf_free(nwb); + } +#endif } #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */ else {