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
This commit is contained in:
Visweswara Tanuku 2019-06-11 10:16:30 +05:30 committed by nshrivas
parent 82415b1dcf
commit 2e839e540c
10 changed files with 105 additions and 2 deletions

1
Kbuild
View File

@ -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

View File

@ -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
###################################

View File

@ -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
###################################

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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) {

View File

@ -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_ */

View File

@ -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);

View File

@ -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;