diff options
| author | Ganesh Babu Kumaravel <kganesh@qti.qualcomm.com> | 2014-08-09 12:53:05 +0530 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-08-09 18:53:15 -0700 |
| commit | c82a763544ed7e4b09fa15807fb065aba76b47ad (patch) | |
| tree | 5994444d83155f1320e9ff6f4cfde21d074f3978 | |
| parent | c073da8e1398ece64b6bcb41dccd78612e376c7b (diff) | |
qcacld/txrx:support for credit completion for HL
For HL i.e SDIO tx completion indication from firmware
for every frame is an additional overhead. This impacts
the throughput.
so new bit tx_compl_req is added to HTT Tx Descriptor.
If tx_compl_req is set Host requires tx completion indication
from Firmware.
If tx_compl_req is not set Firmware won't send Tx Completion
for every frame. Instead Firmware update the Host regarding
credit using HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND.
tx_compl_req is set 1 for all frames if tx_free_at_download
is not set.
If tx_free_at_download is set then tx_compl_req is set for
management and non standard frames and tx_compl_req is not
for data frames.
Change-Id: I89bd896525531a3251bec61922bd68bae7e0d4a2
CRs-Fixed: 707290
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt.c | 2 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_h2t.c | 19 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_t2h.c | 30 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/HTT/htt_types.h | 1 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_cfg.c | 1 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx.c | 26 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx_send.c | 20 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx.c | 1 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx_types.h | 1 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_htt_tx_api.h | 3 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_txrx_htt_api.h | 3 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h | 12 |
12 files changed, 82 insertions, 37 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt.c b/CORE/CLD_TXRX/HTT/htt.c index 7ce284a19bae..c16e6c8d31b6 100644 --- a/CORE/CLD_TXRX/HTT/htt.c +++ b/CORE/CLD_TXRX/HTT/htt.c @@ -184,6 +184,8 @@ htt_attach( /* for efficiency, store a local copy of the is_high_latency flag */ pdev->cfg.is_high_latency = ol_cfg_is_high_latency(pdev->ctrl_pdev); + pdev->cfg.default_tx_comp_req = + !ol_cfg_tx_free_at_download(pdev->ctrl_pdev); pdev->cfg.is_full_reorder_offload = ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev); diff --git a/CORE/CLD_TXRX/HTT/htt_h2t.c b/CORE/CLD_TXRX/HTT/htt_h2t.c index 3ac693fd6f13..d9d5ee573776 100644 --- a/CORE/CLD_TXRX/HTT/htt_h2t.c +++ b/CORE/CLD_TXRX/HTT/htt_h2t.c @@ -158,6 +158,10 @@ htt_h2t_ver_req_msg(struct htt_pdev_t *pdev) #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } return A_OK; } @@ -486,6 +490,9 @@ htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev) #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif + if (!pdev->cfg.default_tx_comp_req) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } return A_OK; } @@ -576,6 +583,10 @@ htt_h2t_dbg_stats_get( #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } return 0; } @@ -634,6 +645,10 @@ htt_h2t_sync_msg(struct htt_pdev_t *pdev, u_int8_t sync_cnt) #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } return A_OK; } @@ -701,6 +716,10 @@ htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev, #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif + if ((pdev->cfg.is_high_latency) && + (!pdev->cfg.default_tx_comp_req)) { + ol_tx_target_credit_update(pdev->txrx_pdev, -1); + } return 0; } diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c index bd0ec60c0632..2593ff29377e 100644 --- a/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -334,28 +334,14 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) #endif case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: { - A_INT16 htt_credit_delta_abs = HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word); - struct ol_txrx_pdev_t* ptxrx_pdev = pdev->txrx_pdev; - if ( HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ) { - /* negative delta */ -#if DEBUG_CREDIT - adf_os_print(" <HTT> Decrease Credit %d - %d = %d(Msg).\n", - adf_os_atomic_read(&ptxrx_pdev->target_tx_credit), - htt_credit_delta_abs, - adf_os_atomic_read(&ptxrx_pdev->target_tx_credit) - htt_credit_delta_abs); -#endif - adf_os_atomic_add((A_INT32)(-htt_credit_delta_abs), &ptxrx_pdev->target_tx_credit); - } else { - /* positive delta */ -#if DEBUG_CREDIT - adf_os_print(" <HTT> Increase Credit %d + %d = %d(Msg).\n", - adf_os_atomic_read(&ptxrx_pdev->target_tx_credit), - htt_credit_delta_abs, - adf_os_atomic_read(&ptxrx_pdev->target_tx_credit) + htt_credit_delta_abs); -#endif - adf_os_atomic_add((A_INT32)htt_credit_delta_abs, &ptxrx_pdev->target_tx_credit); - } - + u_int32_t htt_credit_delta_abs; + int32_t htt_credit_delta; + int sign; + + htt_credit_delta_abs = HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word); + sign = HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ? -1 : 1; + htt_credit_delta = sign * htt_credit_delta_abs; + ol_tx_credit_completion_handler(pdev->txrx_pdev, htt_credit_delta); break; } diff --git a/CORE/CLD_TXRX/HTT/htt_types.h b/CORE/CLD_TXRX/HTT/htt_types.h index 51fddfc3552a..56369a42c303 100644 --- a/CORE/CLD_TXRX/HTT/htt_types.h +++ b/CORE/CLD_TXRX/HTT/htt_types.h @@ -213,6 +213,7 @@ struct htt_pdev_t { struct { int is_high_latency; int is_full_reorder_offload; + int default_tx_comp_req; } cfg; struct { u_int8_t major; diff --git a/CORE/CLD_TXRX/TXRX/ol_cfg.c b/CORE/CLD_TXRX/TXRX/ol_cfg.c index ba111262162c..6d4aaf22e1f4 100644 --- a/CORE/CLD_TXRX/TXRX/ol_cfg.c +++ b/CORE/CLD_TXRX/TXRX/ol_cfg.c @@ -53,6 +53,7 @@ ol_pdev_handle ol_pdev_cfg_attach(adf_os_device_t osdev, cfg_ctx->is_high_latency = 1; /* 802.1Q and SNAP / LLC headers are accounted for elsewhere */ cfg_ctx->tx_download_size = 1500; + cfg_ctx->tx_free_at_download = 0; #else /* * Need to change HTT_LL_TX_HDR_SIZE_IP accordingly. diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.c b/CORE/CLD_TXRX/TXRX/ol_tx.c index 1d9233bb8a60..b340c549bdcb 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx.c @@ -78,6 +78,7 @@ ol_tx_ll(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list) struct ol_txrx_msdu_info_t msdu_info; msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type; + msdu_info.htt.action.tx_comp_req = 0; /* * The msdu_list variable could be used instead of the msdu var, * but just to clarify which operations are done on a single MSDU @@ -398,6 +399,7 @@ ol_tx_non_std_ll( struct ol_txrx_msdu_info_t msdu_info; msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type; + msdu_info.htt.action.tx_comp_req = 0; /* * The msdu_list variable could be used instead of the msdu var, @@ -480,7 +482,8 @@ static inline adf_nbuf_t ol_tx_hl_base( ol_txrx_vdev_handle vdev, enum ol_tx_spec tx_spec, - adf_nbuf_t msdu_list) + adf_nbuf_t msdu_list, + int tx_comp_req) { struct ol_txrx_pdev_t *pdev = vdev->pdev; adf_nbuf_t msdu = msdu_list; @@ -562,6 +565,7 @@ ol_tx_hl_base( tx_msdu_info.htt.info.vdev_id = vdev->vdev_id; tx_msdu_info.htt.info.frame_type = htt_frm_type_data; tx_msdu_info.htt.info.l2_hdr_type = pdev->htt_pkt_type; + tx_msdu_info.htt.action.tx_comp_req = tx_comp_req; txq = ol_tx_classify(vdev, tx_desc, msdu, &tx_msdu_info); @@ -644,7 +648,10 @@ MSDU_LOOP_BOTTOM: adf_nbuf_t ol_tx_hl(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list) { - return ol_tx_hl_base(vdev, ol_tx_spec_std, msdu_list); + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req; + + return ol_tx_hl_base(vdev, ol_tx_spec_std, msdu_list, tx_comp_req); } adf_nbuf_t @@ -653,7 +660,16 @@ ol_tx_non_std_hl( enum ol_tx_spec tx_spec, adf_nbuf_t msdu_list) { - return ol_tx_hl_base(vdev, tx_spec, msdu_list); + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req; + + if (!tx_comp_req) { + if ((tx_spec == ol_tx_spec_no_free) && + (pdev->tx_data_callback.func)) { + tx_comp_req = 1; + } + } + return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req); } adf_nbuf_t @@ -754,8 +770,11 @@ ol_txrx_mgmt_send( adf_nbuf_map_single(pdev->osdev, tx_mgmt_frm, ADF_OS_DMA_TO_DEVICE); if (pdev->cfg.is_high_latency) { + tx_msdu_info.htt.action.tx_comp_req = 1; tx_desc = ol_tx_desc_hl(pdev, vdev, tx_mgmt_frm, &tx_msdu_info); } else { + /* For LL tx_comp_req is not used so initialized to 0 */ + tx_msdu_info.htt.action.tx_comp_req = 0; tx_desc = ol_tx_desc_ll(pdev, vdev, tx_mgmt_frm, &tx_msdu_info); /* FIX THIS - * The FW currently has trouble using the host's fragments table @@ -844,6 +863,7 @@ adf_nbuf_t ol_tx_reinject( msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type; msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_INVALID; msdu_info.peer = NULL; + msdu_info.htt.action.tx_comp_req = 0; ol_tx_prepare_ll(tx_desc, vdev, msdu, &msdu_info); HTT_TX_DESC_POSTPONED_SET(*((u_int32_t *)(tx_desc->htt_tx_desc)), TRUE); diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c index faf499ddf2a4..86c86adaeae7 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -326,7 +326,14 @@ ol_tx_download_done_hl_free( tx_desc = ol_tx_desc_find(pdev, msdu_id); adf_os_assert(tx_desc); - ol_tx_desc_frame_free_nonstd(pdev, tx_desc, status != A_OK); + + ol_tx_download_done_base(pdev, status, msdu, msdu_id); + + if ((tx_desc->pkt_type != ol_tx_frm_no_free) && + (tx_desc->pkt_type < OL_TXRX_MGMT_TYPE_BASE)) { + adf_os_atomic_add(1, &pdev->tx_queue.rsrc_cnt); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, status != A_OK); + } #if 0 /* TODO: Advanced feature */ //ol_tx_dwl_sched(pdev, OL_TX_HL_SCHED_DOWNLOAD_DONE); adf_os_assert(0); @@ -468,6 +475,17 @@ ol_tx_discard_target_frms(ol_txrx_pdev_handle pdev) } } +void +ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits) +{ + ol_tx_target_credit_update(pdev, credits); + if (pdev->cfg.is_high_latency) { + ol_tx_sched(pdev); + } + /* UNPAUSE OS Q */ + OL_TX_FLOW_CT_UNPAUSE_OS_Q(pdev); +} + /* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of ol_tx_completion_handler(). * any change in ol_tx_completion_handler() must be mirrored in ol_tx_inspect_handler(). */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index 9b7c1a903d9b..ea8382edf4d2 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -255,6 +255,7 @@ ol_txrx_pdev_attach( /* init LL/HL cfg here */ pdev->cfg.is_high_latency = ol_cfg_is_high_latency(ctrl_pdev); + pdev->cfg.default_tx_comp_req = !ol_cfg_tx_free_at_download(ctrl_pdev); /* store provided params */ pdev->ctrl_pdev = ctrl_pdev; diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h index 42d7e69adb38..a60c1acb8286 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -391,6 +391,7 @@ struct ol_txrx_pdev_t { int is_high_latency; int host_addba; int ll_pause_txq_limit; + int default_tx_comp_req; } cfg; /* WDI subscriber's event list */ diff --git a/CORE/SERVICES/COMMON/ol_htt_tx_api.h b/CORE/SERVICES/COMMON/ol_htt_tx_api.h index 323c71d0b2fa..f4eeafbf9aac 100644 --- a/CORE/SERVICES/COMMON/ol_htt_tx_api.h +++ b/CORE/SERVICES/COMMON/ol_htt_tx_api.h @@ -154,6 +154,8 @@ struct htt_msdu_info_t { u_int8_t use_6mbps; /* mgmt frames: option to force 6 Mbps rate */ u_int8_t do_encrypt; u_int8_t do_tx_complete; + u_int8_t tx_comp_req; + /* * cksum_offload - Specify whether checksum offload is enabled or not * Target FW uses this flag to turn on HW checksumming @@ -409,6 +411,7 @@ htt_tx_desc_init( HTT_TX_DESC_VDEV_ID_SET(local_word0, msdu_info->info.vdev_id); HTT_TX_DESC_EXT_TID_SET(local_word0, msdu_info->info.ext_tid); HTT_TX_DESC_CKSUM_OFFLOAD_SET(local_word0, msdu_info->action.cksum_offload); + HTT_TX_DESC_TX_COMP_SET(local_word0, msdu_info->action.tx_comp_req); HTT_TX_DESC_NO_ENCRYPT_SET(local_word0, msdu_info->action.do_encrypt ? 0 : 1); *word0 = local_word0; diff --git a/CORE/SERVICES/COMMON/ol_txrx_htt_api.h b/CORE/SERVICES/COMMON/ol_txrx_htt_api.h index e0e07e6ccf69..9a1f164f9b3c 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_htt_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_htt_api.h @@ -164,6 +164,9 @@ ol_tx_completion_handler( enum htt_tx_status status, void *tx_msdu_id_iterator); +void +ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits); + /** * @brief Init the total amount of target credit. * @details diff --git a/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h b/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h index 1016a25dec2a..513d03259148 100644 --- a/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h +++ b/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h @@ -210,17 +210,7 @@ #ifndef HIF_SDIO #define CFG_TGT_NUM_MSDU_DESC (32) #else -/* - * For SDIO Only 16 tx-buffers are hooked onto SDIO MBOX DMA engine - * in Firmware. So set the targe number of descriptors to map the - * same. - * This is only temporary solution. - * The better solution is defining CFG_TGT_NUM_MSDU_DESC to be 0 - * and waiting for an initial TX_TARGET_CREDIT_UPDATE_IND message - * from the FW to know how many tx buffers the FW has provided - * for the host's downloads. - */ -#define CFG_TGT_NUM_MSDU_DESC (16) +#define CFG_TGT_NUM_MSDU_DESC (0) #endif /* * Maximum number of frag table entries |
