Example #1
0
/* set HTC/Mbox operational parameters, this can only be called when the target is in the
 * BMI phase */
A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice,
                               A_UINT32    TargetType,
                               A_UINT32    MboxIsrYieldValue,
                               A_UINT8     HtcControlBuffers)
{
    A_STATUS status;
    A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];

    do {
            /* get the block sizes */
        status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
                                    blocksizes, sizeof(blocksizes));

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n"));
            break;
        }
            /* note: we actually get the block size for mailbox 1, for SDIO the block
             * size on mailbox 0 is artificially set to 1 */
            /* must be a power of 2 */
        A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);

        if (HtcControlBuffers != 0) {
                /* set override for number of control buffers to use */
            blocksizes[1] |=  ((A_UINT32)HtcControlBuffers) << 16;
        }

            /* set the host interest area for the block size */
        status = BMIWriteMemory(hifDevice,
                                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
                                (A_UCHAR *)&blocksizes[1],
                                4);

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n"));
            break;
        }

        AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n",
                blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz)));

        if (MboxIsrYieldValue != 0) {
                /* set the host interest area for the mbox ISR yield limit */
            status = BMIWriteMemory(hifDevice,
                                    HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit),
                                    (A_UCHAR *)&MboxIsrYieldValue,
                                    4);

            if (A_FAILED(status)) {
                AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
                break;
            }
        }

    } while (FALSE);

    return status;
}
Example #2
0
    /* can only be called during bmi init stage */
