diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9cb2e23cc2b8..920c7af33b51 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3677,6 +3677,11 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) */ static void dp_pdev_deinit_wifi3(struct cdp_pdev *txrx_pdev, int force) { + struct dp_pdev *pdev = (struct dp_pdev *)txrx_pdev; + struct dp_soc *soc = pdev->soc; + + soc->dp_soc_reinit = TRUE; + dp_pdev_deinit(txrx_pdev, force); } diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 5fb29191653b..8fec9c2c1112 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1892,7 +1892,10 @@ dp_rx_pdev_detach(struct dp_pdev *pdev) rx_desc_pool = &soc->rx_desc_buf[pdev_id]; if (rx_desc_pool->pool_size != 0) { - dp_rx_desc_pool_free(soc, pdev_id, rx_desc_pool); + if (!dp_is_soc_reinit(soc)) + dp_rx_desc_pool_free(soc, pdev_id, rx_desc_pool); + else + dp_rx_desc_nbuf_pool_free(soc, rx_desc_pool); } return; diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index e34552024a4e..8eeec3e57e60 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -364,6 +364,9 @@ void dp_rx_desc_pool_free(struct dp_soc *soc, uint32_t pool_id, struct rx_desc_pool *rx_desc_pool); +void dp_rx_desc_nbuf_pool_free(struct dp_soc *soc, + struct rx_desc_pool *rx_desc_pool); + void dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list, struct dp_peer *peer); diff --git a/dp/wifi3.0/dp_rx_desc.c b/dp/wifi3.0/dp_rx_desc.c index b9e6e623bbda..67e41a94b1da 100644 --- a/dp/wifi3.0/dp_rx_desc.c +++ b/dp/wifi3.0/dp_rx_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -35,15 +35,17 @@ QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id, { uint32_t i; - rx_desc_pool->array = - qdf_mem_malloc(pool_size * - sizeof(union dp_rx_desc_list_elem_t)); + if (!dp_is_soc_reinit(soc)) { + rx_desc_pool->array = + qdf_mem_malloc(pool_size * + sizeof(union dp_rx_desc_list_elem_t)); - if (!(rx_desc_pool->array)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s: RX Desc Pool[%d] allocation failed", - __func__, pool_id); - return QDF_STATUS_E_NOMEM; + if (!(rx_desc_pool->array)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s: RX Desc Pool[%d] allocation failed", + __func__, pool_id); + return QDF_STATUS_E_NOMEM; + } } /* Initialize the lock */ @@ -96,6 +98,33 @@ void dp_rx_desc_pool_free(struct dp_soc *soc, uint32_t pool_id, qdf_spinlock_destroy(&rx_desc_pool->lock); } +/* + * dp_rx_desc_pool_free_nbuf() - free the sw rx desc nbufs called during + * de-initialization of wifi module. + * + * @soc: core txrx main context + * @pool_id: pool_id which is one of 3 mac_ids + * @rx_desc_pool: rx descriptor pool pointer + */ +void dp_rx_desc_nbuf_pool_free(struct dp_soc *soc, + struct rx_desc_pool *rx_desc_pool) +{ + int i; + + qdf_spin_lock_bh(&rx_desc_pool->lock); + for (i = 0; i < rx_desc_pool->pool_size; i++) { + if (rx_desc_pool->array[i].rx_desc.in_use) { + if (!(rx_desc_pool->array[i].rx_desc.unmapped)) + qdf_nbuf_unmap_single(soc->osdev, + rx_desc_pool->array[i].rx_desc.nbuf, + QDF_DMA_BIDIRECTIONAL); + qdf_nbuf_free(rx_desc_pool->array[i].rx_desc.nbuf); + } + } + qdf_spin_unlock_bh(&rx_desc_pool->lock); + qdf_spinlock_destroy(&rx_desc_pool->lock); +} + /* * dp_rx_get_free_desc_list() - provide a list of descriptors from * the free rx desc pool. diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 3a7dfc08d51c..c8ab3e74be7a 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -1179,8 +1179,12 @@ dp_rx_pdev_mon_buf_detach(struct dp_pdev *pdev, int mac_id) struct rx_desc_pool *rx_desc_pool; rx_desc_pool = &soc->rx_desc_mon[mac_id]; - if (rx_desc_pool->pool_size != 0) - dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + if (rx_desc_pool->pool_size != 0) { + if (!dp_is_soc_reinit(soc)) + dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + else + dp_rx_desc_nbuf_pool_free(soc, rx_desc_pool); + } return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 657a611fcf75..b9b3e1ce091a 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -832,8 +832,12 @@ dp_rx_pdev_mon_status_detach(struct dp_pdev *pdev, int mac_id) struct rx_desc_pool *rx_desc_pool; rx_desc_pool = &soc->rx_desc_status[mac_id]; - if (rx_desc_pool->pool_size != 0) - dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + if (rx_desc_pool->pool_size != 0) { + if (!dp_is_soc_reinit(soc)) + dp_rx_desc_pool_free(soc, mac_id, rx_desc_pool); + else + dp_rx_desc_nbuf_pool_free(soc, rx_desc_pool); + } return QDF_STATUS_SUCCESS; }