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:
Vulupala Shashank Reddy
2020-02-12 09:43:48 +05:30
committed by nshrivas
parent aa481cc459
commit a7e26ef49f
6 changed files with 25 additions and 827 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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