/** @brief wpalReadDeviceMemory provides a mechansim for a client to read data from the hardware address space @param address: Start address of physical memory to be read @param d_buffer: Virtual destination address to which the data will be written @param len: Number of bytes of data to be read @return SUCCESS if the data was successfully read */ wpt_status wpalReadDeviceMemory ( wpt_uint32 address, wpt_uint8* d_buffer, wpt_uint32 len ) { /* if SSR is in progress, and WCNSS is not out of reset (re-init * not invoked), then do not access WCNSS registers */ if (NULL == gpEnv || (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: invoked before subsystem initialized", __func__); return eWLAN_PAL_STATUS_E_INVAL; } if ((address < gpEnv->wcnss_memory->start) || ((address + len) > gpEnv->wcnss_memory->end)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Memory address 0x%0x len %d out of range 0x%0x - 0x%0x", __func__, address, len, (u32) gpEnv->wcnss_memory->start, (u32) gpEnv->wcnss_memory->end); return eWLAN_PAL_STATUS_E_INVAL; } memcpy(d_buffer, gpEnv->mmio + (address - WCNSS_BASE_ADDRESS), len); rmb(); return eWLAN_PAL_STATUS_SUCCESS; }
/** @brief wpalReadDeviceMemory provides a mechansim for a client to read data from the hardware address space @param address: Start address of physical memory to be read @param d_buffer: Virtual destination address to which the data will be written @param len: Number of bytes of data to be read @return SUCCESS if the data was successfully read */ wpt_status wpalReadDeviceMemory ( wpt_uint32 address, wpt_uint8* d_buffer, wpt_uint32 len ) { if (NULL == gpEnv || wcnss_device_is_shutdown() || (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: invoked before subsystem initialized", __func__); return eWLAN_PAL_STATUS_E_INVAL; } address = (address | gpEnv->wcnss_memory->start); if ((address < gpEnv->wcnss_memory->start) || ((address + len) > gpEnv->wcnss_memory->end)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Memory address 0x%0x len %d out of range 0x%0x - 0x%0x", __func__, address, len, gpEnv->wcnss_memory->start, gpEnv->wcnss_memory->end); return eWLAN_PAL_STATUS_E_INVAL; } vos_mem_copy(d_buffer, gpEnv->mmio + (address - gpEnv->wcnss_memory->start), len); rmb(); return eWLAN_PAL_STATUS_SUCCESS; }
/** @brief wpalReadRegister provides a mechansim for a client to read data from a hardware data register @param address: Physical memory address of the register @param data: Return location for value that is read @return SUCCESS if the data was successfully read */ wpt_status wpalReadRegister ( wpt_uint32 address, wpt_uint32 *data ) { /* if SSR is in progress, and WCNSS is not out of reset (re-init * not invoked), then do not access WCNSS registers */ if (NULL == gpEnv || wcnss_device_is_shutdown() || (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { /* Ratelimit wpalReadRegister failure messages which * can flood serial console during improper system * initialization or wcnss_device in shutdown state. * wpalRegisterInterrupt() call to wpalReadRegister is * likely to cause flooding. */ if (__ratelimit(&wpalReadRegister_rs)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: invoked before subsystem initialized", __func__); } return eWLAN_PAL_STATUS_E_INVAL; } address = (address | gpEnv->wcnss_memory->start); if ((address < gpEnv->wcnss_memory->start) || (address > gpEnv->wcnss_memory->end)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Register address 0x%0x out of range 0x%0x - 0x%0x", __func__, address, (u32) gpEnv->wcnss_memory->start, (u32) gpEnv->wcnss_memory->end); return eWLAN_PAL_STATUS_E_INVAL; } if (0 != (address & 0x3)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Register address 0x%0x is not word aligned", __func__, address); return eWLAN_PAL_STATUS_E_INVAL; } *data = readl_relaxed(gpEnv->mmio + (address - gpEnv->wcnss_memory->start)); rmb(); return eWLAN_PAL_STATUS_SUCCESS; }
/** @brief wpalWriteRegister provides a mechansim for a client to write data into a hardware data register @param address: Physical memory address of the register @param data: Data value to be written @return SUCCESS if the data was successfully written */ wpt_status wpalWriteRegister ( wpt_uint32 address, wpt_uint32 data ) { /* if SSR is in progress, and WCNSS is not out of reset (re-init * not invoked), then do not access WCNSS registers */ if (NULL == gpEnv || wcnss_device_is_shutdown() || (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: invoked before subsystem initialized", __func__); return eWLAN_PAL_STATUS_E_INVAL; } address = (address | gpEnv->wcnss_memory->start); if ((address < gpEnv->wcnss_memory->start) || (address > gpEnv->wcnss_memory->end)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Register address 0x%0x out of range 0x%0x - 0x%0x", __func__, address, (u32) gpEnv->wcnss_memory->start, (u32) gpEnv->wcnss_memory->end); return eWLAN_PAL_STATUS_E_INVAL; } if (0 != (address & 0x3)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Register address 0x%0x is not word aligned", __func__, address); return eWLAN_PAL_STATUS_E_INVAL; } wmb(); writel_relaxed(data, gpEnv->mmio + (address - gpEnv->wcnss_memory->start)); return eWLAN_PAL_STATUS_SUCCESS; }
wpt_status wpalReadRegister ( wpt_uint32 address, wpt_uint32 *data ) { if (NULL == gpEnv || wcnss_device_is_shutdown() || (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: invoked before subsystem initialized", __func__); return eWLAN_PAL_STATUS_E_INVAL; } address = (address | gpEnv->wcnss_memory->start); if ((address < gpEnv->wcnss_memory->start) || (address > gpEnv->wcnss_memory->end)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Register address 0x%0x out of range 0x%0x - 0x%0x", __func__, address, gpEnv->wcnss_memory->start, gpEnv->wcnss_memory->end); return eWLAN_PAL_STATUS_E_INVAL; } if (0 != (address & 0x3)) { WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: Register address 0x%0x is not word aligned", __func__, address); return eWLAN_PAL_STATUS_E_INVAL; } *data = readl_relaxed(gpEnv->mmio + (address - gpEnv->wcnss_memory->start)); rmb(); return eWLAN_PAL_STATUS_SUCCESS; }
VOS_STATUS vos_start( v_CONTEXT_t vosContext ) { VOS_STATUS vStatus = VOS_STATUS_SUCCESS; tSirRetStatus sirStatus = eSIR_SUCCESS; pVosContextType pVosContext = (pVosContextType)vosContext; tHalMacStartParameters halStartParams; VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: Starting Libra SW", __func__); if (gpVosContext != pVosContext) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: mismatch in context", __func__); return VOS_STATUS_E_FAILURE; } if (( pVosContext->pWDAContext == NULL) || ( pVosContext->pMACContext == NULL) || ( pVosContext->pTLContext == NULL)) { if (pVosContext->pWDAContext == NULL) VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: WDA NULL context", __func__); else if (pVosContext->pMACContext == NULL) VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: MAC NULL context", __func__); else VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: TL NULL context", __func__); return VOS_STATUS_E_FAILURE; } vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); vStatus = WDA_NVDownload_Start(pVosContext); if ( vStatus != VOS_STATUS_SUCCESS ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Failed to start NV Download", __func__); return VOS_STATUS_E_FAILURE; } vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), VOS_WDA_TIMEOUT ); if ( vStatus != VOS_STATUS_SUCCESS ) { if ( vStatus == VOS_STATUS_E_TIMEOUT ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Timeout occurred before WDA_NVDownload_start complete", __func__); } else { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: WDA_NVDownload_start reporting other error", __func__); } VOS_ASSERT(0); vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { VOS_BUG(0); } WDA_setNeedShutdown(vosContext); return VOS_STATUS_E_FAILURE; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: WDA_NVDownload_start correctly started", __func__); vStatus = WDA_start(pVosContext); if ( vStatus != VOS_STATUS_SUCCESS ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Failed to start WDA", __func__); return VOS_STATUS_E_FAILURE; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: WDA correctly started", __func__); vos_mem_zero((v_PVOID_t)&halStartParams, sizeof(tHalMacStartParameters)); sirStatus = macStart(pVosContext->pMACContext,(v_PVOID_t)&halStartParams); if (eSIR_SUCCESS != sirStatus) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Failed to start MAC", __func__); goto err_wda_stop; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: MAC correctly started", __func__); vStatus = sme_Start(pVosContext->pMACContext); if (!VOS_IS_STATUS_SUCCESS(vStatus)) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Failed to start SME", __func__); goto err_mac_stop; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: SME correctly started", __func__); vStatus = WLANTL_Start(pVosContext); if (!VOS_IS_STATUS_SUCCESS(vStatus)) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Failed to start TL", __func__); goto err_sme_stop; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "TL correctly started"); VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: VOSS Start is successful!!", __func__); return VOS_STATUS_SUCCESS; err_sme_stop: sme_Stop(pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET); err_mac_stop: macStop( pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET ); err_wda_stop: vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); vStatus = WDA_stop( pVosContext, HAL_STOP_TYPE_RF_KILL); if (!VOS_IS_STATUS_SUCCESS(vStatus)) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Failed to stop WDA", __func__); VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vStatus ) ); WDA_setNeedShutdown(vosContext); } else { vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), VOS_WDA_TIMEOUT ); if( vStatus != VOS_STATUS_SUCCESS ) { if( vStatus == VOS_STATUS_E_TIMEOUT ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Timeout occurred before WDA_stop complete", __func__); } else { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: WDA_stop reporting other error", __func__); } VOS_ASSERT( 0 ); WDA_setNeedShutdown(vosContext); } } return VOS_STATUS_E_FAILURE; }