qcacmn: Enable monitor mode in mission mode

While in mission mode, add support for monitor mode to be created as
another interface to support STA + monitor mode. Create a new
mon_vdev_timer to be started during vdev_attach and calling
dp_mon_vdev_timer to reap monitor rings while in this mode.

CRs-Fixed: 2815653
Change-Id: I631deb5121d7997cded524befd11883079a23aaf
这个提交包含在:
Saket Jha
2020-11-05 19:10:04 -08:00
提交者 snandini
父节点 8f311b08dd
当前提交 b46ee401e1
修改 2 个文件,包含 95 行新增6 行删除

查看文件

@@ -248,6 +248,9 @@ static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc,
int ring_num);
#define DP_INTR_POLL_TIMER_MS 5
#define MON_VDEV_TIMER_INIT 0x1
#define MON_VDEV_TIMER_RUNNING 0x2
/* Generic AST entry aging timer value */
#define DP_AST_AGING_TIMER_DEFAULT_MS 1000
#define DP_MCS_LENGTH (6*MAX_MCS)
@@ -2030,12 +2033,14 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
int_ctx->intr_stats.num_reo_status_ring_masks++;
}
work_done = dp_process_lmac_rings(int_ctx, remaining_quota);
if (work_done) {
budget -= work_done;
if (budget <= 0)
goto budget_done;
remaining_quota = budget;
if (qdf_unlikely(!(soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING))) {
work_done = dp_process_lmac_rings(int_ctx, remaining_quota);
if (work_done) {
budget -= work_done;
if (budget <= 0)
goto budget_done;
remaining_quota = budget;
}
}
qdf_lro_flush(int_ctx->lro_ctx);
@@ -2045,6 +2050,70 @@ budget_done:
return dp_budget - budget;
}
/* dp_mon_vdev_timer()- timer poll for interrupts
*
* @arg: SoC Handle
*
* Return:
*
*/
static void dp_mon_vdev_timer(void *arg)
{
struct dp_soc *soc = (struct dp_soc *)arg;
struct dp_pdev *pdev = soc->pdev_list[0];
enum timer_yield_status yield = DP_TIMER_NO_YIELD;
uint32_t work_done = 0, total_work_done = 0;
int budget = 0xffff;
uint32_t remaining_quota = budget;
uint64_t start_time;
uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
uint32_t lmac_iter;
int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
if (!qdf_atomic_read(&soc->cmn_init_done))
return;
if (pdev->mon_chan_band != REG_BAND_UNKNOWN)
lmac_id = pdev->ch_band_lmac_id_mapping[pdev->mon_chan_band];
start_time = qdf_get_log_timestamp();
dp_is_hw_dbs_enable(soc, &max_mac_rings);
while (yield == DP_TIMER_NO_YIELD) {
for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
if (lmac_iter == lmac_id)
work_done = dp_mon_process(
soc, NULL,
lmac_iter, remaining_quota);
else
work_done =
dp_mon_drop_packets_for_mac(pdev,
lmac_iter,
remaining_quota);
if (work_done) {
budget -= work_done;
if (budget <= 0) {
yield = DP_TIMER_WORK_EXHAUST;
goto budget_done;
}
remaining_quota = budget;
total_work_done += work_done;
}
}
yield = dp_should_timer_irq_yield(soc, total_work_done,
start_time);
total_work_done = 0;
}
budget_done:
if (yield == DP_TIMER_WORK_EXHAUST ||
yield == DP_TIMER_TIME_EXHAUST)
qdf_timer_mod(&soc->mon_vdev_timer, 1);
else
qdf_timer_mod(&soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
}
/* dp_interrupt_timer()- timer poll for interrupts
*
* @arg: SoC Handle
@@ -4668,6 +4737,10 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID);
wlan_cfg_soc_detach(soc->wlan_cfg_ctx);
dp_soc_rx_history_detach(soc);
if (soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
qdf_timer_free(&soc->mon_vdev_timer);
soc->mon_vdev_timer_state = 0;
}
qdf_mem_free(soc);
}
@@ -4873,6 +4946,10 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
dp_mon_reap_timer_handler, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
soc->reap_timer_init = 1;
qdf_timer_init(soc->osdev, &soc->mon_vdev_timer,
dp_mon_vdev_timer, (void *)soc,
QDF_TIMER_TYPE_WAKE_APPS);
soc->mon_vdev_timer_state |= MON_VDEV_TIMER_INIT;
return status;
}
#else
@@ -5382,6 +5459,11 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
if ((pdev->vdev_count == 0) ||
(wlan_op_mode_monitor == vdev->opmode))
qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
} else if (soc->intr_mode == DP_INTR_MSI &&
wlan_op_mode_monitor == vdev->opmode &&
soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
qdf_timer_mod(&soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
soc->mon_vdev_timer_state |= MON_VDEV_TIMER_RUNNING;
}
dp_vdev_id_map_tbl_add(soc, vdev, vdev_id);
@@ -6643,6 +6725,11 @@ void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev,
if (soc->intr_mode == DP_INTR_POLL) {
qdf_timer_sync_cancel(&soc->int_timer);
dp_flush_monitor_rings(soc);
} else if (soc->intr_mode == DP_INTR_MSI &&
soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING) {
qdf_timer_sync_cancel(&soc->mon_vdev_timer);
dp_flush_monitor_rings(soc);
soc->mon_vdev_timer_state &= ~MON_VDEV_TIMER_RUNNING;
}
pdev->monitor_vdev = NULL;
goto free_vdev;