From e1ffcf089ed4708cf42ceb5456c569b698b9b268 Mon Sep 17 00:00:00 2001 From: Jinwei Chen Date: Wed, 12 Jun 2019 22:31:27 +0800 Subject: [PATCH] qcacmn: fix monitor packets radiotap channel incorrect issue The channel number is always 0 from HAL RX PPDU TLV, then monitor mode frames radiotap channel frequency is always 2407, get the correct channel number that we saved when set monitor channel. Change-Id: Ib927fe9aca3a4c1f98845fe37c9b1d37d1d6cf5a CRs-Fixed: 2471161 --- dp/inc/cdp_txrx_mon.h | 19 ++++++++++++++++++- dp/inc/cdp_txrx_ops.h | 3 +++ dp/wifi3.0/dp_main.c | 18 ++++++++++++++++++ dp/wifi3.0/dp_rx_mon_dest.c | 6 ++++++ dp/wifi3.0/dp_types.h | 3 +++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/dp/inc/cdp_txrx_mon.h b/dp/inc/cdp_txrx_mon.h index 3595cc2abe..19830a3516 100644 --- a/dp/inc/cdp_txrx_mon.h +++ b/dp/inc/cdp_txrx_mon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. 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 @@ -149,4 +149,21 @@ static inline QDF_STATUS cdp_reset_monitor_mode return soc->ops->mon_ops->txrx_reset_monitor_mode(pdev); } + +static inline void cdp_record_monitor_chan_num +(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int chan_num) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_monitor_record_channel) + return; + + soc->ops->mon_ops->txrx_monitor_record_channel(pdev, chan_num); +} #endif diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index dd33b9d484..c8ba190fb5 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -720,6 +720,9 @@ struct cdp_mon_ops { /* HK advance monitor filter support */ QDF_STATUS (*txrx_set_advance_monitor_filter) (struct cdp_pdev *pdev, struct cdp_monitor_filter *filter_val); + + void (*txrx_monitor_record_channel) + (struct cdp_pdev *, int val); }; struct cdp_host_stats_ops { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9a4d62f7cd..9ae93a1810 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4874,6 +4874,9 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, qdf_spin_unlock_bh(&pdev->vdev_list_lock); free_vdev: + if (wlan_op_mode_monitor == vdev->opmode) + pdev->monitor_vdev = NULL; + qdf_mem_free(vdev); if (callback) @@ -6408,6 +6411,20 @@ dp_pdev_set_advance_monitor_filter(struct cdp_pdev *pdev_handle, return QDF_STATUS_SUCCESS; } +/** + * dp_pdev_set_monitor_channel() - set monitor channel num in pdev + * @pdev_handle: Datapath PDEV handle + * + * Return: None + */ +static +void dp_pdev_set_monitor_channel(struct cdp_pdev *pdev_handle, int chan_num) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + + pdev->mon_chan_num = chan_num; +} + /** * dp_get_pdev_id_frm_pdev() - get pdev_id * @pdev_handle: Datapath PDEV handle @@ -8960,6 +8977,7 @@ static struct cdp_mon_ops dp_ops_mon = { .txrx_reset_monitor_mode = dp_reset_monitor_mode, /* Added support for HK advance filter */ .txrx_set_advance_monitor_filter = dp_pdev_set_advance_monitor_filter, + .txrx_monitor_record_channel = dp_pdev_set_monitor_channel, }; static struct cdp_host_stats_ops dp_ops_host_stats = { diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 8ea1809379..8fbf8f1564 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -950,6 +950,12 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, pdev->ppdu_info.rx_status.device_id = soc->device_id; pdev->ppdu_info.rx_status.chan_noise_floor = pdev->chan_noise_floor; + /* + * if chan_num is not fetched correctly from ppdu RX TLV, + * get it from pdev saved. + */ + if (pdev->ppdu_info.rx_status.chan_num == 0) + pdev->ppdu_info.rx_status.chan_num = pdev->mon_chan_num; qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), mon_mpdu, sizeof(struct rx_pkt_tlvs)); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index cd3ac2f237..fc0ed82e3f 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1380,6 +1380,9 @@ struct dp_pdev { /* Monitor mode interface and status storage */ struct dp_vdev *monitor_vdev; + /* Monitor mode operation channel */ + int mon_chan_num; + /* monitor mode lock */ qdf_spinlock_t mon_lock;