Beispiel #1
0
/*  Strrcl_ChipDown - Utility function to bring the chip down. Also sets
 *	 driver booleans to prevent any unwanted activity until the chip is
 *	 brought back up.
 *      void *pCxt - the driver context.
 *****************************************************************************/
static void Strrcl_ChipDown(void *pCxt)
{
    /* disable interrupt line - prevent un-expected INTs when chip powers down */
    //	EnableDisableSPIIRQHwDetect(pDevice,false);
    GET_DRIVER_COMMON(pCxt)->chipDown = true;
    GET_DRIVER_COMMON(pCxt)->wmiReady = false;
    /* assert pwd line */
    HW_PowerUpDown(pCxt, false);
}
Beispiel #2
0
/*  Api_DeInitFinish - implements common code for de-initializing the driver.
 *	 This should be called after Api_DeInitStart().
 *      A_VOID *pCxt - the driver context.    
 *****************************************************************************/
A_STATUS 
Api_DeInitFinish(A_VOID *pCxt)
{
    A_STATUS status = A_ERROR;
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    
    do{
    	/* 1 - block until driver thread is cleaned up. in systems without
    	 * 		a driver thread this is a NOP. */
    	if(A_OK != CUSTOM_DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->driver_up), A_FALSE, 5000)){            
            break;
        }
    	/* 2 - remove driver from system */
        CUSTOM_DRIVER_REMOVE(pCxt);
       	/* 3 - De-initialize context */
        Driver_ContextDeInit(pCxt);
        
        /*4 - Deinitialize socket context*/
	    SOCKET_CONTEXT_DEINIT();
       
        status = A_OK;
    }while(0);

    return status;
}
Beispiel #3
0
A_ENDPOINT_T *
Util_GetEndpoint(A_VOID *pCxt, A_UINT16 id)
{
    /* this translation allows multiple virtual endpoints to be mapped to 
     * a common endpoint object. */
    if(id >= ENDPOINT_MANAGED_MAX){
        id = ENDPOINT_MANAGED_MAX-1;
    }
    return &(GET_DRIVER_COMMON(pCxt)->ep[id]);
}
Beispiel #4
0
/*  Api_WMIInitFinish - implements common code for sending default wmi commands 
 *                      to target.
 *	 This should be called after Api_InitFinish().
 *      A_VOID *pCxt - the driver context.    
 *****************************************************************************/
A_VOID 
Api_WMIInitFinish(A_VOID *pCxt)
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    A_STATUS status;    
    WMI_ALLOW_AGGR_CMD allow_aggr_cmd;
        
    if(pDCxt->wmiReady == A_TRUE)
    {
        do{
            status = STACK_INIT(pCxt);
            
            if(status == A_OK){
                CUSTOM_WAIT_FOR_WMI_RESPONSE(pCxt);              
                break;            
            }else if(status == A_NO_MEMORY){
                pDCxt->tx_complete_pend = A_TRUE;
                
                if(A_OK != CUSTOM_DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->tx_complete_pend), A_FALSE, 5000)){
                    A_ASSERT(0);
                }
            }else{
                A_ASSERT(0);
            }
        }while(1);       

      
      /* issue some default WMI commands appropriate for most systems */
#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
        wmi_cmd_process(pCxt, WMI_SET_POWER_PARAMS_CMDID, &default_power_param, sizeof(WMI_POWER_PARAMS_CMD));    
#endif
        wmi_cmd_process(pCxt, WMI_SET_SCAN_PARAMS_CMDID, &default_scan_param, sizeof(WMI_SCAN_PARAMS_CMD));
        
        wmi_cmd_process(pCxt, WMI_STORERECALL_CONFIGURE_CMDID, 
            &default_strrcl_config_cmd, sizeof(WMI_STORERECALL_CONFIGURE_CMD));                     
        pDCxt->strrclState = STRRCL_ST_INIT;
        /* technically this call to wmi_allow_aggr_cmd is not necessary if both 
         * masks are 0 as the firmware has 0,0 as the default. */
        allow_aggr_cmd.tx_allow_aggr = A_CPU2LE16(pDCxt->txAggrTidMask);
        allow_aggr_cmd.rx_allow_aggr = A_CPU2LE16(pDCxt->rxAggrTidMask);
        wmi_cmd_process(pCxt, WMI_ALLOW_AGGR_CMDID, &allow_aggr_cmd, sizeof(WMI_ALLOW_AGGR_CMD));      
