summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhangq <zhangq@codeaurora.org>2016-12-22 16:47:24 +0800
committerSandeep Puligilla <spuligil@codeaurora.org>2017-03-10 20:26:53 -0800
commit8553db2fcd1bc895e9f210f7cae5031e1a12c801 (patch)
treee07ee26e1027b8437ed8f9535bcd96a0ee7b3636
parent8dad8927888ff9373c78884b28878abc90624ec2 (diff)
qcacld-3.0: Add monitor for peer PS change and TX fail
qcacld-2.0 to qcacld-3.0 propagation Once a peer sta's power state changes, fw will send WMI_PEER_STA_PS_STATECHG_EVENTID to host. Once there is TX failure on air, HTT_T2H_MSG_TYPE_TX_COMPL_IND with an unsuccess status will be received by host. These two kinds of messages from FW will be transferred into SME message and sent to HDD layer. Change-Id: If37798bcd06fb8c3f7a2690e77a572b41d7b266f CRs-fixed: 1048388
-rw-r--r--core/mac/inc/sir_api.h26
-rw-r--r--core/mac/inc/wni_api.h1
-rw-r--r--core/sme/inc/sme_api.h3
-rw-r--r--core/sme/inc/sme_internal.h2
-rw-r--r--core/sme/src/common/sme_api.c32
-rw-r--r--core/wma/inc/wma_api.h16
-rw-r--r--core/wma/src/wma_utils.c163
7 files changed, 241 insertions, 2 deletions
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 010193deed88..d46aed0f3801 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -55,6 +55,7 @@ typedef struct sAniSirGlobal *tpAniSirGlobal;
#include "cds_regdomain.h"
#include "wmi_unified.h"
#include "wmi_unified_param.h"
+#include "ol_txrx_htt_api.h"
#include <dot11f.h>
#define MAX_PEERS 32
@@ -5265,8 +5266,12 @@ typedef struct {
struct qdf_mac_addr peerMacAddress;
/* peer WIFI_CAPABILITY_XXX */
uint32_t capabilities;
- /* number of rates */
- uint32_t numRate;
+ union {
+ /* peer power saving mode */
+ uint32_t power_saving;
+ /* number of rates */
+ uint32_t numRate;
+ };
/* per rate statistics, number of entries = num_rate */
tSirWifiRateStat rateStats[0];
} tSirWifiPeerInfo, *tpSirWifiPeerInfo;
@@ -5407,6 +5412,19 @@ typedef struct {
/* Clear particular peer stats depending on the peer_mac */
#define WIFI_STATS_IFACE_PER_PEER 0x00000200
+/**
+ * struct sir_wifi_iface_tx_fail - TX failure event
+ * @tid: TX TID
+ * @msdu_num: TX MSDU failed counter
+ * @status: TX status from HTT message.
+ * Only failure status will be involved.
+ */
+struct sir_wifi_iface_tx_fail {
+ uint8_t tid;
+ uint16_t msdu_num;
+ enum htt_tx_status status;
+};
+
typedef struct {
uint32_t paramId;
uint8_t ifaceId;
@@ -5423,6 +5441,10 @@ typedef struct {
uint8_t results[0];
} tSirLLStatsResults, *tpSirLLStatsResults;
+/* Result ID for LL stats extension */
+#define WMI_LL_STATS_EXT_PS_CHG 0x00000100
+#define WMI_LL_STATS_EXT_TX_FAIL 0x00000200
+#define WMI_LL_STATS_EXT_MAC_COUNTER 0x00000400
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
typedef struct sAniGetLinkStatus {
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 521d8542b350..06f23001ee00 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -264,6 +264,7 @@ enum eWniMsgTypes {
eWNI_SME_ROAM_SCAN_OFFLOAD_REQ,
eWNI_SME_LOST_LINK_INFO_IND,
eWNI_SME_RSO_CMD_STATUS_IND,
+ eWMI_SME_LL_STATS_IND,
eWNI_SME_MSG_TYPES_END
};
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 9799dda80c2f..bd6f96417aa9 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -932,6 +932,9 @@ QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal,
QDF_STATUS sme_set_link_layer_stats_ind_cb(tHalHandle hHal,
void (*callbackRoutine)(void *callbackCtx,
int indType, void *pRsp));
+QDF_STATUS sme_set_link_layer_ext_cb(tHalHandle hal,
+ void (*ll_stats_ext_cb)(tHddHandle callback_ctx,
+ tSirLLStatsResults * rsp));
QDF_STATUS sme_reset_link_layer_stats_ind_cb(tHalHandle hhal);
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 9eac66b2ee48..02fe14adb5b9 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -182,6 +182,8 @@ typedef struct tagSmeStruct {
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
void (*pLinkLayerStatsIndCallback)(void *callbackContext,
int indType, void *pRsp);
+ void (*link_layer_stats_ext_cb)(tHddHandle callback_ctx,
+ tSirLLStatsResults *rsp);
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
#ifdef WLAN_POWER_DEBUGFS
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 5b3085b4ce2d..016f0429d457 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -3087,6 +3087,12 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg)
pMac->sme.rso_cmd_status_cb(pMac->hHdd, pMsg->bodyptr);
qdf_mem_free(pMsg->bodyptr);
break;
+ case eWMI_SME_LL_STATS_IND:
+ if (pMac->sme.link_layer_stats_ext_cb)
+ pMac->sme.link_layer_stats_ext_cb(pMac->hHdd,
+ pMsg->bodyptr);
+ qdf_mem_free(pMsg->bodyptr);
+ break;
default:
if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
@@ -14344,6 +14350,32 @@ QDF_STATUS sme_set_link_layer_stats_ind_cb
}
/**
+ * sme_set_link_layer_ext_cb() - Register callback for link layer statistics
+ * @hal: Mac global handle
+ * @ll_stats_ext_cb: HDD callback which needs to be invoked after getting
+ * status notification from FW
+ *
+ * Return: eHalStatus
+ */
+QDF_STATUS sme_set_link_layer_ext_cb(tHalHandle hal,
+ void (*ll_stats_ext_cb)(tHddHandle callback_ctx,
+ tSirLLStatsResults *rsp))
+{
+ QDF_STATUS status;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (status == QDF_STATUS_SUCCESS) {
+ mac->sme.link_layer_stats_ext_cb = ll_stats_ext_cb;
+ sme_release_global_lock(&mac->sme);
+ } else {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: sme_qcquire_global_lock error", __func__);
+ }
+ return status;
+}
+
+/**
* sme_reset_link_layer_stats_ind_cb() - SME API to reset link layer stats
* indication
* @h_hal: Hal Handle
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index b4f28168f4da..39853137cb6a 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -399,4 +399,20 @@ void wma_peer_debug_log(uint8_t vdev_id, uint8_t op,
void *peer_obj, uint32_t val1, uint32_t val2);
void wma_peer_debug_dump(void);
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/**
+ * wma_tx_failure_cb() - TX failure callback
+ * @ctx: txrx context
+ * @num_msdu: number of msdu with the same status
+ * @tid: TID number
+ * @status: failure status
+ */
+void wma_tx_failure_cb(void *ctx, uint32_t num_msdu,
+ uint8_t tid, enum htt_tx_status status);
+#else
+static inline void wma_tx_failure_cb(void *ctx, uint32_t num_msdu,
+ uint8_t tid, enum htt_tx_status status)
+{
+}
+#endif
#endif
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index d7401eb677cb..d65d62592eec 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -1018,6 +1018,165 @@ static int wma_unified_link_radio_stats_event_handler(void *handle,
return 0;
}
+#ifdef WLAN_PEER_PS_NOTIFICATION
+/**
+ * wma_peer_ps_evt_handler() - handler for PEER power state change.
+ * @handle: wma handle
+ * @event: FW event
+ * @len: length of FW event
+ *
+ * Once peer STA power state changes, an event will be indicated by
+ * FW. This function send a link layer state change msg to HDD. HDD
+ * link layer callback will converts the event to NL msg.
+ *
+ * Return: 0 Success. Others fail.
+ */
+static int wma_peer_ps_evt_handler(void *handle, u_int8_t *event,
+ u_int32_t len)
+{
+ WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *param_buf;
+ wmi_peer_sta_ps_statechange_event_fixed_param *fixed_param;
+ tSirWifiPeerStat *peer_stat;
+ tSirWifiPeerInfo *peer_info;
+ tSirLLStatsResults *link_stats_results;
+ tSirMacAddr mac_address;
+ uint32_t result_len;
+ cds_msg_t sme_msg = { 0 };
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+
+ tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+ if (!mac) {
+ WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+ return -EINVAL;
+ }
+
+ if (!mac->sme.link_layer_stats_ext_cb) {
+ WMA_LOGD("%s: HDD callback is null", __func__);
+ return -EINVAL;
+ }
+
+ WMA_LOGD("%s: Posting Peer Stats PS event to HDD", __func__);
+
+ param_buf = (WMI_PEER_STA_PS_STATECHG_EVENTID_param_tlvs *)event;
+ fixed_param = param_buf->fixed_param;
+
+ result_len = sizeof(tSirLLStatsResults) +
+ sizeof(tSirWifiPeerStat) +
+ sizeof(tSirWifiPeerInfo);
+ link_stats_results = qdf_mem_malloc(result_len);
+ if (link_stats_results == NULL) {
+ WMA_LOGE("%s: Cannot allocate link layer stats.", __func__);
+ return -EINVAL;
+ }
+
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_param->peer_macaddr, &mac_address[0]);
+ WMA_LOGD("Peer power state change event from FW");
+ WMA_LOGD("Fixed Param:");
+ WMA_LOGD("MAC address: %2x:%2x:%2x:%2x:%2x:%2x, Power state: %d",
+ mac_address[0], mac_address[1], mac_address[2],
+ mac_address[3], mac_address[4], mac_address[5],
+ fixed_param->peer_ps_state);
+
+ link_stats_results->paramId = WMI_LL_STATS_EXT_PS_CHG;
+ link_stats_results->num_peers = 1;
+ link_stats_results->peer_event_number = 1;
+ link_stats_results->moreResultToFollow = 0;
+
+ peer_stat = (tSirWifiPeerStat *)link_stats_results->results;
+ peer_stat->numPeers = 1;
+ peer_info = (tSirWifiPeerInfo *)peer_stat->peerInfo;
+ qdf_mem_copy(&peer_info->peerMacAddress,
+ &mac_address,
+ sizeof(tSirMacAddr));
+ peer_info->power_saving = fixed_param->peer_ps_state;
+
+ sme_msg.type = eWMI_SME_LL_STATS_IND;
+ sme_msg.bodyptr = link_stats_results;
+ sme_msg.bodyval = 0;
+
+ qdf_status = cds_mq_post_message(QDF_MODULE_ID_SME, &sme_msg);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ WMA_LOGE("%s: Fail to post ps change ind msg", __func__);
+ qdf_mem_free(link_stats_results);
+ }
+
+ return 0;
+}
+#else
+/**
+ * wma_peer_ps_evt_handler() - handler for PEER power state change.
+ * @handle: wma handle
+ * @event: FW event
+ * @len: length of FW event
+ *
+ * Once peer STA power state changes, an event will be indicated by
+ * FW. This function send a link layer state change msg to HDD. HDD
+ * link layer callback will converts the event to NL msg.
+ *
+ * Return: 0 Success. Others fail.
+ */
+static inline int wma_peer_ps_evt_handler(void *handle, u_int8_t *event,
+ u_int32_t len)
+{
+ return 0;
+}
+#endif
+
+/**
+ * wma_tx_failure_cb() - TX failure callback
+ * @ctx: txrx context
+ * @num_msdu: number of msdu with the same status
+ * @tid: TID number
+ * @status: failure status
+ */
+void wma_tx_failure_cb(void *ctx, uint32_t num_msdu,
+ uint8_t tid, enum htt_tx_status status)
+{
+ tSirLLStatsResults *results;
+ struct sir_wifi_iface_tx_fail *tx_fail;
+ cds_msg_t sme_msg = { 0 };
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
+
+ if (!mac) {
+ WMA_LOGD("%s: NULL mac ptr. Exiting", __func__);
+ return;
+ }
+
+ if (!mac->sme.link_layer_stats_ext_cb) {
+ WMA_LOGD("%s: HDD callback is null", __func__);
+ return;
+ }
+
+ results = qdf_mem_malloc(sizeof(tSirLLStatsResults) +
+ sizeof(struct sir_wifi_iface_tx_fail));
+ if (results == NULL) {
+ WMA_LOGE("%s: Cannot allocate link layer stats.", __func__);
+ return;
+ }
+
+ results->paramId = WMI_LL_STATS_EXT_TX_FAIL;
+ results->num_peers = 1;
+ results->peer_event_number = 1;
+ results->moreResultToFollow = 0;
+
+ tx_fail = (struct sir_wifi_iface_tx_fail *)results->results;
+ tx_fail->tid = tid;
+ tx_fail->msdu_num = num_msdu;
+ tx_fail->status = status;
+
+ sme_msg.type = eWMI_SME_LL_STATS_IND;
+ sme_msg.bodyptr = results;
+ sme_msg.bodyval = 0;
+
+ qdf_status = cds_mq_post_message(QDF_MODULE_ID_SME, &sme_msg);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ WMA_LOGE("%s: Fail to post TX failure ind msg", __func__);
+ qdf_mem_free(results);
+ }
+}
+
/**
* wma_register_ll_stats_event_handler() - register link layer stats related
* event handler
@@ -1048,6 +1207,10 @@ void wma_register_ll_stats_event_handler(tp_wma_handle wma_handle)
WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID,
wma_unified_radio_tx_power_level_stats_event_handler,
WMA_RX_SERIALIZER_CTX);
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_PEER_STA_PS_STATECHG_EVENTID,
+ wma_peer_ps_evt_handler,
+ WMA_RX_SERIALIZER_CTX);
return;
}