コード例 #1
0
/** 
 * \fn     context_EnableClient / context_DisableClient
 * \brief  Enable a specific client activation
 * 
 * Called by the driver main when needed to enble/disable a specific event handling.
 * The Enable function also schedules the driver-task if the specified client is pending.
 * 
 * \note   
 * \param  hContext   - The module handle
 * \param  uClientId  - The client's index
 * \return void 
 * \sa     context_DriverTask
 */ 
void context_EnableClient (TI_HANDLE hContext, TI_UINT32 uClientId)
{
	TContext *pContext = (TContext *)hContext;

#ifdef TI_DBG
    if (pContext->aClientEnabled[uClientId])
    {
        TRACE0(pContext->hReport, REPORT_SEVERITY_ERROR , "context_EnableClient() Client  already enabled!!\n");
        return;
    }
    TRACE3(pContext->hReport, REPORT_SEVERITY_INFORMATION , "context_EnableClient(): Client=, ID=%d, enabled=%d, pending=%d\n", uClientId, pContext->aClientEnabled[uClientId], pContext->aClientPending[uClientId]);
#endif /* TI_DBG */

    /* Enable client */
    pContext->aClientEnabled[uClientId] = TI_TRUE;

    /* If client is pending, schedule driver task */
    if (pContext->aClientPending[uClientId])
    {
        /* 
         * If configured to switch context, request driver task scheduling.
         * Else (context switch not required) call the driver task directly. 
         */
        if (pContext->bContextSwitchRequired)
        {
            os_RequestSchedule (pContext->hOs);
        }
        else 
        {
            context_DriverTask (hContext);
        }
    }
}
コード例 #2
0
/** 
 * \fn     context_RequestSchedule
 * \brief  Handle client's switch to driver's context.
 * 
 * This function is called by a client from external context event.
 * It sets the client's Pending flag and requests the driver's task scheduling.
 * Thus, the client's callback will be called afterwards from the driver context.
 * 
 * \note   
 * \param  hContext   - The module handle
 * \param  uClientId  - The client's index
 * \return void 
 * \sa     context_DriverTask
 */ 
void context_RequestSchedule (TI_HANDLE hContext, TI_UINT32 uClientId)
{
	TContext *pContext = (TContext *)hContext;
#ifdef TI_DBG
    pContext->aRequestCount[uClientId]++; 
    TRACE3(pContext->hReport, REPORT_SEVERITY_INFORMATION , "context_RequestSchedule(): Client=, ID=%d, enabled=%d, pending=%d\n", uClientId, pContext->aClientEnabled[uClientId], pContext->aClientPending[uClientId]);
#endif /* TI_DBG */

    /* Set client's Pending flag */
    pContext->aClientPending[uClientId] = TI_TRUE;

    /* 
     * If configured to switch context, request driver task scheduling.
     * Else (context switch not required) call the driver task directly. 
     */
    if (pContext->bContextSwitchRequired)
     {
        os_RequestSchedule (pContext->hOs);
    }
    else 

    {
        context_DriverTask (hContext);
    }
}
コード例 #3
0
ファイル: context.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     context_EnableClient / context_DisableClient
 * \brief  Enable a specific client activation
 *
 * Called by the driver main when needed to enble/disable a specific event handling.
 * The Enable function also schedules the driver-task if the specified client is pending.
 *
 * \note
 * \param  hContext   - The module handle
 * \param  uClientId  - The client's index
 * \return void
 * \sa     context_DriverTask
 */