#if ENABLE_P2P_MODE
        if(WLAN_NUM_OF_DEVICES == 2) {
            /* Device-0 is P2P Device and Device-1 is Legacy STA.\
               Set Default P2P Params 
             */
            wmi_cmd_process(pCxt,WMI_P2P_SET_CONFIG_CMDID,&default_p2p_config,sizeof(WMI_P2P_FW_SET_CONFIG_CMD));                           
        }
#endif
        /* Set the BSS Filter to None. If this is not set, by default the firmware 
       sets to forward the beacons to host. This causes unnecessary BSSINFO events in 
       the host even after connecting to the AP */
        wmi_bssfilter_cmd(pDCxt->pWmiCxt, NONE_BSS_FILTER, 0);
    }
}
Beispiel #5
0
/*  Strrcl_ChipUpStart - Utility function to bring bring the chip back up. Also
 * 	 sets up the driver tempFunc so that when the WMI_READY is received the
 *	 store recall process can be completed via Strrcl_ChipUpFinish.
 *      void *pCxt - the driver context.
 *****************************************************************************/
static A_STATUS Strrcl_ChipUpStart(void *pCxt)
{
    A_STATUS status = A_ERROR;
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    A_MDELAY(2);
    /* assert pwd line */
    HW_PowerUpDown(pCxt, true);

    A_MDELAY(2);
    do
    {
        /* reset htc_creditInit to re-process the HTC interrupt */
        pDCxt->htc_creditInit = 0;

        if ((status = Hcd_ReinitTarget(pCxt)) != A_OK)
        {
            break;
        }

        A_MDELAY(1);

        if (A_OK != (status = Driver_BootComm(pCxt)))
        {
            break;
        }

#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD)
        if (A_OK != (status = Driver_StoreRecallFirmwareDownload(pCxt)))
        {
            break;
        }
#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */

        /* unmask the packet interrupt on-chip */
        Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_PKT_AVAIL);
        /* when the driver receives the WMI_READY event chip_up_finish
         * will complete the re-boot process and open the way for
         * outside requests to resume. */
        pDCxt->asynchRequest = Strrcl_ChipUpFinish;

    } while (0);

    return status;
}
Beispiel #6
0
/*  Api_InitFinish - implements common code for initializing the driver.
 *	 This should be called after Api_InitStart().
 *      A_VOID *pCxt - the driver context.    
 *****************************************************************************/
A_STATUS 
Api_InitFinish(A_VOID *pCxt)
{    
    //A_INT32     timeleft;
    //A_INT16     i;
    A_STATUS     ret = A_OK;
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);

    if(ath_custom_init.skipWmi){
    	return A_OK;
    }

	do { 
//		Api_BootProfile(pCxt, 0x00);	   		    
        /* Wait for Wmi event to be ready Implementation of this macro is platform specific
         * as multi-threaded systems will implement differently from single threaded. */ 
        /* Increased the WMI_READY timeout from 5 seconds to 15 seconds to allow 
           firmware download over SPI interface */  
        if(A_OK != CUSTOM_DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->wmiReady), A_TRUE, 15000)){
            ret = A_ERROR;
            break;
        }
        
//        Api_BootProfile(pCxt, BOOT_PROFILE_WMI_READY);       
        
        if(pDCxt->wmiReady != A_TRUE)
        {            
            ret = A_ERROR;
            break;
        }
        /* WMI_EVENT will have populated arVersion so now confirm that version is compatible */		
		if(pDCxt->abiVersion != 1){
            if ((pDCxt->abiVersion & ABI_MAJOR_MASK) != (AR6K_ABI_VERSION & ABI_MAJOR_MASK)) {          
                ret = A_ERROR;
                break;
            }
        }
		
    }while(0);

    return ret;
}
Beispiel #7
0
/*  Custom_DeliverFrameToNetworkStack - Called by API_RxComplete to
 *   deliver a data frame to the network stack. This code will perform
 *   platform specific operations.
 *      void *pCxt - the driver context.
 *      void *pReq - the packet.
 *****************************************************************************/
