diff options
| author | Nirav Shah <nnshah@qti.qualcomm.com> | 2016-02-04 11:17:26 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-02-22 12:19:15 +0530 |
| commit | 2f237b8049e97f5a2791d29dabd2fce3233a557b (patch) | |
| tree | 9a3ca9a2dcb76d1626085234d2e97e886438956d | |
| parent | c24b369acc31d5ea863fde8c2d514a586af476ff (diff) | |
qcacld-2.0: Add logic to bundle packets for HL
Add logic to queue and bundle packets before
giving it to scheduler to ensure predictive HTC
bundling to reduce SDIO overhead and improvement
in TX throughput
CRs-Fixed: 972009
Change-Id: I5135adf62a83fbb457c0ee09dbe5d7ae6abd661d
| -rw-r--r-- | CORE/CLD_TXRX/TLSHIM/tl_shim.h | 25 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_cfg.c | 53 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx.c | 253 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx.h | 34 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx_queue.c | 5 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx.c | 13 | ||||
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_txrx_types.h | 12 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_cfg.h | 40 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 30 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 3 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 30 | ||||
| -rw-r--r-- | CORE/MAC/inc/aniGlobal.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_cfg.h | 20 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_txrx_osif_api.h | 22 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 27 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_cnss.h | 5 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_api.c | 24 | ||||
| -rw-r--r-- | Kbuild | 8 |
21 files changed, 590 insertions, 21 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h index 617bc5b267c5..0fb1f8809653 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -132,4 +132,27 @@ static inline void tl_shim_set_peer_authorized_event(void *vos_ctx, v_U8_t sessi { } #endif + +static inline +void tlshim_set_bundle_require(uint8_t vdev_id, unsigned long tx_bytes, + uint32_t time_in_ms, uint32_t high_th, uint32_t low_th) +{ + ol_tx_vdev_set_bundle_require(vdev_id, tx_bytes, + time_in_ms, high_th, low_th); +} + +static inline void tlshim_reset_bundle_require(void) +{ + void *vos_ctx = vos_get_global_context(VOS_MODULE_ID_TL, NULL); + void *pdev; + + if (!vos_ctx) + return; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_ctx); + if (!pdev) + return; + + ol_tx_pdev_reset_bundle_require(pdev); +} #endif diff --git a/CORE/CLD_TXRX/TXRX/ol_cfg.c b/CORE/CLD_TXRX/TXRX/ol_cfg.c index 26a3f2433a16..368d220dca78 100644 --- a/CORE/CLD_TXRX/TXRX/ol_cfg.c +++ b/CORE/CLD_TXRX/TXRX/ol_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -33,6 +33,29 @@ module_param(vow_config, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); MODULE_PARM_DESC(vow_config, "Do VoW Configuration"); EXPORT_SYMBOL(vow_config); +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +/** + * ol_cfg_update_bundle_params() - update tx bundle params + * @cfg_ctx: cfg context + * @cfg_param: parameters + * + * Return: none + */ +void ol_cfg_update_bundle_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t cfg_param) +{ + cfg_ctx->pkt_bundle_timer_value = cfg_param.pkt_bundle_timer_value; + cfg_ctx->pkt_bundle_size = cfg_param.pkt_bundle_size; +} +#else +void ol_cfg_update_bundle_params(struct txrx_pdev_cfg_t *cfg_ctx, + struct txrx_pdev_cfg_param_t cfg_param) +{ + return; +} +#endif + + /* FIX THIS - * For now, all these configuration parameters are hardcoded. * Many of these should actually be determined dynamically instead. @@ -87,9 +110,37 @@ ol_pdev_handle ol_pdev_cfg_attach(adf_os_device_t osdev, cfg_ctx->ipa_uc_rsc.rx_ind_ring_size = cfg_param.uc_rx_indication_ring_count; cfg_ctx->ipa_uc_rsc.tx_partition_base = cfg_param.uc_tx_partition_base; #endif /* IPA_UC_OFFLOAD */ + + ol_cfg_update_bundle_params(cfg_ctx, cfg_param); return (ol_pdev_handle) cfg_ctx; } +#ifdef FEATURE_BUS_BANDWIDTH +/** + * ol_cfg_get_bundle_timer_value() - get bundle timer value + * @pdev: pdev handle + * + * Return: bundle timer value + */ +int ol_cfg_get_bundle_timer_value(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->pkt_bundle_timer_value; +} + +/** + * ol_cfg_get_bundle_size() - get bundle size value + * @pdev: pdev handle + * + * Return: bundle size value + */ +int ol_cfg_get_bundle_size(ol_pdev_handle pdev) +{ + struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; + return cfg->pkt_bundle_size; +} +#endif + int ol_cfg_is_high_latency(ol_pdev_handle pdev) { struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev; diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.c b/CORE/CLD_TXRX/TXRX/ol_tx.c index ad29d3245b7e..b335c325b844 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -556,7 +556,7 @@ ol_tx_hl_base( ol_txrx_vdev_handle vdev, enum ol_tx_spec tx_spec, adf_nbuf_t msdu_list, - int tx_comp_req) + int tx_comp_req, bool call_sched) { struct ol_txrx_pdev_t *pdev = vdev->pdev; adf_nbuf_t msdu = msdu_list; @@ -717,18 +717,261 @@ ol_tx_hl_base( MSDU_LOOP_BOTTOM: msdu = next; } - ol_tx_sched(pdev); + + if (call_sched == true) + ol_tx_sched(pdev); return NULL; /* all MSDUs were accepted */ } +/** + * ol_txrx_get_vdev_from_vdev_id() - get vdev from vdev_id + * @vdev_id: vdev_id + * + * Return: vdev handle + * NULL if not found. + */ +ol_txrx_vdev_handle ol_txrx_get_vdev_from_vdev_id(uint8_t vdev_id) +{ + v_CONTEXT_t vos_context = vos_get_global_context(VOS_MODULE_ID_TXRX, + NULL); + ol_txrx_pdev_handle pdev = vos_get_context(VOS_MODULE_ID_TXRX, + vos_context); + ol_txrx_vdev_handle vdev = NULL; + + if (adf_os_unlikely(!pdev)) + return NULL; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) + if (vdev->vdev_id == vdev_id) + break; + + return vdev; +} + +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +/** + * ol_tx_pdev_reset_bundle_require() - reset bundle require flag + * @pdev_handle: pdev handle + * + * Return: none + */ +void +ol_tx_pdev_reset_bundle_require(void* pdev_handle) +{ + struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)pdev_handle; + struct ol_txrx_vdev_t *vdev; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + vdev->bundling_reqired = false; + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "vdev_id %d bundle_require %d\n", + vdev->vdev_id, vdev->bundling_reqired); + } +} + +/** + * ol_tx_vdev_set_bundle_require() - set bundle require flag if required + * @vdev_id: vdev id + * @tx_packets: number of tx packets + * @time_in_ms: time in ms + * @high_th: high threashold + * @low_th: low threashold + * + * Return: none + */ +void +ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_bytes, + uint32_t time_in_ms, uint32_t high_th, uint32_t low_th) +{ + struct ol_txrx_vdev_t* vdev = ol_txrx_get_vdev_from_vdev_id(vdev_id); + bool old_bundle_required; + + if ((!vdev) || (low_th > high_th)) + return; + + old_bundle_required = vdev->bundling_reqired; + if (tx_bytes > ((high_th * time_in_ms * 1500)/1000)) + vdev->bundling_reqired = true; + else if (tx_bytes < ((low_th * time_in_ms * 1500)/1000)) + vdev->bundling_reqired = false; + + if (old_bundle_required != vdev->bundling_reqired) + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "vdev_id %d bundle_require %d tx_bytes %ld time_in_ms %d high_th %d low_th %d\n", + vdev->vdev_id, vdev->bundling_reqired, tx_bytes, + time_in_ms, high_th, low_th); +} + +/** + * ol_tx_hl_queue_flush_all() - drop all packets in vdev bundle queue + * @vdev: vdev handle + * + * Return: none + */ +void +ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t* vdev) +{ + adf_os_spin_lock_bh(&vdev->bundle_queue.mutex); + if (vdev->bundle_queue.txq.depth != 0) { + adf_os_timer_cancel(&vdev->bundle_queue.timer); + vdev->pdev->total_bundle_queue_length -= + vdev->bundle_queue.txq.depth; + adf_nbuf_tx_free(vdev->bundle_queue.txq.head, 1/*error*/); + vdev->bundle_queue.txq.depth = 0; + vdev->bundle_queue.txq.head = NULL; + vdev->bundle_queue.txq.tail = NULL; + } + adf_os_spin_unlock_bh(&vdev->bundle_queue.mutex); +} + +/** + * ol_tx_hl_vdev_queue_append() - append pkt in tx queue + * @vdev: vdev handle + * @msdu_list: msdu list + * + * Return: none + */ +static void +ol_tx_hl_vdev_queue_append(struct ol_txrx_vdev_t* vdev, adf_nbuf_t msdu_list) +{ + adf_os_spin_lock_bh(&vdev->bundle_queue.mutex); + + if (!vdev->bundle_queue.txq.head) { + adf_os_timer_start( + &vdev->bundle_queue.timer, + ol_cfg_get_bundle_timer_value(vdev->pdev->ctrl_pdev)); + vdev->bundle_queue.txq.head = msdu_list; + vdev->bundle_queue.txq.tail = msdu_list; + } else { + adf_nbuf_set_next(vdev->bundle_queue.txq.tail, msdu_list); + } + + while (adf_nbuf_next(msdu_list) != NULL) { + vdev->bundle_queue.txq.depth++; + vdev->pdev->total_bundle_queue_length++; + msdu_list = adf_nbuf_next(msdu_list); + } + + vdev->bundle_queue.txq.depth++; + vdev->pdev->total_bundle_queue_length++; + vdev->bundle_queue.txq.tail = msdu_list; + adf_os_spin_unlock_bh(&vdev->bundle_queue.mutex); + + return; +} + +/** + * ol_tx_hl_vdev_queue_send_all() - send all packets in vdev bundle queue + * @vdev: vdev handle + * @call_sched: invoke scheduler + * + * Return: NULL for success + */ +adf_nbuf_t +ol_tx_hl_vdev_queue_send_all(struct ol_txrx_vdev_t* vdev, bool call_sched) +{ + adf_nbuf_t msdu_list = NULL; + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req; + + adf_os_spin_lock_bh(&vdev->bundle_queue.mutex); + + if (vdev->bundle_queue.txq.depth != 0) { + adf_os_timer_cancel(&vdev->bundle_queue.timer); + vdev->pdev->total_bundle_queue_length -= + vdev->bundle_queue.txq.depth; + msdu_list = ol_tx_hl_base(vdev, ol_tx_spec_std, + vdev->bundle_queue.txq.head, tx_comp_req, call_sched); + + vdev->bundle_queue.txq.depth = 0; + vdev->bundle_queue.txq.head = NULL; + vdev->bundle_queue.txq.tail = NULL; + } + adf_os_spin_unlock_bh(&vdev->bundle_queue.mutex); + + return msdu_list; +} + +/** + * ol_tx_hl_pdev_queue_send_all() - send all packets from all vdev bundle queue + * @pdev: pdev handle + * + * Return: NULL for success + */ +adf_nbuf_t +ol_tx_hl_pdev_queue_send_all(struct ol_txrx_pdev_t* pdev) +{ + struct ol_txrx_vdev_t* vdev; + adf_nbuf_t msdu_list; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + msdu_list = ol_tx_hl_vdev_queue_send_all(vdev, false); + if (msdu_list) + adf_nbuf_tx_free(msdu_list, 1/*error*/); + } + ol_tx_sched(pdev); + return NULL; /* all msdus were accepted */ +} + +/** + * ol_tx_hl_vdev_bundle_timer() - bundle timer function + * @vdev: vdev handle + * + * Return: none + */ +void +ol_tx_hl_vdev_bundle_timer(void *vdev) +{ + adf_nbuf_t msdu_list; + + msdu_list = ol_tx_hl_vdev_queue_send_all(vdev, true); + if (msdu_list) + adf_nbuf_tx_free(msdu_list, 1/*error*/); +} + +/** + * ol_tx_hl_queue() - queueing logic to bundle in HL + * @vdev: vdev handle + * @msdu_list: msdu list + * + * Return: NULL for success/drop msdu list + */ +adf_nbuf_t +ol_tx_hl_queue(struct ol_txrx_vdev_t* vdev, adf_nbuf_t msdu_list) +{ + struct ol_txrx_pdev_t *pdev = vdev->pdev; + int tx_comp_req = pdev->cfg.default_tx_comp_req; + + if (vdev->bundling_reqired == true && + (ol_cfg_get_bundle_size(vdev->pdev->ctrl_pdev) > 1)) { + ol_tx_hl_vdev_queue_append(vdev, msdu_list); + if (pdev->total_bundle_queue_length >= + ol_cfg_get_bundle_size(vdev->pdev->ctrl_pdev)){ + return ol_tx_hl_pdev_queue_send_all(pdev); + } + } else { + if (vdev->bundle_queue.txq.depth != 0) { + ol_tx_hl_vdev_queue_append(vdev, msdu_list); + return ol_tx_hl_vdev_queue_send_all(vdev, true); + } else { + return ol_tx_hl_base(vdev, ol_tx_spec_std, msdu_list, + tx_comp_req, true); + } + } + + return NULL; /* all msdus were accepted */ +} + +#endif + adf_nbuf_t ol_tx_hl(ol_txrx_vdev_handle vdev, adf_nbuf_t 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); + return ol_tx_hl_base(vdev, ol_tx_spec_std, msdu_list, tx_comp_req, true); } adf_nbuf_t @@ -746,7 +989,7 @@ ol_tx_non_std_hl( tx_comp_req = 1; } } - return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req); + return ol_tx_hl_base(vdev, tx_spec, msdu_list, tx_comp_req, true); } adf_nbuf_t diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.h b/CORE/CLD_TXRX/TXRX/ol_tx.h index a2290ae0cc6b..ed6e6439c16c 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.h +++ b/CORE/CLD_TXRX/TXRX/ol_tx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -35,7 +35,6 @@ #include <adf_nbuf.h> /* adf_nbuf_t */ #include <adf_os_lock.h> #include <ol_txrx_api.h> /* ol_txrx_vdev_handle */ - #include <ol_txrx_types.h> /* ol_tx_desc_t, ol_txrx_msdu_info_t */ adf_nbuf_t @@ -44,12 +43,43 @@ ol_tx_ll(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list); adf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list); +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +void +ol_tx_hl_vdev_bundle_timer(void *vdev); + +void +ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t* vdev); + +adf_nbuf_t +ol_tx_hl_queue(struct ol_txrx_vdev_t* vdev, adf_nbuf_t msdu_list); + +#else + +static inline void ol_tx_hl_vdev_bundle_timer(void *vdev) +{ + return; +} + +static inline void +ol_tx_hl_queue_flush_all(struct ol_txrx_vdev_t* vdev) +{ + return; +} + +#endif + #ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ #define OL_TX_LL ol_tx_ll_queue #else #define OL_TX_LL ol_tx_ll #endif +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +#define OL_TX_HL ol_tx_hl_queue +#else +#define OL_TX_HL ol_tx_hl +#endif + void ol_tx_vdev_ll_pause_queue_send(void *context); adf_nbuf_t diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c index 4844e8bbde5c..bf993d3667de 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -105,6 +105,9 @@ ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) struct ol_txrx_peer_t *peer, *peers[PEER_ARRAY_COUNT]; int i, j, peer_count; + /* flush bundling queue */ + ol_tx_hl_queue_flush_all(vdev); + /* flush VDEV TX queues */ for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { txq = &vdev->txqs[i]; diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index e328fd410cec..311bc8445386 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -1092,6 +1092,17 @@ ol_txrx_vdev_attach( /* Default MAX Q depth for every VDEV */ vdev->ll_pause.max_q_depth = ol_tx_cfg_max_tx_queue_depth_ll(vdev->pdev->ctrl_pdev); + + vdev->bundling_reqired = false; + adf_os_spinlock_init(&vdev->bundle_queue.mutex); + vdev->bundle_queue.txq.head = vdev->ll_pause.txq.tail = NULL; + vdev->bundle_queue.txq.depth = 0; + adf_os_timer_init( + pdev->osdev, + &vdev->bundle_queue.timer, + ol_tx_hl_vdev_bundle_timer, + vdev, ADF_DEFERRABLE_TIMER); + /* add this vdev into the pdev's list */ TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem); @@ -1118,7 +1129,7 @@ void ol_txrx_osif_vdev_register(ol_txrx_vdev_handle vdev, vdev->osif_rx = txrx_ops->rx.std; if (ol_cfg_is_high_latency(vdev->pdev->ctrl_pdev)) { - txrx_ops->tx.std = vdev->tx = ol_tx_hl; + txrx_ops->tx.std = vdev->tx = OL_TX_HL; txrx_ops->tx.non_std = ol_tx_non_std_hl; } else { txrx_ops->tx.std = vdev->tx = OL_TX_LL; diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h index bd662377f6d0..a0a3feec1364 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -835,6 +835,7 @@ struct ol_txrx_pdev_t { unsigned int num_descs_per_page; void **desc_pages; struct ol_txrx_peer_t *self_peer; + uint32_t total_bundle_queue_length; }; struct ol_txrx_ocb_chan_info { @@ -928,6 +929,17 @@ struct ol_txrx_vdev_t { u_int16_t tx_fl_hwm; ol_txrx_tx_flow_control_fp osif_flow_control_cb; + bool bundling_reqired; + struct { + struct { + adf_nbuf_t head; + adf_nbuf_t tail; + int depth; + } txq; + adf_os_spinlock_t mutex; + adf_os_timer_t timer; + } bundle_queue; + #if defined(CONFIG_HL_SUPPORT) && defined(FEATURE_WLAN_TDLS) union ol_txrx_align_mac_addr_t hl_tdls_ap_mac_addr; bool hlTdlsFlag; diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 75626200a025..db5f75c00179 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2846,6 +2846,7 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #define CFG_TCP_DELACK_THRESHOLD_LOW_MIN ( 0 ) #define CFG_TCP_DELACK_THRESHOLD_LOW_MAX ( 10000 ) + /* TCP_TX_HIGH_TPUT_THRESHOLD specifies the threshold of packets transmitted * over a period of 100 ms beyond which TCP can be considered to have a high * TX throughput requirement. The driver uses this condition to tweak TCP TX @@ -2859,6 +2860,38 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #endif /* FEATURE_BUS_BANDWIDTH */ +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE + +/* + * PKT_BUNDLE_THRESHOLD_HIGH specifies threshold of packets transmitted + * over a period of 100ms beyond which bundling will be enabled and + * TXRX layer bundle packets before giving to scheduler. If numbers + * of packets falls below PKT_BUNDLE_THRESHOLD_LOW than bundling will + * stop. + */ + +#define CFG_PKT_BUNDLE_THRESHOLD_HIGH "gPacketBundleHighThreshold" +#define CFG_PKT_BUNDLE_THRESHOLD_HIGH_DEFAULT ( 4330 ) +#define CFG_PKT_BUNDLE_THRESHOLD_HIGH_MIN ( 0 ) +#define CFG_PKT_BUNDLE_THRESHOLD_HIGH_MAX ( 70000 ) + +#define CFG_PKT_BUNDLE_THRESHOLD_LOW "gPacketBundleLowThreshold" +#define CFG_PKT_BUNDLE_THRESHOLD_LOW_DEFAULT ( 4000 ) +#define CFG_PKT_BUNDLE_THRESHOLD_LOW_MIN ( 0 ) +#define CFG_PKT_BUNDLE_THRESHOLD_LOW_MAX ( 70000 ) + +#define CFG_PKT_BUNDLE_TIMER_IN_MS "gPacketBundleTimerValue" +#define CFG_PKT_BUNDLE_TIMER_IN_MS_DEFAULT ( 100 ) +#define CFG_PKT_BUNDLE_TIMER_IN_MS_MIN ( 10 ) +#define CFG_PKT_BUNDLE_TIMER_IN_MS_MAX ( 10000 ) + +#define CFG_PKT_BUNDLE_SIZE "gPacketBundleSize" +#define CFG_PKT_BUNDLE_SIZE_DEFAULT ( 10 ) +#define CFG_PKT_BUNDLE_SIZE_MIN ( 0 ) +#define CFG_PKT_BUNDLE_SIZE_MAX ( 32 ) + +#endif /* QCA_SUPPORT_TXRX_HL_BUNDLE */ + #ifdef WLAN_FEATURE_11W #define CFG_PMF_SA_QUERY_MAX_RETRIES_NAME "pmfSaQueryMaxRetries" #define CFG_PMF_SA_QUERY_MAX_RETRIES_DEFAULT ( 5 ) @@ -4064,7 +4097,12 @@ typedef struct v_U32_t tcpDelackThresholdLow; uint32_t tcp_tx_high_tput_thres; #endif /* FEATURE_BUS_BANDWIDTH */ - +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE + uint32_t pkt_bundle_threshold_high; + uint32_t pkt_bundle_threshold_low; + uint16_t pkt_bundle_timer_value; + uint16_t pkt_bundle_size; +#endif /* FW debug log parameters */ v_U32_t enableFwLogType; v_U32_t enableFwLogLevel; diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index d7280a628852..f412a6de6e87 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1128,6 +1128,7 @@ struct hdd_adapter_s #ifdef FEATURE_BUS_BANDWIDTH unsigned long prev_rx_packets; unsigned long prev_tx_packets; + unsigned long prev_tx_bytes; int connection; #endif v_BOOL_t is_roc_inprogress; diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 33d09b9b1286..eaac0852221e 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -735,6 +735,7 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo spin_lock_bh(&pHddCtx->bus_bw_lock); pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + pAdapter->prev_tx_bytes = pAdapter->stats.tx_bytes; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_start_bus_bw_compute_timer(pAdapter); #endif @@ -783,6 +784,7 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo spin_lock_bh(&pHddCtx->bus_bw_lock); pAdapter->prev_tx_packets = 0; pAdapter->prev_rx_packets = 0; + pAdapter->prev_tx_bytes = 0; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_stop_bus_bw_compute_timer(pAdapter); #endif diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index eaab10bcb21a..c14d83d6d86b 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -3512,6 +3512,36 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_TCP_TX_HIGH_TPUT_THRESHOLD_DEFAULT, CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN, CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX ), +#endif +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE + + REG_VARIABLE( CFG_PKT_BUNDLE_THRESHOLD_HIGH, WLAN_PARAM_Integer, + hdd_config_t, pkt_bundle_threshold_high, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PKT_BUNDLE_THRESHOLD_HIGH_DEFAULT, + CFG_PKT_BUNDLE_THRESHOLD_HIGH_MIN, + CFG_PKT_BUNDLE_THRESHOLD_HIGH_MAX ), + + REG_VARIABLE( CFG_PKT_BUNDLE_THRESHOLD_LOW, WLAN_PARAM_Integer, + hdd_config_t, pkt_bundle_threshold_low, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PKT_BUNDLE_THRESHOLD_LOW_DEFAULT, + CFG_PKT_BUNDLE_THRESHOLD_LOW_MIN, + CFG_PKT_BUNDLE_THRESHOLD_LOW_MAX ), + + REG_VARIABLE( CFG_PKT_BUNDLE_TIMER_IN_MS, WLAN_PARAM_Integer, + hdd_config_t, pkt_bundle_timer_value, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PKT_BUNDLE_TIMER_IN_MS_DEFAULT, + CFG_PKT_BUNDLE_TIMER_IN_MS_MIN, + CFG_PKT_BUNDLE_TIMER_IN_MS_MAX ), + + REG_VARIABLE( CFG_PKT_BUNDLE_SIZE, WLAN_PARAM_Integer, + hdd_config_t, pkt_bundle_size, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PKT_BUNDLE_SIZE_DEFAULT, + CFG_PKT_BUNDLE_SIZE_MIN, + CFG_PKT_BUNDLE_SIZE_MAX ), #endif diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 6323a742a298..9e6a8bce69ea 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -1795,6 +1795,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa spin_lock_bh(&pHddCtx->bus_bw_lock); pHostapdAdapter->prev_tx_packets = pHostapdAdapter->stats.tx_packets; pHostapdAdapter->prev_rx_packets = pHostapdAdapter->stats.rx_packets; + pHostapdAdapter->prev_tx_bytes = + pHostapdAdapter->stats.tx_bytes; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_start_bus_bw_compute_timer(pHostapdAdapter); } @@ -1978,6 +1980,7 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa spin_lock_bh(&pHddCtx->bus_bw_lock); pHostapdAdapter->prev_tx_packets = 0; pHostapdAdapter->prev_rx_packets = 0; + pHostapdAdapter->prev_tx_bytes = 0; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_stop_bus_bw_compute_timer(pHostapdAdapter); } diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index b6dacec5f518..ea7e813e1dc2 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -132,6 +132,7 @@ void hdd_ch_avoid_cb(void *hdd_context,void *indi_param); #include "ol_fw.h" #include "wlan_hdd_ocb.h" #include "wlan_hdd_tsf.h" +#include "tl_shim.h" #if defined(LINUX_QCMBR) #define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13) @@ -13246,6 +13247,23 @@ static VOS_STATUS wlan_hdd_reg_init(hdd_context_t *hdd_ctx) return status; } +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +static void hdd_set_bundle_require(uint16_t session_id, hdd_context_t *hdd_ctx, + uint64_t tx_bytes) +{ + tlshim_set_bundle_require(session_id, tx_bytes, + hdd_ctx->cfg_ini->busBandwidthComputeInterval, + hdd_ctx->cfg_ini->pkt_bundle_threshold_high, + hdd_ctx->cfg_ini->pkt_bundle_threshold_low); + +} +#else +static void hdd_set_bundle_require(uint16_t session_id, hdd_context_t *hdd_ctx, + uint64_t tx_bytes) +{ + return; +} +#endif #ifdef FEATURE_BUS_BANDWIDTH void hdd_cnss_request_bus_bandwidth(hdd_context_t *pHddCtx, @@ -13342,12 +13360,11 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *pHddCtx, } #define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x))) - static void hdd_bus_bw_compute_cbk(void *priv) { hdd_context_t *pHddCtx = (hdd_context_t *)priv; hdd_adapter_t *pAdapter = NULL; - uint64_t tx_packets= 0, rx_packets= 0; + uint64_t tx_packets= 0, rx_packets= 0, tx_bytes = 0; uint64_t total_tx = 0, total_rx = 0; hdd_adapter_list_node_t *pAdapterNode = NULL; VOS_STATUS status = 0; @@ -13390,15 +13407,20 @@ static void hdd_bus_bw_compute_cbk(void *priv) tx_packets += HDD_BW_GET_DIFF(pAdapter->stats.tx_packets, pAdapter->prev_tx_packets); + tx_bytes += HDD_BW_GET_DIFF(pAdapter->stats.tx_bytes, + pAdapter->prev_tx_bytes); rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets, pAdapter->prev_rx_packets); + hdd_set_bundle_require(pAdapter->sessionId, pHddCtx, tx_bytes); + total_rx += pAdapter->stats.rx_packets; total_tx += pAdapter->stats.tx_packets; spin_lock_bh(&pHddCtx->bus_bw_lock); pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; + pAdapter->prev_tx_bytes = pAdapter->stats.tx_bytes; pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; spin_unlock_bh(&pHddCtx->bus_bw_lock); connected = TRUE; @@ -16587,8 +16609,10 @@ void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *pAdapter) } } - if(can_stop == VOS_TRUE) + if (can_stop == VOS_TRUE) { vos_timer_stop(&pHddCtx->bus_bw_timer); + tlshim_reset_bundle_require(); + } } #endif diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 34f3904ad43f..2ebe7c97868b 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -1124,6 +1124,8 @@ typedef struct sMacOpenParameters #endif uint16_t max_mgmt_tx_fail_count; bool force_target_assert_enabled; + uint16_t pkt_bundle_timer_value; + uint16_t pkt_bundle_size; } tMacOpenParameters; typedef struct sHalMacStartParameters diff --git a/CORE/SERVICES/COMMON/ol_cfg.h b/CORE/SERVICES/COMMON/ol_cfg.h index af5448db9c32..f3fcc69ede75 100644 --- a/CORE/SERVICES/COMMON/ol_cfg.h +++ b/CORE/SERVICES/COMMON/ol_cfg.h @@ -83,6 +83,8 @@ struct txrx_pdev_cfg_t { #ifdef IPA_UC_OFFLOAD struct wlan_ipa_uc_rsc_t ipa_uc_rsc; #endif /* IPA_UC_OFFLOAD */ + uint16_t pkt_bundle_timer_value; + uint16_t pkt_bundle_size; }; /** @@ -497,4 +499,22 @@ unsigned int ol_cfg_ipa_uc_rx_ind_ring_size(ol_pdev_handle pdev); */ unsigned int ol_cfg_ipa_uc_tx_partition_base(ol_pdev_handle pdev); #endif /* IPA_UC_OFFLOAD */ + +#define DEFAULT_BUNDLE_TIMER_VALUE 100 + +#ifdef FEATURE_BUS_BANDWIDTH +int ol_cfg_get_bundle_timer_value(ol_pdev_handle pdev); +int ol_cfg_get_bundle_size(ol_pdev_handle pdev); +#else +int ol_cfg_get_bundle_timer_value(ol_pdev_handle pdev) +{ + return DEFAULT_BUNDLE_TIMER_VALUE; +} + +int ol_cfg_get_bundle_size(ol_pdev_handle pdev) +{ + return 0; +} +#endif + #endif /* _OL_CFG__H_ */ diff --git a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h index 77f4f7e0dc86..621042f36ce6 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h @@ -927,6 +927,8 @@ struct txrx_pdev_cfg_param_t { u_int32_t uc_rx_indication_ring_count; /* IPA Micro controller data path offload TX partition base */ u_int32_t uc_tx_partition_base; + uint16_t pkt_bundle_timer_value; + uint16_t pkt_bundle_size; }; /** diff --git a/CORE/SERVICES/COMMON/ol_txrx_osif_api.h b/CORE/SERVICES/COMMON/ol_txrx_osif_api.h index 6808f64a782a..02dcef13564d 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_osif_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_osif_api.h @@ -208,4 +208,26 @@ adf_nbuf_t ol_txrx_osif_tso_segment( int max_seg_payload_bytes, adf_nbuf_t jumbo_tcp_frame); +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +void +ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_packets, + uint32_t time_in_ms, uint32_t high_th, uint32_t low_th); +void +ol_tx_pdev_reset_bundle_require(void* pdev); + +#else +static inline void +ol_tx_vdev_set_bundle_require(uint8_t vdev_id, unsigned long tx_packets, + uint32_t time_in_ms, uint32_t high_th, uint32_t low_th) +{ + return; +} +static inline void +ol_tx_pdev_reset_bundle_require(void* pdev) +{ + return; +} + +#endif + #endif /* _OL_TXRX_OSIF_API__H_ */ diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index b27d884567a5..f5da59b47e49 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -6714,6 +6714,30 @@ static void wma_set_nan_enable(tp_wma_handle wma_handle, } #endif +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +/** + * ol_cfg_update_bundle_params() - update bundle params + * @olCfg: cfg handle + * @mac_params: mac params + * + * Return: none + */ +static +void ol_cfg_update_bundle_params(struct txrx_pdev_cfg_param_t *olCfg, + tMacOpenParameters *mac_params) +{ + olCfg.pkt_bundle_timer_value = mac_params->pkt_bundle_timer_value; + olCfg.pkt_bundle_size = mac_params->pkt_bundle_size; +} +#else +static +void ol_cfg_update_bundle_params(struct txrx_pdev_cfg_param_t *olCfg, + tMacOpenParameters *mac_params) +{ + return; +} +#endif + #ifdef FEATURE_RUNTIME_PM /** * wma_runtime_context_init() - API to init wma runtime contexts @@ -6932,6 +6956,9 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, #else olCfg.is_full_reorder_offload = 0; #endif + + ol_cfg_update_bundle_params(&olCfg, mac_params); + ((pVosContextType) vos_context)->cfg_ctx = ol_pdev_cfg_attach(((pVosContextType) vos_context)->adf_ctx, olCfg); if (!(((pVosContextType) vos_context)->cfg_ctx)) { diff --git a/CORE/VOSS/inc/vos_cnss.h b/CORE/VOSS/inc/vos_cnss.h index c12bffb1c408..adcc8ce91ed9 100644 --- a/CORE/VOSS/inc/vos_cnss.h +++ b/CORE/VOSS/inc/vos_cnss.h @@ -399,11 +399,6 @@ static inline int vos_request_bus_bandwidth(int bandwidth) { return cnss_request_bus_bandwidth(bandwidth); } -#else -static inline int vos_request_bus_bandwidth(int bandwidth) -{ - return 0; -} #endif #ifdef CONFIG_CNSS_PCI diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 2e70d3c7c39a..f9377494bfa3 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -272,6 +272,29 @@ static void vos_set_nan_enable(tMacOpenParameters *param, } #endif +#ifdef QCA_SUPPORT_TXRX_HL_BUNDLE +/** + * vos_set_bundle_params() - set bundle params in mac open param + * @wma_handle: Pointer to mac open param + * @hdd_ctx: Pointer to hdd context + * + * Return: none + */ +static void vos_set_bundle_params(tMacOpenParameters *param, + hdd_context_t *hdd_ctx) +{ + param->pkt_bundle_timer_value = + hdd_ctx->cfg_ini->pkt_bundle_timer_value; + param->pkt_bundle_size = hdd_ctx->cfg_ini->pkt_bundle_size; +} +#else +static void vos_set_bundle_params(tMacOpenParameters *param, + hdd_context_t *hdd_ctx) +{ +} +#endif + + /*--------------------------------------------------------------------------- \brief vos_open() - Open the vOSS Module @@ -547,6 +570,7 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize ) #endif vos_set_nan_enable(&macOpenParms, pHddCtx); + vos_set_bundle_params(&macOpenParms, pHddCtx); vStatus = WDA_open( gpVosContext, gpVosContext->pHDDContext, hdd_update_tgt_cfg, @@ -175,7 +175,9 @@ endif ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) CONFIG_TX_DESC_HI_PRIO_RESERVE := 1 endif - +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) + CONFIG_SUPPORT_TXRX_HL_BUNDLE := 1 +endif #Enable OS specific IRQ abstraction CONFIG_ATH_SUPPORT_SHARED_IRQ := 1 @@ -974,6 +976,10 @@ CDEFINES += -DFEATURE_BUS_BANDWIDTH endif endif +ifeq ($(CONFIG_SUPPORT_TXRX_HL_BUNDLE), 1) +CDEFINES += -DQCA_SUPPORT_TXRX_HL_BUNDLE +endif + ifeq ($(CONFIG_ARCH_MDM9607), y) CDEFINES += -DCONFIG_TUFELLO_DUAL_FW_SUPPORT endif |