A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice,
                                     A_UINT32    TargetType,
                                     A_UINT32    Flags)
{
    A_STATUS status = A_OK;

    do {

        if (TargetType != TARGET_TYPE_AR6003) {
            AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n",
                TargetType));
            break;
        }

            /* set hci bridge flags */
        status = BMIWriteMemory(hifDevice,
                                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags),
                                (A_UCHAR *)&Flags,
                                4);


    } while (FALSE);

    return status;
}
/* This should be called in BMI phase after firmware is downloaded */
void
ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
{
    A_UINT32 eepHeaderAddr;
    A_UINT8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
    A_UINT8 MCKINLEYCustDataShadow[MCKINLEY_CUST_DATA_SIZE+4];
    A_INT32 i;

    if (BMIReadMemory(hifDevice,
            HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
            (A_UCHAR *)&eepHeaderAddr,
            4)!= A_OK)
    {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
        return;
    }
    if (TargetType == TARGET_TYPE_MCKINLEY) {
        eepHeaderAddr += 36;  /* MCKINLEY customer data section offset is 37 */

        for (i=0; i<MCKINLEY_CUST_DATA_SIZE+4; i+=4){
            if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&MCKINLEYCustDataShadow[i])!= A_OK) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
                return ;
            }  
            eepHeaderAddr +=4;
        }

        memcpy(custDataMCKINLEY, MCKINLEYCustDataShadow+1, MCKINLEY_CUST_DATA_SIZE);
    }


    if (TargetType == TARGET_TYPE_AR6003) {
        eepHeaderAddr += 36;  /* AR6003 customer data section offset is 37 */

        for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){
            if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&AR6003CustDataShadow[i])!= A_OK) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
                return ;
            }  
            eepHeaderAddr +=4;
        }

        memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE);
    }

    if (TargetType == TARGET_TYPE_AR6002) {
        eepHeaderAddr += 64;  /* AR6002 customer data sectioin offset is 64 */

        for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){
            if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&custDataAR6002[i])!= A_OK) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
                return ;
            }  
            eepHeaderAddr +=4;
        }
    }

    return;
}
static A_STATUS prepare_MCKINLEY(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion)
{
    A_STATUS status = A_OK;
    A_UINT32 value  = 0;

    /* force the setting to disable sleep for Bringup FIXME_MK */
    value |= WLAN_SYSTEM_SLEEP_DISABLE_MASK;

    status = BMIWriteMemory(hifDevice,
                            HOST_INTEREST_ITEM_ADDRESS(TARGET_TYPE_AR6002, hi_system_sleep_setting),
                            (A_UCHAR *)&value,
                            4);

    return status;
}
Example #5
0
A_UINT32
dbglog_get_debug_hdr_ptr(A_UINT32 tgtType,
                         HIF_DEVICE *device)
{
    A_UINT32 param   = 0;
    A_UINT32 address = 0;
    A_STATUS status  = A_OK;

    address = HOST_INTEREST_ITEM_ADDRESS(tgtType, hi_dbglog_hdr);

    if ((status = ar6000_ReadDataDiag(device, address, (A_UCHAR *)&param, 4)) != A_OK)
    {
        param = 0;
    }

    return param;
}
Example #6
0
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
{
    A_UINT32 address;
    A_UINT32 regDumpArea = 0;
    A_STATUS status;
    A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX];
    A_UINT32 regDumpCount = 0;
    A_UINT32 i;

    do {

            /* the reg dump pointer is copied to the host interest area */
        address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);

        if (TargetType == TARGET_TYPE_AR6001) {
                /* for AR6001, this is a fixed location because the ptr is actually stuck in cache,
                 * this may be fixed in later firmware versions */
            address = 0x18a0;
            regDumpCount = REG_DUMP_COUNT_AR6001;

        } else  if (TargetType == TARGET_TYPE_AR6002) {

            regDumpCount = REG_DUMP_COUNT_AR6002;

        } else {
            A_ASSERT(0);
        }

            /* read RAM location through diagnostic window */
        status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
            break;
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));

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

        if (TargetType == TARGET_TYPE_AR6001) {
            regDumpArea &= 0x0FFFFFFF;  /* convert to physical address in target memory */
        }

            /* fetch register dump data */
        status = ar6000_ReadDataDiag(hifDevice,
                                     regDumpArea,
                                     (A_UCHAR *)&regDumpValues[0],
                                     regDumpCount * (sizeof(A_UINT32)));

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
            break;
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));

        for (i = 0; i < regDumpCount; i++) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d :  0x%8.8X \n",i, regDumpValues[i]));
        }

    } while (FALSE);

}
Example #7
0
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
{
    A_UINT32 address;
    A_UINT32 regDumpArea = 0;
    A_STATUS status;
    A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX];
    A_UINT32 regDumpCount = 0;
    A_UINT32 i;

    do {

            /* the reg dump pointer is copied to the host interest area */
        address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
        address = TARG_VTOP(TargetType, address);

        if (TargetType == TARGET_TYPE_AR6001) {
                /* for AR6001, this is a fixed location because the ptr is actually stuck in cache,
                 * this may be fixed in later firmware versions */
            address = 0x18a0;
            regDumpCount = REG_DUMP_COUNT_AR6001;
        } else  if (TargetType == TARGET_TYPE_AR6002) {
            regDumpCount = REG_DUMP_COUNT_AR6002;
        } else  if (TargetType == TARGET_TYPE_AR6003) {
            regDumpCount = REG_DUMP_COUNT_AR6003;
        } else {
            A_ASSERT(0);
        }

            /* read RAM location through diagnostic window */
        status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
            break;
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));

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

        regDumpArea = TARG_VTOP(TargetType, regDumpArea);

            /* fetch register dump data */
        status = ar6000_ReadDataDiag(hifDevice,
                                     regDumpArea,
                                     (A_UCHAR *)&regDumpValues[0],
                                     regDumpCount * (sizeof(A_UINT32)));

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
            break;
        }
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));

        for (i = 0; i < regDumpCount; i++) {
            //ATHR_DISPLAY_MSG (_T(" %d :  0x%8.8X \n"), i, regDumpValues[i]);
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d :  0x%8.8X \n",i, regDumpValues[i]));

#ifdef UNDER_CE
        /*
         * For Every logPrintf() Open the File so that in case of Crashes
         * We will have until the Last Message Flushed on to the File
         * So use logPrintf Sparingly..!!
         */
        tgtassertPrintf (ATH_DEBUG_TRC," %d:  0x%8.8X \n",i, regDumpValues[i]);
#endif
        }

    } while (FALSE);

}
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;
}
Example #9
0
static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE     HCIHandle,
                                           struct hci_transport_properties *pProps, 
                                           void                     *pContext)
{
    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
    int              status;
    u32 address, hci_uart_pwr_mgmt_params;
//    struct ar3k_config_info      ar3kconfig;
    
    pHcidevInfo->pHCIDev = HCIHandle;
    
    memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
    
    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", 
            (unsigned long)HCIHandle, 
            pHcidevInfo->HCIProps.HeadRoom, 
            pHcidevInfo->HCIProps.TailRoom,
            pHcidevInfo->HCIProps.IOBlockPad));
    
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
#else
    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
#endif
                             
        /* provide buffers */
    RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
    RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
   
    do {
            /* start transport */
        status = HCI_TransportStart(pHcidevInfo->pHCIDev);
         
        if (status) {
            break;    
        }
        
        if (!pHcidevInfo->HciNormalMode) {
                /* in test mode, no need to go any further */
            break;    
        }

        // The delay is required when AR6K is driving the BT reset line
        // where time is needed after the BT chip is out of reset (HCI_TransportStart)
        // and before the first HCI command is issued (AR3KConfigure)
        // FIXME
        // The delay should be configurable and be only applied when AR6K driving the BT
        // reset line. This could be done by some module parameter or based on some HW config
        // info. For now apply 100ms delay blindly
        A_MDELAY(100);
        
        A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
        ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
        ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
        ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice);