void Custom_DeliverFrameToNetworkStack(void *pCxt, void *pReq)
{
    A_NETBUF *a_netbuf_ptr = (A_NETBUF *)pReq;
    QCA_CONTEXT_STRUCT_PTR qca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(pCxt)->pUpperCxt[0];
    QCA_ECB_STRUCT_PTR RxECB;
    uint32_t len;
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    ATH_PROMISCUOUS_CB prom_cb = (ATH_PROMISCUOUS_CB)(GET_DRIVER_CXT(pCxt)->promiscuous_cb);

    if (a_netbuf_ptr)
    {
        len = A_NETBUF_LEN(pReq);
        _DCACHE_INVALIDATE_MBYTES(A_NETBUF_DATA(pReq), len);

        if (pDCxt->promiscuous_mode)
        {
            if (prom_cb)
            {
                /* send frame to callback function rather than an QCA_receiver */
                a_netbuf_ptr->native.FRAG[0].LENGTH = len;
                a_netbuf_ptr->native.FRAG[0].FRAGMENT = A_NETBUF_DATA(pReq);
                prom_cb((void *)&(a_netbuf_ptr->native));
            }
            else
            {
                A_NETBUF_FREE(pReq);
            }
        }
        else if ((RxECB = QCA_find_receiver(qca_ptr, (QCA_HEADER_PTR)A_NETBUF_DATA(pReq), &len)) != NULL)
        {
            // Call the receiver's service function to pass the PCB to the receiver
            a_netbuf_ptr->native.FRAG[0].LENGTH = len;
            a_netbuf_ptr->native.FRAG[0].FRAGMENT = A_NETBUF_DATA(pReq);
            RxECB->SERVICE((PCB_PTR) & (a_netbuf_ptr->native), RxECB->PRIVATE);
        }
        else
        {
            /* failed to find a receiver for this data packet. */
            A_NETBUF_FREE(pReq);
        }
    }
}
Beispiel #8
0
static
A_STATUS wmi_cmd_process(A_VOID *pCxt, WMI_COMMAND_ID cmd, A_CONST A_VOID *pParam, A_UINT16 length)
{
    A_STATUS status;
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    
    status = wmi_cmd_start(pDCxt->pWmiCxt, pParam, cmd, length);
    
    if(status == A_NO_MEMORY){
        pDCxt->tx_complete_pend = A_TRUE;
        
        if(A_OK != CUSTOM_DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->tx_complete_pend), A_FALSE, 5000)){
            A_ASSERT(0);
        }
    }else if(status != A_OK){
        A_ASSERT(0);
    }
    
    return status;
}
static A_STATUS driver_thread_operation(A_VOID *pCxt)
{
	A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);    	
 union{    
    	A_UINT32 param;    	
    }stackU;      
    
#define PARAM (stackU.param)                	
#define PTR_REG_MOD		((ATH_REGQUERY*)(pQuery))	
		switch(PTR_REG_MOD->operation)
		{
		case ATH_REG_OP_READ: // read			
			Driver_ReadRegDiag(pCxt, &PTR_REG_MOD->address, &(PTR_REG_MOD->value));									
			PTR_REG_MOD->value = A_CPU2LE32((PTR_REG_MOD->value));
			break;
		case ATH_REG_OP_WRITE: //write-
			PTR_REG_MOD->value = A_CPU2LE32((PTR_REG_MOD->value));
			Driver_WriteRegDiag(pCxt, &PTR_REG_MOD->address, &(PTR_REG_MOD->value));																	
			break;
		case ATH_REG_OP_RMW: //read-mod-write
			if(A_OK != Driver_ReadRegDiag(pCxt, &PTR_REG_MOD->address, &PARAM)){
				break;
			}
			
			PARAM = A_CPU2LE32(PARAM);
			PARAM &= ~PTR_REG_MOD->mask;
			PARAM |= PTR_REG_MOD->value;
			PARAM = A_CPU2LE32(PARAM);
			
			Driver_WriteRegDiag(pCxt, &PTR_REG_MOD->address, &PARAM);						
			break;
		}
	pDCxt->asynchRequest = NULL;
	reg_query_bool = A_TRUE;
	CUSTOM_DRIVER_WAKE_USER(pCxt);
