mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
qcacld-3.0: clean up to avoid NULL pointer dereference IPA
Fix a few things in one shot. - clean up some code to avoid potential NULL pointer dereference. - add a helper function - wlan_ipa_free_tx_desc_list() to avoid duplication. - rearrage wlan_ipa_teardown_sys_pipe() to allow others' reference Change-Id: I9d6391a7f20ae427bf59f07958bd13f349e61d83 CRs-Fixed: 2233867
This commit is contained in:
parent
0342407471
commit
b5783cfcb2
2 changed files with 101 additions and 63 deletions
|
|
@ -1360,6 +1360,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
|||
qdf_ipa_wlan_msg_ex_t *msg_ex = NULL;
|
||||
int i;
|
||||
QDF_STATUS status;
|
||||
uint8_t sta_session_id = WLAN_IPA_MAX_SESSION;
|
||||
|
||||
ipa_debug("%s: EVT: %d, MAC: %pM, sta_id: %d",
|
||||
net_dev->name, type, mac_addr, sta_id);
|
||||
|
|
@ -1373,6 +1374,14 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (ipa_ctx->sta_connected) {
|
||||
iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
|
||||
if (iface_ctx)
|
||||
sta_session_id = iface_ctx->session_id;
|
||||
else
|
||||
ipa_err("sta iface_ctx is NULL");
|
||||
}
|
||||
|
||||
/*
|
||||
* During IPA UC resource loading/unloading new events can be issued.
|
||||
*/
|
||||
|
|
@ -1644,14 +1653,10 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
|||
/* Enable IPA UC Data PIPEs when first STA connected */
|
||||
if (ipa_ctx->sap_num_connected_sta == 0 &&
|
||||
ipa_ctx->uc_loaded == true) {
|
||||
struct wlan_ipa_iface_context *iface_ctx;
|
||||
uint8_t sta_session_id;
|
||||
|
||||
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
|
||||
ipa_ctx->sta_connected) {
|
||||
qdf_mutex_release(&ipa_ctx->event_lock);
|
||||
iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_STA_MODE);
|
||||
sta_session_id = iface_ctx->session_id;
|
||||
wlan_ipa_uc_offload_enable_disable(ipa_ctx,
|
||||
SIR_STA_RX_DATA_OFFLOAD,
|
||||
sta_session_id, true);
|
||||
|
|
@ -1667,9 +1672,6 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
|||
ipa_ctx->config) &&
|
||||
ipa_ctx->sta_connected) {
|
||||
qdf_mutex_release(&ipa_ctx->event_lock);
|
||||
iface_ctx = wlan_ipa_get_iface(ipa_ctx,
|
||||
QDF_STA_MODE);
|
||||
sta_session_id = iface_ctx->session_id;
|
||||
wlan_ipa_uc_offload_enable_disable(
|
||||
ipa_ctx,
|
||||
SIR_STA_RX_DATA_OFFLOAD,
|
||||
|
|
@ -1760,13 +1762,6 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
|
|||
|
||||
if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config) &&
|
||||
ipa_ctx->sta_connected) {
|
||||
struct wlan_ipa_iface_context *iface_ctx;
|
||||
uint8_t sta_session_id;
|
||||
|
||||
iface_ctx = wlan_ipa_get_iface(ipa_ctx,
|
||||
QDF_STA_MODE);
|
||||
sta_session_id = iface_ctx->session_id;
|
||||
|
||||
qdf_mutex_release(&ipa_ctx->event_lock);
|
||||
wlan_ipa_uc_offload_enable_disable(ipa_ctx,
|
||||
SIR_STA_RX_DATA_OFFLOAD,
|
||||
|
|
@ -1925,13 +1920,39 @@ wlan_ipa_uc_proc_pending_event(struct wlan_ipa_priv *ipa_ctx, bool is_loading)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_ipa_free_tx_desc_list() - Free IPA Tx desc list
|
||||
* @ipa_ctx: IPA context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void wlan_ipa_free_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
|
||||
{
|
||||
struct wlan_ipa_tx_desc *tmp_desc;
|
||||
qdf_ipa_rx_data_t *ipa_tx_desc;
|
||||
qdf_list_node_t *node;
|
||||
|
||||
while (qdf_list_remove_front(&ipa_ctx->tx_desc_list, &node) ==
|
||||
QDF_STATUS_SUCCESS) {
|
||||
tmp_desc = qdf_container_of(node, struct wlan_ipa_tx_desc,
|
||||
node);
|
||||
|
||||
ipa_tx_desc = tmp_desc->ipa_tx_desc_ptr;
|
||||
if (ipa_tx_desc)
|
||||
qdf_ipa_free_skb(ipa_tx_desc);
|
||||
|
||||
qdf_mem_free(tmp_desc);
|
||||
tmp_desc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_ipa_alloc_tx_desc_list() - Allocate IPA Tx desc list
|
||||
* @ipa_ctx: IPA context
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static int wlan_ipa_alloc_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
|
||||
static QDF_STATUS wlan_ipa_alloc_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
|
||||
{
|
||||
int i;
|
||||
uint32_t max_desc_cnt;
|
||||
|
|
@ -1944,6 +1965,12 @@ static int wlan_ipa_alloc_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
|
|||
qdf_spin_lock_bh(&ipa_ctx->q_lock);
|
||||
for (i = 0; i < max_desc_cnt; i++) {
|
||||
tmp_desc = qdf_mem_malloc(sizeof(*tmp_desc));
|
||||
|
||||
if (!tmp_desc) {
|
||||
qdf_spin_unlock_bh(&ipa_ctx->q_lock);
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
tmp_desc->id = i;
|
||||
tmp_desc->ipa_tx_desc_ptr = NULL;
|
||||
qdf_list_insert_back(&ipa_ctx->tx_desc_list,
|
||||
|
|
@ -1957,6 +1984,11 @@ static int wlan_ipa_alloc_tx_desc_list(struct wlan_ipa_priv *ipa_ctx)
|
|||
qdf_spin_unlock_bh(&ipa_ctx->q_lock);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
alloc_fail:
|
||||
wlan_ipa_free_tx_desc_list(ipa_ctx);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
}
|
||||
|
||||
#ifndef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
|
|
@ -2068,6 +2100,33 @@ static int wlan_ipa_setup_rx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_ipa_teardown_sys_pipe() - Tear down all IPA Sys pipes
|
||||
* @ipa_ctx: Global IPA IPA context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
if (!ipa_ctx)
|
||||
return;
|
||||
|
||||
for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) {
|
||||
if (ipa_ctx->sys_pipe[i].conn_hdl_valid) {
|
||||
ret = wlan_ipa_wdi_teardown_sys_pipe(ipa_ctx,
|
||||
ipa_ctx->sys_pipe[i].conn_hdl);
|
||||
if (ret)
|
||||
ipa_err("Failed:%d", ret);
|
||||
|
||||
ipa_ctx->sys_pipe[i].conn_hdl_valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
wlan_ipa_free_tx_desc_list(ipa_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_ipa_setup_sys_pipe() - Setup all IPA system pipes
|
||||
* @ipa_ctx: Global IPA IPA context
|
||||
|
|
@ -2076,7 +2135,7 @@ static int wlan_ipa_setup_rx_sys_pipe(struct wlan_ipa_priv *ipa_ctx,
|
|||
*/
|
||||
static int wlan_ipa_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
|
||||
{
|
||||
int i = WLAN_IPA_MAX_IFACE, ret = 0;
|
||||
int ret = 0;
|
||||
uint32_t desc_fifo_sz;
|
||||
|
||||
/* The maximum number of descriptors that can be provided to a BAM at
|
||||
|
|
@ -2113,54 +2172,11 @@ static int wlan_ipa_setup_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
|
|||
return ret;
|
||||
|
||||
setup_sys_pipe_fail:
|
||||
|
||||
for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) {
|
||||
if (ipa_ctx->sys_pipe[i].conn_hdl_valid)
|
||||
qdf_ipa_teardown_sys_pipe(
|
||||
ipa_ctx->sys_pipe[i].conn_hdl);
|
||||
qdf_mem_zero(&ipa_ctx->sys_pipe[i],
|
||||
sizeof(struct wlan_ipa_sys_pipe));
|
||||
}
|
||||
wlan_ipa_teardown_sys_pipe(ipa_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_ipa_teardown_sys_pipe() - Tear down all IPA Sys pipes
|
||||
* @ipa_ctx: Global IPA IPA context
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct wlan_ipa_tx_desc *tmp_desc;
|
||||
qdf_ipa_rx_data_t *ipa_tx_desc;
|
||||
qdf_list_node_t *node;
|
||||
|
||||
for (i = 0; i < WLAN_IPA_MAX_SYSBAM_PIPE; i++) {
|
||||
if (ipa_ctx->sys_pipe[i].conn_hdl_valid) {
|
||||
ret = wlan_ipa_wdi_teardown_sys_pipe(ipa_ctx,
|
||||
ipa_ctx->sys_pipe[i].conn_hdl);
|
||||
if (ret)
|
||||
ipa_err("Failed:%d", ret);
|
||||
|
||||
ipa_ctx->sys_pipe[i].conn_hdl_valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (qdf_list_remove_front(&ipa_ctx->tx_desc_list, &node) ==
|
||||
QDF_STATUS_SUCCESS) {
|
||||
tmp_desc = qdf_container_of(node, struct wlan_ipa_tx_desc,
|
||||
node);
|
||||
ipa_tx_desc = tmp_desc->ipa_tx_desc_ptr;
|
||||
if (ipa_tx_desc)
|
||||
qdf_ipa_free_skb(ipa_tx_desc);
|
||||
|
||||
qdf_mem_free(tmp_desc);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
|
||||
bool mcc_mode)
|
||||
|
|
@ -2294,7 +2310,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
|
|||
if (status == QDF_STATUS_E_BUSY)
|
||||
status = wlan_ipa_uc_send_wdi_control_msg(false);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
ipa_err("IPA WDI init failed: ret=%d", ret);
|
||||
ipa_err("IPA WDI init failed: ret=%d", status);
|
||||
goto fail_create_sys_pipe;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2442,6 +2458,12 @@ static void wlan_ipa_uc_loaded_handler(struct wlan_ipa_priv *ipa_ctx)
|
|||
QDF_STATUS status;
|
||||
|
||||
ipa_info("UC READY");
|
||||
|
||||
if (!qdf_dev) {
|
||||
ipa_err("qdf device is NULL!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (true == ipa_ctx->uc_loaded) {
|
||||
ipa_info("UC already loaded");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,12 @@ QDF_STATUS ol_txrx_ipa_uc_get_resource(struct cdp_pdev *ppdev)
|
|||
struct ol_txrx_ipa_resources *ipa_res = &pdev->ipa_resource;
|
||||
qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
|
||||
if (!osdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: qdf device is null!", __func__);
|
||||
return QDF_STATUS_E_NOENT;
|
||||
}
|
||||
|
||||
htt_ipa_uc_get_resource(pdev->htt_pdev,
|
||||
&ipa_res->ce_sr,
|
||||
&ipa_res->tx_comp_ring,
|
||||
|
|
@ -414,6 +420,12 @@ static inline void ol_txrx_ipa_wdi_tx_params(
|
|||
{
|
||||
qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
|
||||
if (!osdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: qdf device is null!", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
QDF_IPA_WDI_SETUP_INFO_CLIENT(tx) = IPA_CLIENT_WLAN1_CONS;
|
||||
QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(tx) =
|
||||
qdf_mem_get_dma_addr(osdev,
|
||||
|
|
@ -496,8 +508,12 @@ QDF_STATUS ol_txrx_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
|
|||
uint32_t tx_comp_db_dmaaddr = 0, rx_rdy_db_dmaaddr = 0;
|
||||
int ret;
|
||||
|
||||
qdf_mem_zero(&tx, sizeof(qdf_ipa_wdi_pipe_setup_info_t));
|
||||
qdf_mem_zero(&rx, sizeof(qdf_ipa_wdi_pipe_setup_info_t));
|
||||
if (!osdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: qdf device is null!", __func__);
|
||||
return QDF_STATUS_E_NOENT;
|
||||
}
|
||||
|
||||
qdf_mem_zero(&pipe_in, sizeof(pipe_in));
|
||||
qdf_mem_zero(&pipe_out, sizeof(pipe_out));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue