summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Babu Kumaravel <kganesh@qti.qualcomm.com>2014-08-09 12:53:05 +0530
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-08-09 18:53:15 -0700
commitc82a763544ed7e4b09fa15807fb065aba76b47ad (patch)
tree5994444d83155f1320e9ff6f4cfde21d074f3978
parentc073da8e1398ece64b6bcb41dccd78612e376c7b (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.c2
-rw-r--r--CORE/CLD_TXRX/HTT/htt_h2t.c19
-rw-r--r--CORE/CLD_TXRX/HTT/htt_t2h.c30
-rw-r--r--CORE/CLD_TXRX/HTT/htt_types.h1
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_cfg.c1
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_tx.c26
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_tx_send.c20
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx.c1
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_types.h1
-rw-r--r--CORE/SERVICES/COMMON/ol_htt_tx_api.h3
-rw-r--r--CORE/SERVICES/COMMON/ol_txrx_htt_api.h3
-rw-r--r--CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h12
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