From 905b4c512fed0adc9dc3b1e51fb04d7bef54b409 Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Tue, 17 Oct 2017 19:38:14 +0530 Subject: [PATCH] qcacld-3.0: Management MGMT TXRX component over HTT Currently there is no support for management MGMT TXRX component over HTT endpoint and supports only over WMI. As a result for platforms which does not support MGMT over WMI will break other components which uses MGMT TXRX component to send mgmt packets. In this change support MGMT TXRX component over HTT. Change-Id: I414269abb5a5c616cc890dab450a7782e6829d0e CRs-Fixed: 2128213 --- core/dp/txrx/ol_tx.c | 11 +- core/dp/txrx/ol_tx.h | 3 +- core/dp/txrx/ol_tx_desc.c | 8 +- core/dp/txrx/ol_tx_send.c | 6 +- core/dp/txrx/ol_txrx_types.h | 10 +- core/wma/src/wma_data.c | 203 +++++++++-------------------------- core/wma/src/wma_mgmt.c | 20 +++- 7 files changed, 82 insertions(+), 179 deletions(-) diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c index a4d167ddbc4c..10a3d6d38f77 100644 --- a/core/dp/txrx/ol_tx.c +++ b/core/dp/txrx/ol_tx.c @@ -1893,17 +1893,16 @@ ol_txrx_data_tx_cb_set(struct cdp_vdev *pvdev, } void -ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, - uint8_t type, +ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type, ol_txrx_mgmt_tx_cb download_cb, ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt) { struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; TXRX_ASSERT1(type < OL_TXRX_MGMT_NUM_TYPES); - pdev->tx_mgmt.callbacks[type].download_cb = download_cb; - pdev->tx_mgmt.callbacks[type].ota_ack_cb = ota_ack_cb; - pdev->tx_mgmt.callbacks[type].ctxt = ctxt; + pdev->tx_mgmt_cb.download_cb = download_cb; + pdev->tx_mgmt_cb.ota_ack_cb = ota_ack_cb; + pdev->tx_mgmt_cb.ctxt = ctxt; } #if defined(HELIUMPLUS) @@ -1965,7 +1964,7 @@ ol_txrx_mgmt_send_ext(struct cdp_vdev *pvdev, tx_msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_MGMT; tx_msdu_info.htt.info.vdev_id = vdev->vdev_id; tx_msdu_info.htt.action.do_tx_complete = - pdev->tx_mgmt.callbacks[type].ota_ack_cb ? 1 : 0; + pdev->tx_mgmt_cb.ota_ack_cb ? 1 : 0; /* * FIX THIS: l2_hdr_type should only specify L2 header type diff --git a/core/dp/txrx/ol_tx.h b/core/dp/txrx/ol_tx.h index d9dc02c9de85..be0ac0da788e 100644 --- a/core/dp/txrx/ol_tx.h +++ b/core/dp/txrx/ol_tx.h @@ -140,8 +140,7 @@ void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err); * for a given type of management frame. */ void -ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, - uint8_t type, +ol_txrx_mgmt_tx_cb_set(struct cdp_pdev *ppdev, uint8_t type, ol_txrx_mgmt_tx_cb download_cb, ol_txrx_mgmt_tx_cb ota_ack_cb, void *ctxt); diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index fb8178b04143..dbd0e74737ec 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -771,6 +771,7 @@ void ol_tx_desc_frame_free_nonstd(struct ol_txrx_pdev_t *pdev, OL_TX_RESTORE_HDR(tx_desc, (tx_desc->netbuf)); #endif if (tx_desc->pkt_type == OL_TX_FRM_NO_FREE) { + /* free the tx desc but don't unmap or free the frame */ if (pdev->tx_data_callback.func) { qdf_nbuf_set_next(tx_desc->netbuf, NULL); @@ -816,15 +817,12 @@ void ol_tx_desc_frame_free_nonstd(struct ol_txrx_pdev_t *pdev, * provided to the txrx layer. * no need to check it a 2nd time. */ - ota_ack_cb = pdev->tx_mgmt.callbacks[mgmt_type].ota_ack_cb; + ota_ack_cb = pdev->tx_mgmt_cb.ota_ack_cb; if (ota_ack_cb) { void *ctxt; - - ctxt = pdev->tx_mgmt.callbacks[mgmt_type].ctxt; + ctxt = pdev->tx_mgmt_cb.ctxt; ota_ack_cb(ctxt, tx_desc->netbuf, had_error); } - /* free the netbuf */ - qdf_nbuf_free(tx_desc->netbuf); } else if (had_error == htt_tx_status_download_fail) { /* Failed to send to target */ diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c index 8eee570e9f38..d350cd949a69 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -327,12 +327,10 @@ ol_tx_download_done_base(struct ol_txrx_pdev_t *pdev, * call the download callback if registered */ if (tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE) { - int tx_mgmt_index = tx_desc->pkt_type - OL_TXRX_MGMT_TYPE_BASE; ol_txrx_mgmt_tx_cb download_cb = - pdev->tx_mgmt.callbacks[tx_mgmt_index].download_cb; - + pdev->tx_mgmt_cb.download_cb; if (download_cb) { - download_cb(pdev->tx_mgmt.callbacks[tx_mgmt_index].ctxt, + download_cb(pdev->tx_mgmt_cb.ctxt, tx_desc->netbuf, status != A_OK); } } diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index 8836e726551d..e04859795bed 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -702,12 +702,10 @@ struct ol_txrx_pdev_t { /* tx management delivery notification callback functions */ struct { - struct { - ol_txrx_mgmt_tx_cb download_cb; - ol_txrx_mgmt_tx_cb ota_ack_cb; - void *ctxt; - } callbacks[OL_TXRX_MGMT_NUM_TYPES]; - } tx_mgmt; + ol_txrx_mgmt_tx_cb download_cb; + ol_txrx_mgmt_tx_cb ota_ack_cb; + void *ctxt; + } tx_mgmt_cb; data_stall_detect_cb data_stall_detect_callback; /* packetdump callback functions */ diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 59054f192778..bf7c71819837 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -82,6 +82,7 @@ #include "wlan_objmgr_peer_obj.h" #include #include +#include "wlan_lmac_if_api.h" struct wma_search_rate { int32_t rate; @@ -1368,66 +1369,6 @@ QDF_STATUS wma_process_rate_update_indicate(tp_wma_handle wma, return QDF_STATUS_SUCCESS; } -/** - * wma_mgmt_tx_ack_work_handler() - mgmt tx ack work queue - * @ack_work: work structure - * - * Return: none - */ -static void wma_mgmt_tx_ack_work_handler(void *ack_work) -{ - struct wma_tx_ack_work_ctx *work; - tp_wma_handle wma_handle; - wma_tx_ota_comp_callback ack_cb; - - if (cds_is_load_or_unload_in_progress()) { - WMA_LOGE("%s: Driver load/unload in progress", __func__); - return; - } - - work = (struct wma_tx_ack_work_ctx *)ack_work; - - wma_handle = work->wma_handle; - ack_cb = wma_handle->umac_ota_ack_cb[work->sub_type]; - - WMA_LOGD("Tx Ack Cb SubType %d Status %d", - work->sub_type, work->status); - - /* Call the Ack Cb registered by UMAC */ - ack_cb((tpAniSirGlobal) (wma_handle->mac_context), NULL, - work->status ? 0 : 1, NULL); - - qdf_mem_free(work); - wma_handle->ack_work_ctx = NULL; -} - -/** - * wma_mgmt_tx_comp_conf_ind() - Post mgmt tx complete indication to PE. - * @wma_handle: Pointer to WMA handle - * @sub_type: Tx mgmt frame sub type - * @status: Mgmt frame tx status - * - * This function sends mgmt complition confirmation to PE for deauth - * and deassoc frames. - * - * Return: none - */ -static void -wma_mgmt_tx_comp_conf_ind(tp_wma_handle wma_handle, uint8_t sub_type, - int32_t status) -{ - int32_t tx_comp_status; - - tx_comp_status = status ? 0 : 1; - if (sub_type == SIR_MAC_MGMT_DISASSOC) { - wma_send_msg(wma_handle, WMA_DISASSOC_TX_COMP, NULL, - tx_comp_status); - } else if (sub_type == SIR_MAC_MGMT_DEAUTH) { - wma_send_msg(wma_handle, WMA_DEAUTH_TX_COMP, NULL, - tx_comp_status); - } -} - /** * wma_mgmt_tx_ack_comp_hdlr() - handles tx ack mgmt completion * @context: context with which the handler is registered @@ -1442,34 +1383,14 @@ wma_mgmt_tx_comp_conf_ind(tp_wma_handle wma_handle, uint8_t sub_type, static void wma_mgmt_tx_ack_comp_hdlr(void *wma_context, qdf_nbuf_t netbuf, int32_t status) { - tpSirMacFrameCtl pFc = (tpSirMacFrameCtl) (qdf_nbuf_data(netbuf)); tp_wma_handle wma_handle = (tp_wma_handle) wma_context; + struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *) + wma_handle->psoc; + uint16_t desc_id; - if (wma_handle && wma_handle->umac_ota_ack_cb[pFc->subType]) { - if ((pFc->subType == SIR_MAC_MGMT_DISASSOC) || - (pFc->subType == SIR_MAC_MGMT_DEAUTH)) { - wma_mgmt_tx_comp_conf_ind(wma_handle, - (uint8_t) pFc->subType, - status); - } else { - struct wma_tx_ack_work_ctx *ack_work; + desc_id = QDF_NBUF_CB_MGMT_TXRX_DESC_ID(netbuf); - ack_work = qdf_mem_malloc(sizeof( - struct wma_tx_ack_work_ctx)); - - if (ack_work) { - ack_work->wma_handle = wma_handle; - ack_work->sub_type = pFc->subType; - ack_work->status = status; - - qdf_create_work(0, &ack_work->ack_cmp_work, - wma_mgmt_tx_ack_work_handler, - ack_work); - - qdf_sched_work(0, &ack_work->ack_cmp_work); - } - } - } + mgmt_txrx_tx_completion_handler(psoc, desc_id, status, NULL); } /** @@ -1529,16 +1450,7 @@ QDF_STATUS wma_tx_attach(tp_wma_handle wma_handle) void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* Register for Tx Management Frames */ - cdp_mgmt_tx_cb_set(soc, txrx_pdev, - GENERIC_NODOWLOAD_ACK_COMP_INDEX, - NULL, wma_mgmt_tx_ack_comp_hdlr, wma_handle); - - cdp_mgmt_tx_cb_set(soc, txrx_pdev, - GENERIC_DOWNLD_COMP_NOACK_COMP_INDEX, - wma_mgmt_tx_dload_comp_hldr, NULL, wma_handle); - - cdp_mgmt_tx_cb_set(soc, txrx_pdev, - GENERIC_DOWNLD_COMP_ACK_COMP_INDEX, + cdp_mgmt_tx_cb_set(soc, txrx_pdev, 0, wma_mgmt_tx_dload_comp_hldr, wma_mgmt_tx_ack_comp_hdlr, wma_handle); @@ -1558,7 +1470,6 @@ QDF_STATUS wma_tx_attach(tp_wma_handle wma_handle) */ QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle) { - uint32_t frame_index = 0; void *soc = cds_get_context(QDF_MODULE_ID_SOC); /* Get the Vos Context */ @@ -1575,12 +1486,7 @@ QDF_STATUS wma_tx_detach(tp_wma_handle wma_handle) if (txrx_pdev) { /* Deregister with TxRx for Tx Mgmt completion call back */ - for (frame_index = 0; frame_index < FRAME_INDEX_MAX; - frame_index++) { - cdp_mgmt_tx_cb_set(soc, - txrx_pdev, - frame_index, NULL, NULL, txrx_pdev); - } + cdp_mgmt_tx_cb_set(soc, txrx_pdev, 0, NULL, NULL, txrx_pdev); } /* Reset Tx Frm Callbacks */ @@ -2774,11 +2680,6 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, else tx_frm_index = GENERIC_NODOWLOAD_ACK_COMP_INDEX; - /* Store the Ack Cb sent by UMAC */ - if (pFc->subType < SIR_MAC_MGMT_RESERVED15) { - wma_handle->umac_ota_ack_cb[pFc->subType] = - tx_frm_ota_comp_cb; - } } else { if (downld_comp_required) tx_frm_index = @@ -2841,58 +2742,52 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, } } - if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, - WMI_SERVICE_MGMT_TX_WMI)) { - mgmt_param.tx_frame = tx_frame; - mgmt_param.frm_len = frmLen; - mgmt_param.vdev_id = vdev_id; - mgmt_param.pdata = pData; - mgmt_param.chanfreq = chanfreq; - mgmt_param.qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + mgmt_param.tx_frame = tx_frame; + mgmt_param.frm_len = frmLen; + mgmt_param.vdev_id = vdev_id; + mgmt_param.pdata = pData; + mgmt_param.chanfreq = chanfreq; + mgmt_param.qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); + mgmt_param.use_6mbps = use_6mbps; + mgmt_param.tx_type = tx_frm_index; - /* - * Update the tx_params TLV only for rates - * other than 1Mbps and 6 Mbps - */ - if (rid < RATEID_DEFAULT && - (rid != RATEID_1MBPS && rid != RATEID_6MBPS)) { - WMA_LOGD(FL("using rate id: %d for Tx"), rid); - mgmt_param.tx_params_valid = true; - wma_update_tx_send_params(&mgmt_param.tx_param, rid); - } + /* + * Update the tx_params TLV only for rates + * other than 1Mbps and 6 Mbps + */ + if (rid < RATEID_DEFAULT && + (rid != RATEID_1MBPS && rid != RATEID_6MBPS)) { + WMA_LOGD(FL("using rate id: %d for Tx"), rid); + mgmt_param.tx_params_valid = true; + wma_update_tx_send_params(&mgmt_param.tx_param, rid); + } - psoc = wma_handle->psoc; - if (!psoc) { - WMA_LOGE("%s: psoc ctx is NULL", __func__); - goto error; - } + psoc = wma_handle->psoc; + if (!psoc) { + WMA_LOGE("%s: psoc ctx is NULL", __func__); + goto error; + } - wh = (struct ieee80211_frame *)(qdf_nbuf_data(tx_frame)); - mac_addr = wh->i_addr1; - peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_MGMT_NB_ID); - if (!peer) { - mac_addr = wh->i_addr2; - peer = wlan_objmgr_get_peer(psoc, mac_addr, - WLAN_MGMT_NB_ID); - } + wh = (struct ieee80211_frame *)(qdf_nbuf_data(tx_frame)); + mac_addr = wh->i_addr1; + peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_MGMT_NB_ID); + if (!peer) { + mac_addr = wh->i_addr2; + peer = wlan_objmgr_get_peer(psoc, mac_addr, + WLAN_MGMT_NB_ID); + } - status = wlan_mgmt_txrx_mgmt_frame_tx(peer, - (tpAniSirGlobal)wma_handle->mac_context, - (qdf_nbuf_t)tx_frame, - NULL, tx_frm_ota_comp_cb, - WLAN_UMAC_COMP_MLME, &mgmt_param); + status = wlan_mgmt_txrx_mgmt_frame_tx(peer, + (tpAniSirGlobal)wma_handle->mac_context, + (qdf_nbuf_t)tx_frame, + NULL, tx_frm_ota_comp_cb, + WLAN_UMAC_COMP_MLME, &mgmt_param); - wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID); - if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: mgmt tx failed", __func__); - qdf_nbuf_free((qdf_nbuf_t)tx_frame); - goto error; - } - } else { - /* Hand over the Tx Mgmt frame to TxRx */ - status = cdp_mgmt_send_ext(soc, - txrx_vdev, tx_frame, - tx_frm_index, use_6mbps, chanfreq); + wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_NB_ID); + if (status != QDF_STATUS_SUCCESS) { + WMA_LOGE("%s: mgmt tx failed", __func__); + qdf_nbuf_free((qdf_nbuf_t)tx_frame); + goto error; } /* diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index e5d04f990c88..b5d8cc519a3f 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3968,6 +3968,8 @@ QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct wmi_mgmt_params *mgmt_params = (struct wmi_mgmt_params *)mgmt_tx_params; + void *soc = cds_get_context(QDF_MODULE_ID_SOC); + struct cdp_vdev *txrx_vdev; if (!mgmt_params) { WMA_LOGE("%s: mgmt_params ptr passed is NULL", __func__); @@ -3986,8 +3988,22 @@ QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } - status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle, - mgmt_params); + txrx_vdev = wma_handle->interfaces[mgmt_params->vdev_id].handle; + + if (WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_MGMT_TX_WMI)) { + status = wmi_mgmt_unified_cmd_send(wma_handle->wmi_handle, + mgmt_params); + } else { + QDF_NBUF_CB_MGMT_TXRX_DESC_ID(buf) + = mgmt_params->desc_id; + + status = cdp_mgmt_send_ext(soc, txrx_vdev, buf, + mgmt_params->tx_type, + mgmt_params->use_6mbps, + mgmt_params->chanfreq); + } + if (status != QDF_STATUS_SUCCESS) { WMA_LOGE("%s: mgmt tx failed", __func__); return status;