summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Chang <schang@qca.qualcomm.com>2014-03-13 14:47:12 -0700
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-03-16 21:21:04 -0700
commit8587f2df82e43fcbfaf5dd66c520107e72d1e57e (patch)
tree76daf1aa817588bcc0d56bd89c6e33887673601c
parent6b78c371a7a18e2875a5acd9d04d5cf5df1fdb19 (diff)
qca-cld: IBSS-RMC TX Flow control enable
IBSS-RMC requirement is packet drop rate should be less than 1%. To achieve this requirement, OS level UDP flow control is needed. WLAN Rome driver is drop based flow control. Then packet drop rate is pretty high. Instead blindly drop packet, back pressuring to OS NET layer is needed. Change-Id: I6066548ff720ea4ac57946956cd61249394a07df CRs-fixed: 611027
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c158
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.h5
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_tx_send.c15
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx.c26
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_internal.h7
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_types.h4
-rw-r--r--CORE/HDD/inc/wlan_hdd_tx_rx.h14
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c8
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c39
-rw-r--r--CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h14
-rw-r--r--CORE/SERVICES/COMMON/ol_txrx_osif_api.h12
-rw-r--r--CORE/SERVICES/COMMON/wdi_in.h3
-rw-r--r--CORE/TL/inc/wlan_qct_tl.h115
-rw-r--r--Kbuild1
14 files changed, 421 insertions, 0 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index 0707159b12ec..1c41e725f9a1 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -922,6 +922,9 @@ void WLANTL_RegisterVdev(void *vos_ctx, void *vdev)
return;
}
+#ifdef QCA_LL_TX_FLOW_CT
+ txrx_ops.tx.flow_control_cb = WLANTL_TXFlowControlCb;
+#endif /* QCA_LL_TX_FLOW_CT */
txrx_ops.rx.std = tlshim_data_rx_handler;
wdi_in_osif_vdev_register(vdev_handle, tl_shim, &txrx_ops);
/* TODO: Keep vdev specific tx callback, if needed */
@@ -1634,6 +1637,11 @@ VOS_STATUS WLANTL_Open(void *vos_ctx, WLANTL_ConfigInfoType *tl_cfg)
adf_os_spinlock_init(&tl_shim->sta_info[i].stainfo_lock);
tl_shim->sta_info[i].flags = 0;
INIT_LIST_HEAD(&tl_shim->sta_info[i].cached_bufq);
+#ifdef QCA_LL_TX_FLOW_CT
+ tl_shim->sta_info[i].flowControl = NULL;
+ tl_shim->sta_info[i].sessionId = 0xFF;
+ tl_shim->sta_info[i].adpaterCtxt = NULL;
+#endif /* QCA_LL_TX_FLOW_CT */
}
INIT_WORK(&tl_shim->cache_flush_work, tl_shim_cache_flush_work);
@@ -1724,3 +1732,153 @@ void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id)
return peer->vdev;
}
+
+#ifdef QCA_LL_TX_FLOW_CT
+/*=============================================================================
+ FUNCTION WLANTL_GetTxResource
+
+ DESCRIPTION
+ This function will query WLAN kernel driver TX resource availability.
+ Per STA/VDEV instance, if TX resource is not available, should back
+ pressure to OS NET layer.
+
+ DEPENDENCIES
+ NONE
+
+ PARAMETERS
+ IN
+ vos_context : Pointer to VOS global context
+ sta_id : STA/VDEV instance to query TX resource
+
+ RETURN VALUE
+ VOS_TRUE : Enough resource available, Not need to PAUSE TX OS Q
+ VOS_FALSE : TX resource is not enough, stop OS TX Q
+
+ SIDE EFFECTS
+
+==============================================================================*/
+v_BOOL_t WLANTL_GetTxResource
+(
+ void *vos_context,
+ uint8_t sta_id
+)
+{
+ struct ol_txrx_peer_t *peer = NULL;
+
+ if (!vos_context) {
+ return VOS_TRUE;
+ }
+
+ peer = ol_txrx_peer_find_by_local_id(
+ ((pVosContextType) vos_context)->pdev_txrx_ctx,
+ sta_id);
+ if (!peer) {
+ return VOS_TRUE;
+ }
+
+ return (v_BOOL_t)wdi_in_get_tx_resource(peer->vdev);
+}
+
+/*=============================================================================
+ FUNCTION WLANTL_TXFlowControlCb
+
+ DESCRIPTION
+ This function will be called bu TX resource management unit.
+ If TC resource management unit reserved enough resource for TX session,
+ Call this function to resume OS TX Q.
+
+ PARAMETERS
+ IN
+ tlContext : Pointer to TL SHIM context
+ sessionId : STA/VDEV instance to query TX resource
+ resume_tx : Resume OS TX Q or not
+
+ RETURN VALUE
+ NONE
+
+ SIDE EFFECTS
+
+==============================================================================*/
+void WLANTL_TXFlowControlCb
+(
+ void *tlContext,
+ v_U8_t sessionId,
+ v_BOOL_t resume_tx
+)
+{
+ struct txrx_tl_shim_ctx *tl_shim;
+ v_U8_t sta_loop;
+ WLANTL_TxFlowControlCBType flow_control_cb = NULL;
+ void *adpter_ctxt = NULL;
+
+ tl_shim = (struct txrx_tl_shim_ctx *)tlContext;
+ if (!tl_shim) {
+ /* Invalid instace */
+ return;
+ }
+
+ for (sta_loop = 0; sta_loop < WLAN_MAX_STA_COUNT; sta_loop++) {
+ if ((tl_shim->sta_info[sta_loop].sessionId == sessionId) &&
+ (tl_shim->sta_info[sta_loop].flowControl))
+ {
+ flow_control_cb = tl_shim->sta_info[sta_loop].flowControl;
+ adpter_ctxt = tl_shim->sta_info[sta_loop].adpaterCtxt;
+ break;
+ }
+ }
+
+ if ((flow_control_cb) && (adpter_ctxt)) {
+ flow_control_cb(adpter_ctxt, resume_tx);
+ }
+ return;
+}
+
+/*=============================================================================
+ FUNCTION WLANTL_RegisterTXFlowControl
+
+ DESCRIPTION
+ This function will be called by TL client.
+ Any device want to enable TX flow control, should register Cb function
+ And needed information into TL SHIM
+
+ PARAMETERS
+ IN
+ vos_ctx : Global OS context context
+ sta_id : STA/VDEV instance index
+ flowControl : Flow control callback function pointer
+ sessionId : VDEV ID
+ adpaterCtxt : VDEV os interface adapter context
+
+ RETURN VALUE
+ NONE
+
+ SIDE EFFECTS
+
+==============================================================================*/
+void WLANTL_RegisterTXFlowControl
+(
+ void *vos_ctx,
+ v_U8_t sta_id,
+ WLANTL_TxFlowControlCBType flowControl,
+ v_U8_t sessionId,
+ void *adpaterCtxt
+)
+{
+ struct txrx_tl_shim_ctx *tl_shim;
+ struct tlshim_sta_info *sta_info;
+
+ tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx);
+ if (!tl_shim) {
+ TLSHIM_LOGE("tl_shim is NULL");
+ return;
+ }
+
+ sta_info = &tl_shim->sta_info[sta_id];
+ sta_info->flowControl = flowControl;
+ sta_info->sessionId = sessionId;
+ sta_info->adpaterCtxt = adpaterCtxt;
+
+ return;
+}
+#endif /* QCA_LL_TX_FLOW_CT */
+
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
index 4029179e7743..0530a8f61506 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
@@ -55,6 +55,11 @@ struct tlshim_sta_info {
adf_os_spinlock_t stainfo_lock;
struct list_head cached_bufq;
unsigned long flags;
+#ifdef QCA_LL_TX_FLOW_CT
+ WLANTL_TxFlowControlCBType flowControl;
+ v_U8_t sessionId;
+ void *adpaterCtxt;
+#endif /* QCA_LL_TX_FLOW_CT */
};
struct txrx_tl_shim_ctx {
diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c
index 8a879a9373b6..24337792928a 100644
--- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c
+++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c
@@ -456,6 +456,7 @@ ol_tx_completion_handler(
u_int16_t tx_desc_id;
struct ol_tx_desc_t *tx_desc;
char *trace_str;
+ struct ol_txrx_vdev_t *vdev;
uint32_t byte_cnt = 0;
union ol_tx_desc_list_elem_t *td_array = pdev->tx_desc.array;
@@ -516,6 +517,20 @@ ol_tx_completion_handler(
} else {
OL_TX_TARGET_CREDIT_ADJUST(num_msdus, pdev, NULL);
}
+
+#ifdef QCA_LL_TX_FLOW_CT
+ adf_os_spin_lock(&pdev->tx_mutex);
+ TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem)
+ {
+ if (vdev->os_q_paused &&
+ (pdev->tx_desc.num_free > TXRX_LL_FLOW_CT_FREE_D_HWM)) {
+ vdev->osif_flow_control_cb(vdev->osif_dev, vdev->vdev_id, A_TRUE);
+ vdev->os_q_paused = A_FALSE;
+ }
+ }
+ adf_os_spin_unlock(&pdev->tx_mutex);
+#endif /* QCA_LL_TX_FLOW_CT */
+
/* Do one shot statistics */
TXRX_STATS_UPDATE_TX_STATS(pdev, status, num_msdus, byte_cnt);
}
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c
index b8dbec773ac7..859cd0f1a685 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c
@@ -839,6 +839,11 @@ ol_txrx_vdev_attach(
ol_tx_vdev_ll_pause_queue_send,
vdev);
+#ifdef QCA_LL_TX_FLOW_CT
+ vdev->os_q_paused = A_FALSE;
+ vdev->osif_flow_control_cb = NULL;
+#endif /* QCA_LL_TX_FLOW_CT */
+
/* add this vdev into the pdev's list */
TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem);
@@ -870,6 +875,9 @@ void ol_txrx_osif_vdev_register(ol_txrx_vdev_handle vdev,
} else {
txrx_ops->tx.std = vdev->tx = OL_TX_LL;
txrx_ops->tx.non_std = ol_tx_non_std_ll;
+#ifdef QCA_LL_TX_FLOW_CT
+ vdev->osif_flow_control_cb = txrx_ops->tx.flow_control_cb;
+#endif /* QCA_LL_TX_FLOW_CT */
}
}
@@ -1971,3 +1979,21 @@ ol_vdev_rx_set_intrabss_fwd(
vdev->disable_intrabss_fwd = val;
}
+#ifdef QCA_LL_TX_FLOW_CT
+a_bool_t
+ol_txrx_get_tx_resource(
+ ol_txrx_vdev_handle vdev
+)
+{
+ adf_os_spin_lock_bh(&vdev->pdev->tx_mutex);
+ if ((vdev->pdev->tx_desc.num_free) <
+ TXRX_LL_FLOW_CT_FREE_D_LWM) {
+ /* Not enough free resource, stop TX OS Q */
+ vdev->os_q_paused = A_TRUE;
+ adf_os_spin_unlock_bh(&vdev->pdev->tx_mutex);
+ return A_FALSE;
+ }
+ adf_os_spin_unlock_bh(&vdev->pdev->tx_mutex);
+ return A_TRUE;
+}
+#endif /* QCA_LL_TX_FLOW_CT */
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h b/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h
index 6b8a6f6b85fa..43894a50fece 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h
@@ -667,4 +667,11 @@ do {
#define QCA_SUPPORT_TXRX_VDEV_LL_TXQ
#endif
+#ifdef QCA_LL_TX_FLOW_CT
+#define TXRX_LL_FLOW_CT_FREE_Q_LWM 100
+#define TXRX_LL_FLOW_CT_FREE_Q_HWM 300
+#define TXRX_LL_FLOW_CT_FREE_D_LWM 500
+#define TXRX_LL_FLOW_CT_FREE_D_HWM 550
+#endif /* QCA_LL_TX_FLOW_CT */
+
#endif /* _OL_TXRX_INTERNAL__H_ */
diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
index 6dd6cddc42c0..66cf4a31576e 100644
--- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
+++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h
@@ -754,6 +754,10 @@ struct ol_txrx_vdev_t {
adf_os_timer_t timer;
} ll_pause;
a_bool_t disable_intrabss_fwd;
+#ifdef QCA_LL_TX_FLOW_CT
+ a_bool_t os_q_paused;
+ ol_txrx_tx_fc_fp osif_flow_control_cb;
+#endif /* QCA_LL_TX_FLOW_CT */
};
struct ol_rx_reorder_array_elem_t {
diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h
index 050fa972fa81..96377948a27f 100644
--- a/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -309,4 +309,18 @@ void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId);
========================================================================*/
void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
WLANTL_ACEnumType acType);
+
+#ifdef QCA_LL_TX_FLOW_CT
+/**============================================================================
+ @brief hdd_tx_resume_cb() - Resume OS TX Q.
+ Q was stopped due to WLAN TX path low resource condition
+
+ @param adapter_context : [in] pointer to vdev apdapter
+ @param tx_resume : [in] TX Q resume trigger
+
+ @return : NONE
+ ===========================================================================*/
+void hdd_tx_resume_cb(void *adapter_context,
+ v_U8_t tx_resume);
+#endif /* QCA_LL_TX_FLOW_CT */
#endif // end #if !defined( WLAN_HDD_TX_RX_H )
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 62748ac31302..353da498816e 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -1122,6 +1122,14 @@ static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter,
return vosStatus;
}
+#ifdef QCA_LL_TX_FLOW_CT
+ WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext,
+ staDesc.ucSTAId,
+ hdd_tx_resume_cb,
+ pAdapter->sessionId,
+ (void *)pAdapter);
+#endif /* QCA_LL_TX_FLOW_CT */
+
if ( cfg_param->dynSplitscan &&
( VOS_TIMER_STATE_RUNNING !=
vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index d2ae468b6221..7633775a4cbc 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -809,6 +809,36 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
#else
+#ifdef QCA_LL_TX_FLOW_CT
+/**============================================================================
+ @brief hdd_tx_resume_cb() - Resume OS TX Q.
+ Q was stopped due to WLAN TX path low resource condition
+
+ @param adapter_context : [in] pointer to vdev apdapter
+ @param tx_resume : [in] TX Q resume trigger
+
+ @return : NONE
+ ===========================================================================*/
+void hdd_tx_resume_cb(void *adapter_context,
+ v_U8_t tx_resume)
+{
+ hdd_adapter_t *pAdapter = (hdd_adapter_t *)adapter_context;
+
+ if (!pAdapter)
+ {
+ /* INVALID ARG */
+ return;
+ }
+
+ /* Resume TX */
+ if (VOS_TRUE == tx_resume)
+ {
+ netif_tx_wake_all_queues(pAdapter->dev);
+ }
+ return;
+}
+#endif /* QCA_LL_TX_FLOW_CT */
+
/**============================================================================
@brief hdd_hard_start_xmit() - Function registered with the Linux OS for
transmitting packets. This version of the function directly passes the packet
@@ -867,6 +897,15 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
kfree_skb(skb);
return NETDEV_TX_OK;
}
+#ifdef QCA_LL_TX_FLOW_CT
+ if(VOS_FALSE == WLANTL_GetTxResource((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+ STAId))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
+ "%s: Out of TX resource, stop Q", __func__);
+ netif_tx_stop_all_queues(dev);
+ }
+#endif /* QCA_LL_TX_FLOW_CT */
}
else
{
diff --git a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h
index 4ec903979b67..22ada2a448b9 100644
--- a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h
+++ b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h
@@ -997,4 +997,18 @@ static inline void ol_tx_throttle_init_period(struct ol_txrx_pdev_t *pdev,
void ol_vdev_rx_set_intrabss_fwd(ol_txrx_vdev_handle vdev, a_bool_t val);
+#ifdef QCA_LL_TX_FLOW_CT
+/**
+ * @brief Query TX resource availability by OS IF
+ * @details
+ * OS IF will query TX resource status to decide back pressuring or not
+ *
+ * @param vdev - the virtual device
+ */
+a_bool_t
+ol_txrx_get_tx_resource(
+ ol_txrx_vdev_handle vdev
+);
+#endif /* QCA_LL_TX_FLOW_CT */
+
#endif /* _OL_TXRX_CTRL_API__H_ */
diff --git a/CORE/SERVICES/COMMON/ol_txrx_osif_api.h b/CORE/SERVICES/COMMON/ol_txrx_osif_api.h
index 43e3c2130601..5e7c102cacee 100644
--- a/CORE/SERVICES/COMMON/ol_txrx_osif_api.h
+++ b/CORE/SERVICES/COMMON/ol_txrx_osif_api.h
@@ -90,6 +90,15 @@ typedef void (*ol_txrx_rx_fp)(void *osif_dev, adf_nbuf_t msdus);
#endif /* OSIF_NEED_RX_PEER_ID */
/**
+ * @typedef ol_txrx_tx_fc_fp
+ * @brief tx flow control notification function from txrx to OS shim
+ * @param osif_dev - the virtual device's OS shim object
+ * @param vdev_id - virtual device id
+ * @param tx_resume - tx os q should be resumed or not
+ */
+typedef void (*ol_txrx_tx_fc_fp)(void *osif_dev, u_int8_t vdev_id, a_bool_t tx_resume);
+
+/**
* @typedef ol_txrx_rx_fp
* @brief receive function to hand batches of data frames from txrx to OS shim
*/
@@ -99,6 +108,9 @@ struct ol_txrx_osif_ops {
struct {
ol_txrx_tx_fp std;
ol_txrx_tx_non_std_fp non_std;
+#ifdef QCA_LL_TX_FLOW_CT
+ ol_txrx_tx_fc_fp flow_control_cb;
+#endif /* QCA_LL_TX_FLOW_CT */
} tx;
/* rx function pointers - specified by OS shim, stored by txrx */
diff --git a/CORE/SERVICES/COMMON/wdi_in.h b/CORE/SERVICES/COMMON/wdi_in.h
index 7f7f0c807787..b015b24828b0 100644
--- a/CORE/SERVICES/COMMON/wdi_in.h
+++ b/CORE/SERVICES/COMMON/wdi_in.h
@@ -1222,6 +1222,9 @@ ol_tx_queue_log_display(ol_txrx_pdev_handle pdev);
#define wdi_in_peer_state_update ol_txrx_peer_state_update
#define wdi_in_peer_keyinstalled_state_update ol_txrx_peer_keyinstalled_state_update
#define wdi_in_vdev_rx_fwd_disabled ol_vdev_rx_set_intrabss_fwd
+#ifdef QCA_LL_TX_FLOW_CT
+#define wdi_in_get_tx_resource ol_txrx_get_tx_resource
+#endif /* QCA_LL_TX_FLOW_CT */
#include <ol_txrx_dbg.h>
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index a2944c554c2d..a23ba91ca460 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -630,6 +630,29 @@ typedef VOS_STATUS (*WLANTL_STARxCBType)( v_PVOID_t pvosGCtx,
typedef VOS_STATUS (*WLANTL_STARxCBType)(v_PVOID_t pvosGCtx,
adf_nbuf_t pDataBuff,
v_U8_t ucSTAId);
+
+#ifdef QCA_LL_TX_FLOW_CT
+/*----------------------------------------------------------------------------
+
+ DESCRIPTION
+ Type of the TX Flow Control callback registered with TL.
+
+ TL will call this to notify the client when TX resource condition
+ is chnaged
+
+ PARAMETERS
+
+ IN
+ adapterCtxt: pointer to device apapter context
+ resume_tx: Ressume OS TX Q
+
+ RETURN VALUE
+ NONE
+
+----------------------------------------------------------------------------*/
+typedef void (*WLANTL_TxFlowControlCBType)(void *adapterCtxt,
+ v_BOOL_t resume_tx);
+#endif /* QCA_LL_TX_FLOW_CT */
#endif /* QCA_WIFI_2_0 */
/*----------------------------------------------------------------------------
@@ -2993,4 +3016,96 @@ WLANTL_TLDebugMessage
}
#endif /* QCA_WIFI_2_0 */
+
+#ifdef QCA_WIFI_2_0
+#ifdef QCA_LL_TX_FLOW_CT
+/*=============================================================================
+ FUNCTION WLANTL_GetTxResource
+
+ DESCRIPTION
+ This function will query WLAN kernel driver TX resource availability.
+ Per STA/VDEV instance, if TX resource is not available, should back
+ pressure to OS NET layer.
+
+ DEPENDENCIES
+ NONE
+
+ PARAMETERS
+ IN
+ vos_context : Pointer to VOS global context
+ sta_id : STA/VDEV instance to query TX resource
+
+ RETURN VALUE
+ VOS_TRUE : Enough resource available, Not need to PAUSE TX OS Q
+ VOS_FALSE : TX resource is not enough, stop OS TX Q
+
+ SIDE EFFECTS
+
+==============================================================================*/
+v_BOOL_t WLANTL_GetTxResource
+(
+ void *vos_context,
+ uint8_t sta_id
+);
+
+/*=============================================================================
+ FUNCTION WLANTL_TXFlowControlCb
+
+ DESCRIPTION
+ This function will be called by TX resource management unit.
+ If TC resource management unit reserved enough resource for TX session,
+ Call this function to resume OS TX Q.
+
+ PARAMETERS
+ IN
+ tlContext : Pointer to TL SHIM context
+ sessionId : STA/VDEV instance to query TX resource
+ resume_tx : Resume OS TX Q or not
+
+ RETURN VALUE
+ NONE
+
+ SIDE EFFECTS
+
+==============================================================================*/
+void WLANTL_TXFlowControlCb
+(
+ void *tlContext,
+ v_U8_t sessionId,
+ v_BOOL_t resume_tx
+);
+
+/*=============================================================================
+ FUNCTION WLANTL_RegisterTXFlowControl
+
+ DESCRIPTION
+ This function will be called by TL client.
+ Any device want to enable TX flow control, should register Cb function
+ And needed information into TL SHIM
+
+ PARAMETERS
+ IN
+ vos_ctx : Global OS context context
+ sta_id : STA/VDEV instance index
+ flowControl : Flow control callback function pointer
+ sessionId : VDEV ID
+ adpaterCtxt : VDEV os interface adapter context
+
+ RETURN VALUE
+ NONE
+
+ SIDE EFFECTS
+
+==============================================================================*/
+void WLANTL_RegisterTXFlowControl
+(
+ void *vos_ctx,
+ v_U8_t sta_id,
+ WLANTL_TxFlowControlCBType flowControl,
+ v_U8_t sessionId,
+ void *adpaterCtxt
+);
+#endif /* QCA_LL_TX_FLOW_CT */
+#endif /* QCA_WIFI_2_0 */
+
#endif /* #ifndef WLAN_QCT_WLANTL_H */
diff --git a/Kbuild b/Kbuild
index 8095ebc86a2d..74de600c1a90 100644
--- a/Kbuild
+++ b/Kbuild
@@ -880,6 +880,7 @@ CDEFINES += -DWLANTL_DEBUG
else
CDEFINES += -DOSIF_NEED_RX_PEER_ID \
-DQCA_SUPPORT_TXRX_LOCAL_PEER_ID
+CDEFINES += -DQCA_LL_TX_FLOW_CT
endif
ifeq ($(CONFIG_QCA_WIFI_2_0), 1)