void context_EnableClient (TI_HANDLE hContext, TI_UINT32 uClientId)
{
	TContext *pContext = (TContext *)hContext;

#ifdef TI_DBG
	if (pContext->aClientEnabled[uClientId]) {
		return;
	}
#endif /* TI_DBG */

	/* Enable client */
	pContext->aClientEnabled[uClientId] = TI_TRUE;

	/* If client is pending, schedule driver task */
	if (pContext->aClientPending[uClientId]) {

		/*
		 * If configured to switch context, request driver task scheduling.
		 * Else (context switch not required) call the driver task directly.
		 */
		if (pContext->bContextSwitchRequired) {
			os_RequestSchedule (pContext->hOs);
		} else {
			context_DriverTask (hContext);
		}
	}
}
コード例 #4
0
ファイル: WlanDrvIf.c プロジェクト: Achotjan/FreeXperia
static void wlanDrvIf_DriverTask (void *hDrv)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hDrv;
#else
static void wlanDrvIf_DriverTask(struct work_struct *work)
{
	TWlanDrvIfObj *drv = container_of(work, TWlanDrvIfObj, tWork);
#endif

#ifdef STACK_PROFILE
	unsigned int curr1,base1;
	unsigned int curr2,base2;
	static unsigned int maximum_stack = 0;
#endif
	TI_BOOL bShouldLock;

	os_profile (drv, 0, 0);

#ifdef STACK_PROFILE
	curr1 = check_stack_start(&base1);
#endif

	/* we must read the value first here */
	bShouldLock = ! context_IsSuspending(pDrvStaticHandle->tCommon.hContext);

	/* Call the driver main task */
	context_DriverTask (drv->tCommon.hContext);

	if (bShouldLock)
	{
		os_wake_lock_timeout(drv);
		os_wake_unlock(drv);
	}

#ifdef STACK_PROFILE
	curr2 = check_stack_stop(&base2);
	if (base2 == base1)
	{
		/* if the current measurement is bigger then the maximum store it and print*/
		if ((curr1 - curr2) > maximum_stack)
		{
			printk("STACK PROFILER GOT THE LOCAL MAXIMMUM!!!! \n");
			printk("current operation stack use =%d \n",(curr1 - curr2));
			printk("total stack use=%d \n",8192 - curr2 + base2);
			printk("total stack usage= %d percent \n",100 * (8192 - curr2 + base2) / 8192);
			maximum_stack = curr1 - curr2;
		}
	}
#endif

	os_profile (drv, 1, 0);
}
コード例 #5
0
ファイル: context.c プロジェクト: IdeosDev/vendor_ti_wlan
/**
 * \fn     context_RequestSchedule
 * \brief  Handle client's switch to driver's context.
 *
 * This function is called by a client from external context event.
 * It sets the client's Pending flag and requests the driver's task scheduling.
 * Thus, the client's callback will be called afterwards from the driver context.
 *
 * \note
 * \param  hContext   - The module handle
 * \param  uClientId  - The client's index
 * \return void
 * \sa     context_DriverTask
 */
void context_RequestSchedule (TI_HANDLE hContext, TI_UINT32 uClientId)
{
	TContext *pContext = (TContext *)hContext;

#ifdef TI_DBG
	pContext->aRequestCount[uClientId]++;
#endif /* TI_DBG */

	/* Set client's Pending flag */
	pContext->aClientPending[uClientId] = TI_TRUE;

	/*
	 * If configured to switch context, request driver task scheduling.
	 * Else (context switch not required) call the driver task directly.
	 */
	if (pContext->bContextSwitchRequired) {
		os_RequestSchedule (pContext->hOs);
	} else {
		context_DriverTask (hContext);
	}
}
コード例 #6
0
static void wlanDrvIf_DriverTask (void *hDrv)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hDrv;
#else
static void wlanDrvIf_DriverTask(struct work_struct *work)
{
#ifdef STACK_PROFILE
	register unsigned long sp asm ("sp");
	unsigned long local_sp = sp;
#endif
	TWlanDrvIfObj *drv = container_of(work, TWlanDrvIfObj, tWork);
#endif

#ifdef STACK_PROFILE
	unsigned long curr1, base1;
	unsigned long curr2, base2;
	static unsigned long maximum_stack = 0;
#endif   
	os_profile (drv, 0, 0);

#ifdef STACK_PROFILE
	curr1 = check_stack_start(&base1, local_sp + 4, 0);
#endif

	/* Call the driver main task */
	context_DriverTask (drv->tCommon.hContext);

	os_profile (drv, 1, 0);
	os_wake_lock_timeout(drv);
	os_wake_unlock(drv);
#ifdef STACK_PROFILE
	curr2 = check_stack_stop(&base2, 0);
	if (base2 == base1) {
	/* if the current measurement is bigger then the maximum store it and print*/
		if ((curr1 - curr2) > maximum_stack) {
			printk("STACK PROFILER GOT THE LOCAL MAXIMMUM!!!! \n");
			printk("current operation stack use=%lu \n",(curr1 - curr2));
			printk("total stack use=%lu \n",8192 - curr2 + base2);
			printk("total stack usage=%lu percent \n",100 * (8192 - curr2 + base2) / 8192);
			maximum_stack = curr1 - curr2;
		}
	}
#endif
}


