From 2e839e540c929c944e9f777c13f74dbeea65bf68 Mon Sep 17 00:00:00 2001 From: Visweswara Tanuku Date: Tue, 11 Jun 2019 10:16:30 +0530 Subject: [PATCH] qcacld-3.0: Genoa: SDIO: Handle Tx Padding & Credits In Genoa SDIO ADMA implementation Host sends packets to FW in multiples of SDIO Block size. If the packet/bundle is not block aligned Host adds padding at the end of Packet/Bundle. If the TX packet plus padding exceeds one FW TX Buffer, Padding data will occupy the next FW TX buffer. Same applies for bundle TX packet. For above scenario, HTC_FLAGS_PADDING_CHECK of HTC header Flags is used to notify the FW that - Padding data follows the currentHTC packet Since the padding data will take one extra FW Tx Buffer, host need to handle the extra Tx credit being used by the padding data/buffer CRs-Fixed: 2516619 Change-Id: Ie2d2292fabb30e1a13eebe4d11b57f452e42afa8 --- Kbuild | 1 + configs/genoa.sdio.debug_defconfig | 1 + configs/genoa.sdio.perf_defconfig | 1 + core/dp/htt/htt.c | 2 ++ core/dp/htt/htt_internal.h | 2 ++ core/dp/htt/htt_tx.c | 35 ++++++++++++++++++++++ core/dp/txrx/ol_tx_sched.c | 47 +++++++++++++++++++++++++++++- core/dp/txrx/ol_tx_sched.h | 11 ++++++- core/dp/txrx/ol_txrx.c | 2 ++ core/dp/txrx/ol_txrx_types.h | 5 ++++ 10 files changed, 105 insertions(+), 2 deletions(-) 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;