qcacmn: Deregister IPA handler from pdev during deinit
A htt message arrived after ipa context is freed as part of deinitialization which was dereferenced by event handler assigned to pdev->ipa_uc_op_cb, resulting in crash. To fix this, during deinit pdev->ipa_uc_op_cb is deregistered and assigned NULL before freeing up ipa context. Change-Id: I8125cb104a538e88cda93960f7443129fabd850a CRs-Fixed: 2793295
This commit is contained in:
@@ -161,6 +161,28 @@ cdp_ipa_register_op_cb(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_deregister_op_cb() - deregister event handler function pointer
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Deregister event handler function pointer from pdev
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline
|
||||
void cdp_ipa_deregister_op_cb(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_deregister_op_cb)
|
||||
soc->ops->ipa_ops->ipa_deregister_op_cb(soc, pdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_get_stat() - get IPA data path stats from FW
|
||||
* @soc - data path soc handle
|
||||
|
@@ -1555,6 +1555,8 @@ struct cdp_ipa_ops {
|
||||
void (*ipa_uc_op_cb_type)
|
||||
(uint8_t *op_msg, void *osif_ctxt),
|
||||
void *usr_ctxt);
|
||||
void (*ipa_deregister_op_cb)(struct cdp_soc_t *soc_hdl,
|
||||
uint8_t pdev_id);
|
||||
QDF_STATUS (*ipa_get_stat)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
qdf_nbuf_t (*ipa_tx_data_frame)(struct cdp_soc_t *soc_hdl,
|
||||
uint8_t vdev_id, qdf_nbuf_t skb);
|
||||
|
@@ -845,6 +845,21 @@ QDF_STATUS dp_ipa_register_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void dp_ipa_deregister_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
|
||||
|
||||
if (!pdev) {
|
||||
dp_err("Invalid instance");
|
||||
return;
|
||||
}
|
||||
|
||||
dp_debug("Deregister OP handler callback");
|
||||
pdev->ipa_uc_op_cb = NULL;
|
||||
pdev->usr_ctxt = NULL;
|
||||
}
|
||||
|
||||
QDF_STATUS dp_ipa_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
||||
{
|
||||
/* TBD */
|
||||
|
@@ -95,6 +95,15 @@ QDF_STATUS dp_ipa_op_response(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
QDF_STATUS dp_ipa_register_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
ipa_uc_op_cb_type op_cb, void *usr_ctxt);
|
||||
|
||||
/**
|
||||
* dp_ipa_register_op_cb() - Deregister OP handler function
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_ipa_deregister_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_ipa_get_stat() - Get firmware wdi status
|
||||
* @soc_hdl - data path soc handle
|
||||
|
@@ -11419,6 +11419,7 @@ static struct cdp_ipa_ops dp_ops_ipa = {
|
||||
.ipa_set_doorbell_paddr = dp_ipa_set_doorbell_paddr,
|
||||
.ipa_op_response = dp_ipa_op_response,
|
||||
.ipa_register_op_cb = dp_ipa_register_op_cb,
|
||||
.ipa_deregister_op_cb = dp_ipa_deregister_op_cb,
|
||||
.ipa_get_stat = dp_ipa_get_stat,
|
||||
.ipa_tx_data_frame = dp_tx_send_ipa_data_frame,
|
||||
.ipa_enable_autonomy = dp_ipa_enable_autonomy,
|
||||
|
Reference in New Issue
Block a user