/** 
 * \fn     wlanDrvIf_LoadFiles
 * \brief  Load init files from loader
 * 
 * This function is called from the loader context right after the driver
 *     is created (in IDLE state).
 * It copies the following files to the driver's memory:
 *     - Ini-File - The driver's default parameters values
 *     - NVS-File - The NVS data for FW usage
 *     - FW-Image - The FW program image
 *
 * \note   
 * \param  drv - The driver object handle
 * \return void
 * \sa     wlanDrvIf_GetFile
 */ 
int wlanDrvIf_LoadFiles (TWlanDrvIfObj *drv, TLoaderFilesData *pInitFiles)
{
    if (!pInitFiles)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "No Init Files!\n");
        return -EINVAL;
    }

    if (drv->tCommon.eDriverState != DRV_STATE_IDLE)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "Trying to load files not in IDLE state!\n");
        return -EINVAL;
    }

    if (pInitFiles->uIniFileLength) 
    {
        drv->tCommon.tIniFile.uSize = pInitFiles->uIniFileLength;
        drv->tCommon.tIniFile.pImage = kmalloc (pInitFiles->uIniFileLength, GFP_KERNEL);
        #ifdef TI_MEM_ALLOC_TRACE        
          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, pInitFiles->uIniFileLength, GFP_KERNEL, pInitFiles->uIniFileLength);
        #endif
        if (!drv->tCommon.tIniFile.pImage)
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for Ini-File!\n");
            return -ENOMEM;
        }
        memcpy (drv->tCommon.tIniFile.pImage,
                &pInitFiles->data[pInitFiles->uNvsFileLength + pInitFiles->uFwFileLength],
                drv->tCommon.tIniFile.uSize);
    }

    if (pInitFiles->uNvsFileLength)
    {
        drv->tCommon.tNvsImage.uSize = pInitFiles->uNvsFileLength;
        drv->tCommon.tNvsImage.pImage = kmalloc (drv->tCommon.tNvsImage.uSize, GFP_KERNEL);
        #ifdef TI_MEM_ALLOC_TRACE        
          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", 
              __FUNCTION__, __LINE__, drv->tCommon.tNvsImage.uSize, GFP_KERNEL, drv->tCommon.tNvsImage.uSize);
        #endif
        if (!drv->tCommon.tNvsImage.pImage)
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for NVS image\n");
            return -ENOMEM;
        }
        memcpy (drv->tCommon.tNvsImage.pImage, &pInitFiles->data[0], drv->tCommon.tNvsImage.uSize );
    }
    
    drv->tCommon.tFwImage.uSize = pInitFiles->uFwFileLength;
    if (!drv->tCommon.tFwImage.uSize)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "No firmware image\n");
        return -EINVAL;
    }
    drv->tCommon.tFwImage.pImage = os_memoryAlloc (drv, drv->tCommon.tFwImage.uSize);
    #ifdef TI_MEM_ALLOC_TRACE        
      os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", 
          __FUNCTION__, __LINE__, drv->tCommon.tFwImage.uSize, GFP_KERNEL, drv->tCommon.tFwImage.uSize);
    #endif
    if (!drv->tCommon.tFwImage.pImage)
    {
        ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate buffer for firmware image\n");
        return -ENOMEM;
    }
    memcpy (drv->tCommon.tFwImage.pImage,
            &pInitFiles->data[pInitFiles->uNvsFileLength],
            drv->tCommon.tFwImage.uSize);

    ti_dprintf(TIWLAN_LOG_OTHER, "--------- Eeeprom=%p(%lu), Firmware=%p(%lu), IniFile=%p(%lu)\n", 
        drv->tCommon.tNvsImage.pImage, drv->tCommon.tNvsImage.uSize, 
        drv->tCommon.tFwImage.pImage,  drv->tCommon.tFwImage.uSize,
        drv->tCommon.tIniFile.pImage,  drv->tCommon.tIniFile.uSize);
    
    return 0;
}