#undef PTR_REG_MOD	
#undef PARAM

	return A_OK;
}
static uint_32 ath_ioctl_handler_ext(A_VOID* enet_ptr, ATH_IOCTL_PARAM_STRUCT_PTR param_ptr)
{
	A_VOID* pCxt;
    A_DRIVER_CONTEXT *pDCxt;        
	A_STATUS status = A_OK;
	uint_32 error = ENET_OK;
	ATH_REGQUERY regQuery;
	uint_32 *ptr,i;
   		
	if((pCxt = ((ENET_CONTEXT_STRUCT_PTR)enet_ptr)->MAC_CONTEXT_PTR) == NULL)
	{
	   	return ENET_ERROR;
	}  
	pDCxt = GET_DRIVER_COMMON(pCxt);    	
	
	switch(param_ptr->cmd_id)
	{			
		case ATH_REG_QUERY:
			/* set the operation to be executed by the driver thread */
			pQuery = param_ptr->data;
			reg_query_bool = A_FALSE;
			if(pDCxt->asynchRequest != NULL){
				break;
			}
			pDCxt->asynchRequest = driver_thread_operation;
			/* wake up driver thread */
			CUSTOM_DRIVER_WAKE_DRIVER(pCxt);
			/* wait for driver thread completion */
			Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000);  
		
			break;	
		case ATH_MEM_QUERY:
			// read the memory location for stat storage
			regQuery.address = TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present));
			regQuery.operation = ATH_REG_OP_READ;
			pQuery = &regQuery;
			reg_query_bool = A_FALSE;
			
			if(pDCxt->asynchRequest != NULL){
				break;
			}
			
			pDCxt->asynchRequest = driver_thread_operation;			
			CUSTOM_DRIVER_WAKE_DRIVER(pCxt);			
			Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000);
			
			if(reg_query_bool == A_FALSE){
				break;
			}
			//capture the value in regQuery.address
			regQuery.address = TARG_VTOP(regQuery.value);
			ptr = (uint_32*)param_ptr->data;
			
			for(i=0 ; i<5 ; i++){
				reg_query_bool = A_FALSE;
			
				if(pDCxt->asynchRequest != NULL){
					break;
				}
				
				pDCxt->asynchRequest = driver_thread_operation;
				CUSTOM_DRIVER_WAKE_DRIVER(pCxt);
				Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000);
			
				if(reg_query_bool == A_FALSE){
					break;
				}
				/* CAUTION: this next line assumes that the stats are stored in 
				 * the same order that they appear in the ATH_MEMQUERY structure. */
				ptr[i] = regQuery.value;
				regQuery.address+=4;
			}
			/* for allocram remaining we query address allocram_remaining_bytes.*/
			regQuery.address = TARG_VTOP(0x541f2c);
			reg_query_bool = A_FALSE;
		
			if(pDCxt->asynchRequest != NULL){
				break;
			}
			
			pDCxt->asynchRequest = driver_thread_operation;
			CUSTOM_DRIVER_WAKE_DRIVER(pCxt);
			Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000);
		
			if(reg_query_bool == A_FALSE){
				break;
			}
			/* CAUTION: this next line assumes that the stats are stored in 
			 * the same order that they appear in the ATH_MEMQUERY structure. */
			ptr[5] = regQuery.value;							
			
			break;	
		default:
			error = ENET_ERROR;
			break;
	}
	
	
	return  error;
}
Beispiel #11
0
/*  Strrcl_ChipUpFinish - Utility function to complete the chip_up process.
 *	 when WMI_READY is received from chip this function clears the chipDown
 * 	 boolean and sends the wmi store recall command to the chip so that its
 *	 associated State can be refreshed.
 *      void *pCxt - the driver context.
 *****************************************************************************/
static A_STATUS Strrcl_ChipUpFinish(void *pCxt)
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    WMI_STORERECALL_RECALL_CMD *pDsetInfo;
    uint32_t dset_info_len;

    if (pDCxt->wmiReady == true)
    {
        switch (pDCxt->strrclState)
        {
            case STRRCL_ST_ACTIVE:
                /* clear the chipDown boolean to allow outside activity to resume */
                pDCxt->chipDown = false;

                if (A_OK != STACK_INIT(pCxt))
                {
                    break;
                }

                pDCxt->strrclState = STRRCL_ST_ACTIVE_B;
            // INTENTIONAL FALL_THRU
            case STRRCL_ST_ACTIVE_B:
/* send recall */
#if 0
		    pEv = (WMI_STORERECALL_STORE_EVENT*)pDCxt->strrclCxt;

            if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pEv->length), &pEv->data[0])){
                break; //try again later this is likely because a previous wmi cmd has not finished.
            }
