qcacmn: Drop beacon/probe frames posted on Scan Queue if queue is full
Drop beacon/probe frames before posting on Scan queue if the queue already has too many beacon/probes to process. Also add scheduler API to get the queue size given the module ID. Change-Id: I9153c7e77e74377863774b68e8163839e992358d CRs-Fixed: 2298584
This commit is contained in:

committed by
nshrivas

parent
cbc53dd023
commit
87a8e44583
@@ -283,4 +283,14 @@ QDF_STATUS scheduler_deregister_wma_legacy_handler(void);
|
|||||||
*/
|
*/
|
||||||
void scheduler_mc_timer_callback(unsigned long data);
|
void scheduler_mc_timer_callback(unsigned long data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scheduler_get_queue_size() - Get the current size of the scheduler queue
|
||||||
|
* @qid: Queue ID for which the size is requested
|
||||||
|
* @size: Pointer to size where the size would be returned to the caller
|
||||||
|
*
|
||||||
|
* This API finds the size of the scheduler queue for the given Queue ID
|
||||||
|
*
|
||||||
|
* Return: QDF Status
|
||||||
|
*/
|
||||||
|
QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -619,3 +619,30 @@ void scheduler_mc_timer_callback(unsigned long data)
|
|||||||
if (QDF_IS_STATUS_ERROR(status))
|
if (QDF_IS_STATUS_ERROR(status))
|
||||||
sched_err("Could not enqueue timer to timer queue");
|
sched_err("Could not enqueue timer to timer queue");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size)
|
||||||
|
{
|
||||||
|
uint8_t qidx;
|
||||||
|
struct scheduler_mq_type *target_mq;
|
||||||
|
struct scheduler_ctx *sched_ctx;
|
||||||
|
|
||||||
|
sched_ctx = scheduler_get_context();
|
||||||
|
if (!sched_ctx)
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
|
||||||
|
/* WMA also uses the target_if queue, so replace the QID */
|
||||||
|
if (QDF_MODULE_ID_WMA == qid)
|
||||||
|
qid = QDF_MODULE_ID_TARGET_IF;
|
||||||
|
|
||||||
|
qidx = sched_ctx->queue_ctx.scheduler_msg_qid_to_qidx[qid];
|
||||||
|
if (qidx >= SCHEDULER_NUMBER_OF_MSG_QUEUE) {
|
||||||
|
sched_err("Scheduler is deinitialized");
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_mq = &(sched_ctx->queue_ctx.sch_msg_q[qidx]);
|
||||||
|
|
||||||
|
*size = qdf_list_size(&target_mq->mq_list);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
@@ -44,6 +44,18 @@
|
|||||||
#define scm_debug(params...) \
|
#define scm_debug(params...) \
|
||||||
QDF_TRACE_DEBUG(QDF_MODULE_ID_SCAN, params)
|
QDF_TRACE_DEBUG(QDF_MODULE_ID_SCAN, params)
|
||||||
|
|
||||||
|
/* Rate Limited Logs */
|
||||||
|
#define scm_alert_rl(params...) \
|
||||||
|
QDF_TRACE_FATAL_RL(QDF_MODULE_ID_SCAN, params)
|
||||||
|
#define scm_err_rl(params...) \
|
||||||
|
QDF_TRACE_ERROR_RL(QDF_MODULE_ID_SCAN, params)
|
||||||
|
#define scm_warn_rl(params...) \
|
||||||
|
QDF_TRACE_WARN_RL(QDF_MODULE_ID_SCAN, params)
|
||||||
|
#define scm_info_rl(params...) \
|
||||||
|
QDF_TRACE_INFO_RL(QDF_MODULE_ID_SCAN, params)
|
||||||
|
#define scm_debug_rl(params...) \
|
||||||
|
QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_SCAN, params)
|
||||||
|
|
||||||
#define scm_nofl_alert(params...) \
|
#define scm_nofl_alert(params...) \
|
||||||
QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_SCAN, params)
|
QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_SCAN, params)
|
||||||
#define scm_nofl_err(params...) \
|
#define scm_nofl_err(params...) \
|
||||||
|
@@ -69,6 +69,12 @@ typedef uint32_t wlan_scan_id;
|
|||||||
#define MAX_INDEX_SCORE 100
|
#define MAX_INDEX_SCORE 100
|
||||||
#define MAX_INDEX_PER_INI 4
|
#define MAX_INDEX_PER_INI 4
|
||||||
|
|
||||||
|
#ifdef CONFIG_MCL
|
||||||
|
#define MAX_BCN_PROBE_IN_SCAN_QUEUE 150
|
||||||
|
#else
|
||||||
|
#define MAX_BCN_PROBE_IN_SCAN_QUEUE 2000
|
||||||
|
#endif
|
||||||
|
|
||||||
#define WLAN_GET_BITS(_val, _index, _num_bits) \
|
#define WLAN_GET_BITS(_val, _index, _num_bits) \
|
||||||
(((_val) >> (_index)) & ((1 << (_num_bits)) - 1))
|
(((_val) >> (_index)) & ((1 << (_num_bits)) - 1))
|
||||||
|
|
||||||
|
@@ -257,29 +257,29 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc,
|
|||||||
enum mgmt_frame_type frm_type)
|
enum mgmt_frame_type frm_type)
|
||||||
{
|
{
|
||||||
struct scheduler_msg msg = {0};
|
struct scheduler_msg msg = {0};
|
||||||
struct scan_bcn_probe_event *bcn;
|
struct scan_bcn_probe_event *bcn = NULL;
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
|
uint32_t scan_queue_size = 0;
|
||||||
|
|
||||||
if ((frm_type != MGMT_PROBE_RESP) &&
|
if ((frm_type != MGMT_PROBE_RESP) &&
|
||||||
(frm_type != MGMT_BEACON)) {
|
(frm_type != MGMT_BEACON)) {
|
||||||
scm_err("frame is not beacon or probe resp");
|
scm_err("frame is not beacon or probe resp");
|
||||||
qdf_nbuf_free(buf);
|
status = QDF_STATUS_E_INVAL;
|
||||||
return QDF_STATUS_E_INVAL;
|
goto free;
|
||||||
}
|
}
|
||||||
bcn = qdf_mem_malloc_atomic(sizeof(*bcn));
|
bcn = qdf_mem_malloc_atomic(sizeof(*bcn));
|
||||||
|
|
||||||
if (!bcn) {
|
if (!bcn) {
|
||||||
scm_err("Failed to allocate memory for bcn");
|
scm_err("Failed to allocate memory for bcn");
|
||||||
qdf_nbuf_free(buf);
|
status = QDF_STATUS_E_NOMEM;
|
||||||
return QDF_STATUS_E_NOMEM;
|
goto free;
|
||||||
}
|
}
|
||||||
bcn->rx_data =
|
bcn->rx_data =
|
||||||
qdf_mem_malloc_atomic(sizeof(*rx_param));
|
qdf_mem_malloc_atomic(sizeof(*rx_param));
|
||||||
if (!bcn->rx_data) {
|
if (!bcn->rx_data) {
|
||||||
scm_err("Failed to allocate memory for rx_data");
|
scm_err("Failed to allocate memory for rx_data");
|
||||||
qdf_mem_free(bcn);
|
status = QDF_STATUS_E_NOMEM;
|
||||||
qdf_nbuf_free(buf);
|
goto free;
|
||||||
return QDF_STATUS_E_NOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm_type == MGMT_PROBE_RESP)
|
if (frm_type == MGMT_PROBE_RESP)
|
||||||
@@ -287,13 +287,20 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc,
|
|||||||
else
|
else
|
||||||
bcn->frm_type = MGMT_SUBTYPE_BEACON;
|
bcn->frm_type = MGMT_SUBTYPE_BEACON;
|
||||||
|
|
||||||
|
/* Check if the beacon/probe frame can be posted in the scan queue */
|
||||||
|
status = scheduler_get_queue_size(QDF_MODULE_ID_SCAN, &scan_queue_size);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status) ||
|
||||||
|
scan_queue_size > MAX_BCN_PROBE_IN_SCAN_QUEUE) {
|
||||||
|
scm_debug_rl("Dropping beacon/probe frame, queue size %d",
|
||||||
|
scan_queue_size);
|
||||||
|
status = QDF_STATUS_E_FAILURE;
|
||||||
|
goto free;
|
||||||
|
}
|
||||||
|
|
||||||
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID);
|
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_SCAN_ID);
|
||||||
if (QDF_IS_STATUS_ERROR(status)) {
|
if (QDF_IS_STATUS_ERROR(status)) {
|
||||||
scm_info("unable to get reference");
|
scm_info("unable to get reference");
|
||||||
qdf_mem_free(bcn->rx_data);
|
goto free;
|
||||||
qdf_mem_free(bcn);
|
|
||||||
qdf_nbuf_free(buf);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bcn->psoc = psoc;
|
bcn->psoc = psoc;
|
||||||
@@ -306,13 +313,19 @@ QDF_STATUS tgt_scan_bcn_probe_rx_callback(struct wlan_objmgr_psoc *psoc,
|
|||||||
|
|
||||||
status = scheduler_post_msg(QDF_MODULE_ID_SCAN, &msg);
|
status = scheduler_post_msg(QDF_MODULE_ID_SCAN, &msg);
|
||||||
|
|
||||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
if (QDF_IS_STATUS_SUCCESS(status))
|
||||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_SCAN_ID);
|
return status;
|
||||||
scm_err("failed to post to QDF_MODULE_ID_SCAN");
|
|
||||||
|
wlan_objmgr_psoc_release_ref(psoc, WLAN_SCAN_ID);
|
||||||
|
scm_err("failed to post to QDF_MODULE_ID_SCAN");
|
||||||
|
|
||||||
|
free:
|
||||||
|
if (bcn && bcn->rx_data)
|
||||||
qdf_mem_free(bcn->rx_data);
|
qdf_mem_free(bcn->rx_data);
|
||||||
|
if (bcn)
|
||||||
qdf_mem_free(bcn);
|
qdf_mem_free(bcn);
|
||||||
|
if (buf)
|
||||||
qdf_nbuf_free(buf);
|
qdf_nbuf_free(buf);
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user