diff mbox series

[1/3] ath11k: add htt cmd to enable full monitor mode

Message ID 20210721171905.61838-2-jouni@codeaurora.org (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series ath11k: add full monitor mode support for QCN9074 | expand

Commit Message

Jouni Malinen July 21, 2021, 5:19 p.m. UTC
From: Anilkumar Kolli <akolli@codeaurora.org>

Add a new hw_param full_monitor_mode to enable full monitor support for
QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
firmware to enable the full monitor mode.

Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1

Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/core.c  |  4 ++
 drivers/net/wireless/ath/ath11k/dp.h    | 74 +++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/dp_tx.c | 48 ++++++++++++++++
 drivers/net/wireless/ath/ath11k/dp_tx.h |  2 +
 drivers/net/wireless/ath/ath11k/hw.h    |  1 +
 5 files changed, 129 insertions(+)

Comments

Kalle Valo Sept. 24, 2021, 11:42 a.m. UTC | #1
Jouni Malinen <jouni@codeaurora.org> writes:

> From: Anilkumar Kolli <akolli@codeaurora.org>
>
> Add a new hw_param full_monitor_mode to enable full monitor support for
> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
> firmware to enable the full monitor mode.

Nowhere it's explained what "full monitor mode" means from an user's
point of view. Can someone give a high level summary what advantages
this feature has? For example, more frames delivered to user space or
what?
Kalle Valo Sept. 24, 2021, 1:52 p.m. UTC | #2
Jouni Malinen <jouni@codeaurora.org> writes:

> From: Anilkumar Kolli <akolli@codeaurora.org>
>
> Add a new hw_param full_monitor_mode to enable full monitor support for
> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
> firmware to enable the full monitor mode.
>
> Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
> Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
> ---
>  drivers/net/wireless/ath/ath11k/core.c  |  4 ++
>  drivers/net/wireless/ath/ath11k/dp.h    | 74 +++++++++++++++++++++++++
>  drivers/net/wireless/ath/ath11k/dp_tx.c | 48 ++++++++++++++++
>  drivers/net/wireless/ath/ath11k/dp_tx.h |  2 +
>  drivers/net/wireless/ath/ath11k/hw.h    |  1 +
>  5 files changed, 129 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
> index 969bf1a590d9..3179495cb3c9 100644
> --- a/drivers/net/wireless/ath/ath11k/core.c
> +++ b/drivers/net/wireless/ath/ath11k/core.c
> @@ -65,6 +65,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
>  					BIT(NL80211_IFTYPE_AP) |
>  					BIT(NL80211_IFTYPE_MESH_POINT),
>  		.supports_monitor = true,
> +		.full_monitor_mode = false,
>  		.supports_shadow_regs = false,
>  		.idle_ps = false,
>  		.cold_boot_calib = true,
> @@ -106,6 +107,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
>  					BIT(NL80211_IFTYPE_AP) |
>  					BIT(NL80211_IFTYPE_MESH_POINT),
>  		.supports_monitor = true,
> +		.full_monitor_mode = false,
>  		.supports_shadow_regs = false,
>  		.idle_ps = false,
>  		.cold_boot_calib = true,
> @@ -146,6 +148,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
>  		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
>  					BIT(NL80211_IFTYPE_AP),
>  		.supports_monitor = false,
> +		.full_monitor_mode = false,
>  		.supports_shadow_regs = true,
>  		.idle_ps = true,
>  		.cold_boot_calib = false,
> @@ -184,6 +187,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
>  					BIT(NL80211_IFTYPE_AP) |
>  					BIT(NL80211_IFTYPE_MESH_POINT),
>  		.supports_monitor = true,
> +		.full_monitor_mode = true,
>  		.supports_shadow_regs = false,
>  		.idle_ps = false,
>  		.cold_boot_calib = false,

wcn6855 was not updated, I added that.

> --- a/drivers/net/wireless/ath/ath11k/dp_tx.c
> +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
> @@ -1034,6 +1034,15 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
>  	struct htt_rx_ring_tlv_filter tlv_filter = {0};
>  	int ret = 0, ring_id = 0, i;
>  
> +	if (ab->hw_params.full_monitor_mode) {
> +		ret = ath11k_dp_tx_htt_rx_full_mon_setup(ab,
> +							 dp->mac_id, !reset);
> +		if (ret < 0) {
> +			ath11k_err(ab, "failed to setup full monitor %d\n", ret);

I changed this to:

		if (ret) {
			ath11k_warn(ab, "failed to setup full monitor: %d\n", ret);
			return ret;
		}
Anilkumar Kolli Sept. 27, 2021, 4:19 a.m. UTC | #3
On 2021-09-24 17:12, Kalle Valo wrote:
> Jouni Malinen <jouni@codeaurora.org> writes:
> 
>> From: Anilkumar Kolli <akolli@codeaurora.org>
>> 
>> Add a new hw_param full_monitor_mode to enable full monitor support 
>> for
>> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
>> firmware to enable the full monitor mode.
> 
> Nowhere it's explained what "full monitor mode" means from an user's
> point of view. Can someone give a high level summary what advantages
> this feature has? For example, more frames delivered to user space or
> what?

Yes, more frames delivered with full monitor mode. The advantage with 
full
monitor mode is, hardware has status buffers available for all the MPDUs 
in
mon_dst_ring. Both status buffer and MPDUs from mon_dst_ring is used to 
build
the frame.

Patch "ath11k: Process full monitor mode rx support" has the commit 
message.

In full monitor mode, monitor destination ring is read before monitor
status ring. mon_dst_ring has ppdu id, reap till the end of PPDU. Add
all the MPDUs to list. Start processing the status ring, if PPDU id in
status ring is lagging behind, reap the status ring, once the PPDU ID
matches, deliver the MSDU to upper layer. If status PPDU id leading,
reap the mon_dst_ring. The advantage with full monitor mode is hardware
has status buffers available for all the MPDUs in mon_dst_ring.

- Anil.
Anilkumar Kolli Sept. 27, 2021, 4:31 a.m. UTC | #4
On 2021-09-24 19:22, Kalle Valo wrote:
> Jouni Malinen <jouni@codeaurora.org> writes:
> 
>> From: Anilkumar Kolli <akolli@codeaurora.org>
>> 
>> Add a new hw_param full_monitor_mode to enable full monitor support 
>> for
>> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
>> firmware to enable the full monitor mode.
>> 
>> Tested-on: QCN9074 hw1.0 PCI 
>> WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1
>> 
>> Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
>> Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
>> ---
>>  drivers/net/wireless/ath/ath11k/core.c  |  4 ++
>>  drivers/net/wireless/ath/ath11k/dp.h    | 74 
>> +++++++++++++++++++++++++
>>  drivers/net/wireless/ath/ath11k/dp_tx.c | 48 ++++++++++++++++
>>  drivers/net/wireless/ath/ath11k/dp_tx.h |  2 +
>>  drivers/net/wireless/ath/ath11k/hw.h    |  1 +
>>  5 files changed, 129 insertions(+)
>> 
>> diff --git a/drivers/net/wireless/ath/ath11k/core.c 
>> b/drivers/net/wireless/ath/ath11k/core.c
>> index 969bf1a590d9..3179495cb3c9 100644
>> --- a/drivers/net/wireless/ath/ath11k/core.c
>> +++ b/drivers/net/wireless/ath/ath11k/core.c
>> @@ -65,6 +65,7 @@ static const struct ath11k_hw_params 
>> ath11k_hw_params[] = {
>>  					BIT(NL80211_IFTYPE_AP) |
>>  					BIT(NL80211_IFTYPE_MESH_POINT),
>>  		.supports_monitor = true,
>> +		.full_monitor_mode = false,
>>  		.supports_shadow_regs = false,
>>  		.idle_ps = false,
>>  		.cold_boot_calib = true,
>> @@ -106,6 +107,7 @@ static const struct ath11k_hw_params 
>> ath11k_hw_params[] = {
>>  					BIT(NL80211_IFTYPE_AP) |
>>  					BIT(NL80211_IFTYPE_MESH_POINT),
>>  		.supports_monitor = true,
>> +		.full_monitor_mode = false,
>>  		.supports_shadow_regs = false,
>>  		.idle_ps = false,
>>  		.cold_boot_calib = true,
>> @@ -146,6 +148,7 @@ static const struct ath11k_hw_params 
>> ath11k_hw_params[] = {
>>  		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
>>  					BIT(NL80211_IFTYPE_AP),
>>  		.supports_monitor = false,
>> +		.full_monitor_mode = false,
>>  		.supports_shadow_regs = true,
>>  		.idle_ps = true,
>>  		.cold_boot_calib = false,
>> @@ -184,6 +187,7 @@ static const struct ath11k_hw_params 
>> ath11k_hw_params[] = {
>>  					BIT(NL80211_IFTYPE_AP) |
>>  					BIT(NL80211_IFTYPE_MESH_POINT),
>>  		.supports_monitor = true,
>> +		.full_monitor_mode = true,
>>  		.supports_shadow_regs = false,
>>  		.idle_ps = false,
>>  		.cold_boot_calib = false,
> 
> wcn6855 was not updated, I added that.
> 

Thanks. 'full_monitor_mode = false' to be added.

>> --- a/drivers/net/wireless/ath/ath11k/dp_tx.c
>> +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
>> @@ -1034,6 +1034,15 @@ int 
>> ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool 
>> reset)
>>  	struct htt_rx_ring_tlv_filter tlv_filter = {0};
>>  	int ret = 0, ring_id = 0, i;
>> 
>> +	if (ab->hw_params.full_monitor_mode) {
>> +		ret = ath11k_dp_tx_htt_rx_full_mon_setup(ab,
>> +							 dp->mac_id, !reset);
>> +		if (ret < 0) {
>> +			ath11k_err(ab, "failed to setup full monitor %d\n", ret);
> 
> I changed this to:
> 
> 		if (ret) {
> 			ath11k_warn(ab, "failed to setup full monitor: %d\n", ret);
> 			return ret;
> 		}

Thanks.
Kalle Valo Sept. 28, 2021, 6:56 a.m. UTC | #5
akolli@codeaurora.org writes:

> On 2021-09-24 17:12, Kalle Valo wrote:
>> Jouni Malinen <jouni@codeaurora.org> writes:
>>
>>> From: Anilkumar Kolli <akolli@codeaurora.org>
>>>
>>> Add a new hw_param full_monitor_mode to enable full monitor support
>>> for
>>> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
>>> firmware to enable the full monitor mode.
>>
>> Nowhere it's explained what "full monitor mode" means from an user's
>> point of view. Can someone give a high level summary what advantages
>> this feature has? For example, more frames delivered to user space or
>> what?
>
> Yes, more frames delivered with full monitor mode. The advantage with
> full monitor mode is, hardware has status buffers available for all
> the MPDUs in mon_dst_ring. Both status buffer and MPDUs from
> mon_dst_ring is used to build the frame.

Users, and developers outside of the wireless domain, have no clue what
"MPDUs in mon_dst_ring" means, just as an example. Can you give a higher
level summary of this feature and what benefit it brings, please? I'll
then add that to the commit log.

For example, what kind of frames are we now able to deliver to the user
space (which we before couldn't) and are there still some types of
frames which we are not delivering?

In other words, instead of technical low level jargon I'm looking for a
summary in plain english which is understandable by everyone.
Anilkumar Kolli Sept. 30, 2021, 6:47 a.m. UTC | #6
On 2021-09-28 12:26, Kalle Valo wrote:
> akolli@codeaurora.org writes:
> 
>> On 2021-09-24 17:12, Kalle Valo wrote:
>>> Jouni Malinen <jouni@codeaurora.org> writes:
>>> 
>>>> From: Anilkumar Kolli <akolli@codeaurora.org>
>>>> 
>>>> Add a new hw_param full_monitor_mode to enable full monitor support
>>>> for
>>>> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
>>>> firmware to enable the full monitor mode.
>>> 
>>> Nowhere it's explained what "full monitor mode" means from an user's
>>> point of view. Can someone give a high level summary what advantages
>>> this feature has? For example, more frames delivered to user space or
>>> what?
>> 
>> Yes, more frames delivered with full monitor mode. The advantage with
>> full monitor mode is, hardware has status buffers available for all
>> the MPDUs in mon_dst_ring. Both status buffer and MPDUs from
>> mon_dst_ring is used to build the frame.
> 
> Users, and developers outside of the wireless domain, have no clue what
> "MPDUs in mon_dst_ring" means, just as an example. Can you give a 
> higher
> level summary of this feature and what benefit it brings, please? I'll
> then add that to the commit log.
> 
> For example, what kind of frames are we now able to deliver to the user
> space (which we before couldn't) and are there still some types of
> frames which we are not delivering?
> 
> In other words, instead of technical low level jargon I'm looking for a
> summary in plain english which is understandable by everyone.

Full monitor mode is hardware enhancement for QCN9074. With this more 
frames are delivered to mac80211.

In earlier hardware like IPQ8074, on each interrupt, reap complete 
monitor status ring.
For each PPDU_DONE status, reap monitor destination ring, this needs 
more processing on driver.

With full monitor, on Interrupt, there is no need to reap the complete 
monitor status ring.
Instead only one PPDU is reap from monitor destination ring and 
corresponding PPDU status is reaped.

In older approach, in noisy environments status buffers are missing for 
few PPDU, even in that case
Host reaps monitor destination ring, which is not needed and these 
frames are dropped.

In full monitor mode, for all MPDUs in a PPDU, status is guaranteed, 
this is achieved in hardware using lock-stepping.
So more frames delivered to mac80211 and more fames seen in sniffer. "

- Anil.
Anilkumar Kolli Oct. 4, 2021, 4:23 a.m. UTC | #7
On 2021-09-30 12:17, Anilkumar Kolli wrote:
> On 2021-09-28 12:26, Kalle Valo wrote:
>> akolli@codeaurora.org writes:
>> 
>>> On 2021-09-24 17:12, Kalle Valo wrote:
>>>> Jouni Malinen <jouni@codeaurora.org> writes:
>>>> 
>>>>> From: Anilkumar Kolli <akolli@codeaurora.org>
>>>>> 
>>>>> Add a new hw_param full_monitor_mode to enable full monitor support
>>>>> for
>>>>> QCN9074. HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to the
>>>>> firmware to enable the full monitor mode.
>>>> 
>>>> Nowhere it's explained what "full monitor mode" means from an user's
>>>> point of view. Can someone give a high level summary what advantages
>>>> this feature has? For example, more frames delivered to user space 
>>>> or
>>>> what?
>>> 
>>> Yes, more frames delivered with full monitor mode. The advantage with
>>> full monitor mode is, hardware has status buffers available for all
>>> the MPDUs in mon_dst_ring. Both status buffer and MPDUs from
>>> mon_dst_ring is used to build the frame.
>> 
>> Users, and developers outside of the wireless domain, have no clue 
>> what
>> "MPDUs in mon_dst_ring" means, just as an example. Can you give a 
>> higher
>> level summary of this feature and what benefit it brings, please? I'll
>> then add that to the commit log.
>> 
>> For example, what kind of frames are we now able to deliver to the 
>> user
>> space (which we before couldn't) and are there still some types of
>> frames which we are not delivering?
>> 
>> In other words, instead of technical low level jargon I'm looking for 
>> a
>> summary in plain english which is understandable by everyone.
> 
> Full monitor mode is hardware enhancement for QCN9074. With this more
> frames are delivered to mac80211.
> 
> In earlier hardware like IPQ8074, on each interrupt, reap complete
> monitor status ring.
> For each PPDU_DONE status, reap monitor destination ring, this needs
> more processing on driver.
> 
> With full monitor, on Interrupt, there is no need to reap the complete
> monitor status ring.
> Instead only one PPDU is reap from monitor destination ring and
> corresponding PPDU status is reaped.
> 
> In older approach, in noisy environments status buffers are missing
> for few PPDU, even in that case
> Host reaps monitor destination ring, which is not needed and these
> frames are dropped.
> 

Radiotap header is constructed from monitor status buffer tlvs. Since 
there is
no update of status buffer for few PPDU, complete 80211 frame is not 
formed and
is dropped in ath11k.

> In full monitor mode, for all MPDUs in a PPDU, status is guaranteed,
> this is achieved in hardware using lock-stepping.
> So more frames delivered to mac80211 and more fames seen in sniffer. "
> 


- Anil.
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 969bf1a590d9..3179495cb3c9 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -65,6 +65,7 @@  static const struct ath11k_hw_params ath11k_hw_params[] = {
 					BIT(NL80211_IFTYPE_AP) |
 					BIT(NL80211_IFTYPE_MESH_POINT),
 		.supports_monitor = true,
+		.full_monitor_mode = false,
 		.supports_shadow_regs = false,
 		.idle_ps = false,
 		.cold_boot_calib = true,
@@ -106,6 +107,7 @@  static const struct ath11k_hw_params ath11k_hw_params[] = {
 					BIT(NL80211_IFTYPE_AP) |
 					BIT(NL80211_IFTYPE_MESH_POINT),
 		.supports_monitor = true,
+		.full_monitor_mode = false,
 		.supports_shadow_regs = false,
 		.idle_ps = false,
 		.cold_boot_calib = true,
@@ -146,6 +148,7 @@  static const struct ath11k_hw_params ath11k_hw_params[] = {
 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
 					BIT(NL80211_IFTYPE_AP),
 		.supports_monitor = false,
+		.full_monitor_mode = false,
 		.supports_shadow_regs = true,
 		.idle_ps = true,
 		.cold_boot_calib = false,
@@ -184,6 +187,7 @@  static const struct ath11k_hw_params ath11k_hw_params[] = {
 					BIT(NL80211_IFTYPE_AP) |
 					BIT(NL80211_IFTYPE_MESH_POINT),
 		.supports_monitor = true,
+		.full_monitor_mode = true,
 		.supports_shadow_regs = false,
 		.idle_ps = false,
 		.cold_boot_calib = false,
diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
index ee768ccce46e..b39a6652d631 100644
--- a/drivers/net/wireless/ath/ath11k/dp.h
+++ b/drivers/net/wireless/ath/ath11k/dp.h
@@ -289,6 +289,7 @@  enum htt_h2t_msg_type {
 	HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG	= 0xc,
 	HTT_H2T_MSG_TYPE_EXT_STATS_CFG		= 0x10,
 	HTT_H2T_MSG_TYPE_PPDU_STATS_CFG		= 0x11,
+	HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE	= 0x17,
 };
 
 #define HTT_VER_REQ_INFO_MSG_ID		GENMASK(7, 0)
@@ -953,6 +954,79 @@  struct htt_rx_ring_tlv_filter {
 	u32 pkt_filter_flags3; /* DATA */
 };
 
+/**
+ * @brief Host-->target HTT RX Full monitor mode register configuration message
+ * @details
+ * The host will send this Full monitor mode register configuration message.
+ * This message can be sent per SOC or per PDEV which is differentiated
+ * by pdev id values.
+ *
+ *       |31                            16|15  11|10   8|7      3|2|1|0|
+ *       |-------------------------------------------------------------|
+ *       |             reserved           |   pdev_id   |  MSG_TYPE    |
+ *       |-------------------------------------------------------------|
+ *       |                      reserved         |Release Ring   |N|Z|E|
+ *       |-------------------------------------------------------------|
+ *
+ * where E  is 1-bit full monitor mode enable/disable.
+ *       Z  is 1-bit additional descriptor for zero mpdu enable/disable
+ *       N  is 1-bit additional descriptor for non zero mdpu enable/disable
+ *
+ * The following field definitions describe the format of the full monitor
+ * mode configuration message sent from the host to target for each pdev.
+ *
+ * Header fields:
+ *  dword0 - b'7:0   - msg_type: This will be set to
+ *                     HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE.
+ *           b'15:8  - pdev_id:  0 indicates msg is for all LMAC rings, i.e. soc
+ *                     1, 2, 3 indicates pdev_id 0,1,2 and the msg is for the
+ *                     specified pdev's LMAC ring.
+ *           b'31:16 - reserved : Reserved for future use.
+ *  dword1 - b'0     - full_monitor_mode enable: This indicates that the full
+ *                     monitor mode rxdma register is to be enabled or disabled.
+ *           b'1     - addnl_descs_zero_mpdus_end: This indicates that the
+ *                     additional descriptors at ppdu end for zero mpdus
+ *                     enabled or disabled.
+ *           b'2     - addnl_descs_non_zero_mpdus_end: This indicates that the
+ *                     additional descriptors at ppdu end for non zero mpdus
+ *                     enabled or disabled.
+ *           b'10:3  - release_ring: This indicates the destination ring
+ *                     selection for the descriptor at the end of PPDU
+ *                     0 - REO ring select
+ *                     1 - FW  ring select
+ *                     2 - SW  ring select
+ *                     3 - Release ring select
+ *                     Refer to htt_rx_full_mon_release_ring.
+ *           b'31:11  - reserved for future use
+ */
+
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_MSG_TYPE	GENMASK(7, 0)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_PDEV_ID	GENMASK(15, 8)
+
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ENABLE			BIT(0)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ZERO_MPDUS_END		BIT(1)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_NON_ZERO_MPDUS_END	BIT(2)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_RELEASE_RING		GENMASK(10, 3)
+
+/**
+ * Enumeration for full monitor mode destination ring select
+ * 0 - REO destination ring select
+ * 1 - FW destination ring select
+ * 2 - SW destination ring select
+ * 3 - Release destination ring select
+ */
+enum htt_rx_full_mon_release_ring {
+	HTT_RX_MON_RING_REO,
+	HTT_RX_MON_RING_FW,
+	HTT_RX_MON_RING_SW,
+	HTT_RX_MON_RING_RELEASE,
+};
+
+struct htt_rx_full_monitor_mode_cfg_cmd {
+	u32 info0;
+	u32 cfg;
+} __packed;
+
 /* HTT message target->host */
 
 enum htt_t2h_msg_type {
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c
index 253d0564f923..2f21e3378ae1 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -1034,6 +1034,15 @@  int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
 	int ret = 0, ring_id = 0, i;
 
+	if (ab->hw_params.full_monitor_mode) {
+		ret = ath11k_dp_tx_htt_rx_full_mon_setup(ab,
+							 dp->mac_id, !reset);
+		if (ret < 0) {
+			ath11k_err(ab, "failed to setup full monitor %d\n", ret);
+			return ret;
+		}
+	}
+
 	ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id;
 
 	if (!reset) {
@@ -1100,3 +1109,42 @@  int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
 
 	return ret;
 }
+
+int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id,
+				       bool config)
+{
+	struct htt_rx_full_monitor_mode_cfg_cmd *cmd;
+	struct sk_buff *skb;
+	int ret, len = sizeof(*cmd);
+
+	skb = ath11k_htc_alloc_skb(ab, len);
+	if (!skb)
+		return -ENOMEM;
+
+	skb_put(skb, len);
+	cmd = (struct htt_rx_full_monitor_mode_cfg_cmd *)skb->data;
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->info0 = FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_MSG_TYPE,
+				HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE);
+
+	cmd->info0 |= FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_PDEV_ID, mac_id);
+
+	cmd->cfg = HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ENABLE |
+		   FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_RELEASE_RING,
+			      HTT_RX_MON_RING_SW);
+	if (config) {
+		cmd->cfg |= HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ZERO_MPDUS_END |
+			    HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_NON_ZERO_MPDUS_END;
+	}
+
+	ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb);
+	if (ret)
+		goto err_free;
+
+	return 0;
+
+err_free:
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.h b/drivers/net/wireless/ath/ath11k/dp_tx.h
index 698b907b878d..e373dbccf417 100644
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
@@ -37,4 +37,6 @@  int ath11k_dp_tx_htt_rx_filter_setup(struct ath11k_base *ab, u32 ring_id,
 				     int rx_buf_size,
 				     struct htt_rx_ring_tlv_filter *tlv_filter);
 
+int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id,
+				       bool config);
 #endif
diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h
index 62f5978b3005..5b7ce4c7e489 100644
--- a/drivers/net/wireless/ath/ath11k/hw.h
+++ b/drivers/net/wireless/ath/ath11k/hw.h
@@ -157,6 +157,7 @@  struct ath11k_hw_params {
 
 	u16 interface_modes;
 	bool supports_monitor;
+	bool full_monitor_mode;
 	bool supports_shadow_regs;
 	bool idle_ps;
 	bool cold_boot_calib;