/** 
 * \fn     wlanDrvIf_GetFile
 * \brief  Provides access to a requested init file
 * 
 * Provide the requested file information and call the requester callback.
 * Note that in Linux the files were previously loaded to driver memory 
 *     by the loader (see wlanDrvIf_LoadFiles).
 *
 * \note   
 * \param  hOs       - The driver object handle
 * \param  pFileInfo - The requested file's properties
 * \return TI_OK
 * \sa     wlanDrvIf_LoadFiles
 */ 
int wlanDrvIf_GetFile (TI_HANDLE hOs, TFileInfo *pFileInfo)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;

	if (drv == NULL || pFileInfo == NULL) {
		ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: Null File Handler, Exiting");
		return TI_NOK;
	}

	/* Future option for getting the FW image part by part */ 
	pFileInfo->hOsFileDesc = NULL;

	/* Fill the file's location and size in the file's info structure */
	switch (pFileInfo->eFileType) 
	{
	case FILE_TYPE_INI: 
		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tIniFile.pImage; 
		pFileInfo->uLength = drv->tCommon.tIniFile.uSize; 
		break;
	case FILE_TYPE_NVS:     
		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tNvsImage.pImage; 
		pFileInfo->uLength = drv->tCommon.tNvsImage.uSize; 
		break;
	case FILE_TYPE_FW:
		if (drv->tCommon.tFwImage.pImage == NULL)
		{
			ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: no Firmware image, exiting\n");
			return TI_NOK;
		}

		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tFwImage.pImage; 
		pFileInfo->bLast		= TI_FALSE;
		pFileInfo->uLength	= 0;
		pFileInfo->uOffset 				= 0;
		pFileInfo->uChunkBytesLeft 		= 0;
		pFileInfo->uChunksLeft 			= BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
		/* check uChunksLeft's Validity */
		if (( pFileInfo->uChunksLeft == 0 ) || ( pFileInfo->uChunksLeft > MAX_CHUNKS_IN_FILE ))
		{
			ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() Read Invalid Chunks Left: %d!\n",pFileInfo->uChunksLeft);
			return TI_NOK;
		}
		pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
		/* FALL THROUGH */
	case FILE_TYPE_FW_NEXT:
		/* check dec. validity */
		if ( pFileInfo->uChunkBytesLeft >= pFileInfo->uLength )
		{
			pFileInfo->uChunkBytesLeft 		-= pFileInfo->uLength;
		}
		/* invalid Dec. */
		else
		{
			ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() No. of Bytes Left < File Length\n");
			return TI_NOK;
		}
		pFileInfo->pBuffer 	+= pFileInfo->uLength; 

		/* Finished reading all Previous Chunk */
		if ( pFileInfo->uChunkBytesLeft == 0 )
		{
			/* check dec. validity */
			if ( pFileInfo->uChunksLeft > 0 )
			{
				pFileInfo->uChunksLeft--;
			}
			/* invalid Dec. */
			else
			{
				ti_dprintf (TIWLAN_LOG_ERROR, "No. of Bytes Left = 0 and Chunks Left <= 0\n");
				return TI_NOK;
			}
			/* read Chunk's address */
			pFileInfo->uAddress = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
			pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
			/* read Portion's length */
			pFileInfo->uChunkBytesLeft = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
			pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
		}
		/* Reading Chunk is NOT complete */
		else
		{
			pFileInfo->uAddress += pFileInfo->uLength;
		}
		
		if ( pFileInfo->uChunkBytesLeft < OS_SPECIFIC_RAM_ALLOC_LIMIT )
		{
			pFileInfo->uLength = pFileInfo->uChunkBytesLeft;
		}
		else
		{
			pFileInfo->uLength = OS_SPECIFIC_RAM_ALLOC_LIMIT;
		}

		/* If last chunk to download */
		if (( pFileInfo->uChunksLeft == 0 ) && 
			( pFileInfo->uLength == pFileInfo->uChunkBytesLeft ))
		{
			pFileInfo->bLast = TI_TRUE;
		}

		break;
	}

	/* Call the requester callback */
	if (pFileInfo->fCbFunc)
	{
		pFileInfo->fCbFunc (pFileInfo->hCbHndl);
	}

	return TI_OK;
}