diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 787c7a4f61..3290e01055 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -1962,6 +1962,32 @@ cdp_soc_map_pdev_to_lmac(ol_txrx_soc_handle soc, void *pdev_handle, lmac_id); } +/** + * cdp_txrx_set_pdev_status_down() - set pdev down/up status + * @soc: soc opaque handle + * @pdev_handle: data path pdev handle + * @is_pdev_down: pdev down/up status + * + * return: void + */ +static inline void cdp_txrx_set_pdev_status_down(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev_handle, + bool is_pdev_down) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, + "%s: Invalid Instance:", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->set_pdev_status_down) + return; + + soc->ops->cmn_drv_ops->set_pdev_status_down(pdev_handle, is_pdev_down); +} + /** * cdp_tx_send() - enqueue frame for transmission * @soc: soc opaque handle diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index b15c76dee0..8672076c1e 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -412,6 +412,8 @@ struct cdp_cmn_ops { void (*map_pdev_to_lmac)(struct cdp_pdev *pdev_hdl, uint32_t lmac_id); + void (*set_pdev_status_down)(struct cdp_pdev *pdev_hdl, bool is_pdev_down); + void (*txrx_peer_reset_ast) (ol_txrx_soc_handle soc, uint8_t *ast_macaddr, uint8_t *peer_macaddr, void *vdev_hdl); diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 786aea36fc..9c0746ccf3 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1717,6 +1717,8 @@ enum _ol_ath_param_t { OL_ATH_PARAM_RCHWIDTH = 422, /* Whether external ACS request is in progress */ OL_ATH_EXT_ACS_REQUEST_IN_PROGRESS = 423, + /* set/get hw mode */ + OL_ATH_PARAM_HW_MODE = 424, }; #endif /* Bitmasks for stats that can block */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 834a970588..48814cd27b 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3510,7 +3510,6 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, goto fail1; } soc->num_reo_dest_rings++; - } ring_size = @@ -8410,6 +8409,21 @@ dp_soc_map_pdev_to_lmac(struct cdp_pdev *pdev_hdl, uint32_t lmac_id) (lmac_id + 1)); } +/** + * dp_soc_set_pdev_status_down() - set pdev down/up status + * @pdev_hdl: datapath pdev handle + * @is_pdev_down: pdev down/up status + * + * Return: void + */ +static void +dp_soc_set_pdev_status_down(struct cdp_pdev *pdev_hdl, bool is_pdev_down) +{ + struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl; + + pdev->is_pdev_down = is_pdev_down; +} + /** * dp_get_cfg_capabilities() - get dp capabilities * @soc_handle: datapath soc handle @@ -9163,6 +9177,7 @@ static struct cdp_cmn_ops dp_ops_cmn = { .get_soc_dp_txrx_handle = dp_soc_get_dp_txrx_handle, .set_soc_dp_txrx_handle = dp_soc_set_dp_txrx_handle, .map_pdev_to_lmac = dp_soc_map_pdev_to_lmac, + .set_pdev_status_down = dp_soc_set_pdev_status_down, .txrx_set_ba_aging_timeout = dp_set_ba_aging_timeout, .txrx_get_ba_aging_timeout = dp_get_ba_aging_timeout, .tx_send = dp_tx_send, diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index a31c5ea993..a9faec2585 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -730,9 +730,9 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, pdev = dp_get_pdev_for_mac_id(soc, mac_id); - if (!pdev) { + if (!pdev || qdf_unlikely(pdev->is_pdev_down)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "PDEV not found"); + "PDEV %s", !pdev ? "not found" : "down"); goto free; } @@ -751,7 +751,6 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu, } } - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, @@ -1733,6 +1732,7 @@ more_data: * In this case host will dump the last 128 descriptors * including the software descriptor rx_desc and assert. */ + if (qdf_unlikely(!rx_desc->in_use)) { DP_STATS_INC(soc, rx.err.hal_reo_dest_dup, 1); dp_info_rl("Reaping rx_desc not in use!"); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 32230c2222..69bf65ac71 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -3460,6 +3460,20 @@ more_data: continue; } + if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) { + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_INFO, + "pdev in down state %d", + tx_desc_id); + + num_processed += !(count & DP_TX_NAPI_BUDGET_DIV_MASK); + count++; + + dp_tx_comp_free_buf(soc, tx_desc); + dp_tx_desc_release(tx_desc, tx_desc->pool_id); + continue; + } + /* * If the release source is FW, process the HTT status */ diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 3f51331f3f..1edfaa1abe 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1372,6 +1372,13 @@ struct dp_pdev { */ bool pdev_deinit; + /* pdev status down or up required to handle dynamic hw + * mode switch between DBS and DBS_SBS. + * 1 = down + * 0 = up + */ + bool is_pdev_down; + /* Second ring used to replenish rx buffers */ struct dp_srng rx_refill_buf_ring2;