From d6c08f2f0eab03b02be1219d84574166342851d3 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Wed, 25 Apr 2018 16:55:26 +0530 Subject: [PATCH] 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 --- core/dp/txrx/ol_txrx.c | 54 +++++++++++++++++++++++++++++++-- core/dp/txrx/ol_txrx.h | 32 +++++++++++++++++-- core/hdd/src/wlan_hdd_assoc.c | 16 ++++++++++ core/hdd/src/wlan_hdd_hostapd.c | 14 +++++++++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index eb08f3a265ff..a554bd5cf999 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/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 = { }; diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h index 2d369cca49b3..487d90e44539 100644 --- a/core/dp/txrx/ol_txrx.h +++ b/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) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 35ee7863f8f2..3c16ab08851a 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/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 */ diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 44de57ed86c7..e89acd1dd4a3 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/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));