#else
        ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
#endif
        ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
        
        if (ar3khcibaud != 0) {
                /* user wants ar3k baud rate change */
            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
            ar3kconfig.AR3KBaudRate = ar3khcibaud;    
        }
        
        if ((hciuartscale != 0) || (hciuartstep != 0)) {   
                /* user wants to tune HCI bridge UART scale/step values */
            ar3kconfig.AR6KScale = (u16)hciuartscale;
            ar3kconfig.AR6KStep = (u16)hciuartstep;
            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
        }
        
        /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
        address = TARG_VTOP(pHcidevInfo->ar->arTargetType, 
                            HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params));
        status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
        if (0 == status) {
            ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1);
            ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16;
            ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8;
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
        }
        /* configure the AR3K device */         
		memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
        status = AR3KConfigure(&ar3kconfig);
        if (status) {
            break; 
        }

        /* Make sure both AR6K and AR3K have power management enabled */
        if (ar3kconfig.PwrMgmtEnabled) {
            status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
            if (status) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
            }
        }
        
        status = bt_register_hci(pHcidevInfo);
        
    } while (false);
static A_STATUS ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE     HCIHandle, 
                                           HCI_TRANSPORT_PROPERTIES *pProps, 
                                           void                     *pContext)
{
    AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
    A_STATUS              status;
    AR_SOFTC_DEV_T *arDev = pHcidevInfo->ar->arDev[0];

    
    pHcidevInfo->pHCIDev = HCIHandle;
    
    A_MEMCPY(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
    
    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", 
            (unsigned long)HCIHandle, 
            pHcidevInfo->HCIProps.HeadRoom, 
            pHcidevInfo->HCIProps.TailRoom,
            pHcidevInfo->HCIProps.IOBlockPad));
    
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
#else
    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= arDev->arNetDev->hard_header_len);
#endif
                             
        /* provide buffers */
    RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
    RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
   
    do {
            /* start transport */
        status = HCI_TransportStart(pHcidevInfo->pHCIDev);
         
        if (A_FAILED(status)) {
            break;    
        }
        
        if (!pHcidevInfo->HciNormalMode) {
                /* in test mode, no need to go any further */
            break;    
        }

        /* The delay is required when AR6K is driving the BT reset line */
        /* where time is needed after the BT chip is out of reset (HCI_TransportStart) */
        /* and before the first HCI command is issued (AR3KConfigure) */
        /* FIXME */
        /* The delay should be configurable and be only applied when AR6K driving the BT */
        /* reset line. This could be done by some module parameter or based on some HW config */
        /* info. For now apply 100ms delay blindly */
        A_MDELAY(100);
        
        A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig));
        ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev;
        ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps;
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
        ar3kconfig.pHIFDevice = (HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevice);
#else
        ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
