diff options
| author | zhangq <zhangq@codeaurora.org> | 2016-12-22 16:47:24 +0800 |
|---|---|---|
| committer | Sandeep Puligilla <spuligil@codeaurora.org> | 2017-03-10 20:26:53 -0800 |
| commit | 8553db2fcd1bc895e9f210f7cae5031e1a12c801 (patch) | |
| tree | e07ee26e1027b8437ed8f9535bcd96a0ee7b3636 | |
| parent | 8dad8927888ff9373c78884b28878abc90624ec2 (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.h | 26 | ||||
| -rw-r--r-- | core/mac/inc/wni_api.h | 1 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 3 | ||||
| -rw-r--r-- | core/sme/inc/sme_internal.h | 2 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 32 | ||||
| -rw-r--r-- | core/wma/inc/wma_api.h | 16 | ||||
| -rw-r--r-- | core/wma/src/wma_utils.c | 163 |
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; } |
