diff --git a/dp/inc/cdp_txrx_mon.h b/dp/inc/cdp_txrx_mon.h index 7a8753d908..1e0dbaa7d7 100644 --- a/dp/inc/cdp_txrx_mon.h +++ b/dp/inc/cdp_txrx_mon.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -68,4 +69,153 @@ cdp_deliver_tx_mgmt(ol_txrx_soc_handle soc, uint8_t pdev_id, return soc->ops->mon_ops->txrx_deliver_tx_mgmt(soc, pdev_id, nbuf); } +#ifdef QCA_SUPPORT_LITE_MONITOR +/* + * cdp_set_lite_mon_config() - Set lite monitor config/filter + * + *@soc: dp soc handle + *@config: lite monitor config + *@pdev_id: pdev id + * + * This API is used to enable/disable lite monitor feature + * + * Return: QDF_STATUS_SUCCESS if value set successfully + * QDF_STATUS_E_INVAL false if error + */ +static inline QDF_STATUS +cdp_set_lite_mon_config(ol_txrx_soc_handle soc, + struct cdp_lite_mon_filter_config *config, + uint8_t pdev_id) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + return QDF_STATUS_E_INVAL; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_set_lite_mon_config) + return QDF_STATUS_E_INVAL; + + return soc->ops->mon_ops->txrx_set_lite_mon_config(soc, config, + pdev_id); +} + +/* + * cdp_get_lite_mon_config() - Get lite monitor config + * + *@soc: dp soc handle + *@config: lite monitor config + *@pdev_id: pdev id + * + * This API is used to get lite monitor feature config + * + * Return: QDF_STATUS_SUCCESS if get is successfully + * QDF_STATUS_E_INVAL false if error + */ +static inline QDF_STATUS +cdp_get_lite_mon_config(ol_txrx_soc_handle soc, + struct cdp_lite_mon_filter_config *config, + uint8_t pdev_id) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + return QDF_STATUS_E_INVAL; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_get_lite_mon_config) + return QDF_STATUS_E_INVAL; + + return soc->ops->mon_ops->txrx_get_lite_mon_config(soc, config, + pdev_id); +} + +/* + * cdp_set_lite_mon_peer_config() - Set lite monitor peer config + * + *@soc: dp soc handle + *@config: lite monitor peer config + *@pdev_id: pdev id + * + * This API is used to add/del lite monitor peers + * + * Return: QDF_STATUS_SUCCESS if value set successfully + * QDF_STATUS_E_INVAL false if error + */ +static inline QDF_STATUS +cdp_set_lite_mon_peer_config(ol_txrx_soc_handle soc, + struct cdp_lite_mon_peer_config *config, + uint8_t pdev_id) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + return QDF_STATUS_E_INVAL; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_set_lite_mon_peer_config) + return QDF_STATUS_E_INVAL; + + return soc->ops->mon_ops->txrx_set_lite_mon_peer_config(soc, config, + pdev_id); +} + +/* + * cdp_get_lite_mon_peer_config() - Get lite monitor peer list + * + *@soc: dp soc handle + *@info: lite monitor peer info + *@pdev_id: pdev id + * + * This API is used to get lite monitor peers + * + * Return: QDF_STATUS_SUCCESS if value set successfully + * QDF_STATUS_E_INVAL false if error + */ +static inline QDF_STATUS +cdp_get_lite_mon_peer_config(ol_txrx_soc_handle soc, + struct cdp_lite_mon_peer_info *info, + uint8_t pdev_id) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + return QDF_STATUS_E_INVAL; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_get_lite_mon_peer_config) + return QDF_STATUS_E_INVAL; + + return soc->ops->mon_ops->txrx_get_lite_mon_peer_config(soc, info, + pdev_id); +} + +/* + * cdp_is_lite_mon_enabled() - Get lite monitor enable status + * + *@soc: dp soc handle + *@pdev_id: pdev id + *@dir: direction tx/rx + * + * This API is used to get lite monitor enable status + * + * Return: 0 if disabled + * 1 if enabled + */ +static inline int +cdp_is_lite_mon_enabled(ol_txrx_soc_handle soc, + uint8_t pdev_id, uint8_t dir) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance"); + return 0; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_is_lite_mon_enabled) + return 0; + + return soc->ops->mon_ops->txrx_is_lite_mon_enabled(soc, pdev_id, dir); +} +#endif #endif diff --git a/dp/inc/cdp_txrx_mon_struct.h b/dp/inc/cdp_txrx_mon_struct.h index 9f0d0f4d20..14cdec6502 100644 --- a/dp/inc/cdp_txrx_mon_struct.h +++ b/dp/inc/cdp_txrx_mon_struct.h @@ -25,6 +25,35 @@ #ifndef _CDP_TXRX_MON_STRUCT_H_ #define _CDP_TXRX_MON_STRUCT_H_ + +#ifdef QCA_SUPPORT_LITE_MONITOR +#define CDP_LITE_MON_MODE_MAX 3 +#define CDP_LITE_MON_FRM_TYPE_MAX 3 +#define CDP_LITE_MON_PEER_MAX 16 + +/* lite mon peer action */ +enum cdp_lite_mon_peer_action { + CDP_LITE_MON_PEER_ADD = 0, + CDP_LITE_MON_PEER_REMOVE = 1, +}; + +/* lite mon peer types */ +enum cdp_lite_mon_peer_type { + CDP_LITE_MON_PEER_TYPE_ASSOCIATED = 0, + CDP_LITE_MON_PEER_TYPE_NON_ASSOCIATED = 1, + CDP_LITE_MON_PEER_TYPE_MAX = 2, +}; + +/* lite mon config direction */ +enum cdp_lite_mon_direction { + CDP_LITE_MON_DIRECTION_RX = 1, + CDP_LITE_MON_DIRECTION_TX = 2, +}; + +/* This should align with nac mac type enumerations in ieee80211_ioctl.h */ +#define CDP_LITE_MON_PEER_MAC_TYPE_CLIENT 2 +#endif + /* XXX not really a mode; there are really multiple PHY's */ enum cdp_mon_phymode { /* autoselect */ @@ -354,4 +383,62 @@ struct cdp_pdev_mon_stats { uint32_t rx_undecoded_error[CDP_PHYRX_ERR_MAX]; #endif }; + +#ifdef QCA_SUPPORT_LITE_MONITOR +/** + * cdp_lite_mon_filter_config - lite mon set/get filter config + * @direction: direction tx/rx + * @disable: disables lite mon + * @level: MSDU/MPDU/PPDU levels + * @metadata: meta information to be added + * @mgmt_filter: mgmt filter for modes fp,md,mo + * @ctrl_filter: ctrl filter for modes fp,md,mo + * @data_filter: data filter for modes fp,md,mo + * @len: mgmt/ctrl/data frame lens + * @debug: debug options + * @vdev_id: output vdev id + */ +struct cdp_lite_mon_filter_config { + uint8_t direction; + uint8_t disable; + uint8_t level; + uint8_t metadata; + uint16_t mgmt_filter[CDP_LITE_MON_MODE_MAX]; + uint16_t ctrl_filter[CDP_LITE_MON_MODE_MAX]; + uint16_t data_filter[CDP_LITE_MON_MODE_MAX]; + uint16_t len[CDP_LITE_MON_FRM_TYPE_MAX]; + uint8_t debug; + uint8_t vdev_id; +}; + +/** + * cdp_lite_mon_peer_config - lite mon set peer config + * @direction: direction tx/rx + * @action: add/del + * @type: assoc/non-assoc + * @vdev_id: peer vdev id + * @mac: peer mac + */ +struct cdp_lite_mon_peer_config { + uint8_t direction; + uint8_t action; + uint8_t type; + uint8_t vdev_id; + uint8_t mac[QDF_MAC_ADDR_SIZE]; +}; + +/** + * cdp_lite_mon_peer_info - lite mon get peer config + * @direction: direction tx/rx + * @type: assoc/non-assoc + * @count: no of peers + * @mac: peer macs + */ +struct cdp_lite_mon_peer_info { + uint8_t direction; + uint8_t type; + uint8_t count; + uint8_t mac[CDP_LITE_MON_PEER_MAX][QDF_MAC_ADDR_SIZE]; +}; +#endif #endif diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index c36548dfaf..3d7e11d218 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -930,6 +930,42 @@ struct cdp_mon_ops { void (*txrx_enable_mon_reap_timer)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool enable); + +#ifdef QCA_SUPPORT_LITE_MONITOR + /* set lite monitor config */ + QDF_STATUS + (*txrx_set_lite_mon_config)( + struct cdp_soc_t *soc, + struct cdp_lite_mon_filter_config *mon_config, + uint8_t pdev_id); + + /* get lite monitor config */ + QDF_STATUS + (*txrx_get_lite_mon_config)( + struct cdp_soc_t *soc, + struct cdp_lite_mon_filter_config *mon_config, + uint8_t pdev_id); + + /* set lite monitor peer config */ + QDF_STATUS + (*txrx_set_lite_mon_peer_config)( + struct cdp_soc_t *soc, + struct cdp_lite_mon_peer_config *peer_config, + uint8_t pdev_id); + + /* get lite monitor peer list */ + QDF_STATUS + (*txrx_get_lite_mon_peer_config)( + struct cdp_soc_t *soc, + struct cdp_lite_mon_peer_info *info, + uint8_t pdev_id); + + /* get lite monitor enable/disable status */ + int + (*txrx_is_lite_mon_enabled)(struct cdp_soc_t *soc, + uint8_t pdev_id, + uint8_t direction); +#endif }; struct cdp_host_stats_ops { @@ -1344,6 +1380,13 @@ struct ol_if_ops { uint32_t module_id, uint32_t arg_count, uint32_t *arg); +#ifdef QCA_SUPPORT_LITE_MONITOR + int (*config_lite_mon_peer)(struct cdp_ctrl_objmgr_psoc *psoc, + uint8_t pdev_id, + uint8_t vdev_id, + enum cdp_nac_param_cmd cmd, + uint8_t *peer_mac); +#endif }; #ifdef DP_PEER_EXTENDED_API diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 7e0b4d3b2c..dc3d5185c5 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -706,6 +706,8 @@ enum WDI_EVENT { #ifdef QCA_UNDECODED_METADATA_SUPPORT WDI_EVENT_RX_PPDU_DESC_UNDECODED_METADATA, #endif + WDI_EVENT_LITE_MON_RX, + WDI_EVENT_LITE_MON_TX, /* End of new event items */ WDI_EVENT_LAST }; diff --git a/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c b/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c index b2adf2ff20..8a60c0660e 100644 --- a/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c @@ -1211,6 +1211,9 @@ struct dp_mon_ops monitor_ops_1_0 = { .mon_tx_ppdu_stats_detach = NULL, .mon_peer_tx_capture_filter_check = NULL, #endif + .mon_lite_mon_alloc = NULL, + .mon_lite_mon_dealloc = NULL, + .mon_lite_mon_vdev_delete = NULL, }; struct cdp_mon_ops dp_ops_mon_1_0 = { @@ -1222,6 +1225,13 @@ struct cdp_mon_ops dp_ops_mon_1_0 = { .soc_config_full_mon_mode = dp_soc_config_full_mon_mode, .get_mon_pdev_rx_stats = dp_pdev_get_rx_mon_stats, .txrx_enable_mon_reap_timer = dp_enable_mon_reap_timer, +#ifdef QCA_SUPPORT_LITE_MONITOR + .txrx_set_lite_mon_config = NULL, + .txrx_get_lite_mon_config = NULL, + .txrx_set_lite_mon_peer_config = NULL, + .txrx_get_lite_mon_peer_config = NULL, + .txrx_is_lite_mon_enabled = NULL, +#endif }; #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c index 7505e73efa..8b16fae038 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c @@ -29,6 +29,9 @@ #include #include #include +#ifdef QCA_SUPPORT_LITE_MONITOR +#include "dp_lite_mon.h" +#endif #if !defined(DISABLE_MON_CONFIG) @@ -1317,6 +1320,9 @@ struct dp_mon_ops monitor_ops_2_0 = { #endif .mon_pdev_ext_init = dp_mon_pdev_ext_init_2_0, .mon_pdev_ext_deinit = dp_mon_pdev_ext_deinit_2_0, + .mon_lite_mon_alloc = dp_lite_mon_alloc, + .mon_lite_mon_dealloc = dp_lite_mon_dealloc, + .mon_lite_mon_vdev_delete = dp_lite_mon_vdev_delete, }; struct cdp_mon_ops dp_ops_mon_2_0 = { @@ -1328,6 +1334,13 @@ struct cdp_mon_ops dp_ops_mon_2_0 = { .soc_config_full_mon_mode = NULL, .get_mon_pdev_rx_stats = dp_pdev_get_rx_mon_stats, .txrx_enable_mon_reap_timer = dp_enable_mon_reap_timer, +#ifdef QCA_SUPPORT_LITE_MONITOR + .txrx_set_lite_mon_config = dp_lite_mon_set_config, + .txrx_get_lite_mon_config = dp_lite_mon_get_config, + .txrx_set_lite_mon_peer_config = dp_lite_mon_set_peer_config, + .txrx_get_lite_mon_peer_config = dp_lite_mon_get_peer_config, + .txrx_is_lite_mon_enabled = dp_lite_mon_is_enabled, +#endif }; #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h index 61fe633667..492ae3d95b 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h @@ -130,6 +130,10 @@ struct dp_mon_pdev_be { uint16_t rx_mon_queue_depth; uint16_t desc_count; struct dp_mon_desc *status[DP_MON_MAX_STATUS_BUF]; +#ifdef QCA_SUPPORT_LITE_MONITOR + struct dp_lite_mon_rx_config *lite_mon_rx_config; + struct dp_lite_mon_tx_config *lite_mon_tx_config; +#endif }; /** diff --git a/dp/wifi3.0/monitor/dp_mon.c b/dp/wifi3.0/monitor/dp_mon.c index 4865a00772..a03f7c30c7 100644 --- a/dp/wifi3.0/monitor/dp_mon.c +++ b/dp/wifi3.0/monitor/dp_mon.c @@ -4974,10 +4974,17 @@ QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev) if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS) goto fail2; + if (mon_ops->mon_lite_mon_alloc) { + if (mon_ops->mon_lite_mon_alloc(pdev) != QDF_STATUS_SUCCESS) { + dp_mon_err("%pK: lite mon alloc failed", pdev); + goto fail3; + } + } + if (mon_ops->mon_rings_init) { if (mon_ops->mon_rings_init(pdev)) { dp_mon_err("%pK: MONITOR rings setup failed", pdev); - goto fail3; + goto fail4; } } @@ -4989,7 +4996,7 @@ QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev) if (mon_ops->rx_mon_buffers_alloc) { if (mon_ops->rx_mon_buffers_alloc(pdev)) { dp_mon_err("%pK: rx mon buffers alloc failed", pdev); - goto fail4; + goto fail5; } } @@ -5004,13 +5011,15 @@ QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev) return QDF_STATUS_SUCCESS; -fail4: +fail5: if (mon_ops->rx_mon_desc_pool_deinit) mon_ops->rx_mon_desc_pool_deinit(pdev); if (mon_ops->mon_rings_deinit) mon_ops->mon_rings_deinit(pdev); - +fail4: + if (mon_ops->mon_lite_mon_dealloc) + mon_ops->mon_lite_mon_dealloc(pdev); fail3: dp_htt_ppdu_stats_detach(pdev); fail2: @@ -5050,6 +5059,8 @@ QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev) if (mon_ops->mon_rings_deinit) mon_ops->mon_rings_deinit(pdev); dp_cal_client_detach(&mon_pdev->cal_client_ctx); + if (mon_ops->mon_lite_mon_dealloc) + mon_ops->mon_lite_mon_dealloc(pdev); dp_htt_ppdu_stats_detach(pdev); qdf_spinlock_destroy(&mon_pdev->ppdu_stats_lock); dp_neighbour_peers_detach(pdev); @@ -5090,6 +5101,10 @@ QDF_STATUS dp_mon_vdev_detach(struct dp_vdev *vdev) { struct dp_mon_vdev *mon_vdev = vdev->monitor_vdev; struct dp_pdev *pdev = vdev->pdev; + struct dp_mon_ops *mon_ops = dp_mon_ops_get(pdev->soc); + + if (!mon_ops) + return QDF_STATUS_E_FAILURE; if (!mon_vdev) return QDF_STATUS_E_FAILURE; @@ -5104,6 +5119,9 @@ QDF_STATUS dp_mon_vdev_detach(struct dp_vdev *vdev) if (pdev->monitor_pdev->mvdev == vdev) pdev->monitor_pdev->mvdev = NULL; + if (mon_ops->mon_lite_mon_vdev_delete) + mon_ops->mon_lite_mon_vdev_delete(pdev, vdev); + return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/monitor/dp_mon.h b/dp/wifi3.0/monitor/dp_mon.h index 68acee83ef..5147ae83ec 100644 --- a/dp/wifi3.0/monitor/dp_mon.h +++ b/dp/wifi3.0/monitor/dp_mon.h @@ -28,6 +28,10 @@ #include "dp_tx_capture.h" #endif +#ifdef QCA_SUPPORT_LITE_MONITOR +#include "dp_lite_mon.h" +#endif + #define DP_INTR_POLL_TIMER_MS 5 #define MON_VDEV_TIMER_INIT 0x1 @@ -765,6 +769,10 @@ struct dp_mon_ops { #endif QDF_STATUS (*mon_pdev_ext_init)(struct dp_pdev *pdev); QDF_STATUS (*mon_pdev_ext_deinit)(struct dp_pdev *pdev); + QDF_STATUS (*mon_lite_mon_alloc)(struct dp_pdev *pdev); + void (*mon_lite_mon_dealloc)(struct dp_pdev *pdev); + void (*mon_lite_mon_vdev_delete)(struct dp_pdev *pdev, + struct dp_vdev *vdev); }; struct dp_mon_soc { @@ -3907,6 +3915,7 @@ void dp_mon_register_feature_ops(struct dp_soc *soc) */ QDF_STATUS dp_pdev_get_rx_mon_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, struct cdp_pdev_mon_stats *stats); + /* * dp_enable_mon_reap_timer() - enable/disable reap timer * @soc_hdl: Datapath soc handle @@ -3917,4 +3926,34 @@ QDF_STATUS dp_pdev_get_rx_mon_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, */ void dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool enable); + +#ifndef QCA_SUPPORT_LITE_MONITOR +static inline int +dp_lite_mon_is_rx_enabled(struct dp_mon_pdev *mon_pdev) +{ + return 0; +} + +static inline int +dp_lite_mon_is_tx_enabled(struct dp_mon_pdev *mon_pdev) +{ + return 0; +} + +static inline QDF_STATUS +dp_lite_mon_alloc(struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void +dp_lite_mon_dealloc(struct dp_pdev *pdev) +{ +} + +static inline void +dp_lite_mon_vdev_delete(struct dp_pdev *pdev, struct dp_vdev *vdev) +{ +} +#endif #endif /* _DP_MON_H_ */ diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index be003befb3..5663d1f14e 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -285,6 +285,7 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_MLO_MGR_ID: MLO manager reference id * @WLAN_MGMT_RX_REO_ID: Management rx reorder reference id * @WLAN_MGMT_RX_REO_SIM_ID: Management rx reorder simulation reference id + * @WLAN_LITE_MON_ID: Lite monitor operations * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ /* New value added to the enum must also be reflected in function @@ -387,6 +388,7 @@ typedef enum { WLAN_MGMT_RX_REO_ID = 92, WLAN_MGMT_RX_REO_SIM_ID = 93, WLAN_TWT_ID = 94, + WLAN_LITE_MON_ID = 95, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; diff --git a/wmi/src/wmi_unified_vdev_api.c b/wmi/src/wmi_unified_vdev_api.c index 0cd33a5929..d676608602 100644 --- a/wmi/src/wmi_unified_vdev_api.c +++ b/wmi/src/wmi_unified_vdev_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -167,6 +168,8 @@ QDF_STATUS wmi_unified_vdev_set_neighbour_rx_cmd_send( return QDF_STATUS_E_FAILURE; } +qdf_export_symbol(wmi_unified_vdev_set_neighbour_rx_cmd_send); + QDF_STATUS wmi_extract_multi_vdev_restart_resp_event( struct wmi_unified *wmi_handle, void *evt_buf,