Commit c7fd8d23 authored by Balaji Pothunoori's avatar Balaji Pothunoori Committed by Kalle Valo

ath10k: average ack rssi support for data frames

Average ack rssi value is weighted average of ack rssi for
no of msdu's has been sent.
This feature is enabled by the host driver if firmware is capable.
After receiving event from host, firmware allocates the necessary
memory to store the ack_rssi for data packets during the init time.

After each successful transmission, If tx completion status is OK
and 24th bit is set in HTT message header then host will fetch the
ack_rssi else host can ignore the ack_rssi field.
Signed-off-by: default avatarBalaji Pothunoori <bpothuno@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 97c69a70
...@@ -2549,6 +2549,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, ...@@ -2549,6 +2549,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
ar->wmi.svc_map)) ar->wmi.svc_map))
val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA; val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;
if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI,
ar->wmi.svc_map))
val |= WMI_10_4_TX_DATA_ACK_RSSI;
status = ath10k_mac_ext_resource_config(ar, val); status = ath10k_mac_ext_resource_config(ar, val);
if (status) { if (status) {
ath10k_err(ar, ath10k_err(ar,
......
...@@ -577,6 +577,8 @@ struct htt_mgmt_tx_completion { ...@@ -577,6 +577,8 @@ struct htt_mgmt_tx_completion {
#define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_MASK 0xFF000000 #define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_MASK 0xFF000000
#define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_LSB 24 #define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_LSB 24
#define HTT_TX_CMPL_FLAG_DATA_RSSI BIT(0)
struct htt_rx_indication_hdr { struct htt_rx_indication_hdr {
u8 info0; /* %HTT_RX_INDICATION_INFO0_ */ u8 info0; /* %HTT_RX_INDICATION_INFO0_ */
__le16 peer_id; __le16 peer_id;
...@@ -840,7 +842,7 @@ struct htt_data_tx_completion { ...@@ -840,7 +842,7 @@ struct htt_data_tx_completion {
} __packed; } __packed;
} __packed; } __packed;
u8 num_msdus; u8 num_msdus;
u8 rsvd0; u8 flags2; /* HTT_TX_CMPL_FLAG_DATA_RSSI */
__le16 msdus[0]; /* variable length based on %num_msdus */ __le16 msdus[0]; /* variable length based on %num_msdus */
} __packed; } __packed;
......
...@@ -1884,7 +1884,9 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, ...@@ -1884,7 +1884,9 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
struct htt_resp *resp = (struct htt_resp *)skb->data; struct htt_resp *resp = (struct htt_resp *)skb->data;
struct htt_tx_done tx_done = {}; struct htt_tx_done tx_done = {};
int status = MS(resp->data_tx_completion.flags, HTT_DATA_TX_STATUS); int status = MS(resp->data_tx_completion.flags, HTT_DATA_TX_STATUS);
__le16 msdu_id; __le16 msdu_id, *msdus;
bool rssi_enabled = false;
u8 msdu_count = 0;
int i; int i;
switch (status) { switch (status) {
...@@ -1908,10 +1910,30 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, ...@@ -1908,10 +1910,30 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n", ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n",
resp->data_tx_completion.num_msdus); resp->data_tx_completion.num_msdus);
for (i = 0; i < resp->data_tx_completion.num_msdus; i++) { msdu_count = resp->data_tx_completion.num_msdus;
msdu_id = resp->data_tx_completion.msdus[i];
if (resp->data_tx_completion.flags2 & HTT_TX_CMPL_FLAG_DATA_RSSI)
rssi_enabled = true;
for (i = 0; i < msdu_count; i++) {
msdus = resp->data_tx_completion.msdus;
msdu_id = msdus[i];
tx_done.msdu_id = __le16_to_cpu(msdu_id); tx_done.msdu_id = __le16_to_cpu(msdu_id);
if (rssi_enabled) {
/* Total no of MSDUs should be even,
* if odd MSDUs are sent firmware fills
* last msdu id with 0xffff
*/
if (msdu_count & 0x01) {
msdu_id = msdus[msdu_count + i + 1];
tx_done.ack_rssi = __le16_to_cpu(msdu_id);
} else {
msdu_id = msdus[msdu_count + i];
tx_done.ack_rssi = __le16_to_cpu(msdu_id);
}
}
/* kfifo_put: In practice firmware shouldn't fire off per-CE /* kfifo_put: In practice firmware shouldn't fire off per-CE
* interrupt and main interrupt (MSI/-X range case) for the same * interrupt and main interrupt (MSI/-X range case) for the same
* HTC service so it should be safe to use kfifo_put w/o lock. * HTC service so it should be safe to use kfifo_put w/o lock.
......
...@@ -8479,6 +8479,10 @@ int ath10k_mac_register(struct ath10k *ar) ...@@ -8479,6 +8479,10 @@ int ath10k_mac_register(struct ath10k *ar)
wiphy_ext_feature_set(ar->hw->wiphy, wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_SET_SCAN_DWELL); NL80211_EXT_FEATURE_SET_SCAN_DWELL);
if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map))
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT);
/* /*
* on LL hardware queues are managed entirely by the FW * on LL hardware queues are managed entirely by the FW
* so we only advertise to mac we can do the queues thing * so we only advertise to mac we can do the queues thing
......
...@@ -203,6 +203,7 @@ enum wmi_service { ...@@ -203,6 +203,7 @@ enum wmi_service {
WMI_SERVICE_TPC_STATS_FINAL, WMI_SERVICE_TPC_STATS_FINAL,
WMI_SERVICE_RESET_CHIP, WMI_SERVICE_RESET_CHIP,
WMI_SERVICE_SPOOF_MAC_SUPPORT, WMI_SERVICE_SPOOF_MAC_SUPPORT,
WMI_SERVICE_TX_DATA_ACK_RSSI,
/* keep last */ /* keep last */
WMI_SERVICE_MAX, WMI_SERVICE_MAX,
...@@ -350,6 +351,8 @@ enum wmi_10_4_service { ...@@ -350,6 +351,8 @@ enum wmi_10_4_service {
WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT, WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
WMI_10_4_SERVICE_TPC_STATS_FINAL, WMI_10_4_SERVICE_TPC_STATS_FINAL,
WMI_10_4_SERVICE_CFR_CAPTURE_SUPPORT,
WMI_10_4_SERVICE_TX_DATA_ACK_RSSI,
}; };
static inline char *wmi_service_name(int service_id) static inline char *wmi_service_name(int service_id)
...@@ -463,6 +466,7 @@ static inline char *wmi_service_name(int service_id) ...@@ -463,6 +466,7 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT); SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT);
SVCSTR(WMI_SERVICE_TPC_STATS_FINAL); SVCSTR(WMI_SERVICE_TPC_STATS_FINAL);
SVCSTR(WMI_SERVICE_RESET_CHIP); SVCSTR(WMI_SERVICE_RESET_CHIP);
SVCSTR(WMI_SERVICE_TX_DATA_ACK_RSSI);
default: default:
return NULL; return NULL;
} }
...@@ -771,6 +775,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out, ...@@ -771,6 +775,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, len); WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, len);
SVCMAP(WMI_10_4_SERVICE_TPC_STATS_FINAL, SVCMAP(WMI_10_4_SERVICE_TPC_STATS_FINAL,
WMI_SERVICE_TPC_STATS_FINAL, len); WMI_SERVICE_TPC_STATS_FINAL, len);
SVCMAP(WMI_10_4_SERVICE_TX_DATA_ACK_RSSI,
WMI_SERVICE_TX_DATA_ACK_RSSI, len);
} }
#undef SVCMAP #undef SVCMAP
...@@ -2924,6 +2930,7 @@ enum wmi_coex_version { ...@@ -2924,6 +2930,7 @@ enum wmi_coex_version {
* @WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE: TDLS connection tracker in host * @WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE: TDLS connection tracker in host
* enable/disable * enable/disable
* @WMI_10_4_TDLS_EXPLICIT_MODE_ONLY:Explicit TDLS mode enable/disable * @WMI_10_4_TDLS_EXPLICIT_MODE_ONLY:Explicit TDLS mode enable/disable
* @WMI_10_4_TX_DATA_ACK_RSSI: Enable DATA ACK RSSI if firmware is capable
*/ */
enum wmi_10_4_feature_mask { enum wmi_10_4_feature_mask {
WMI_10_4_LTEU_SUPPORT = BIT(0), WMI_10_4_LTEU_SUPPORT = BIT(0),
...@@ -2939,6 +2946,7 @@ enum wmi_10_4_feature_mask { ...@@ -2939,6 +2946,7 @@ enum wmi_10_4_feature_mask {
WMI_10_4_TDLS_UAPSD_SLEEP_STA = BIT(10), WMI_10_4_TDLS_UAPSD_SLEEP_STA = BIT(10),
WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE = BIT(11), WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE = BIT(11),
WMI_10_4_TDLS_EXPLICIT_MODE_ONLY = BIT(12), WMI_10_4_TDLS_EXPLICIT_MODE_ONLY = BIT(12),
WMI_10_4_TX_DATA_ACK_RSSI = BIT(16),
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment