diff --git a/Kbuild b/Kbuild index aa7fcb25b309..225b8c7831fd 100644 --- a/Kbuild +++ b/Kbuild @@ -2545,6 +2545,7 @@ cppflags-$(CONFIG_DP_LFR) += -DDP_LFR cppflags-$(CONFIG_DUP_RX_DESC_WAR) += -DDUP_RX_DESC_WAR cppflags-$(CONFIG_HTT_PADDR64) += -DHTT_PADDR64 cppflags-$(CONFIG_WLAN_FEATURE_BMI) += -DWLAN_FEATURE_BMI +cppflags-$(CONFIG_QCA_TX_PADDING_CREDIT_SUPPORT) += -DQCA_TX_PADDING_CREDIT_SUPPORT cppflags-$(CONFIG_QCN7605_SUPPORT) += -DQCN7605_SUPPORT -DPLATFORM_GENOA cppflags-$(CONFIG_HIF_REG_WINDOW_SUPPORT) += -DHIF_REG_WINDOW_SUPPORT cppflags-$(CONFIG_WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY) += -DWLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY diff --git a/configs/genoa.sdio.debug_defconfig b/configs/genoa.sdio.debug_defconfig index 53e8d3b4aa42..99f92665ed58 100644 --- a/configs/genoa.sdio.debug_defconfig +++ b/configs/genoa.sdio.debug_defconfig @@ -54,4 +54,5 @@ CONFIG_LINUX_QCMBR :=y CONFIG_TGT_NUM_MSDU_DESC := 0 CONFIG_RX_PN_CHECK_OFFLOAD := y CONFIG_QCN7605_SUPPORT := y +CONFIG_QCA_TX_PADDING_CREDIT_SUPPORT := y ################################### diff --git a/configs/genoa.sdio.perf_defconfig b/configs/genoa.sdio.perf_defconfig index 7919f0fe5c07..f767051803e4 100644 --- a/configs/genoa.sdio.perf_defconfig +++ b/configs/genoa.sdio.perf_defconfig @@ -59,4 +59,5 @@ CONFIG_LINUX_QCMBR := n CONFIG_TGT_NUM_MSDU_DESC := 0 CONFIG_RX_PN_CHECK_OFFLOAD := y CONFIG_QCN7605_SUPPORT := y +CONFIG_QCA_TX_PADDING_CREDIT_SUPPORT := y ################################### diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c index 65b1da1c47f2..8481221dd933 100644 --- a/core/dp/htt/htt.c +++ b/core/dp/htt/htt.c @@ -794,6 +794,8 @@ int htt_htc_attach(struct htt_pdev_t *pdev, uint16_t service_id) connect.EpCallbacks.EpTxCompleteMultiple = NULL; connect.EpCallbacks.EpRecv = htt_t2h_msg_handler; connect.EpCallbacks.ep_resume_tx_queue = htt_tx_resume_handler; + connect.EpCallbacks.ep_padding_credit_update = + htt_tx_padding_credit_update_handler; /* rx buffers currently are provided by HIF, not by EpRecvRefill */ connect.EpCallbacks.EpRecvRefill = NULL; diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h index 9e39ae62dffe..8a1479277159 100644 --- a/core/dp/htt/htt_internal.h +++ b/core/dp/htt/htt_internal.h @@ -582,6 +582,8 @@ void htt_h2t_send_complete(void *context, HTC_PACKET *pkt); QDF_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev); +int htt_tx_padding_credit_update_handler(void *context, int pad_credit); + #if defined(HELIUMPLUS) QDF_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev); diff --git a/core/dp/htt/htt_tx.c b/core/dp/htt/htt_tx.c index c7c5c2bb5bd6..658a47f480fb 100644 --- a/core/dp/htt/htt_tx.c +++ b/core/dp/htt/htt_tx.c @@ -865,8 +865,43 @@ htt_tx_send_nonstd(htt_pdev_handle pdev, return htt_tx_send_std(pdev, msdu, msdu_id); } +#ifndef QCA_TX_PADDING_CREDIT_SUPPORT +int htt_tx_padding_credit_update_handler(void *context, int pad_credit) +{ + return 1; +} +#endif + #else /*ATH_11AC_TXCOMPACT */ +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT +static int htt_tx_padding_credit_update(htt_pdev_handle htt_pdev, + int pad_credit) +{ + int ret = 0; + + if (pad_credit) + qdf_atomic_add(pad_credit, + &htt_pdev->txrx_pdev->pad_reserve_tx_credit); + + ret = qdf_atomic_read(&htt_pdev->txrx_pdev->pad_reserve_tx_credit); + + return ret; +} + +int htt_tx_padding_credit_update_handler(void *context, int pad_credit) +{ + struct htt_pdev_t *htt_pdev = (struct htt_pdev_t *)context; + + return htt_tx_padding_credit_update(htt_pdev, pad_credit); +} +#else +int htt_tx_padding_credit_update_handler(void *context, int pad_credit) +{ + return 1; +} +#endif + #ifdef QCA_TX_HTT2_SUPPORT static inline HTC_ENDPOINT_ID htt_tx_htt2_get_ep_id(htt_pdev_handle pdev, qdf_nbuf_t msdu) diff --git a/core/dp/txrx/ol_tx_sched.c b/core/dp/txrx/ol_tx_sched.c index 733f93132019..ca3a9a79717e 100644 --- a/core/dp/txrx/ol_tx_sched.c +++ b/core/dp/txrx/ol_tx_sched.c @@ -1439,7 +1439,50 @@ ol_tx_sched_dispatch( TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } - void +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT +static void replenish_tx_pad_credit(struct ol_txrx_pdev_t *pdev) +{ + int replenish_credit = 0, avail_targ_tx_credit = 0; + int cur_tx_pad_credit = 0, grp_credit = 0, i = 0; + qdf_atomic_t *tx_grp_credit = NULL; + + cur_tx_pad_credit = qdf_atomic_read(&pdev->pad_reserve_tx_credit); + if (cur_tx_pad_credit < MIN_TX_PAD_CREDIT_THRESH) { + replenish_credit = MAX_TX_PAD_CREDIT_THRESH - cur_tx_pad_credit; + avail_targ_tx_credit = qdf_atomic_read(&pdev->target_tx_credit); + replenish_credit = (replenish_credit < avail_targ_tx_credit) ? + replenish_credit : avail_targ_tx_credit; + if (replenish_credit < 0) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_FATAL, + "Tx Pad Credits = %d Target Tx Credits = %d", + cur_tx_pad_credit, + avail_targ_tx_credit); + qdf_assert(0); + } + qdf_atomic_add(replenish_credit, &pdev->pad_reserve_tx_credit); + qdf_atomic_add(-replenish_credit, &pdev->target_tx_credit); + + while (replenish_credit > 0) { + for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) { + tx_grp_credit = &pdev->txq_grps[i].credit; + grp_credit = qdf_atomic_read(tx_grp_credit); + if (grp_credit) { + qdf_atomic_add(-1, tx_grp_credit); + replenish_credit--; + } + if (!replenish_credit) + break; + } + } + } +} +#else +static void replenish_tx_pad_credit(struct ol_txrx_pdev_t *pdev) +{ +} +#endif + +void ol_tx_sched(struct ol_txrx_pdev_t *pdev) { struct ol_tx_sched_ctx sctx; @@ -1458,6 +1501,7 @@ ol_tx_sched(struct ol_txrx_pdev_t *pdev) *adf_os_print("BEFORE tx sched:\n"); *ol_tx_queues_display(pdev); */ + replenish_tx_pad_credit(pdev); qdf_spin_unlock_bh(&pdev->tx_queue_spinlock); TAILQ_INIT(&sctx.head); @@ -1468,6 +1512,7 @@ ol_tx_sched(struct ol_txrx_pdev_t *pdev) int num_credits; qdf_spin_lock_bh(&pdev->tx_queue_spinlock); + replenish_tx_pad_credit(pdev); credit = qdf_atomic_read(&pdev->target_tx_credit); num_credits = ol_tx_sched_select_batch(pdev, &sctx, credit); if (num_credits > 0) { diff --git a/core/dp/txrx/ol_tx_sched.h b/core/dp/txrx/ol_tx_sched.h index 75b554e0846f..d80123f5784b 100644 --- a/core/dp/txrx/ol_tx_sched.h +++ b/core/dp/txrx/ol_tx_sched.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013, 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -157,6 +157,14 @@ static inline void ol_tx_target_credit_incr(struct ol_txrx_pdev_t *pdev, { ol_tx_target_credit_adjust(1, pdev, msdu); } + +#ifdef QCA_TX_PADDING_CREDIT_SUPPORT + +#define MIN_TX_PAD_CREDIT_THRESH 4 +#define MAX_TX_PAD_CREDIT_THRESH 5 + +#endif /* QCA_TX_PADDING_CREDIT_SUPPORT */ + #else /* * LL does not need to keep track of target credit. @@ -180,5 +188,6 @@ static inline void ol_tx_target_credit_incr(struct ol_txrx_pdev_t *pdev, qdf_nbuf_t msdu) { } + #endif #endif /* _OL_TX_SCHED__H_ */ diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index d3082799fa4a..8be1eec0d702 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -743,6 +743,8 @@ ol_txrx_pdev_attach(ol_txrx_soc_handle soc, /* initialize the counter of the target's tx buffer availability */ qdf_atomic_init(&pdev->target_tx_credit); qdf_atomic_init(&pdev->orig_target_tx_credit); + qdf_atomic_init(&pdev->pad_reserve_tx_credit); + qdf_atomic_add(1, &pdev->pad_reserve_tx_credit); if (ol_cfg_is_high_latency(cfg_pdev)) { qdf_spinlock_create(&pdev->tx_queue_spinlock); diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index baf4e69b960a..454754af3541 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -687,6 +687,11 @@ struct ol_txrx_pdev_t { qdf_atomic_t target_tx_credit; qdf_atomic_t orig_target_tx_credit; + /* + * needed for SDIO HL, Genoa Adma + */ + qdf_atomic_t pad_reserve_tx_credit; + struct { uint16_t pool_size; struct ol_txrx_fw_stats_desc_elem_t *pool;