Browse Source

qcacld-3.0: Add function to set vdev tx_desc limit

1) Add ol txrx function to set TX descriptor limits for a
vdev.
2) Set the TX descriptor limits for STA and AP mode.

Change-Id: Ie9b1e52c3aff05db99ba3748a94792cc8116cdca
CRs-fixed: 2236321
Ajit Pal Singh 7 years ago
parent
commit
d6c08f2f0e
4 changed files with 112 additions and 4 deletions
  1. 52 2
      core/dp/txrx/ol_txrx.c
  2. 30 2
      core/dp/txrx/ol_txrx.h
  3. 16 0
      core/hdd/src/wlan_hdd_assoc.c
  4. 14 0
      core/hdd/src/wlan_hdd_hostapd.c

+ 52 - 2
core/dp/txrx/ol_txrx.c

@@ -112,6 +112,13 @@ ol_txrx_set_wmm_param(struct cdp_pdev *data_pdev,
 extern void ol_txrx_get_pn_info(void *ppeer, uint8_t **last_pn_valid,
 		    uint64_t **last_pn, uint32_t **rmf_pn_replays);
 
+#ifdef QCA_HL_NETDEV_FLOW_CONTROL
+static u16 ol_txrx_tx_desc_alloc_table[TXRX_FC_MAX] = {
+	[TXRX_FC_5GH_80M_2x2] = 2000,
+	[TXRX_FC_2GH_40M_2x2] = 800,
+};
+#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
+
 /* thresh for peer's cached buf queue beyond which the elements are dropped */
 #define OL_TXRX_CACHED_BUFQ_THRESH 128
 
@@ -1586,7 +1593,6 @@ ol_txrx_pdev_post_attach(struct cdp_pdev *ppdev)
 	 */
 	if (pdev->cfg.is_high_latency) {
 		desc_pool_size = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev);
-
 		qdf_atomic_init(&pdev->tx_queue.rsrc_cnt);
 		qdf_atomic_add(desc_pool_size, &pdev->tx_queue.rsrc_cnt);
 
@@ -5024,6 +5030,15 @@ static int ol_txrx_register_hl_flow_control(struct cdp_soc_t *soc,
 					    tx_pause_callback flowcontrol)
 {
 	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	u32 desc_pool_size = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev);
+
+	/*
+	 * Assert if the tx descriptor pool size meets the requirements
+	 * Maximum 2 sessions are allowed on a band.
+	 */
+	QDF_ASSERT((2 * ol_txrx_tx_desc_alloc_table[TXRX_FC_5GH_80M_2x2] +
+		    ol_txrx_tx_desc_alloc_table[TXRX_FC_2GH_40M_2x2])
+		    <= desc_pool_size);
 
 	if (!pdev || !flowcontrol) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
@@ -5063,6 +5078,40 @@ static int ol_txrx_set_vdev_os_queue_status(u8 vdev_id,
 	}
 	return 0;
 }
+
+/**
+ * ol_txrx_set_vdev_tx_desc_limit() - Set TX descriptor limits for a vdev
+ * @vdev_id: vdev id for the vdev under consideration.
+ * @chan: Channel on which the vdev has been started.
+ */
+static int ol_txrx_set_vdev_tx_desc_limit(u8 vdev_id, u8 chan)
+{
+	struct ol_txrx_vdev_t *vdev =
+	(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);
+	enum ol_txrx_fc_limit_id fc_limit_id;
+	u32 td_limit;
+
+	if (!vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid vdev_id %d", __func__, vdev_id);
+		return -EINVAL;
+	}
+
+	/* TODO: Handle no of spatial streams and channel BW */
+	if (WLAN_REG_IS_5GHZ_CH(chan))
+		fc_limit_id = TXRX_FC_5GH_80M_2x2;
+	else
+		fc_limit_id = TXRX_FC_2GH_40M_2x2;
+
+	qdf_spin_lock_bh(&vdev->pdev->tx_mutex);
+	td_limit = ol_txrx_tx_desc_alloc_table[fc_limit_id];
+	vdev->tx_desc_limit = td_limit;
+	vdev->queue_stop_th = td_limit - TXRX_HL_TX_DESC_HI_PRIO_RESERVED;
+	vdev->queue_restart_th = td_limit - TXRX_HL_TX_DESC_QUEUE_RESTART_TH;
+	qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
+
+	return 0;
+}
 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
 
 /**
@@ -6069,7 +6118,8 @@ static struct cdp_lflowctl_ops ol_ops_l_flowctl = {
 	.vdev_flush = ol_txrx_vdev_flush,
 	.vdev_pause = ol_txrx_vdev_pause,
 	.vdev_unpause = ol_txrx_vdev_unpause,
-	.set_vdev_os_queue_status = ol_txrx_set_vdev_os_queue_status
+	.set_vdev_os_queue_status = ol_txrx_set_vdev_os_queue_status,
+	.set_vdev_tx_desc_limit = ol_txrx_set_vdev_tx_desc_limit
 };
 #else /* QCA_HL_NETDEV_FLOW_CONTROL */
 static struct cdp_lflowctl_ops ol_ops_l_flowctl = { };

+ 30 - 2
core/dp/txrx/ol_txrx.h

