qcacld-3.0: Implement htc runtime suspend/resume

Provide the apis to suspend & resume the htc layer
for runtime suspend.

Change-Id: Ia4c4f00fa62b250c5097e6bc14137b0114c5c90f
CRs-Fixed: 935300
This commit is contained in:
Houston Hoffman 2015-10-20 17:04:42 -07:00 • committed by Akash Patel
commit 47e387baf7
7 changed files with 121 additions and 7 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014-2015 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.
*
@ -43,6 +43,7 @@
#include <ol_htt_api.h>
#include <htt_internal.h>
#include <ol_htt_tx_api.h>
#include "hif.h"
#define HTT_HTC_PKT_POOL_INIT_SIZE 100 /* enough for a large A-MPDU */
@ -405,6 +406,7 @@ int htt_htc_attach(struct htt_pdev_t *pdev)
connect.EpCallbacks.EpTxComplete = htt_h2t_send_complete;
connect.EpCallbacks.EpTxCompleteMultiple = NULL;
connect.EpCallbacks.EpRecv = htt_t2h_msg_handler;
connect.EpCallbacks.ep_resume_tx_queue = htt_tx_resume_handler;
/* rx buffers currently are provided by HIF, not by EpRecvRefill */
connect.EpCallbacks.EpRecvRefill = NULL;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014-2015 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.
*
@ -413,6 +413,7 @@ static inline void htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc)
#endif
void htt_tx_resume_handler(void *);
#ifdef ATH_11AC_TXCOMPACT
#define HTT_TX_SCHED htt_tx_sched
#else

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014-2015 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.
*
@ -625,6 +625,24 @@ int htt_tx_send_std(htt_pdev_handle pdev, cdf_nbuf_t msdu, uint16_t msdu_id)
}
#ifdef FEATURE_RUNTIME_PM
/**
* htt_tx_resume_handler() - resume callback for the htt endpoint
* @context: a pointer to the htt context
*
* runs htt_tx_sched.
*/
void htt_tx_resume_handler(void *context)
{
struct htt_pdev_t *pdev = (struct htt_pdev_t *) context;
htt_tx_sched(pdev);
}
#else
void
htt_tx_resume_handler(void *context) { }
#endif
cdf_nbuf_t
htt_tx_send_batch(htt_pdev_handle pdev, cdf_nbuf_t head_msdu, int num_msdus)
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -34,6 +34,7 @@
#include "epping_main.h"
#include "hif_io32.h"
#include "cds_concurrency.h"
#include <cds_api.h>
#ifdef DEBUG
static ATH_DEBUG_MASK_DESCRIPTION g_htc_debug_description[] = {
@ -214,6 +215,7 @@ HTC_HANDLE htc_create(void *ol_sc, HTC_INIT_INFO *pInfo, cdf_device_t osdev)
A_MEMZERO(target, sizeof(HTC_TARGET));
htc_runtime_pm_init(target);
cdf_spinlock_init(&target->HTCLock);
cdf_spinlock_init(&target->HTCRxLock);
cdf_spinlock_init(&target->HTCTxLock);
@ -681,7 +683,60 @@ void htc_stop(HTC_HANDLE HTCHandle)
reset_endpoint_states(target);
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop \n"));
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop\n"));
}
/**
* htc_runtime_pm_init(): runtime pm related intialization
*
* need to initialize a work item.
*/
void htc_runtime_pm_init(HTC_TARGET *target)
{
cdf_create_work(&target->queue_kicker, htc_kick_queues, target);
}
/**
* htc_runtime_suspend(): ensure htc is ready to suspend
*
* htc is ready to suspend if there are no pending pactets
* in the txrx queues.
*
* Return: 0 on success or -EBUSY if there are queued packets.
*/
int htc_runtime_suspend(void)
{
ol_txrx_pdev_handle txrx_pdev = cds_get_context(CDF_MODULE_ID_TXRX);
if (txrx_pdev == NULL) {
HTC_ERROR("%s: txrx context null", __func__);
return CDF_STATUS_E_FAULT;
}
if (ol_txrx_get_tx_pending(txrx_pdev))
return -EBUSY;
else
return 0;
}
/**
* htc_runtime_resume(): resume htc
*
* The htc message queue needs to be kicked off after
* a runtime resume. Otherwise messages would get stuck.
*
* Return: 0 for success;
*/
int htc_runtime_resume(void)
{
HTC_HANDLE htc_ctx = cds_get_context(CDF_MODULE_ID_HTC);
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_ctx);
if (target == NULL)
return 0;
cdf_schedule_work(&target->queue_kicker);
return 0;
}
void htc_dump_credit_states(HTC_HANDLE HTCHandle)

View file

@ -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.
*
@ -66,6 +66,9 @@ struct ol_ath_htc_stats {
int htc_send_q_empty_count;
};
/* To resume HTT Tx queue during runtime resume */
typedef void (*HTC_EP_RESUME_TX_QUEUE)(void *);
/* per service connection send completion */
typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *, HTC_PACKET *);
/* per service connection callback when a plurality of packets have been sent
@ -151,6 +154,7 @@ typedef struct _HTC_EP_CALLBACKS {
indications (EpTxComplete must be NULL) */
HTC_EP_RECV_PKT_MULTIPLE EpRecvPktMultiple; /* OPTIONAL completion handler for multiple
recv packet indications (EpRecv must be NULL) */
HTC_EP_RESUME_TX_QUEUE ep_resume_tx_queue;
int RecvAllocThreshold; /* if EpRecvAllocThresh is non-NULL, HTC will compare the
threshold value to the current recv packet length and invoke
the EpRecvAllocThresh callback to acquire a packet buffer */
@ -694,6 +698,8 @@ void htc_dump_counter_info(HTC_HANDLE HTCHandle);
void *htc_get_targetdef(HTC_HANDLE htc_handle);
void htc_set_target_to_sleep(void *context);
void htc_cancel_deferred_target_sleep(void *context);
int htc_runtime_suspend(void);
int htc_runtime_resume(void);
/* Disable ASPM : Disable PCIe low power */
void htc_disable_aspm(void);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -184,6 +184,7 @@ typedef struct _HTC_TARGET {
A_UINT32 ce_send_cnt;
A_UINT32 TX_comp_cnt;
A_UINT8 MaxMsgsPerHTCBundle;
cdf_work_t queue_kicker;
} HTC_TARGET;
#define HTC_ENABLE_BUNDLE(target) (target->MaxMsgsPerHTCBundle > 1)
@ -245,6 +246,8 @@ void htc_process_credit_rpt(HTC_TARGET *target,
int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
void htc_fw_event_handler(void *context, CDF_STATUS status);
void htc_send_complete_check_cleanup(void *context);
void htc_runtime_pm_init(HTC_TARGET *target);
void htc_kick_queues(void *context);
void htc_credit_record(htc_credit_exchange_type type, uint32_t tx_credit,
uint32_t htc_tx_queue_depth);

View file

@ -1669,6 +1669,35 @@ void htc_tx_resource_avail_handler(void *context, A_UINT8 pipeID)
htc_try_send(target, pEndpoint, NULL);
}
/**
* htc_kick_queues(): resumes tx transactions of suspended endpoints
* @context: pointer to the htc target context
*
* Iterates throught the enpoints and provides a context to empty queues
* int the hif layer when they are stalled due to runtime suspend.
*
* Return: none
*/
void htc_kick_queues(void *context)
{
int i;
HTC_TARGET *target = (HTC_TARGET *)context;
HTC_ENDPOINT *endpoint = NULL;
for (i = 0; i < ENDPOINT_MAX; i++) {
endpoint = &target->endpoint[i];
if (endpoint->service_id == 0)
continue;
if (endpoint->EpCallBacks.ep_resume_tx_queue)
endpoint->EpCallBacks.ep_resume_tx_queue(
endpoint->EpCallBacks.pContext);
htc_try_send(target, endpoint, NULL);
}
}
/* flush endpoint TX queue */
void htc_flush_endpoint_tx(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint,
HTC_TX_TAG Tag)