From 9e32a28d729b644992ec8fb5eadcb4764c427a41 Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Wed, 19 Jul 2017 17:59:06 +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: I013deb6e526fc0c99b1620a9d267063d1c3406f0 CRs-Fixed: 2097697 --- core/dp/txrx/ol_tx.c | 10 +- core/dp/txrx/ol_tx.h | 2 - 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 | 201 +++++++++-------------------------- core/wma/src/wma_mgmt.c | 20 +++- 7 files changed, 79 insertions(+), 178 deletions(-) diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c index 6bcef6cab599..779a824c7d78 100644 --- a/core/dp/txrx/ol_tx.c +++ b/core/dp/txrx/ol_tx.c @@ -1894,15 +1894,13 @@ 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 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) @@ -1964,7 +1962,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..5522a17300c6 100644 --- a/core/dp/txrx/ol_tx.h +++ b/core/dp/txrx/ol_tx.h @@ -124,7 +124,6 @@ void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err); * ol_txrx_mgmt_tx_cb_set() - Store a callback for delivery * notifications for management frames. * @ppdev: the data physical device object - * @type: the type of mgmt frame the callback is used for * @download_cb: the callback for notification of delivery to the target * @ota_ack_cb: the callback for notification of delivery to the peer * @ctxt: context to use with the callback @@ -141,7 +140,6 @@ void ol_txrx_mgmt_tx_complete(void *ctxt, qdf_nbuf_t netbuf, int err); */ void 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 9c0940e72571..17817678d6e8 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -325,12 +325,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..0713a20147e5 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); } /** @@ -1530,15 +1451,6 @@ QDF_STATUS wma_tx_attach(tp_wma_handle wma_handle) /* 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, 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, 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 8e33bb7dfad1..87bf5026b7ad 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3922,6 +3922,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__); @@ -3940,8 +3942,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;