@@ -31,6 +31,34 @@
  */
 #define OL_TX_NON_FWD_RESERVE	100
 
+/**
+ * enum ol_txrx_fc_limit_id - Flow control identifier for
+ * vdev limits based on band, channel bw and number of spatial streams
+ * @TXRX_FC_5GH_80M_2x2: Limit for 5GHz, 80MHz BW, 2x2 NSS
+ * @TXRX_FC_5GH_40M_2x2:
+ * @TXRX_FC_5GH_20M_2x2:
+ * @TXRX_FC_5GH_80M_1x1:
+ * @TXRX_FC_5GH_40M_1x1:
+ * @TXRX_FC_5GH_20M_1x1:
+ * @TXRX_FC_2GH_40M_2x2:
+ * @TXRX_FC_2GH_20M_2x2:
+ * @TXRX_FC_2GH_40M_1x1:
+ * @TXRX_FC_2GH_20M_1x1:
+ */
+enum ol_txrx_fc_limit_id {
+	TXRX_FC_5GH_80M_2x2,
+	TXRX_FC_5GH_40M_2x2,
+	TXRX_FC_5GH_20M_2x2,
+	TXRX_FC_5GH_80M_1x1,
+	TXRX_FC_5GH_40M_1x1,
+	TXRX_FC_5GH_20M_1x1,
+	TXRX_FC_2GH_40M_2x2,
+	TXRX_FC_2GH_20M_2x2,
+	TXRX_FC_2GH_40M_1x1,
+	TXRX_FC_2GH_20M_1x1,
+	TXRX_FC_MAX
+};
+
 ol_txrx_peer_handle ol_txrx_peer_get_ref_by_addr(ol_txrx_pdev_handle pdev,
 						 u8 *peer_addr,
 						 u8 *peer_id,
@@ -67,9 +95,9 @@ ol_tx_desc_pool_size_hl(struct cdp_cfg *ctrl_pdev);
 #define TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED 100
 #endif
 
-#ifdef CONFIG_TX_DESC_HI_PRIO_RESERVE
 #define TXRX_HL_TX_DESC_HI_PRIO_RESERVED 20
-#endif
+#define TXRX_HL_TX_DESC_QUEUE_RESTART_TH \
+		(TXRX_HL_TX_DESC_HI_PRIO_RESERVED + 100)
 
 #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS)
 

+ 16 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -2704,6 +2704,7 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 	tSirResultCodes timeout_reason = 0;
 	bool ok;
 	mac_handle_t mac_handle;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
 
 	if (!hdd_ctx) {
 		hdd_err("HDD context is NULL");
@@ -3041,6 +3042,12 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 							pConnectedProfile->SSID.ssId,
 							roam_info->u.
 							pConnectedProfile->SSID.length);
+
+						cdp_hl_fc_set_td_limit(soc,
+						adapter->session_id,
+						sta_ctx->
+						conn_info.operationChannel);
+
 						hdd_send_roamed_ind(
 								dev,
 								roam_bss,
@@ -3085,6 +3092,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 				} else if (!hddDisconInProgress) {
 					hdd_debug("ft_carrier_on is %d, sending connect indication",
 						 ft_carrier_on);
+					cdp_hl_fc_set_td_limit(soc,
+					adapter->session_id,
+					sta_ctx->conn_info.operationChannel);
 					hdd_connect_result(dev,
 							   roam_info->
 							   bssid.bytes,
@@ -3141,6 +3151,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 								   false,
 								   roam_info->statusCode);
 					}
+					cdp_hl_fc_set_td_limit(soc,
+					adapter->session_id,
+					sta_ctx->conn_info.operationChannel);
 				}
 			}
 			if (!hddDisconInProgress) {
@@ -3175,6 +3188,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 						adapter->session_id,
 						&reqRsnLength, reqRsnIe);
 
+			cdp_hl_fc_set_td_limit(soc,
+				adapter->session_id,
+				sta_ctx->conn_info.operationChannel);
 			hdd_send_re_assoc_event(dev, adapter, roam_info,
 						reqRsnIe, reqRsnLength);
 			/* Reassoc successfully */

+ 14 - 0
core/hdd/src/wlan_hdd_hostapd.c

@@ -1718,6 +1718,16 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 			ap_ctx->broadcast_sta_id =
 				pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
 
+			cdp_hl_fc_set_td_limit(
+				cds_get_context(QDF_MODULE_ID_SOC),
+				adapter->session_id,
+				ap_ctx->operating_channel);
+
+			hdd_register_tx_flow_control(adapter,
+				hdd_softap_tx_resume_timer_expired_handler,
+				hdd_softap_tx_resume_cb,
+				hdd_tx_flow_control_is_pause);
+
 			/* @@@ need wep logic here to set privacy bit */
 			qdf_status =
 				hdd_softap_register_bc_sta(adapter,
@@ -2399,6 +2409,10 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 			pSapEvent->sapevt.sap_ch_selected.ht_sec_ch,
 			&sap_ch_param);
 
+		cdp_hl_fc_set_td_limit(cds_get_context(QDF_MODULE_ID_SOC),
+				       adapter->session_id,
+				       ap_ctx->operating_channel);
+
 		phy_mode = wlan_sap_get_phymode(
 				WLAN_HDD_GET_SAP_CTX_PTR(adapter));