diff mbox

ath10k: Add tx ack signal support for management frames

Message ID 1514369696-28029-1-git-send-email-vnaralas@qti.qualcomm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Venkateswara Naralasetty Dec. 27, 2017, 10:14 a.m. UTC
From: Venkateswara Naralasetty <vnaralas@qti.qualcomm.com>

This patch add support to get RSSI from acknowledgment
frames for transmitted management frames.

hardware_used: QCA4019, QCA9984.
firmware version: 10.4-3.5.3-00052.

Signed-off-by: Venkateswara Naralasetty <vnaralas@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.h   |  2 ++
 drivers/net/wireless/ath/ath10k/htt.h    |  9 ++++++++-
 drivers/net/wireless/ath/ath10k/htt_rx.c |  9 +++++++++
 drivers/net/wireless/ath/ath10k/txrx.c   |  4 ++++
 drivers/net/wireless/ath/ath10k/wmi.h    | 18 ++++++++++++++++++
 5 files changed, 41 insertions(+), 1 deletion(-)

Comments

Peter Oh Dec. 27, 2017, 6:22 p.m. UTC | #1
On 12/27/2017 02:14 AM, vnaralas@qti.qualcomm.com wrote:
> From: Venkateswara Naralasetty <vnaralas@qti.qualcomm.com>
>
> This patch add support to get RSSI from acknowledgment
> frames for transmitted management frames.
>
> hardware_used: QCA4019, QCA9984.
> firmware version: 10.4-3.5.3-00052.
>
> Signed-off-by: Venkateswara Naralasetty <vnaralas@qti.qualcomm.com>
> ---
>   drivers/net/wireless/ath/ath10k/core.h   |  2 ++
>   drivers/net/wireless/ath/ath10k/htt.h    |  9 ++++++++-
>   drivers/net/wireless/ath/ath10k/htt_rx.c |  9 +++++++++
>   drivers/net/wireless/ath/ath10k/txrx.c   |  4 ++++
>   drivers/net/wireless/ath/ath10k/wmi.h    | 18 ++++++++++++++++++
>   5 files changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
> index 643041e..64c23a5 100644
> --- a/drivers/net/wireless/ath/ath10k/core.h
> +++ b/drivers/net/wireless/ath/ath10k/core.h
> @@ -51,6 +51,8 @@
>   /* Antenna noise floor */
>   #define ATH10K_DEFAULT_NOISE_FLOOR -95
>   
> +#define ATH10K_INVALID_RSSI 128
> +
>   #define ATH10K_MAX_NUM_MGMT_PENDING 128
>   
>   /* number of failed packets (20 packets with 16 sw reties each) */
> diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
> index 6305308..2168558d 100644
> --- a/drivers/net/wireless/ath/ath10k/htt.h
> +++ b/drivers/net/wireless/ath/ath10k/htt.h
> @@ -480,12 +480,18 @@ struct htt_ver_resp {
>   	u8 rsvd0;
>   } __packed;
>   
> +#define HTT_MGMT_TX_CMPL_FLAG_ACK_RSSI BIT(0)
> +
> +#define HTT_MGMT_TX_CMPL_INFO_ACK_RSSI	GENMASK(7, 0)
Better to have xxx_MASK as postfix to represent its usage.
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 643041e..64c23a5 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -51,6 +51,8 @@ 
 /* Antenna noise floor */
 #define ATH10K_DEFAULT_NOISE_FLOOR -95
 
+#define ATH10K_INVALID_RSSI 128
+
 #define ATH10K_MAX_NUM_MGMT_PENDING 128
 
 /* number of failed packets (20 packets with 16 sw reties each) */
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 6305308..2168558d 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -480,12 +480,18 @@  struct htt_ver_resp {
 	u8 rsvd0;
 } __packed;
 
+#define HTT_MGMT_TX_CMPL_FLAG_ACK_RSSI BIT(0)
+
+#define HTT_MGMT_TX_CMPL_INFO_ACK_RSSI	GENMASK(7, 0)
+
 struct htt_mgmt_tx_completion {
 	u8 rsvd0;
 	u8 rsvd1;
-	u8 rsvd2;
+	u8 flags;
 	__le32 desc_id;
 	__le32 status;
+	__le32 ppdu_id;
+	__le32 info;
 } __packed;
 
 #define HTT_RX_INDICATION_INFO0_EXT_TID_MASK  (0x1F)
