Exemplo n.º 1
0
static A_STATUS
_do_write_diag(HIF_DEVICE *hifDevice, A_UINT32 addr, A_UINT32 value)
{
    A_STATUS status;

    status = ar6000_WriteRegDiag(hifDevice, &addr, &value);
    if (status != A_OK)
    {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
    }

    return status;
}
Exemplo n.º 2
0
A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice, 
                                A_UINT32 scale, 
                                A_UINT32 step)
{
    A_UINT32 regAddress;
    A_UINT32 regVal;
    A_STATUS status;

    regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
    regVal = ((A_UINT32)scale << 16) | step;
    /* change the HCI UART scale/step values through the diagnostic window */
    status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);                     

    return status;
}
Exemplo n.º 3
0
int ar6000_set_uart_config(struct hif_device *hifDevice,
                           u32 scale,
                           u32 step)
{
    u32 regAddress;
    u32 regVal;
    int status;

    regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS;
    regVal = ((u32)scale << 16) | step;
    /* change the HCI UART scale/step values through the diagnostic window */
    status = ar6000_WriteRegDiag(hifDevice, &regAddress, &regVal);

    return status;
}
Exemplo n.º 4
0
A_STATUS
ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
                     A_UCHAR *data, A_UINT32 length)
{
    A_UINT32 count;
    A_STATUS status = A_OK;

    for (count = 0; count < length; count += 4, address += 4) {
        if ((status = ar6000_WriteRegDiag(hifDevice, &address,
                                          (A_UINT32 *)&data[count])) != A_OK)
        {
            break;
        }
    }

    return status;
}
Exemplo n.º 5
0
/* reset device */
A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
{

#if !defined(DWSIM)
    A_STATUS status = A_OK;
    A_UINT32 address;
    A_UINT32 data;

    do {

        // address = RESET_CONTROL_ADDRESS;
        data = RESET_CONTROL_COLD_RST_MASK;

          /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
        if (TargetType == TARGET_TYPE_AR6001) {
            address = 0x0C000000;
        } else {
            if (TargetType == TARGET_TYPE_AR6002) {
                address = 0x00004000;
            } else {
                A_ASSERT(0);
            }
        }

        status = ar6000_WriteRegDiag(hifDevice, &address, &data);

        if (A_FAILED(status)) {
            break;
        }

        /*
         * Read back the RESET CAUSE register to ensure that the cold reset
         * went through.
         */
        msleep(2000); /* 2 second delay to allow things to settle down */


        // address = RESET_CAUSE_ADDRESS;
        /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
        if (TargetType == TARGET_TYPE_AR6001) {
            address = 0x0C0000CC;
        } else {
            if (TargetType == TARGET_TYPE_AR6002) {
                address = 0x000040C0;
            } else {
                A_ASSERT(0);
            }
        }

        data = 0;
        status = ar6000_ReadRegDiag(hifDevice, &address, &data);

        if (A_FAILED(status)) {
            break;
        }

        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
        data &= RESET_CAUSE_LAST_MASK;
        if (data != 2) {
            AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
        }

    } while (FALSE);

    if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
    }
