diff options
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/copy_engine.c | 48 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/hif_pci.c | 5 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 76 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/ath_procfs.c | 4 |
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)); |
