diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 57f31a6a3d..ba1d83febe 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -359,6 +359,16 @@ static inline void dp_set_peer_isolation(struct dp_peer *peer, bool val) } #endif /* QCA_SUPPORT_PEER_ISOLATION */ +/** + * The lmac ID for a particular channel band is fixed. + * 2.4GHz band uses lmac_id = 1 + * 5GHz/6GHz band uses lmac_id=0 + */ +#define DP_MON_INVALID_LMAC_ID (-1) +#define DP_MON_2G_LMAC_ID 1 +#define DP_MON_5G_LMAC_ID 0 +#define DP_MON_6G_LMAC_ID 0 + #ifdef FEATURE_TSO_STATS /** * dp_init_tso_stats() - Clear tso stats @@ -1737,7 +1747,7 @@ static inline void dp_peer_unref_del_find_by_id(struct dp_peer *peer) #ifdef WLAN_FEATURE_DP_EVENT_HISTORY /** * dp_srng_access_start() - Wrapper function to log access start of a hal ring - * @int_ctx: pointer to DP interrupt context + * @int_ctx: pointer to DP interrupt context. This should not be NULL * @soc: DP Soc handle * @hal_ring: opaque pointer to the HAL Rx Error Ring, which will be serviced * @@ -1748,7 +1758,7 @@ int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc, /** * dp_srng_access_end() - Wrapper function to log access end of a hal ring - * @int_ctx: pointer to DP interrupt context + * @int_ctx: pointer to DP interrupt context. This should not be NULL * @soc: DP Soc handle * @hal_ring: opaque pointer to the HAL Rx Error Ring, which will be serviced * diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index b58396d804..06e9822b7e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -427,7 +427,7 @@ static void dp_service_mon_rings(struct dp_soc *soc, uint32_t quota) pdev = dp_get_pdev_for_lmac_id(soc, ring); if (!pdev) continue; - work_done = dp_mon_process(soc, ring, quota); + work_done = dp_mon_process(soc, NULL, ring, quota); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, FL("Reaped %d descs from Monitor rings"), @@ -593,7 +593,7 @@ static void dp_service_lmac_rings(void *arg) rx_refill_buf_ring = &soc->rx_refill_buf_ring[mac_for_pdev]; - dp_mon_process(soc, mac_for_pdev, + dp_mon_process(soc, NULL, mac_for_pdev, QCA_NAPI_BUDGET); for (i = 0; @@ -1572,6 +1572,9 @@ int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc, uint32_t hp, tp; uint8_t ring_id; + if (!int_ctx) + return hal_srng_access_start(hal_soc, hal_ring_hdl); + hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp); ring_id = hal_srng_ring_id_get(hal_ring_hdl); @@ -1588,6 +1591,9 @@ void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc, uint32_t hp, tp; uint8_t ring_id; + if (!int_ctx) + return hal_srng_access_end(hal_soc, hal_ring_hdl); + hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp); ring_id = hal_srng_ring_id_get(hal_ring_hdl); @@ -1596,6 +1602,32 @@ void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc, return hal_srng_access_end(hal_soc, hal_ring_hdl); } + +static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc, + uint8_t hist_group_id) +{ + hif_record_event(dp_soc->hif_handle, hist_group_id, + 0, 0, 0, HIF_EVENT_TIMER_ENTRY); +} + +static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc, + uint8_t hist_group_id) +{ + hif_record_event(dp_soc->hif_handle, hist_group_id, + 0, 0, 0, HIF_EVENT_TIMER_EXIT); +} +#else + +static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc, + uint8_t hist_group_id) +{ +} + +static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc, + uint8_t hist_group_id) +{ +} + #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ /* @@ -1646,7 +1678,7 @@ static int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget) if (!pdev) continue; if (int_ctx->rx_mon_ring_mask & (1 << mac_for_pdev)) { - work_done = dp_mon_process(soc, mac_for_pdev, + work_done = dp_mon_process(soc, int_ctx, mac_for_pdev, remaining_quota); if (work_done) intr_stats->num_rx_mon_ring_masks++; @@ -1830,6 +1862,31 @@ budget_done: return dp_budget - budget; } +/** + * dp_mon_get_lmac_id_from_ch_band() - get the lmac id corresponding + * to a particular channel band. + * @soc: Datapath soc handle + * @band: channel band configured + * + * Returns: lmac id corresponding to the channel band + * + * Currently the 5GHz/6GHz packets will be captured on lmac id 0 + * and the 2.4GHz packets are captured on lmac id 1. + * This function returns the mapping on the basis of above information. + */ +static inline int dp_mon_get_lmac_id_from_ch_band(struct dp_soc *soc, + enum reg_wifi_band band) +{ + if (band == REG_BAND_2G) + return DP_MON_2G_LMAC_ID; + else if (band == REG_BAND_5G) + return DP_MON_5G_LMAC_ID; + else if (band == REG_BAND_6G) + return DP_MON_6G_LMAC_ID; + + return DP_MON_INVALID_LMAC_ID; +} + /* dp_interrupt_timer()- timer poll for interrupts * * @arg: SoC Handle @@ -1840,35 +1897,44 @@ budget_done: static void dp_interrupt_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; - int i; + uint32_t lmac_id; + uint8_t dp_intr_id; if (!qdf_atomic_read(&soc->cmn_init_done)) return; + if (pdev->mon_chan_band == REG_BAND_UNKNOWN) { + qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); + return; + } + + lmac_id = dp_mon_get_lmac_id_from_ch_band(soc, pdev->mon_chan_band); + if (qdf_unlikely(lmac_id == DP_MON_INVALID_LMAC_ID)) { + qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); + return; + } + + dp_intr_id = soc->mon_intr_id_lmac_map[lmac_id]; + dp_srng_record_timer_entry(soc, dp_intr_id); start_time = qdf_get_log_timestamp(); while (yield == DP_TIMER_NO_YIELD) { - for (i = 0; - i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { - if (!soc->intr_ctx[i].rx_mon_ring_mask) - continue; - - work_done = dp_process_lmac_rings(&soc->intr_ctx[i], - 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; + work_done = dp_mon_process(soc, &soc->intr_ctx[dp_intr_id], + lmac_id, 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, @@ -1882,8 +1948,27 @@ budget_done: qdf_timer_mod(&soc->int_timer, 1); else qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS); + + dp_srng_record_timer_exit(soc, dp_intr_id); } +#ifdef WLAN_FEATURE_DP_EVENT_HISTORY +static inline bool dp_is_mon_mask_valid(struct dp_soc *soc, + struct dp_intr *intr_ctx) +{ + if (intr_ctx->rx_mon_ring_mask) + return true; + + return false; +} +#else +static inline bool dp_is_mon_mask_valid(struct dp_soc *soc, + struct dp_intr *intr_ctx) +{ + return false; +} +#endif + /* * dp_soc_attach_poll() - Register handlers for DP interrupts * @txrx_soc: DP SOC handle @@ -1898,7 +1983,10 @@ static QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; int i; + int lmac_id = 0; + qdf_mem_set(&soc->mon_intr_id_lmac_map, + sizeof(soc->mon_intr_id_lmac_map), DP_MON_INVALID_LMAC_ID); soc->intr_mode = DP_INTR_POLL; for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { @@ -1919,6 +2007,12 @@ static QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc) wlan_cfg_get_rxdma2host_ring_mask(soc->wlan_cfg_ctx, i); soc->intr_ctx[i].soc = soc; soc->intr_ctx[i].lro_ctx = qdf_lro_init(); + + if (dp_is_mon_mask_valid(soc, &soc->intr_ctx[i])) { + hif_event_history_init(soc->hif_handle, i); + soc->mon_intr_id_lmac_map[lmac_id] = i; + lmac_id++; + } } qdf_timer_init(soc->osdev, &soc->int_timer, @@ -2153,6 +2247,9 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) int i = 0; int num_irq = 0; + qdf_mem_set(&soc->mon_intr_id_lmac_map, + sizeof(soc->mon_intr_id_lmac_map), DP_MON_INVALID_LMAC_ID); + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { int ret = 0; @@ -2209,6 +2306,8 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc) return QDF_STATUS_E_FAILURE; } + + hif_event_history_init(soc->hif_handle, i); soc->intr_ctx[i].lro_ctx = qdf_lro_init(); } @@ -2246,8 +2345,12 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) soc->intr_ctx[i].host2rxdma_ring_mask = 0; soc->intr_ctx[i].host2rxdma_mon_ring_mask = 0; + hif_event_history_deinit(soc->hif_handle, i); qdf_lro_deinit(soc->intr_ctx[i].lro_ctx); } + + qdf_mem_set(&soc->mon_intr_id_lmac_map, + REG_BAND_UNKNOWN * sizeof(int), DP_MON_INVALID_LMAC_ID); } #define AVG_MAX_MPDUS_PER_TID 128 @@ -7886,6 +7989,8 @@ static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, break; case CDP_MONITOR_FREQUENCY: pdev->mon_chan_freq = val.cdp_pdev_param_mon_freq; + pdev->mon_chan_band = + wlan_reg_freq_to_band(pdev->mon_chan_freq); break; case CDP_CONFIG_BSS_COLOR: dp_mon_set_bsscolor(pdev, val.cdp_pdev_param_bss_color); @@ -12397,6 +12502,7 @@ static inline QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc, TAILQ_INIT(&pdev->neighbour_peers_list); pdev->neighbour_peers_added = false; pdev->monitor_configured = false; + pdev->mon_chan_band = REG_BAND_UNKNOWN; DP_STATS_INIT(pdev); diff --git a/dp/wifi3.0/dp_rx_mon.h b/dp/wifi3.0/dp_rx_mon.h index cc513c6bb7..fb9fe5d79d 100644 --- a/dp/wifi3.0/dp_rx_mon.h +++ b/dp/wifi3.0/dp_rx_mon.h @@ -28,31 +28,34 @@ /* * dp_rx_mon_status_process() - Process monitor status ring and - *>.....TLV in status ring. + * TLV in status ring. * * @soc: core txrx main context + * @int_ctx: interrupt context * @mac_id: mac_id which is one of 3 mac_ids * @quota: No. of ring entry that can be serviced in one shot. * Return: uint32_t: No. of ring entry that is processed. */ uint32_t -dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota); +dp_rx_mon_status_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota); /** -* dp_rx_mon_dest_process() - Brain of the Rx processing functionality -* Called from the bottom half (tasklet/NET_RX_SOFTIRQ) -* @soc: core txrx main context 164 -* @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced -* @quota: No. of units (packets) that can be serviced in one shot. -* -* This function implements the core of Rx functionality. This is -* expected to handle only non-error frames. -* -* Return: uint32_t: No. of elements processed -*/ -void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, - uint32_t quota); + * dp_rx_mon_dest_process() - Brain of the Rx processing functionality + * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) + * @soc: core txrx main contex + * @int_ctx: interrupt context + * @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced + * @quota: No. of units (packets) that can be serviced in one shot. + * + * This function implements the core of Rx functionality. This is + * expected to handle only non-error frames. + * + * Return: none + */ +void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota); QDF_STATUS dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev); QDF_STATUS dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev); @@ -106,11 +109,13 @@ void dp_full_mon_detach(struct dp_pdev *pdev); * full monitor mode * * @soc: dp soc handle + * @int_ctx: interrupt context * @mac_id: lmac id * @quota: No. of ring entry that can be serviced in one shot. */ -uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota); +uint32_t dp_rx_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota); #else /** @@ -158,7 +163,21 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl, QDF_STATUS dp_mon_link_free(struct dp_pdev *pdev); -uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota); +/** + * dp_mon_process() - Main monitor mode processing roution. + * @soc: core txrx main context + * @int_ctx: interrupt context + * @mac_id: mac_id which is one of 3 mac_ids + * @quota: No. of status ring entry that can be serviced in one shot. + * + * This call monitor status ring process then monitor + * destination ring process. + * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) + * + * Return: uint32_t: No. of ring entry that is processed. + */ +uint32_t dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota); QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu); /* diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 4a39394688..b9dfeb4b8a 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -996,19 +996,8 @@ mon_deliver_non_std_fail: return QDF_STATUS_E_INVAL; } -/** -* dp_rx_mon_dest_process() - Brain of the Rx processing functionality -* Called from the bottom half (tasklet/NET_RX_SOFTIRQ) -* @soc: core txrx main contex -* @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced -* @quota: No. of units (packets) that can be serviced in one shot. -* -* This function implements the core of Rx functionality. This is -* expected to handle only non-error frames. -* -* Return: none -*/ -void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) +void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota) { struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); uint8_t pdev_id; @@ -1044,7 +1033,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) qdf_spin_lock_bh(&pdev->mon_lock); - if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_dst_srng))) { + if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : HAL Monitor Destination Ring access Failed -- %pK", __func__, __LINE__, mon_dst_srng); @@ -1114,7 +1103,8 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, mon_dst_srng); } - hal_srng_access_end(hal_soc, mon_dst_srng); + + dp_srng_access_end(int_ctx, soc, mon_dst_srng); qdf_spin_unlock_bh(&pdev->mon_lock); diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 1f936882f5..fe7df716d0 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -57,13 +57,15 @@ dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev, * Called from bottom half (tasklet/NET_RX_SOFTIRQ) * * @soc: datapath soc context + * @int_ctx: interrupt context * @mac_id: mac_id on which interrupt is received * @quota: Number of status ring entry that can be serviced in one shot. * * @Return: Number of reaped status ring entries */ static inline uint32_t -dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) +dp_rx_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota) { return quota; } @@ -1568,16 +1570,18 @@ dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) #endif /** -* dp_rx_mon_status_process_tlv() - Process status TLV in status -* buffer on Rx status Queue posted by status SRNG processing. -* @soc: core txrx main context -* @mac_id: mac_id which is one of 3 mac_ids _ring -* -* Return: none -*/ + * dp_rx_mon_status_process_tlv() - Process status TLV in status + * buffer on Rx status Queue posted by status SRNG processing. + * @soc: core txrx main context + * @int_ctx: interrupt context + * @mac_id: mac_id which is one of 3 mac_ids _ring + * @quota: amount of work which can be done + * + * Return: none + */ static inline void -dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, - uint32_t quota) +dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota) { struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); struct hal_rx_ppdu_info *ppdu_info; @@ -1718,7 +1722,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, } if (!soc->full_mon_mode) - dp_rx_mon_dest_process(soc, mac_id, quota); + dp_rx_mon_dest_process(soc, int_ctx, mac_id, + quota); pdev->mon_ppdu_status = DP_PPDU_STATUS_START; } @@ -1732,16 +1737,16 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, * processing when status ring is filled with status TLV. * Allocate a new buffer to status ring if the filled buffer * is posted. - * * @soc: core txrx main context + * @int_ctx: interrupt context * @mac_id: mac_id which is one of 3 mac_ids * @quota: No. of ring entry that can be serviced in one shot. * Return: uint32_t: No. of ring entry that is processed. */ static inline uint32_t -dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id, - uint32_t quota) +dp_rx_mon_status_srng_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota) { struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); hal_soc_handle_t hal_soc; @@ -1771,7 +1776,7 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id, qdf_assert(hal_soc); - if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_status_srng))) + if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_status_srng))) goto done; /* mon_status_ring_desc => WBM_BUFFER_RING STRUCT => @@ -1911,50 +1916,33 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id, } done: - hal_srng_access_end(hal_soc, mon_status_srng); + dp_srng_access_end(int_ctx, soc, mon_status_srng); return work_done; } -/* - * dp_rx_mon_status_process() - Process monitor status ring and - * TLV in status ring. - * - * @soc: core txrx main context - * @mac_id: mac_id which is one of 3 mac_ids - * @quota: No. of ring entry that can be serviced in one shot. - - * Return: uint32_t: No. of ring entry that is processed. - */ uint32_t -dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { +dp_rx_mon_status_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota) +{ uint32_t work_done; - work_done = dp_rx_mon_status_srng_process(soc, mac_id, quota); + work_done = dp_rx_mon_status_srng_process(soc, int_ctx, mac_id, quota); quota -= work_done; - dp_rx_mon_status_process_tlv(soc, mac_id, quota); + dp_rx_mon_status_process_tlv(soc, int_ctx, mac_id, quota); return work_done; } -/** - * dp_mon_process() - Main monitor mode processing roution. - * This call monitor status ring process then monitor - * destination ring process. - * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) - * @soc: core txrx main context - * @mac_id: mac_id which is one of 3 mac_ids - * @quota: No. of status ring entry that can be serviced in one shot. - - * Return: uint32_t: No. of ring entry that is processed. - */ uint32_t -dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { +dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, + uint32_t mac_id, uint32_t quota) +{ if (qdf_unlikely(soc->full_mon_mode)) - return dp_rx_mon_process(soc, mac_id, quota); + return dp_rx_mon_process(soc, int_ctx, mac_id, quota); - return dp_rx_mon_status_process(soc, mac_id, quota); + return dp_rx_mon_status_process(soc, int_ctx, mac_id, quota); } QDF_STATUS diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 559daa484d..3fdad06043 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1102,6 +1102,8 @@ struct dp_soc { /* DP Interrupts */ struct dp_intr intr_ctx[WLAN_CFG_INT_NUM_CONTEXTS]; + /* Monitor mode mac id to dp_intr_id map */ + int mon_intr_id_lmac_map[MAX_NUM_LMAC_HW]; /* Rx SW descriptor pool for RXDMA monitor buffer */ struct rx_desc_pool rx_desc_mon[MAX_RXDESC_POOLS]; @@ -1621,6 +1623,9 @@ struct dp_pdev { /* Monitor mode operation frequency */ qdf_freq_t mon_chan_freq; + /* Monitor mode band */ + enum reg_wifi_band mon_chan_band; + /* monitor mode lock */ qdf_spinlock_t mon_lock; diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 99b8c1ef81..612778ee6c 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -315,12 +315,16 @@ struct hif_opaque_softc { /** * enum hif_event_type - Type of DP events to be recorded * @HIF_EVENT_IRQ_TRIGGER: IRQ trigger event + * @HIF_EVENT_TIMER_ENTRY: Monitor Timer entry event + * @HIF_EVENT_TIMER_EXIT: Monitor Timer exit event * @HIF_EVENT_BH_SCHED: NAPI POLL scheduled event * @HIF_EVENT_SRNG_ACCESS_START: hal ring access start event * @HIF_EVENT_SRNG_ACCESS_END: hal ring access end event */ enum hif_event_type { HIF_EVENT_IRQ_TRIGGER, + HIF_EVENT_TIMER_ENTRY, + HIF_EVENT_TIMER_EXIT, HIF_EVENT_BH_SCHED, HIF_EVENT_SRNG_ACCESS_START, HIF_EVENT_SRNG_ACCESS_END, @@ -379,6 +383,24 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx, struct hif_event_record *event, uint8_t intr_grp_id); +/** + * hif_event_history_init() - Initialize SRNG event history buffers + * @hif_ctx: HIF opaque context + * @id: context group ID for which history is recorded + * + * Returns: None + */ +void hif_event_history_init(struct hif_opaque_softc *hif_ctx, uint8_t id); + +/** + * hif_event_history_deinit() - De-initialize SRNG event history buffers + * @hif_ctx: HIF opaque context + * @id: context group ID for which history is recorded + * + * Returns: None + */ +void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx, uint8_t id); + /** * hif_record_event() - Wrapper function to form and record DP event * @hif_ctx: HIF opaque context @@ -418,6 +440,16 @@ static inline void hif_record_event(struct hif_opaque_softc *hif_ctx, enum hif_event_type type) { } + +static inline void hif_event_history_init(struct hif_opaque_softc *hif_ctx, + uint8_t id) +{ +} + +static inline void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx, + uint8_t id) +{ +} #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ /** diff --git a/hif/src/hif_exec.c b/hif/src/hif_exec.c index c5aa4a41c4..21d211d649 100644 --- a/hif/src/hif_exec.c +++ b/hif/src/hif_exec.c @@ -47,25 +47,21 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx, struct hif_event_record *event, uint8_t intr_grp_id) { struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); - struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); - struct hif_exec_context *hif_ext_group; struct hif_event_history *hist_ev; struct hif_event_record *record; int record_index; - if (!hif_state->hif_num_extgroup) - return; - if (scn->event_disable_mask & BIT(event->type)) return; - if (intr_grp_id >= HIF_NUM_INT_CONTEXTS) { + if (qdf_unlikely(intr_grp_id >= HIF_NUM_INT_CONTEXTS)) { hif_err("Invalid interrupt group id %d", intr_grp_id); return; } - hif_ext_group = hif_state->hif_ext_group[intr_grp_id]; - hist_ev = hif_ext_group->evt_hist; + hist_ev = scn->evt_hist[intr_grp_id]; + if (qdf_unlikely(!hist_ev)) + return; record_index = hif_get_next_record_index( &hist_ev->index, HIF_EVENT_HIST_MAX); @@ -80,14 +76,22 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx, record->type = event->type; } -static void hif_event_history_init(struct hif_exec_context *hif_ext_grp) +void hif_event_history_init(struct hif_opaque_softc *hif_ctx, uint8_t id) { - hif_ext_grp->evt_hist = &hif_event_desc_history[hif_ext_grp->grp_id]; - qdf_atomic_set(&hif_ext_grp->evt_hist->index, -1); + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + scn->evt_hist[id] = &hif_event_desc_history[id]; + qdf_atomic_set(&scn->evt_hist[id]->index, -1); + + hif_info("SRNG events history initialized for group: %d", id); } -#else -static inline void hif_event_history_init(struct hif_exec_context *hif_ext_grp) + +void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx, uint8_t id) { + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + + scn->evt_hist[id] = NULL; + hif_info("SRNG events history de-initialized for group: %d", id); } #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ @@ -878,7 +882,6 @@ uint32_t hif_register_ext_group(struct hif_opaque_softc *hif_ctx, hif_ext_group->hif = hif_ctx; hif_ext_group->context_name = context_name; hif_ext_group->type = type; - hif_event_history_init(hif_ext_group); hif_state->hif_num_extgroup++; return QDF_STATUS_SUCCESS; diff --git a/hif/src/hif_exec.h b/hif/src/hif_exec.h index 6a2b7868ed..e13c2efb9c 100644 --- a/hif/src/hif_exec.h +++ b/hif/src/hif_exec.h @@ -54,7 +54,6 @@ struct hif_execution_ops { * hif_tasklet_exec_context * * @context: context for the handler function to use. - * @evt_hist: a pointer to the DP event history * @context_name: a pointer to a const string for debugging. * this should help whenever there could be ambiguity * in what type of context the void* context points to @@ -89,7 +88,6 @@ struct hif_exec_context { const char *context_name; void *context; ext_intr_handler handler; - struct hif_event_history *evt_hist; bool (*work_complete)(struct hif_exec_context *, int work_done); void (*irq_enable)(struct hif_exec_context *); diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 75ac8599d9..f42ed66fbb 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -231,6 +231,10 @@ struct hif_softc { /* Handle to pktlog device */ void *pktlog_dev; #endif +#ifdef WLAN_FEATURE_DP_EVENT_HISTORY + /* Pointer to the srng event history */ + struct hif_event_history *evt_hist[HIF_NUM_INT_CONTEXTS]; +#endif /* * Note: For MCL, #if defined (HIF_CONFIG_SLUB_DEBUG_ON) needs to be checked