#elifndef ENABLE_LARGE_DSET

		    setup_host_dset(pCxt);

		    pDsetData = pDCxt->tempStorage;

            if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pDCxt->strrclCxtLen), pDsetData)){
                break; //try again later this is likely because a previous wmi cmd has not finished.
            }
#else
                setup_host_dset(pCxt);

                pDsetInfo = (WMI_STORERECALL_RECALL_CMD *)pDCxt->tempStorage;
                if (pDsetInfo->length == 0)
                {
                    dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD);
                }
                else
                {
                    dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD) - sizeof(uint8_t);
                    dset_info_len += sizeof(WMI_STORERECALL_RECALL_DSET) * pDsetInfo->length;
                }

                if (A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, dset_info_len, pDsetInfo))
                {
                    break; // try again later this is likely because a previous wmi cmd has not finished.
                }
#endif

                pDCxt->strrclCxt = NULL;
                pDCxt->strrclCxtLen = 0;

                //            pDCxt->strrclState = STRRCL_ST_AWAIT_FW;

                pDCxt->strrclState = STRRCL_ST_INIT;
                pDCxt->strrclBlock = false;

                /* Indicate completion to the custom layer */
                API_STORE_RECALL_EVENT(pCxt);

                /* clear this function from the driver's temporary calls */
                pDCxt->asynchRequest = NULL;
                /* Since we are setting MAX_PERF before going to store-recall we need to set the state
                   after we wakes up */
                restore_power_state(pDCxt, 1); /* POWER_STATE_MOVED_FOR_STRRCL */

                break; // done!!
            default:
                A_ASSERT(0); // should never happen
#if DRIVER_CONFIG_DISABLE_ASSERT
                break;
#endif
        }
    }

    return A_OK;
}
Beispiel #12
0
A_UINT8
Util_EndpointID2AC(A_VOID *pCxt, HTC_ENDPOINT_ID ep )
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    return pDCxt->ep2AcMapping[ep];
}
Beispiel #13
0
HTC_ENDPOINT_ID
Util_AC2EndpointID(A_VOID *pCxt, A_UINT8 ac)
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    return pDCxt->ac2EpMapping[ac];
}
Beispiel #14
0
/*  Driver_DumpAssertInfo - Collects assert information from chip and writes
 *	 it to stdout.
 *      void *pCxt - the driver context.
 *		uint32_t *pData - buffer to store UINT32 results
 *		uint16_t *pLength - IN/OUT param to store length of buffer for IN and
 *		 length of contents for OUT.
 *****************************************************************************/
A_STATUS
Driver_DumpAssertInfo(void *pCxt, uint32_t *pData, uint16_t *pLength)
{
    A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt);
    uint32_t address;
    uint32_t regDumpArea = 0;
    A_STATUS status = A_ERROR;
    uint32_t regDumpCount = 0;

    do
    {
        if (*pLength < REGISTER_DUMP_LEN_MAX)
        {
            break;
        }
        /* clear it */
        *pLength = 0;
        /* the reg dump pointer is copied to the host interest area */
        address = HOST_INTEREST_ITEM_ADDRESS(hi_failure_state);
        address = TARG_VTOP(address);

        if (pDCxt->targetType == TARGET_TYPE_AR4100 || pDCxt->targetType == TARGET_TYPE_AR400X)
        {
            regDumpCount = REG_DUMP_COUNT_AR4100;
        }
        else
        {
            A_ASSERT(0); /* should never happen */
#if DRIVER_CONFIG_DISABLE_ASSERT
            break;
#endif
        }

        /* read RAM location through diagnostic window */
        if (A_OK != (status = Driver_ReadRegDiag(pCxt, &address, &regDumpArea)))
        {
            A_ASSERT(0); /* should never happen */
#if DRIVER_CONFIG_DISABLE_ASSERT
            break;
#endif
        }

        regDumpArea = A_LE2CPU32(regDumpArea);

        if (regDumpArea == 0)
        {
            /* no reg dump */
            break;
        }

        regDumpArea = TARG_VTOP(regDumpArea);

        /* fetch register dump data */
        if (A_OK !=
            (status = Driver_ReadDataDiag(pCxt, regDumpArea, (uint8_t *)&pData[0], regDumpCount * (sizeof(uint32_t)))))
        {
            A_ASSERT(0); /* should never happen */
#if DRIVER_CONFIG_DISABLE_ASSERT
            break;
#endif
        }

        *pLength = regDumpCount;
    } while (0);

    return status;
}