#endif
    return A_OK;
}
Exemplo n.º 6
0
A_STATUS
ar6000_reset_device_skipflash(HIF_DEVICE *hifDevice)
{
    int i;
    struct forceROM_s {
        A_UINT32 addr;
        A_UINT32 data;
    };
    struct forceROM_s *ForceROM;
    int szForceROM;
    A_UINT32 instruction;

    static struct forceROM_s ForceROM_REV2[] = {
        /* NB: This works for old REV2 ROM (old). */
        {0x00001ff0, 0x175b0027}, /* jump instruction at 0xa0001ff0 */
        {0x00001ff4, 0x00000000}, /* nop instruction at 0xa0001ff4 */

        {MC_REMAP_TARGET_ADDRESS, 0x00001ff0}, /* remap to 0xa0001ff0 */
        {MC_REMAP_COMPARE_ADDRESS, 0x01000040},/* ...from 0xbfc00040 */
        {MC_REMAP_SIZE_ADDRESS, 0x00000000},   /* ...1 cache line */
        {MC_REMAP_VALID_ADDRESS, 0x00000001},  /* ...remap is valid */

        {LOCAL_COUNT_ADDRESS+0x10, 0}, /* clear BMI credit counter */

        {RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
    };

    static struct forceROM_s ForceROM_NEW[] = {
        /* NB: This works for AR6000 ROM REV3 and beyond.  */
        {LOCAL_SCRATCH_ADDRESS, AR6K_OPTION_IGNORE_FLASH},
        {LOCAL_COUNT_ADDRESS+0x10, 0}, /* clear BMI credit counter */
        {RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
    };

    /*
     * Examine a semi-arbitrary instruction that's different
     * in REV2 and other revisions.
     * NB: If a Host port does not require simultaneous support
     * for multiple revisions of Target ROM, this code can be elided.
     */
    (void)ar6000_ReadDataDiag(hifDevice, 0x01000040,
                              (A_UCHAR *)&instruction, 4);

    AR_DEBUG_PRINTF(ATH_LOG_ERR, ("instruction=0x%x\n", instruction));

    if (instruction == 0x3c1aa200) {
        /* It's an old ROM */
        ForceROM = ForceROM_REV2;
        szForceROM = sizeof(ForceROM_REV2)/sizeof(*ForceROM);
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Using OLD method\n"));
    } else {
        ForceROM = ForceROM_NEW;
        szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM);
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Using NEW method\n"));
    }

    AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Force Target to execute from ROM....\n"));
    for (i = 0; i < szForceROM; i++)
    {
        if (ar6000_WriteRegDiag(hifDevice,
                                &ForceROM[i].addr,
                                &ForceROM[i].data) != A_OK)
        {
            AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
            return A_ERROR;
        }
    }

    msleep(50); /* delay to allow dragon to come to BMI phase  */
    return A_OK;
}
Exemplo n.º 7
0
/*
 * Call this function just before the call to BMIInit
 * in order to force* AR6002 rev 1.x firmware to detect a Host.
 * THIS IS FOR USE ONLY WITH AR6002 REV 1.x.
 * TBDXXX: Remove this function when REV 1.x is desupported.
 */
A_STATUS
ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice)
{
    A_INT32 i;
    struct forceROM_s {
        A_UINT32 addr;
        A_UINT32 data;
    };
    struct forceROM_s *ForceROM;
    A_INT32 szForceROM;
    A_STATUS status = A_OK;
    A_UINT32 address;
    A_UINT32 data;

    /* Force AR6002 REV1.x to recognize Host presence.
     *
     * Note: Use RAM at 0x52df80..0x52dfa0 with ROM Remap entry 0
     * so that this workaround functions with AR6002.war1.sh.  We
     * could fold that entire workaround into this one, but it's not
     * worth the effort at this point.  This workaround cannot be
     * merged into the other workaround because this must be done
     * before BMI.
     */

    static struct forceROM_s ForceROM_NEW[] = {
        {0x52df80, 0x20f31c07},
        {0x52df84, 0x92374420},
        {0x52df88, 0x1d120c03},
        {0x52df8c, 0xff8216f0},
        {0x52df90, 0xf01d120c},
        {0x52df94, 0x81004136},
        {0x52df98, 0xbc9100bd},
        {0x52df9c, 0x00bba100},

        {0x00008000|MC_TCAM_TARGET_ADDRESS, 0x0012dfe0}, /* Use remap entry 0 */
        {0x00008000|MC_TCAM_COMPARE_ADDRESS, 0x000e2380},
        {0x00008000|MC_TCAM_MASK_ADDRESS, 0x00000000},
        {0x00008000|MC_TCAM_VALID_ADDRESS, 0x00000001},

        {0x00018000|(LOCAL_COUNT_ADDRESS+0x10), 0}, /* clear BMI credit counter */

        {0x00004000|AR6002_RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
    };

    address = 0x004ed4b0; /* REV1 target software ID is stored here */
    status = ar6000_ReadRegDiag(hifDevice, &address, &data);
    if (A_FAILED(status) || (data != AR6002_VERSION_REV1)) {
        return A_ERROR; /* Not AR6002 REV1 */
    }

    ForceROM = ForceROM_NEW;
    szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM);

    ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Force Target to recognize Host....\n"));
    for (i = 0; i < szForceROM; i++)
    {
        if (ar6000_WriteRegDiag(hifDevice,
                                &ForceROM[i].addr,
                                &ForceROM[i].data) != A_OK)
        {
            ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Cannot force Target to recognize Host!\n"));
            return A_ERROR;
        }
    }

    A_MDELAY(1000);

    return A_OK;
}
Exemplo n.º 8
0
/* reset device */
A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset)
{
    A_STATUS status = A_OK;
    A_UINT32 address;
    A_UINT32 data;

    do {
// Workaround BEGIN
        // address = RESET_CONTROL_ADDRESS;
    	
    	if (coldReset) {
            data = RESET_CONTROL_COLD_RST_MASK;
    	}
    	else {
            data = RESET_CONTROL_MBOX_RST_MASK;
    	}

          /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
        if (TargetType == TARGET_TYPE_AR6001) {
            address = AR6001_RESET_CONTROL_ADDRESS;
        } else if (TargetType == TARGET_TYPE_AR6002) {
            address = AR6002_RESET_CONTROL_ADDRESS;
        } else if (TargetType == TARGET_TYPE_AR6003) {
            address = AR6003_RESET_CONTROL_ADDRESS;
        } else {
            A_ASSERT(0);
        }


        status = ar6000_WriteRegDiag(hifDevice, &address, &data);

        if (A_FAILED(status)) {
            break;
        }

        if (!waitForCompletion) {
            break;
        }

#if 0
        /* Up to 2 second delay to allow things to settle down */
        (void)_delay_until_target_alive(hifDevice, 2000, TargetType);

        /*
         * Read back the RESET CAUSE register to ensure that the cold reset
         * went through.
         */

        // address = RESET_CAUSE_ADDRESS;
        /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
        if (TargetType == TARGET_TYPE_AR6001) {
            address = 0x0C0000CC;
        } else if (TargetType == TARGET_TYPE_AR6002) {
            address = 0x000040C0;
        } else if (TargetType == TARGET_TYPE_AR6003) {
            address = 0x000040C0;
        } else {
            A_ASSERT(0);
        }

        data = 0;
        status = ar6000_ReadRegDiag(hifDevice, &address, &data);

        if (A_FAILED(status)) {
            break;
        }

        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
        data &= RESET_CAUSE_LAST_MASK;
        if (data != 2) {
            AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
        }
#endif
// Workaroud END

    } while (FALSE);

    if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
    }

    return A_OK;
}
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; 
}
/* reset device */
A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion)
{
    A_STATUS status = A_OK;
    A_UINT32 address;
    A_UINT32 data;

    do {

        data = RESET_CONTROL_COLD_RST_MASK;

        if (TargetType == TARGET_TYPE_AR6001) {
            address = AR6001_RESET_CONTROL_ADDRESS;
        } else if (TargetType == TARGET_TYPE_AR6002) {
            address = AR6002_RESET_CONTROL_ADDRESS;
        } else if (TargetType == TARGET_TYPE_AR6003) {
            address = AR6003_RESET_CONTROL_ADDRESS;
        } else {
            A_ASSERT(0);
        }

        status = ar6000_WriteRegDiag(hifDevice, &address, &data);

        if (A_FAILED(status)) {
            break;
        }

        if (!waitForCompletion) {
            break;
        }

        (void)_delay_until_target_alive(hifDevice, 1800, TargetType);

        if (TargetType == TARGET_TYPE_AR6001) {
            address = 0x0C0000CC;
        } else if (TargetType == TARGET_TYPE_AR6002) {
            address = 0x000040C0;
        } else if (TargetType == TARGET_TYPE_AR6003) {
            address = 0x000040C0;
        } else {
            A_ASSERT(0);
        }

        data = 0;
        status = ar6000_ReadRegDiag(hifDevice, &address, &data);

        if (A_FAILED(status)) {
            break;
        }

        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
        data &= RESET_CAUSE_LAST_MASK;
        if (data != 2) {
            AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
        }

    } while (FALSE);

    if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
    }

    return A_OK;
}