summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine.c48
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c5
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c76
-rw-r--r--CORE/SERVICES/HIF/ath_procfs.c4
4 files changed, 99 insertions, 34 deletions
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c
index c9c9038fb26d..526314c8f46a 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine.c
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c
@@ -1232,6 +1232,8 @@ CE_init(struct hif_pci_softc *sc,
unsigned int nentries;
adf_os_dma_addr_t base_addr;
struct ol_softc *scn = sc->ol_sc;
+ bool malloc_CE_state = false;
+ bool malloc_src_ring = false;
A_ASSERT(CE_id < sc->ce_count);
ctrl_addr = CE_BASE_ADDRESS(CE_id);
@@ -1242,7 +1244,11 @@ CE_init(struct hif_pci_softc *sc,
if (!CE_state) {
adf_os_spin_unlock(&sc->target_lock);
CE_state = (struct CE_state *)A_MALLOC(sizeof(*CE_state));
- A_ASSERT(CE_state); /* TBDXXX */
+ if (!CE_state) {
+ dev_err(&sc->pdev->dev, "ath ERROR: CE_state has no mem\n");
+ return NULL;
+ } else
+ malloc_CE_state = true;
A_MEMZERO(CE_state, sizeof(*CE_state));
adf_os_spin_lock(&sc->target_lock);
if (!sc->CE_id_to_state[CE_id]) { /* re-check under lock */
@@ -1260,6 +1266,7 @@ CE_init(struct hif_pci_softc *sc,
* CE_state (and free the one we allocated).
*/
A_FREE(CE_state);
+ malloc_CE_state = false;
CE_state = sc->CE_id_to_state[CE_id];
}
}
@@ -1293,7 +1300,24 @@ CE_init(struct hif_pci_softc *sc,
CE_nbytes = sizeof(struct CE_ring_state)
+ (nentries * sizeof(void *)); /* per-send context */
ptr = A_MALLOC(CE_nbytes);
- A_ASSERT(ptr); /* TBDXXX */
+ if (!ptr) {
+ /* cannot allocate src ring. If teh CE_state is allocated
+ * locally free CE_State and return error. */
+ dev_err(&sc->pdev->dev, "ath ERROR: src ring has no mem\n");
+ if (malloc_CE_state) {
+ /* allocated CE_state locally */
+ adf_os_spin_lock(&sc->target_lock);
+ sc->CE_id_to_state[CE_id]= NULL;
+ adf_os_spin_unlock(&sc->target_lock);
+ A_FREE(CE_state);
+ malloc_CE_state = false;
+ }
+ return NULL;
+ } else {
+ /* we can allocate src ring.
+ * Mark that the src ring is allocated locally */
+ malloc_src_ring = true;
+ }
A_MEMZERO(ptr, CE_nbytes);
src_ring = CE_state->src_ring = (struct CE_ring_state *)ptr;
@@ -1366,7 +1390,25 @@ CE_init(struct hif_pci_softc *sc,
CE_nbytes = sizeof(struct CE_ring_state)
+ (nentries * sizeof(void *)); /* per-recv context */
ptr = A_MALLOC(CE_nbytes);
- A_ASSERT(ptr); /* TBDXXX */
+ if (!ptr) {
+ /* cannot allocate dst ring. If the CE_state or src ring is allocated
+ * locally free CE_State and src ring and return error. */
+ dev_err(&sc->pdev->dev, "ath ERROR: dest ring has no mem\n");
+ if (malloc_src_ring) {
+ A_FREE(CE_state->src_ring);
+ CE_state->src_ring= NULL;
+ malloc_src_ring = false;
+ }
+ if (malloc_CE_state) {
+ /* allocated CE_state locally */
+ adf_os_spin_lock(&sc->target_lock);
+ sc->CE_id_to_state[CE_id]= NULL;
+ adf_os_spin_unlock(&sc->target_lock);
+ A_FREE(CE_state);
+ malloc_CE_state = false;
+ }
+ return NULL;
+ }
A_MEMZERO(ptr, CE_nbytes);
dest_ring = CE_state->dest_ring = (struct CE_ring_state *)ptr;
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 4b1e4e2336e4..390e6364afb3 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -523,7 +523,10 @@ hif_completion_thread_startup(struct HIF_CE_state *hif_state)
/* Allocate structures to track pending send/recv completions */
compl_state = (struct HIF_CE_completion_state *)
A_MALLOC(completions_needed * sizeof(struct HIF_CE_completion_state));
- ASSERT(compl_state != NULL); /* TBDXXX */
+ if (!compl_state) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ath ERROR: compl_state has no mem\n"));
+ return;
+ }
pipe_info->completion_space = compl_state;
adf_os_spinlock_init(&pipe_info->completion_freeq_lock);
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index f2cc9621d642..83b1b222f5f1 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -515,7 +515,8 @@ again:
default:
printk(KERN_ERR "unsupported revision id\n");
-
+ ret = -ENODEV;
+ goto err_tgtstate;
}
break;
@@ -551,7 +552,7 @@ again:
*/
A_PCI_WRITE32(mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
while (!hif_pci_targ_is_awake(sc, mem)) {
- ;
+ ;
}
#if PCIE_BAR0_READY_CHECKING
@@ -807,7 +808,8 @@ again:
default:
printk(KERN_ERR "unsupported revision id\n");
-
+ ret = -ENODEV;
+ goto err_tgtstate;
}
break;
@@ -1320,6 +1322,7 @@ hif_pci_suspend(struct pci_dev *pdev, pm_message_t state)
ol_txrx_pdev_handle txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos);
u32 tx_drain_wait_cnt = 0;
u32 val;
+ v_VOID_t * temp_module;
#ifdef WLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND
hdd_suspend_wlan(NULL, NULL);
@@ -1340,21 +1343,30 @@ hif_pci_suspend(struct pci_dev *pdev, pm_message_t state)
A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
#endif
+ if (!txrx_pdev) {
+ printk("%s: txrx_pdev is NULL\n", __func__);
+ return (-1);
+ }
/* Wait for pending tx completion */
while (ol_txrx_get_tx_pending(txrx_pdev)) {
- msleep(OL_ATH_TX_DRAIN_WAIT_DELAY);
- if (++tx_drain_wait_cnt > OL_ATH_TX_DRAIN_WAIT_CNT) {
- printk("%s: tx frames are pending\n", __func__);
- return (-1);
- }
+ msleep(OL_ATH_TX_DRAIN_WAIT_DELAY);
+ if (++tx_drain_wait_cnt > OL_ATH_TX_DRAIN_WAIT_CNT) {
+ printk("%s: tx frames are pending\n", __func__);
+ return (-1);
+ }
}
/* No need to send WMI_PDEV_SUSPEND_CMDID to FW if WOW is enabled */
- if (wma_is_wow_mode_selected(vos_get_context(VOS_MODULE_ID_WDA, vos))) {
- if(wma_enable_wow_in_fw(vos_get_context(VOS_MODULE_ID_WDA, vos)))
+ temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos);
+ if (!temp_module) {
+ printk("%s: WDA module is NULL\n", __func__);
+ return (-1);
+ }
+ if (wma_is_wow_mode_selected(temp_module)) {
+ if(wma_enable_wow_in_fw(temp_module))
return (-1);
} else if (state.event == PM_EVENT_FREEZE || state.event == PM_EVENT_SUSPEND) {
- if (wma_suspend_target(vos_get_context(VOS_MODULE_ID_WDA, vos), 0))
+ if (wma_suspend_target(temp_module, 0))
return (-1);
}
@@ -1378,6 +1390,7 @@ hif_pci_resume(struct pci_dev *pdev)
void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL);
u32 val;
int err;
+ v_VOID_t * temp_module;
err = pci_enable_device(pdev);
if (err)
@@ -1414,9 +1427,14 @@ hif_pci_resume(struct pci_dev *pdev)
#endif
/* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */
- if (!wma_is_wow_mode_selected(vos_get_context(VOS_MODULE_ID_WDA, vos_context)) &&
+ temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos_context);
+ if (!temp_module) {
+ printk("%s: WDA module is NULL\n", __func__);
+ return (-1);
+ }
+ if (!wma_is_wow_mode_selected(temp_module) &&
(val == PM_EVENT_HIBERNATE || val == PM_EVENT_SUSPEND)) {
- return wma_resume_target(vos_get_context(VOS_MODULE_ID_WDA, vos_context));
+ return wma_resume_target(temp_module);
}
#ifdef WLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND
@@ -1436,27 +1454,27 @@ adf_os_size_t initBufferCount(adf_os_size_t maxSize)
#ifdef CONFIG_CNSS
struct cnss_wlan_driver cnss_wlan_drv_id = {
- .name = "hif_pci",
- .id_table = hif_pci_id_table,
- .probe = hif_pci_probe,
- .remove = hif_pci_remove,
- .reinit = hif_pci_reinit,
- .shutdown = hif_pci_shutdown,
+ .name = "hif_pci",
+ .id_table = hif_pci_id_table,
+ .probe = hif_pci_probe,
+ .remove = hif_pci_remove,
+ .reinit = hif_pci_reinit,
+ .shutdown = hif_pci_shutdown,
#ifdef ATH_BUS_PM
- .suspend = hif_pci_suspend,
- .resume = hif_pci_resume,
+ .suspend = hif_pci_suspend,
+ .resume = hif_pci_resume,
#endif
};
#else
MODULE_DEVICE_TABLE(pci, hif_pci_id_table);
struct pci_driver hif_pci_drv_id = {
- .name = "hif_pci",
- .id_table = hif_pci_id_table,
- .probe = hif_pci_probe,
- .remove = hif_pci_remove,
+ .name = "hif_pci",
+ .id_table = hif_pci_id_table,
+ .probe = hif_pci_probe,
+ .remove = hif_pci_remove,
#ifdef ATH_BUS_PM
- .suspend = hif_pci_suspend,
- .resume = hif_pci_resume,
+ .suspend = hif_pci_suspend,
+ .resume = hif_pci_resume,
#endif
};
#endif
@@ -1464,9 +1482,9 @@ struct pci_driver hif_pci_drv_id = {
int hif_register_driver(void)
{
#ifdef CONFIG_CNSS
- return cnss_wlan_register_driver(&cnss_wlan_drv_id);
+ return cnss_wlan_register_driver(&cnss_wlan_drv_id);
#else
- return pci_register_driver(&hif_pci_drv_id);
+ return pci_register_driver(&hif_pci_drv_id);
#endif
}
diff --git a/CORE/SERVICES/HIF/ath_procfs.c b/CORE/SERVICES/HIF/ath_procfs.c
index 907ae48ff4fe..2b2691f83799 100644
--- a/CORE/SERVICES/HIF/ath_procfs.c
+++ b/CORE/SERVICES/HIF/ath_procfs.c
@@ -98,8 +98,10 @@ static ssize_t ath_procfs_diag_write(struct file *file, const char __user *buf,
pr_debug("%s: vos_mem_alloc failed\n", __func__);
return -EINVAL;
}
- if(copy_from_user(write_buffer, buf, count))
+ if(copy_from_user(write_buffer, buf, count)) {
+ vos_mem_free(write_buffer);
return -EFAULT;
+ }
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
scn = (struct hif_pci_softc *)PDE_DATA(file_inode(file));