#endif
        ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
        
        if (ar3khcibaud != 0) {
                /* user wants ar3k baud rate change */
            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD;
            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY;
            ar3kconfig.AR3KBaudRate = ar3khcibaud;    
        }
        
        if ((hciuartscale != 0) || (hciuartstep != 0)) {   
                /* user wants to tune HCI bridge UART scale/step values */
            ar3kconfig.AR6KScale = (A_UINT16)hciuartscale;
            ar3kconfig.AR6KStep = (A_UINT16)hciuartstep;           
            ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP;
        }
        
            /* configure the AR3K device */  
		memcpy(ar3kconfig.bdaddr,arDev->bdaddr,6);       
        status = AR3KConfigure(&ar3kconfig);
        if (A_FAILED(status)) {
            extern unsigned int setuphci;
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Fail to configure AR3K. No device? Cleanup HCI\n"));
            pHcidevInfo->ar->exitCallback = NULL;
            ar6000_cleanup_hci(pHcidevInfo->ar);
            setuphci = 0;
            pHcidevInfo->ar->arBTSharing = 0;
            break; 
        }

        /* Make sure both AR6K and AR3K have power management enabled */
        if (ar3kconfig.PwrMgmtEnabled) {
            A_UINT32 address, hci_uart_pwr_mgmt_params;
            /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */
            address = TARG_VTOP(pHcidevInfo->ar->arTargetType, 
                                HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar->arTargetType, hi_hci_uart_pwr_mgmt_params));
            status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
            hci_uart_pwr_mgmt_params &= 0xFFFF;
            /* wakeup timeout is [31:16] */
            hci_uart_pwr_mgmt_params |= (ar3kconfig.WakeupTimeout << 16);
            status |= ar6000_WriteRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params);
            if (A_OK != status) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to write hci_uart_pwr_mgmt_params!\n"));
            }

            /* Fetch the address of the hi_hci_uart_pwr_mgmt_params_ext instance in the host interest area */
            address = TARG_VTOP(pHcidevInfo->ar->arTargetType, 
                                HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar->arTargetType, hi_hci_uart_pwr_mgmt_params_ext));
            status = ar6000_WriteRegDiag(pHcidevInfo->ar->arHifDevice, &address, &ar3kconfig.IdleTimeout);
            if (A_OK != status) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to write hci_uart_pwr_mgmt_params_ext!\n"));
            }
        
            status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, TRUE);
            if (A_FAILED(status)) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
            }
        }
        
        status = bt_register_hci(pHcidevInfo);
        
    } while (FALSE);

    return status; 
}
Example #11
0
/* Modules for firmware download */
A_STATUS configure_ar6000(HIF_DEVICE *hifDevice,
                           A_UINT32    TargetType,
                           A_UINT32    TargetVersion,
                           A_BOOL      enableUART,
                           A_BOOL      timerWAR,
                           A_UINT32    clkFreq,
                           wchar_t     *fileName,
                           wchar_t     *fileRoot,
                           A_BOOL      bCompressed,
                           A_BOOL      isColdBoot,
                           wchar_t     *eepromFile)
{
    A_STATUS status   = A_OK;
    A_UINT32 value    = 0;
    A_UINT32 oldSleep = 0;

    /* do any target-specific preparation that can be done through BMI */
    do
    {
        if (enableUART)
        {
            A_UINT32 uartparam;
            uartparam = 1;
            status = BMIWriteMemory(hifDevice,
                                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_serial_enable),
                                (A_UCHAR *)&uartparam,
                                4);
            if (status != A_OK)
            {
                break;
            }
        }

        value = HTC_PROTOCOL_VERSION;
        status = BMIWriteMemory (hifDevice,
                                 HOST_INTEREST_ITEM_ADDRESS (TargetType, hi_app_host_interest),
                                (A_UCHAR *)&value,
                                4);
        if (status != A_OK)
        {
            break;
        }

        /* Selectively enable/disable the WAR for Timer Hang Symptom in the
         * firmware by setting a bit in the AR6K Scratch register. The firmware will
         * read this during init and appropriately enable/disable the WAR.
         * This setting will be retained in the firmware till target reset.
         */
        if (timerWAR)
        {
            A_UINT32 timerparam;

            status = BMIReadMemory(hifDevice,
                                   HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag),
                                   (A_UCHAR *)&timerparam,
                                   4);
            if (status != A_OK)
            {
                break;
            }
            timerparam |= HI_OPTION_TIMER_WAR;

            status = BMIWriteMemory(hifDevice,
                                    HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag),
                                    (A_UCHAR *)&timerparam,
                                    4);
            if (status != A_OK)
            {
                break;
            }
        }

        if (TargetType == TARGET_TYPE_AR6001)
        {
#ifdef FLASH_18V
            // Change the flash access time for 1.8V flash to 150ns
            status = BMIWriteSOCRegister (hifDevice,  0xac004004,  0x920100d1);
            if (status != A_OK)
            {
                break;
            }
#endif

        }
         /* set the firmware mode to AP */

        {
            A_UINT32 param;
            A_UINT32 fwmode = HI_OPTION_FW_MODE_BSS_STA;

            if (BMIReadMemory(hifDevice,
                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag),
                (A_UCHAR *)&param,4)!= A_OK)
            {
                return -1;
            }

            param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);

            if (BMIWriteMemory(hifDevice,
                HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag),
                (A_UCHAR *)&param,4) != A_OK)
            {
                return -1;
            }
        }

        if (TargetType == TARGET_TYPE_AR6002)
        {
            // Store the value of sleep
            oldSleep = 0x0;
            status = BMIReadSOCRegister (hifDevice, 0x40C4, &oldSleep);
            if (status != A_OK)
            {
                break;
            }

            // disable sleep
            status = BMIWriteSOCRegister (hifDevice, 0x40C4, oldSleep |  0x1);
            if (status != A_OK)
            {
                break;
            }

            status = ar6002_download_image(hifDevice, TargetVersion, fileName, fileRoot, bCompressed,isColdBoot);
            if (status != A_OK)
            {
               break;
            }

            // Restore the value of sleep
            status = BMIWriteSOCRegister (hifDevice, 0x40C4, oldSleep);
            if (status != A_OK)
            {
                break;
            }

            if ((TargetVersion == AR6002_VERSION_REV2) && (AR6002_REV2_APP_START_OVERRIDE != 0)) {
                    /* override default app start address known to ROM  */
                status = BMISetAppStart(hifDevice, AR6002_REV2_APP_START_OVERRIDE);
                if (status != A_OK) {
                    break;
                }
            }

        }

        status = ar6000_configure_clock (hifDevice, TargetType, TargetVersion, clkFreq);
        if (status != A_OK)
        {
            break;
        }

        status = eeprom_ar6000_transfer (hifDevice, TargetType, fileRoot, eepromFile);
        if (status != A_OK)
        {
            break;
        }

    } while (FALSE);

    return status;
}
Example #12
0
static A_STATUS
ar6000_configure_clock (HIF_DEVICE *hifDevice,
                        A_UINT32    TargetType,
                        A_UINT32    TargetVersion,
                        A_UINT32    clkFreq)
{
    A_UINT32 ext_clk_detected = 0;
    A_STATUS status = A_OK;

    do
    {
        if (TargetType == TARGET_TYPE_AR6001)
        {
            status = BMIWriteSOCRegister(hifDevice, 0xAC000020, 0x203);
            if (status != A_OK)
            {
                break;
            }

            status = BMIWriteSOCRegister (hifDevice, 0xAC000024, 0x203);
            if (status != A_OK)
            {
                break;
            }
        }

        if (TargetType == TARGET_TYPE_AR6002)
        {
            if (TargetVersion == AR6002_VERSION_REV2)
            {
                status = BMIReadMemory(hifDevice,
                         HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_ext_clk_detected),
                         (A_UCHAR *)&ext_clk_detected,
                         4);
                if (status != A_OK)
                {
                    break;
                }

#ifdef FORCE_INTERNAL_CLOCK
                status = BMIWriteSOCRegister (hifDevice, 0x40E0, 0x10000);
                if (status != A_OK)
                {
                    break;
                }
                status = BMIWriteSOCRegister (hifDevice, 0x4028, 0x0);
                if (status != A_OK)
                {
                    break;
                }
#else
                // LPO_CAL.Enable for internal clock
                if (ext_clk_detected == 0x0)
                {
                    status = BMIWriteSOCRegister (hifDevice, 0x40E0, 0x10000);
                    if (status != A_OK)
                    {
                        break;
                    }
                }
#endif
                // Run at 40/44 MHz clock
                status = BMIWriteSOCRegister (hifDevice, 0x4020, 0x0);
                if (status != A_OK)
                {
                    break;
                }
            }

            // Write refclk
            status = BMIWriteMemory(hifDevice,
                                    HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_refclk_hz),
                                    (A_UCHAR *)&clkFreq,
                                    4);
            if (status != A_OK)
            {
                break;
            }
        }
    } while (FALSE);

    return status;
}
Example #13
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;
}
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
{
    A_UINT32 address;
    A_UINT32 regDumpArea = 0;
    A_STATUS status;
    A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX];
    A_UINT32 regDumpCount = 0;
    A_UINT32 i;

    do {

        address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
        address = TARG_VTOP(TargetType, address);

        if (TargetType == TARGET_TYPE_AR6001) {
            address = 0x18a0;
            regDumpCount = REG_DUMP_COUNT_AR6001;
        } else  if (TargetType == TARGET_TYPE_AR6002) {
            regDumpCount = REG_DUMP_COUNT_AR6002;
        } else  if (TargetType == TARGET_TYPE_AR6003) {
            regDumpCount = REG_DUMP_COUNT_AR6003;
        } else {
            A_ASSERT(0);
        }

        status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
            break;
        }

        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));

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

        regDumpArea = TARG_VTOP(TargetType, regDumpArea);

            /* fetch register dump data */
        status = ar6000_ReadDataDiag(hifDevice,
                                     regDumpArea,
                                     (A_UCHAR *)&regDumpValues[0],
                                     regDumpCount * (sizeof(A_UINT32)));

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
            break;
        }
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));

        for (i = 0; i < regDumpCount; i++) {
            ATHR_DISPLAY_MSG (_T(" %d :  0x%8.8X \n"), i, regDumpValues[i]);
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d :  0x%8.8X \n",i, regDumpValues[i]));
#ifdef UNDER_CE
            logPrintf(ATH_DEBUG_ERR," %d:  0x%8.8X \n",i, regDumpValues[i]);
#endif
        }

    } while (FALSE);

}