qcacld-3.0: Resume/suspend of mon thread for packet capture
Resume/suspend of mon thread for packet capture mode. Change-Id: Ib814de13f82181aef923bdc739d018027ea9a173 CRs-Fixed: 2618657
This commit is contained in:

committed by
nshrivas

parent
aa481cc459
commit
a7e26ef49f
@@ -78,88 +78,6 @@ struct cds_ol_rx_pkt {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
/*
|
|
||||||
* Maximum number of cds messages to be allocated for
|
|
||||||
* OL MON thread.
|
|
||||||
*/
|
|
||||||
#define CDS_MAX_OL_MON_PKT 4000
|
|
||||||
|
|
||||||
struct cds_sched_mon_context {
|
|
||||||
/* MON thread lock */
|
|
||||||
spinlock_t ol_mon_thread_lock;
|
|
||||||
|
|
||||||
/* OL MON thread handle */
|
|
||||||
struct task_struct *ol_mon_thread;
|
|
||||||
|
|
||||||
/* Handle of Event for MON thread to signal startup */
|
|
||||||
struct completion ol_mon_start_event;
|
|
||||||
|
|
||||||
/* Completion object to suspend OL MON thread */
|
|
||||||
struct completion ol_suspend_mon_event;
|
|
||||||
|
|
||||||
/* Completion objext to resume OL MON thread */
|
|
||||||
struct completion ol_resume_mon_event;
|
|
||||||
|
|
||||||
/* Completion object for OL MON thread shutdown */
|
|
||||||
struct completion ol_mon_shutdown;
|
|
||||||
|
|
||||||
/* Waitq for OL MON thread */
|
|
||||||
wait_queue_head_t ol_mon_wait_queue;
|
|
||||||
|
|
||||||
unsigned long ol_mon_event_flag;
|
|
||||||
|
|
||||||
/* MON buffer queue */
|
|
||||||
struct list_head ol_mon_thread_queue;
|
|
||||||
|
|
||||||
/* Spinlock to synchronize between tasklet and thread */
|
|
||||||
spinlock_t ol_mon_queue_lock;
|
|
||||||
|
|
||||||
/* MON queue length */
|
|
||||||
unsigned int ol_mon_queue_len;
|
|
||||||
|
|
||||||
/* Lock to synchronize free buffer queue access */
|
|
||||||
spinlock_t cds_ol_mon_pkt_freeq_lock;
|
|
||||||
|
|
||||||
/* Free message queue for OL MON processing */
|
|
||||||
struct list_head cds_ol_mon_pkt_freeq;
|
|
||||||
|
|
||||||
/* MON thread affinity cpu */
|
|
||||||
unsigned long mon_thread_cpu;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* WLAN_FEATURE_PKT_CAPTURE */
|
|
||||||
typedef void (*cds_ol_mon_thread_cb)(
|
|
||||||
void *context, void *monpkt,
|
|
||||||
uint8_t vdev_id, uint8_t tid,
|
|
||||||
uint8_t status, bool pkt_format);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CDS message wrapper for mon data from TXRX
|
|
||||||
*/
|
|
||||||
struct cds_ol_mon_pkt {
|
|
||||||
struct list_head list;
|
|
||||||
void *context;
|
|
||||||
|
|
||||||
/* mon skb */
|
|
||||||
void *monpkt;
|
|
||||||
|
|
||||||
/* vdev id to which this packet is destined */
|
|
||||||
uint8_t vdev_id;
|
|
||||||
|
|
||||||
uint8_t tid;
|
|
||||||
|
|
||||||
/* Tx packet status */
|
|
||||||
uint8_t status;
|
|
||||||
|
|
||||||
/* 0 = 802.3 format , 1 = 802.11 format */
|
|
||||||
bool pkt_format;
|
|
||||||
|
|
||||||
/* Call back to further send this packet to txrx layer */
|
|
||||||
cds_ol_mon_thread_cb callback;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CDS Scheduler context
|
** CDS Scheduler context
|
||||||
** The scheduler context contains the following:
|
** The scheduler context contains the following:
|
||||||
@@ -223,10 +141,6 @@ typedef struct _cds_sched_context {
|
|||||||
bool rx_affinity_required;
|
bool rx_affinity_required;
|
||||||
uint8_t conf_rx_thread_ul_affinity;
|
uint8_t conf_rx_thread_ul_affinity;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
struct cds_sched_mon_context sched_mon_ctx;
|
|
||||||
#endif /* WLAN_FEATURE_PKT_CAPTURE */
|
|
||||||
} cds_sched_context, *p_cds_sched_context;
|
} cds_sched_context, *p_cds_sched_context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -637,162 +551,4 @@ void cds_shutdown_notifier_call(void);
|
|||||||
*/
|
*/
|
||||||
void cds_resume_rx_thread(void);
|
void cds_resume_rx_thread(void);
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
/**
|
|
||||||
* cds_resume_mon_thread() - resume mon thread by completing its resume event
|
|
||||||
*
|
|
||||||
* Resume MON thread by completing RX thread resume event
|
|
||||||
*
|
|
||||||
* Return: None
|
|
||||||
*/
|
|
||||||
void cds_resume_mon_thread(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_drop_monpkt() - API to drop pending mon packets
|
|
||||||
* @pschedcontext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api drops all the pending packets in the queue.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_drop_monpkt(p_cds_sched_context pschedcontext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_indicate_monpkt() - API to Indicate rx data packet
|
|
||||||
* @pschedcontext: pointer to CDS Sched Context
|
|
||||||
* @pkt: CDS OL MON pkt pointer containing to mon data message buffer
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_indicate_monpkt(p_cds_sched_context pschedcontext,
|
|
||||||
struct cds_ol_mon_pkt *pkt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_wakeup_mon_thread() - wakeup mon thread
|
|
||||||
* @Arg: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api wake up cds_ol_mon_thread() to process pkt
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_wakeup_mon_thread(p_cds_sched_context pschedcontext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_close_mon_thread() - close the Tlshim MON thread
|
|
||||||
*
|
|
||||||
* This api closes the Tlshim MON thread:
|
|
||||||
*
|
|
||||||
* Return: qdf status
|
|
||||||
*/
|
|
||||||
QDF_STATUS cds_close_mon_thread(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_open_mon_thread() - open the Tlshim MON thread
|
|
||||||
* @pSchedContext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api opens the Tlshim MON thread:
|
|
||||||
*
|
|
||||||
* Return: qdf status
|
|
||||||
*/
|
|
||||||
QDF_STATUS cds_open_mon_thread(p_cds_sched_context pschedcontext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_alloc_mon_thread() - alloc resources for MON thread
|
|
||||||
* @pSchedContext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api alloc resources for MON thread:
|
|
||||||
*
|
|
||||||
* Return: qdf status
|
|
||||||
*/
|
|
||||||
QDF_STATUS cds_alloc_mon_thread(p_cds_sched_context pschedcontext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_alloc_ol_mon_pkt() - API to return next available cds message
|
|
||||||
* @pSchedContext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api returns next available cds message buffer used for mon data
|
|
||||||
* processing
|
|
||||||
*
|
|
||||||
* Return: Pointer to cds message buffer
|
|
||||||
*/
|
|
||||||
struct cds_ol_mon_pkt *cds_alloc_ol_mon_pkt(p_cds_sched_context pschedcontext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_free_ol_mon_pkt() - api to release cds message to the freeq
|
|
||||||
* This api returns the cds message used for mon data to the free queue
|
|
||||||
* @pSchedContext: Pointer to the global CDS Sched Context
|
|
||||||
* @pkt: CDS message buffer to be returned to free queue.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_free_ol_mon_pkt(p_cds_sched_context pschedcontext,
|
|
||||||
struct cds_ol_mon_pkt *pkt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_free_ol_mon_pkt_freeq() - free cds buffer free queue
|
|
||||||
* @pSchedContext - pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This API does mem free of the buffers available in free cds buffer
|
|
||||||
* queue which is used for mon Data processing.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_free_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext);
|
|
||||||
#else
|
|
||||||
static inline
|
|
||||||
void cds_resume_mon_thread(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
void cds_drop_monpkt(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
void cds_indicate_monpkt(p_cds_sched_context pschedcontext,
|
|
||||||
struct cds_ol_mon_pkt *pkt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
void cds_wakeup_mon_thread(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
QDF_STATUS cds_close_mon_thread(void)
|
|
||||||
{
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
QDF_STATUS cds_open_mon_thread(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
QDF_STATUS cds_alloc_mon_thread(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
struct cds_ol_mon_pkt *cds_alloc_ol_mon_pkt(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
void cds_free_ol_mon_pkt(p_cds_sched_context pschedcontext,
|
|
||||||
struct cds_ol_mon_pkt *pkt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
void cds_free_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif /* WLAN_FEATURE_PKT_CAPTURE */
|
|
||||||
#endif /* #ifndef __CDS_SCHED_H */
|
#endif /* #ifndef __CDS_SCHED_H */
|
||||||
|
@@ -1139,12 +1139,6 @@ QDF_STATUS cds_post_disable(void)
|
|||||||
return QDF_STATUS_E_INVAL;
|
return QDF_STATUS_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_status = cds_close_mon_thread();
|
|
||||||
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
|
||||||
cds_err("Failed to close MON thread!");
|
|
||||||
return QDF_STATUS_E_INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
|
cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
|
||||||
OL_TXRX_PDEV_ID, 1);
|
OL_TXRX_PDEV_ID, 1);
|
||||||
|
|
||||||
|
@@ -57,16 +57,6 @@ enum notifier_state {
|
|||||||
|
|
||||||
static p_cds_sched_context gp_cds_sched_context;
|
static p_cds_sched_context gp_cds_sched_context;
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
static int cds_ol_mon_thread(void *arg);
|
|
||||||
static QDF_STATUS cds_alloc_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext);
|
|
||||||
static inline
|
|
||||||
int cds_set_mon_cpus_allowed_ptr(struct task_struct *task, unsigned long cpu)
|
|
||||||
{
|
|
||||||
return set_cpus_allowed_ptr(task, cpumask_of(cpu));
|
|
||||||
}
|
|
||||||
#endif /* WLAN_FEATURE_PKT_CAPTURE */
|
|
||||||
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
static int cds_ol_rx_thread(void *arg);
|
static int cds_ol_rx_thread(void *arg);
|
||||||
static uint32_t affine_cpu;
|
static uint32_t affine_cpu;
|
||||||
@@ -518,10 +508,6 @@ QDF_STATUS cds_sched_open(void *p_cds_context,
|
|||||||
pSchedContext->high_throughput_required = false;
|
pSchedContext->high_throughput_required = false;
|
||||||
pSchedContext->rx_affinity_required = false;
|
pSchedContext->rx_affinity_required = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (QDF_STATUS_SUCCESS != cds_alloc_mon_thread(pSchedContext))
|
|
||||||
goto mon_freeqalloc_failure;
|
|
||||||
|
|
||||||
gp_cds_sched_context = pSchedContext;
|
gp_cds_sched_context = pSchedContext;
|
||||||
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
@@ -539,29 +525,12 @@ QDF_STATUS cds_sched_open(void *p_cds_context,
|
|||||||
wait_for_completion_interruptible(&pSchedContext->ol_rx_start_event);
|
wait_for_completion_interruptible(&pSchedContext->ol_rx_start_event);
|
||||||
cds_debug("CDS OL Rx Thread has started");
|
cds_debug("CDS OL Rx Thread has started");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (QDF_STATUS_SUCCESS != cds_open_mon_thread(pSchedContext))
|
|
||||||
goto OL_MON_THREAD_START_FAILURE;
|
|
||||||
|
|
||||||
/* We're good now: Let's get the ball rolling!!! */
|
/* We're good now: Let's get the ball rolling!!! */
|
||||||
cds_debug("CDS Scheduler successfully Opened");
|
cds_debug("CDS Scheduler successfully Opened");
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
|
|
||||||
OL_MON_THREAD_START_FAILURE:
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
|
||||||
/* Try and force the Main thread controller to exit */
|
|
||||||
set_bit(RX_SHUTDOWN_EVENT, &pSchedContext->ol_rx_event_flag);
|
|
||||||
set_bit(RX_POST_EVENT, &pSchedContext->ol_rx_event_flag);
|
|
||||||
wake_up_interruptible(&pSchedContext->ol_rx_wait_queue);
|
|
||||||
/* Wait for RX Thread to exit */
|
|
||||||
wait_for_completion(&pSchedContext->ol_rx_shutdown);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
OL_RX_THREAD_START_FAILURE:
|
OL_RX_THREAD_START_FAILURE:
|
||||||
#endif
|
#endif
|
||||||
cds_free_ol_mon_pkt_freeq(gp_cds_sched_context);
|
|
||||||
mon_freeqalloc_failure:
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
qdf_cpuhp_unregister(&pSchedContext->cpuhp_event_handle);
|
qdf_cpuhp_unregister(&pSchedContext->cpuhp_event_handle);
|
||||||
cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
|
cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
|
||||||
@@ -918,8 +887,6 @@ QDF_STATUS cds_sched_close(void)
|
|||||||
|
|
||||||
cds_close_rx_thread();
|
cds_close_rx_thread();
|
||||||
|
|
||||||
cds_close_mon_thread();
|
|
||||||
|
|
||||||
gp_cds_sched_context = NULL;
|
gp_cds_sched_context = NULL;
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
} /* cds_sched_close() */
|
} /* cds_sched_close() */
|
||||||
@@ -1073,462 +1040,3 @@ int cds_get_gfp_flags(void)
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
/**
|
|
||||||
* cds_free_ol_mon_pkt_freeq() - free cds buffer free queue
|
|
||||||
* @pSchedContext - pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This API does mem free of the buffers available in free cds buffer
|
|
||||||
* queue which is used for mon Data processing.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_free_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
struct cds_ol_mon_pkt *pkt;
|
|
||||||
|
|
||||||
if (!cds_is_pktcapture_enabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
while (!list_empty(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq)) {
|
|
||||||
pkt = list_entry((&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq)->next,
|
|
||||||
typeof(*pkt), list);
|
|
||||||
list_del(&pkt->list);
|
|
||||||
spin_unlock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
qdf_mem_free(pkt);
|
|
||||||
spin_lock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
}
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_alloc_ol_mon_pkt_freeq() - Function to allocate free buffer queue
|
|
||||||
* @pSchedContext - pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This API allocates CDS_MAX_OL_MON_PKT number of cds message buffers
|
|
||||||
* which are used for mon data processing.
|
|
||||||
*
|
|
||||||
* Return: status of memory allocation
|
|
||||||
*/
|
|
||||||
static QDF_STATUS cds_alloc_ol_mon_pkt_freeq(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
struct cds_ol_mon_pkt *pkt, *tmp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < CDS_MAX_OL_MON_PKT; i++) {
|
|
||||||
pkt = qdf_mem_malloc(sizeof(*pkt));
|
|
||||||
if (!pkt) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
"%s Vos packet allocation for ol mon thread failed",
|
|
||||||
__func__);
|
|
||||||
goto free;
|
|
||||||
}
|
|
||||||
spin_lock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
list_add_tail(&pkt->list, &pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq);
|
|
||||||
spin_unlock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
free:
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
list_for_each_entry_safe(pkt, tmp,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq,
|
|
||||||
list) {
|
|
||||||
list_del(&pkt->list);
|
|
||||||
spin_unlock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
qdf_mem_free(pkt);
|
|
||||||
spin_lock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
}
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
return QDF_STATUS_E_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_free_ol_mon_pkt() - api to release cds message to the freeq
|
|
||||||
* This api returns the cds message used for mon data to the free queue
|
|
||||||
* @pSchedContext: Pointer to the global CDS Sched Context
|
|
||||||
* @pkt: CDS message buffer to be returned to free queue.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
cds_free_ol_mon_pkt(p_cds_sched_context pschedcontext,
|
|
||||||
struct cds_ol_mon_pkt *pkt)
|
|
||||||
{
|
|
||||||
memset(pkt, 0, sizeof(*pkt));
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
list_add_tail(&pkt->list,
|
|
||||||
&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq);
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_alloc_ol_mon_pkt() - API to return next available cds message
|
|
||||||
* @pSchedContext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api returns next available cds message buffer used for mon data
|
|
||||||
* processing
|
|
||||||
*
|
|
||||||
* Return: Pointer to cds message buffer
|
|
||||||
*/
|
|
||||||
struct cds_ol_mon_pkt *cds_alloc_ol_mon_pkt(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
struct cds_ol_mon_pkt *pkt;
|
|
||||||
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
if (list_empty(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq)) {
|
|
||||||
spin_unlock_bh(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
pkt = list_first_entry(&pschedcontext->
|
|
||||||
sched_mon_ctx.cds_ol_mon_pkt_freeq,
|
|
||||||
struct cds_ol_mon_pkt, list);
|
|
||||||
list_del(&pkt->list);
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
return pkt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_indicate_monpkt() - indicate mon data packet
|
|
||||||
* @Arg: Pointer to the global CDS Sched Context
|
|
||||||
* @pkt: CDS data message buffer
|
|
||||||
*
|
|
||||||
* This api enqueues the mon packet into ol_mon_thread_queue and notifies
|
|
||||||
* cds_ol_mon_thread()
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
cds_indicate_monpkt(p_cds_sched_context pschedcontext,
|
|
||||||
struct cds_ol_mon_pkt *pkt)
|
|
||||||
{
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
list_add_tail(&pkt->list, &pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_thread_queue);
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
set_bit(RX_POST_EVENT, &pschedcontext->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
wake_up_interruptible(&pschedcontext->sched_mon_ctx.ol_mon_wait_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_wakeup_mon_thread() - wakeup mon thread
|
|
||||||
* @Arg: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api wake up cds_ol_mon_thread() to process pkt
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
cds_wakeup_mon_thread(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
set_bit(RX_POST_EVENT, &pschedcontext->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
wake_up_interruptible(&pschedcontext->sched_mon_ctx.ol_mon_wait_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_close_mon_thread() - close the Tlshim Rx thread
|
|
||||||
*
|
|
||||||
* This api closes the Tlshim Rx thread:
|
|
||||||
*
|
|
||||||
* Return: qdf status
|
|
||||||
*/
|
|
||||||
QDF_STATUS cds_close_mon_thread(void)
|
|
||||||
{
|
|
||||||
if (!cds_is_pktcapture_enabled())
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
|
|
||||||
"%s: invoked", __func__);
|
|
||||||
|
|
||||||
if (!gp_cds_sched_context) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
"%s: gp_cds_sched_context == NULL", __func__);
|
|
||||||
return QDF_STATUS_E_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gp_cds_sched_context->sched_mon_ctx.ol_mon_thread)
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
/* Shut down Tlshim Rx thread */
|
|
||||||
set_bit(RX_SHUTDOWN_EVENT,
|
|
||||||
&gp_cds_sched_context->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
set_bit(RX_POST_EVENT,
|
|
||||||
&gp_cds_sched_context->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
wake_up_interruptible(&gp_cds_sched_context->
|
|
||||||
sched_mon_ctx.ol_mon_wait_queue);
|
|
||||||
wait_for_completion(&gp_cds_sched_context->
|
|
||||||
sched_mon_ctx.ol_mon_shutdown);
|
|
||||||
gp_cds_sched_context->sched_mon_ctx.ol_mon_thread = NULL;
|
|
||||||
cds_drop_monpkt(gp_cds_sched_context);
|
|
||||||
cds_free_ol_mon_pkt_freeq(gp_cds_sched_context);
|
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
} /* cds_close_mon_thread */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_open_mon_thread() - open the Tlshim Rx thread
|
|
||||||
*
|
|
||||||
* This api open the Tlshim Rx thread:
|
|
||||||
*
|
|
||||||
* Return: qdf status
|
|
||||||
*/
|
|
||||||
QDF_STATUS cds_open_mon_thread(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
if (!cds_is_pktcapture_enabled())
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
pschedcontext->sched_mon_ctx.ol_mon_thread = kthread_create(
|
|
||||||
cds_ol_mon_thread,
|
|
||||||
pschedcontext,
|
|
||||||
"cds_ol_mon_thread");
|
|
||||||
if (IS_ERR(pschedcontext->sched_mon_ctx.ol_mon_thread)) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
|
|
||||||
"%s: Could not Create CDS OL MON Thread",
|
|
||||||
__func__);
|
|
||||||
return QDF_STATUS_E_FAILURE;
|
|
||||||
}
|
|
||||||
wake_up_process(pschedcontext->sched_mon_ctx.ol_mon_thread);
|
|
||||||
cds_debug("CDS OL MON thread Created");
|
|
||||||
|
|
||||||
wait_for_completion_interruptible(
|
|
||||||
&pschedcontext->sched_mon_ctx.ol_mon_start_event);
|
|
||||||
cds_debug("CDS OL MON Thread has started");
|
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_drop_monpkt() - api to drop pending mon packets for a sta
|
|
||||||
* @pschedcontext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api drops all queued packets for a station.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
void cds_drop_monpkt(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
struct list_head local_list;
|
|
||||||
struct cds_ol_mon_pkt *pkt, *tmp;
|
|
||||||
qdf_nbuf_t buf, next_buf;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&local_list);
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
if (list_empty(&pschedcontext->sched_mon_ctx.ol_mon_thread_queue)) {
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
list_for_each_entry_safe(pkt, tmp,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_thread_queue,
|
|
||||||
list)
|
|
||||||
list_move_tail(&pkt->list, &local_list);
|
|
||||||
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pkt, tmp, &local_list, list) {
|
|
||||||
list_del(&pkt->list);
|
|
||||||
buf = pkt->monpkt;
|
|
||||||
while (buf) {
|
|
||||||
next_buf = qdf_nbuf_queue_next(buf);
|
|
||||||
qdf_nbuf_free(buf);
|
|
||||||
buf = next_buf;
|
|
||||||
}
|
|
||||||
cds_free_ol_mon_pkt(pschedcontext, pkt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_mon_from_queue() - function to process pending mon packets
|
|
||||||
* @pschedcontext: Pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api traverses the pending buffer list and calling the callback.
|
|
||||||
* This callback would essentially send the packet to HDD.
|
|
||||||
*
|
|
||||||
* Return: none
|
|
||||||
*/
|
|
||||||
static void cds_mon_from_queue(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
struct cds_ol_mon_pkt *pkt;
|
|
||||||
uint8_t vdev_id;
|
|
||||||
uint8_t tid;
|
|
||||||
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
while (!list_empty(&pschedcontext->sched_mon_ctx.ol_mon_thread_queue)) {
|
|
||||||
pkt = list_first_entry(&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_thread_queue,
|
|
||||||
struct cds_ol_mon_pkt, list);
|
|
||||||
list_del(&pkt->list);
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
vdev_id = pkt->vdev_id;
|
|
||||||
tid = pkt->tid;
|
|
||||||
pkt->callback(pkt->context, pkt->monpkt, vdev_id,
|
|
||||||
tid, pkt->status, pkt->pkt_format);
|
|
||||||
cds_free_ol_mon_pkt(pschedcontext, pkt);
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
}
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* cds_ol_mon_thread() - cds main tlshim mon thread
|
|
||||||
* @Arg: pointer to the global CDS Sched Context
|
|
||||||
*
|
|
||||||
* This api is the thread handler for mon Data packet processing.
|
|
||||||
*
|
|
||||||
* Return: thread exit code
|
|
||||||
*/
|
|
||||||
static int cds_ol_mon_thread(void *arg)
|
|
||||||
{
|
|
||||||
p_cds_sched_context pschedcontext = (p_cds_sched_context)arg;
|
|
||||||
unsigned long pref_cpu = 0;
|
|
||||||
bool shutdown = false;
|
|
||||||
int status, i;
|
|
||||||
|
|
||||||
if (!arg) {
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
|
||||||
"%s: Bad Args passed", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_user_nice(current, -1);
|
|
||||||
#ifdef MSM_PLATFORM
|
|
||||||
set_wake_up_idle(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the available cpu core other than cpu 0 and
|
|
||||||
* bind the thread
|
|
||||||
*/
|
|
||||||
for_each_online_cpu(i) {
|
|
||||||
if (i == 0)
|
|
||||||
continue;
|
|
||||||
pref_cpu = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cds_set_mon_cpus_allowed_ptr(current, pref_cpu);
|
|
||||||
|
|
||||||
complete(&pschedcontext->sched_mon_ctx.ol_mon_start_event);
|
|
||||||
|
|
||||||
while (!shutdown) {
|
|
||||||
status =
|
|
||||||
wait_event_interruptible(
|
|
||||||
pschedcontext->sched_mon_ctx.ol_mon_wait_queue,
|
|
||||||
test_bit(RX_POST_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag) ||
|
|
||||||
test_bit(RX_SUSPEND_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag));
|
|
||||||
if (status == -ERESTARTSYS)
|
|
||||||
break;
|
|
||||||
|
|
||||||
clear_bit(RX_POST_EVENT,
|
|
||||||
&pschedcontext->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
while (true) {
|
|
||||||
if (test_bit(RX_SHUTDOWN_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag)) {
|
|
||||||
clear_bit(RX_SHUTDOWN_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
if (test_bit(
|
|
||||||
RX_SUSPEND_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag)) {
|
|
||||||
clear_bit(
|
|
||||||
RX_SUSPEND_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
complete
|
|
||||||
(&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_suspend_mon_event);
|
|
||||||
}
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF,
|
|
||||||
QDF_TRACE_LEVEL_INFO,
|
|
||||||
"%s: Shutting down OL MON Thread",
|
|
||||||
__func__);
|
|
||||||
shutdown = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cds_mon_from_queue(pschedcontext);
|
|
||||||
|
|
||||||
if (test_bit(RX_SUSPEND_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag)) {
|
|
||||||
clear_bit(RX_SUSPEND_EVENT,
|
|
||||||
&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
spin_lock(&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_thread_lock);
|
|
||||||
INIT_COMPLETION
|
|
||||||
(pschedcontext->
|
|
||||||
sched_mon_ctx.ol_resume_mon_event);
|
|
||||||
complete(&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_suspend_mon_event);
|
|
||||||
spin_unlock(&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_mon_thread_lock);
|
|
||||||
wait_for_completion_interruptible
|
|
||||||
(&pschedcontext->
|
|
||||||
sched_mon_ctx.ol_resume_mon_event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
|
|
||||||
"%s: Exiting CDS OL mon thread", __func__);
|
|
||||||
complete_and_exit(&pschedcontext->sched_mon_ctx.ol_mon_shutdown, 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cds_resume_mon_thread(void)
|
|
||||||
{
|
|
||||||
p_cds_sched_context cds_sched_context;
|
|
||||||
|
|
||||||
cds_sched_context = get_cds_sched_ctxt();
|
|
||||||
if (!cds_sched_context) {
|
|
||||||
cds_err("cds_sched_context is NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
complete(&cds_sched_context->sched_mon_ctx.ol_resume_mon_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
QDF_STATUS
|
|
||||||
cds_alloc_mon_thread(p_cds_sched_context pschedcontext)
|
|
||||||
{
|
|
||||||
if (!cds_is_pktcapture_enabled())
|
|
||||||
return QDF_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
spin_lock_init(&pschedcontext->sched_mon_ctx.ol_mon_thread_lock);
|
|
||||||
init_waitqueue_head(&pschedcontext->sched_mon_ctx.ol_mon_wait_queue);
|
|
||||||
init_completion(&pschedcontext->sched_mon_ctx.ol_mon_start_event);
|
|
||||||
init_completion(&pschedcontext->sched_mon_ctx.ol_suspend_mon_event);
|
|
||||||
init_completion(&pschedcontext->sched_mon_ctx.ol_resume_mon_event);
|
|
||||||
init_completion(&pschedcontext->sched_mon_ctx.ol_mon_shutdown);
|
|
||||||
pschedcontext->sched_mon_ctx.ol_mon_event_flag = 0;
|
|
||||||
spin_lock_init(&pschedcontext->sched_mon_ctx.ol_mon_queue_lock);
|
|
||||||
spin_lock_init(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
INIT_LIST_HEAD(&pschedcontext->sched_mon_ctx.ol_mon_thread_queue);
|
|
||||||
spin_lock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
INIT_LIST_HEAD(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq);
|
|
||||||
spin_unlock_bh(&pschedcontext->sched_mon_ctx.cds_ol_mon_pkt_freeq_lock);
|
|
||||||
|
|
||||||
return cds_alloc_ol_mon_pkt_freeq(pschedcontext);
|
|
||||||
}
|
|
||||||
#endif /* WLAN_FEATURE_PKT_CAPTURE */
|
|
||||||
|
@@ -1624,10 +1624,6 @@ struct hdd_context {
|
|||||||
|
|
||||||
bool is_scheduler_suspended;
|
bool is_scheduler_suspended;
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
bool is_ol_mon_thread_suspended;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
bool is_ol_rx_thread_suspended;
|
bool is_ol_rx_thread_suspended;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -551,36 +551,6 @@ hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev,
|
|||||||
}
|
}
|
||||||
#endif /* WLAN_SUSPEND_RESUME_TEST */
|
#endif /* WLAN_SUSPEND_RESUME_TEST */
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
/**
|
|
||||||
* wlan_hdd_mon_thread_resume() - Resume MON thread
|
|
||||||
* @hdd_ctx: HDD context
|
|
||||||
*
|
|
||||||
* Check if MON thread is suspended, and resume if yes.
|
|
||||||
*
|
|
||||||
* Return: None
|
|
||||||
*/
|
|
||||||
void wlan_hdd_mon_thread_resume(struct hdd_context *hdd_ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* wlan_hdd_mon_thread_suspend() - Suspend MON thread
|
|
||||||
* @hdd_ctx: HDD context
|
|
||||||
*
|
|
||||||
* To suspend MON thread
|
|
||||||
*
|
|
||||||
* Return: 0 for success
|
|
||||||
*/
|
|
||||||
int wlan_hdd_mon_thread_suspend(struct hdd_context *hdd_ctx);
|
|
||||||
|
|
||||||
#else
|
|
||||||
static inline void wlan_hdd_mon_thread_resume(struct hdd_context *hdd_ctx) {}
|
|
||||||
static inline int wlan_hdd_mon_thread_suspend(struct hdd_context *hdd_ctx)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WLAN_FEATURE_PKT_CAPTURE */
|
|
||||||
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
/**
|
/**
|
||||||
* wlan_hdd_rx_thread_resume() - Resume RX thread
|
* wlan_hdd_rx_thread_resume() - Resume RX thread
|
||||||
|
@@ -82,6 +82,7 @@
|
|||||||
#include "wlan_mlme_ucfg_api.h"
|
#include "wlan_mlme_ucfg_api.h"
|
||||||
#include "wlan_osif_request_manager.h"
|
#include "wlan_osif_request_manager.h"
|
||||||
#include <wlan_hdd_sar_limits.h>
|
#include <wlan_hdd_sar_limits.h>
|
||||||
|
#include "wlan_pkt_capture_ucfg_api.h"
|
||||||
|
|
||||||
/* Preprocessor definitions and constants */
|
/* Preprocessor definitions and constants */
|
||||||
#ifdef QCA_WIFI_NAPIER_EMULATION
|
#ifdef QCA_WIFI_NAPIER_EMULATION
|
||||||
@@ -124,46 +125,6 @@ void hdd_wlan_offload_event(uint8_t type, uint8_t state)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WLAN_FEATURE_PKT_CAPTURE
|
|
||||||
|
|
||||||
/* timeout in msec to wait for RX_THREAD to suspend */
|
|
||||||
#define HDD_MONTHREAD_SUSPEND_TIMEOUT 200
|
|
||||||
|
|
||||||
void wlan_hdd_mon_thread_resume(struct hdd_context *hdd_ctx)
|
|
||||||
{
|
|
||||||
if (hdd_ctx->is_ol_mon_thread_suspended) {
|
|
||||||
cds_resume_mon_thread();
|
|
||||||
hdd_ctx->is_ol_mon_thread_suspended = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int wlan_hdd_mon_thread_suspend(struct hdd_context *hdd_ctx)
|
|
||||||
{
|
|
||||||
p_cds_sched_context cds_sched_context = get_cds_sched_ctxt();
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!cds_sched_context)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
set_bit(RX_SUSPEND_EVENT,
|
|
||||||
&cds_sched_context->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
wake_up_interruptible(&cds_sched_context->
|
|
||||||
sched_mon_ctx.ol_mon_wait_queue);
|
|
||||||
rc = wait_for_completion_timeout(
|
|
||||||
&cds_sched_context->sched_mon_ctx.ol_suspend_mon_event,
|
|
||||||
msecs_to_jiffies(HDD_MONTHREAD_SUSPEND_TIMEOUT));
|
|
||||||
if (!rc) {
|
|
||||||
clear_bit(RX_SUSPEND_EVENT,
|
|
||||||
&cds_sched_context->sched_mon_ctx.ol_mon_event_flag);
|
|
||||||
hdd_err("Failed to stop tl_shim mon thread");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
hdd_ctx->is_ol_mon_thread_suspended = true;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef QCA_CONFIG_SMP
|
#ifdef QCA_CONFIG_SMP
|
||||||
|
|
||||||
/* timeout in msec to wait for RX_THREAD to suspend */
|
/* timeout in msec to wait for RX_THREAD to suspend */
|
||||||
@@ -1349,6 +1310,7 @@ static void hdd_ssr_restart_sap(struct hdd_context *hdd_ctx)
|
|||||||
QDF_STATUS hdd_wlan_shutdown(void)
|
QDF_STATUS hdd_wlan_shutdown(void)
|
||||||
{
|
{
|
||||||
struct hdd_context *hdd_ctx;
|
struct hdd_context *hdd_ctx;
|
||||||
|
struct hdd_adapter *adapter;
|
||||||
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
|
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
|
||||||
|
|
||||||
hdd_info("WLAN driver shutting down!");
|
hdd_info("WLAN driver shutting down!");
|
||||||
@@ -1377,8 +1339,11 @@ QDF_STATUS hdd_wlan_shutdown(void)
|
|||||||
|
|
||||||
dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
|
dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
|
||||||
|
|
||||||
if (cds_is_pktcapture_enabled())
|
if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) {
|
||||||
wlan_hdd_mon_thread_resume(hdd_ctx);
|
adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
|
||||||
|
if (adapter)
|
||||||
|
ucfg_pkt_capture_resume_mon_thread(adapter->vdev);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* After SSR, FW clear its txrx stats. In host,
|
* After SSR, FW clear its txrx stats. In host,
|
||||||
@@ -1730,6 +1695,7 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
|
|||||||
{
|
{
|
||||||
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
||||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||||
|
struct hdd_adapter *adapter;
|
||||||
int exit_code;
|
int exit_code;
|
||||||
|
|
||||||
hdd_enter();
|
hdd_enter();
|
||||||
@@ -1785,8 +1751,11 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
|
|||||||
if (hdd_ctx->enable_dp_rx_threads)
|
if (hdd_ctx->enable_dp_rx_threads)
|
||||||
dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
|
dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
|
||||||
|
|
||||||
if (cds_is_pktcapture_enabled())
|
if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) {
|
||||||
wlan_hdd_mon_thread_resume(hdd_ctx);
|
adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
|
||||||
|
if (adapter)
|
||||||
|
ucfg_pkt_capture_resume_mon_thread(adapter->vdev);
|
||||||
|
}
|
||||||
|
|
||||||
qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
|
qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
|
||||||
TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
|
TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
|
||||||
@@ -1992,9 +1961,11 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
|
|||||||
if (hdd_ctx->enable_dp_rx_threads)
|
if (hdd_ctx->enable_dp_rx_threads)
|
||||||
dp_txrx_suspend(cds_get_context(QDF_MODULE_ID_SOC));
|
dp_txrx_suspend(cds_get_context(QDF_MODULE_ID_SOC));
|
||||||
|
|
||||||
if (cds_is_pktcapture_enabled()) {
|
if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) {
|
||||||
if (wlan_hdd_mon_thread_suspend(hdd_ctx))
|
adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
|
||||||
goto resume_ol_mon;
|
if (adapter)
|
||||||
|
if (ucfg_pkt_capture_suspend_mon_thread(adapter->vdev))
|
||||||
|
goto resume_pkt_capture_mon_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
|
qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
|
||||||
@@ -2017,10 +1988,13 @@ resume_dp_thread:
|
|||||||
if (hdd_ctx->enable_dp_rx_threads)
|
if (hdd_ctx->enable_dp_rx_threads)
|
||||||
dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
|
dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
|
||||||
|
|
||||||
resume_ol_mon:
|
resume_pkt_capture_mon_thread:
|
||||||
/* Resume tlshim MON thread */
|
/* Resume packet capture MON thread */
|
||||||
if (cds_is_pktcapture_enabled())
|
if (ucfg_pkt_capture_get_mode(hdd_ctx->psoc)) {
|
||||||
wlan_hdd_mon_thread_resume(hdd_ctx);
|
adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
|
||||||
|
if (adapter)
|
||||||
|
ucfg_pkt_capture_resume_mon_thread(adapter->vdev);
|
||||||
|
}
|
||||||
|
|
||||||
resume_ol_rx:
|
resume_ol_rx:
|
||||||
/* Resume tlshim Rx thread */
|
/* Resume tlshim Rx thread */
|
||||||
|
Reference in New Issue
Block a user