@@ -1557,6 +1563,7 @@  struct htt_resp {
 struct htt_tx_done {
 	u16 msdu_id;
 	u16 status;
+	u8 ack_rssi;
 };
 
 enum htt_tx_compl_state {
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index e314385..b1ad985 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -24,6 +24,7 @@ 
 #include "mac.h"
 
 #include <linux/log2.h>
+#include <linux/bitfield.h>
 
 #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
 #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
@@ -2479,6 +2480,14 @@  bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 		switch (status) {
 		case HTT_MGMT_TX_STATUS_OK:
 			tx_done.status = HTT_TX_COMPL_STATE_ACK;
+			if (test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
+				     ar->wmi.svc_map) &&
+			    (resp->mgmt_tx_completion.flags &
+			     HTT_MGMT_TX_CMPL_FLAG_ACK_RSSI)) {
+				tx_done.ack_rssi = FIELD_GET(HTT_MGMT_TX_CMPL_INFO_ACK_RSSI,
+							     resp->mgmt_tx_completion.info);
+			}
+
 			break;
 		case HTT_MGMT_TX_STATUS_RETRY:
 			tx_done.status = HTT_TX_COMPL_STATE_NOACK;
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index d4986f6..654a73c 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -113,6 +113,10 @@  int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
 	if (tx_done->status == HTT_TX_COMPL_STATE_NOACK)
 		info->flags &= ~IEEE80211_TX_STAT_ACK;
 
+	if (tx_done->ack_rssi && tx_done->ack_rssi != ATH10K_INVALID_RSSI)
+		info->status.ack_signal = ATH10K_DEFAULT_NOISE_FLOOR +
+						tx_done->ack_rssi;
+
 	if ((tx_done->status == HTT_TX_COMPL_STATE_ACK) &&
 	    (info->flags & IEEE80211_TX_CTL_NO_ACK))
 		info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index c02b21c..6e58a5f 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -195,6 +195,9 @@  enum wmi_service {
 	WMI_SERVICE_SMART_LOGGING_SUPPORT,
 	WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
 	WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
+	WMI_SERVICE_TDLS_WIDER_BANDWIDTH,
+	WMI_SERVICE_RESET_CHIP,
+	WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
 
 	/* keep last */
 	WMI_SERVICE_MAX,
@@ -232,6 +235,8 @@  enum wmi_10x_service {
 	WMI_10X_SERVICE_MESH,
 	WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT,
 	WMI_10X_SERVICE_PEER_STATS,
+	WMI_10X_SERVICE_RESET_CHIP,
+	WMI_10X_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
 };
 
 enum wmi_main_service {
@@ -336,6 +341,8 @@  enum wmi_10_4_service {
 	WMI_10_4_SERVICE_TDLS_UAPSD_SLEEP_STA,
 	WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
 	WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
+	WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
+	WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
 };
 
 static inline char *wmi_service_name(int service_id)
@@ -444,6 +451,9 @@  static inline char *wmi_service_name(int service_id)
 	SVCSTR(WMI_SERVICE_SMART_LOGGING_SUPPORT);
 	SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
 	SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
+	SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH);
+	SVCSTR(WMI_SERVICE_RESET_CHIP);
+	SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS);
 	default:
 		return NULL;
 	}
@@ -534,6 +544,10 @@  static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out,
 	       WMI_SERVICE_EXT_RES_CFG_SUPPORT, len);
 	SVCMAP(WMI_10X_SERVICE_PEER_STATS,
 	       WMI_SERVICE_PEER_STATS, len);
+	SVCMAP(WMI_10X_SERVICE_RESET_CHIP,
+	       WMI_SERVICE_RESET_CHIP, len);
+	SVCMAP(WMI_10X_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
+	       WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
 }
 
 static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out,
@@ -740,6 +754,10 @@  static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
 	       WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, len);
 	SVCMAP(WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
 	       WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len);
+	SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
+	       WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len);
+	SVCMAP(WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
+	       WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
 }
 
 #undef SVCMAP