Ejemplo n.º 1
0
bss_t *
wlan_node_alloc(struct ieee80211_node_table *nt, A_INT32 wh_size)
{
    bss_t *ni;

    ni = A_MALLOC(sizeof(bss_t));

    if (ni != NULL) {
        ni->ni_buf = A_MALLOC(wh_size);
        if (ni->ni_buf == NULL) {
            A_FREE(ni);
            ni = NULL;
        }
    }
	/* Make sure our lists are clean */

    if (ni) {
        ni->ni_list_next = NULL;
        ni->ni_list_prev = NULL;
        ni->ni_hash_next = NULL;
        ni->ni_hash_prev = NULL;
    }

    return ni;
}
Ejemplo n.º 2
0
/* APIs visible to the driver */
A_STATUS
BMIInit(A_VOID *pCxt)
{
    bmiDone = FALSE;
    
    /*
     * On some platforms, it's not possible to DMA to a static variable
     * in a device driver (e.g. Linux loadable driver module).
     * So we need to A_MALLOC space for "command credits" and for commands.
     *
     * Note: implicitly relies on A_MALLOC to provide a buffer that is
     * suitable for DMA (or PIO).  This buffer will be passed down the
     * bus stack.
     */
    if (!pBMICmdCredits) {
        pBMICmdCredits = (A_UINT32 *)A_MALLOC(4, MALLOC_ID_TEMPORARY);
        A_ASSERT(pBMICmdCredits);
    }

    if (!pBMICmdBuf) {
        pBMICmdBuf = (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ, MALLOC_ID_TEMPORARY);
        A_ASSERT(pBMICmdBuf);
    }  
    
    return A_OK;      
}
Ejemplo n.º 3
0
    /* setup scatter DMA resources for each scatter request */
static A_STATUS SetupScatterResource(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq)
{
    A_STATUS status = A_OK;
    void     *pDMAInfo = NULL;
      
    switch (device->ScatterMethod) {
        case HIF_SCATTER_DMA_REAL :
                /* just allocate memory for the scatter list */
            pDMAInfo = A_MALLOC(sizeof(HIF_SCATTER_DMA_REAL_INFO));
            if (NULL == pDMAInfo) {
                status = A_NO_MEMORY;
                break;
            }           
            
            A_MEMZERO(pDMAInfo, sizeof(HIF_SCATTER_DMA_REAL_INFO));           
            pReq->ScatterMethod = HIF_SCATTER_DMA_REAL;
            
            break;
        case HIF_SCATTER_DMA_BOUNCE :               
            {
                HIF_SCATTER_DMA_BOUNCE_INFO *pBounceInfo;    
                
                    /* allocate the management structure */
                pBounceInfo = (HIF_SCATTER_DMA_BOUNCE_INFO *)A_MALLOC(sizeof(HIF_SCATTER_DMA_BOUNCE_INFO));
                if (NULL == pBounceInfo) {
                    status = A_NO_MEMORY;
                    break;    
                }
                
                A_MEMZERO(pBounceInfo, sizeof(HIF_SCATTER_DMA_BOUNCE_INFO));
               
                    /* allocate a bounce buffer for the request */ 
                status = AllocateDMABounceBuffer(device, pBounceInfo);                 
                if (A_FAILED(status)) {
                    A_FREE(pBounceInfo);
                    break;
                }    
                                 
                pDMAInfo = pBounceInfo;
                pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE;
                pReq->pScatterBounceBuffer = pBounceInfo->pBounceBuffer + 
                                                        pBounceInfo->AlignmentOffset;     
            }
            break;
        default:
            break;  
    }
    
    if (pDMAInfo != NULL) {
        SET_DMA_INFO_SR(pReq,pDMAInfo);    
    }
    
    return status;
}
Ejemplo n.º 4
0
Archivo: htc.c Proyecto: KHATEEBNSIT/AP
static HTC_PACKET *BuildHTCTxCtrlPacket(adf_os_device_t osdev)
{
    HTC_PACKET *pPacket = NULL;
    adf_nbuf_t netbuf;

    do {
        pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
        if (NULL == pPacket) {
            break;
        }
        A_MEMZERO(pPacket,sizeof(HTC_PACKET));
#ifdef ATH_USE_NCNB
        netbuf = adf_nbuf_alloc_ncnb(osdev, HTC_CONTROL_BUFFER_SIZE, 20, 4, TRUE);
#else
        netbuf = adf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE, 20, 4, TRUE);
#endif
        if (NULL == netbuf) {
            A_FREE(pPacket);
            pPacket = NULL;
	        adf_os_print("%s: nbuf alloc failed\n",__func__);
            break;
        }
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("alloc ctrl netbuf :0x%p \n", netbuf));
        SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf);
    } while (FALSE);

    return pPacket;
}
Ejemplo n.º 5
0
static A_STATUS SendHCICommand(AR3K_CONFIG_INFO *pConfig,
                               A_UINT8          *pBuffer,
                               int              Length)
{
    HTC_PACKET  *pPacket = NULL;
    A_STATUS    status = A_OK;

    do {

        pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
        if (NULL == pPacket) {
            status = A_NO_MEMORY;
            break;
        }

        A_MEMZERO(pPacket,sizeof(HTC_PACKET));
        SET_HTC_PACKET_INFO_TX(pPacket,
                               NULL,
                               pBuffer,
                               Length,
                               HCI_COMMAND_TYPE,
                               AR6K_CONTROL_PKT_TAG);

            /* issue synchronously */
        status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,TRUE);

    } while (FALSE);

    if (pPacket != NULL) {
        A_FREE(pPacket);
    }

    return status;
}
Ejemplo n.º 6
0
    /* function to set up virtual scatter support if HIF layer has not implemented the interface */
static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev)
{
    A_STATUS                     status = A_OK;
    int                          bufferSize, sgreqSize;
    int                          i;
    DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo;
    HIF_SCATTER_REQ              *pReq;

    bufferSize = sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO) +
                2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;

    sgreqSize = sizeof(HIF_SCATTER_REQ) +
                    (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM));

    for (i = 0; i < AR6K_SCATTER_REQS; i++) {
            /* allocate the scatter request, buffer info and the actual virtual buffer itself */
        pReq = (HIF_SCATTER_REQ *)A_MALLOC(sgreqSize + bufferSize);

        if (NULL == pReq) {
            status = A_NO_MEMORY;
            break;
        }

        A_MEMZERO(pReq, sgreqSize);

            /* the virtual DMA starts after the scatter request struct */
        pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((A_UINT8 *)pReq + sgreqSize);
        A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO));

        pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0];
            /* align buffer to cache line in case host controller can actually DMA this */
        pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer);
            /* store the structure in the private area */
        pReq->HIFPrivate[0] = pVirtualInfo;
            /* we emulate a DMA bounce interface */
        pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE;
        pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer;
            /* free request to the list */
        DevFreeScatterReq((HIF_DEVICE *)pDev,pReq);
    }

    if (A_FAILED(status)) {
        DevCleanupVirtualScatterSupport(pDev);
    } else {
        pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq;
        pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq;
        pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter;
        if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) {
            AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n"));
            pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ;
            pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER;
        } else {
            pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ;
            pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER;
        }
        pDev->ScatterIsVirtual = TRUE;
    }

    return status;
}
Ejemplo n.º 7
0
/* APIs exported to other modules */
A_STATUS
Abf_WlanStackNotificationInit(ATH_BT_FILTER_INSTANCE *pInstance, A_UINT32 flags)
{
    A_STATUS status;
    ATHBT_FILTER_INFO *pInfo;
    ABF_WLAN_INFO *pAbfWlanInfo;

    pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext;
    if (pInfo->pWlanInfo) {
        return A_OK;
    }

    pAbfWlanInfo = (ABF_WLAN_INFO *)A_MALLOC(sizeof(ABF_WLAN_INFO));
    A_MEMZERO(pAbfWlanInfo,sizeof(ABF_WLAN_INFO));

    A_MUTEX_INIT(&pAbfWlanInfo->hWaitEventLock);
    A_COND_INIT(&pAbfWlanInfo->hWaitEvent);
    A_MEMZERO(pAbfWlanInfo, sizeof(ABF_WLAN_INFO));
    pAbfWlanInfo->pInfo = pInfo;
    pAbfWlanInfo->Loop = TRUE;
    pInfo->pWlanInfo = pAbfWlanInfo;

    /* Spawn a thread which will be used to process events from WLAN */
    status = A_TASK_CREATE(&pInfo->hWlanThread, WlanEventThread, pAbfWlanInfo);
    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to spawn a WLAN thread\n", __FUNCTION__);
        return A_ERROR;
    }

    A_INFO("WLAN Stack Notification init complete\n");

    return A_OK;
}
Ejemplo n.º 8
0
static int SendHCICommand(struct ar3k_config_info *pConfig,
                               u8 *pBuffer,
                               int              Length)
{
    struct htc_packet  *pPacket = NULL;
    int    status = 0;
       
    do {   
        
        pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));     
        if (NULL == pPacket) {
            status = A_NO_MEMORY;
            break;    
        }       
        
        A_MEMZERO(pPacket,sizeof(struct htc_packet));      
        SET_HTC_PACKET_INFO_TX(pPacket,
                               NULL,
                               pBuffer, 
                               Length,
                               HCI_COMMAND_TYPE, 
                               AR6K_CONTROL_PKT_TAG);
        
            /* issue synchronously */                                      
        status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true);
        
    } while (false);
   
    if (pPacket != NULL) {
        kfree(pPacket);
    }
        
    return status;
}
Ejemplo n.º 9
0
/* registered target arrival callback from the HIF layer */
HTC_HANDLE HTCCreate(void *hHIF, HTC_INIT_INFO *pInfo)
{
    A_STATUS    status = A_OK;
    HTC_TARGET  *target = NULL;
    
    do {
        
        if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC : Unable to allocate memory\n"));
            status = A_ERROR;
            break;
        }    
        
        A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));


        adf_os_mem_zero(target, sizeof(HTC_TARGET));

        adf_os_spinlock_init(&target->HTCLock);
        adf_os_spinlock_init(&target->HTCRxLock);
        adf_os_spinlock_init(&target->HTCTxLock);

        /* setup HIF layer callbacks */
        adf_os_mem_zero(&htcCallbacks, sizeof(completion_callbacks_t));
        htcCallbacks.Context = target;
        htcCallbacks.rxCompletionHandler = HTCRxCompletionHandler;
        htcCallbacks.txCompletionHandler = HTCTxCompletionHandler;

        HIFPostInit(hHIF, target, &htcCallbacks);
        
        target->hif_dev = hHIF;

        adf_os_init_mutex(&target->htc_rdy_mutex);
        adf_os_mutex_acquire(&target->htc_rdy_mutex);

        /* Get HIF default pipe for HTC message exchange */
        pEndpoint = &target->EndPoint[ENDPOINT0];
        HIFGetDefaultPipe(hHIF, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID);
        adf_os_print("[Default Pipe]UL: %x, DL: %x\n", pEndpoint->UL_PipeID, pEndpoint->DL_PipeID);


        
        /* TODO : other init */
        
    } while (FALSE);


    target->host_handle = htcInfo.pContext;
   /* TODO INTEGRATION supply from host os handle for any os specific calls*/

    target->os_handle = NULL;

    if (A_FAILED(status)) {
        HTCCleanup(target); 
        target = NULL;
    }
    
    return (HTC_HANDLE)target;
}
Ejemplo n.º 10
0
int android_request_firmware(const struct firmware **firmware_p, const char *name,
                     struct device *device)
{
    int ret = 0;
    struct firmware *firmware;
    char filename[256];
    const char *raw_filename = name;
	*firmware_p = firmware = A_MALLOC(sizeof(*firmware));
    if (!firmware) 
		return -ENOMEM;
    A_MEMZERO(firmware, sizeof(*firmware));
	sprintf(filename, "%s/%s", fwpath, raw_filename);
#ifdef TARGET_EUROPA
    if (strcmp(raw_filename, "softmac")==0) {
        sprintf(filename, "/data/.nvmac.info");
    }
#endif /* TARGET_EUROPA */
    do {
        size_t length, bufsize, bmisize;

        if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) {
            break;
        } else {
            length = ret;
        }
    
        bufsize = ALIGN(length, PAGE_SIZE);
        bmisize = A_ROUND_UP(length, 4);
        bufsize = max(bmisize, bufsize);
        firmware->data = vmalloc(bufsize);
        firmware->size = length;
        if (!firmware->data) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Cannot allocate buffer for firmware\n", __FUNCTION__));
            ret = -ENOMEM;
            break;
        }
    
        if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length));
            ret = -1;
            break;
        }
    
    } while (0);

    if (ret<0) {
        if (firmware) {
            if (firmware->data)
                vfree(firmware->data);
            A_FREE(firmware);
        }
        *firmware_p = NULL;
    } else {
        ret = 0;
    }
    return ret;    
}
Ejemplo n.º 11
0
A_STATUS FCore_ModifyControlActionString(BT_FILTER_CORE_INFO          *pCore,
                                         ATHBT_STATE_INDICATION       Indication,
                                         ATHBT_STATE                  State,
                                         A_CHAR                       *pAction,
                                         int                          StringLength,
                                         ATHBT_MODIFY_CONTROL_ACTION  ModifyAction)
{
    BT_CONTROL_ACTION_DESC  *pNewDesc;
    BT_CONTROL_ACTION_DESC  *pDescHead;
    A_CHAR                  *pString;

        /* get first entry at the head */
    pDescHead = &pCore->ActionDescriptors[Indication].Action[State];

        /* allocate and assemble an entry for this action */
    pNewDesc = (BT_CONTROL_ACTION_DESC  *)A_MALLOC(sizeof(BT_CONTROL_ACTION_DESC) + StringLength + 1);

    if (NULL == pNewDesc) {
        return A_NO_MEMORY;
    }

    A_MEMZERO(pNewDesc,sizeof(BT_CONTROL_ACTION_DESC));

        /* setup and copy string */
    pString = (A_CHAR *)((A_UINT8 *)pNewDesc + sizeof(BT_CONTROL_ACTION_DESC));
    A_MEMCPY(pString,pAction,StringLength);
    pString[StringLength] = 0;
    pNewDesc->pActionString = pString;
        /* mark that it was allocated so we can clean it up later */
    pNewDesc->Flags = BT_CA_DESC_FLAGS_ALLOCATED;

    switch (ModifyAction) {
        case ATHBT_MODIFY_CONTROL_ACTION_APPEND:
                /* append to the end of the list */
            while (pDescHead->pNext != NULL) {
                pDescHead = pDescHead->pNext;
            }
            pDescHead->pNext = pNewDesc;
            break;

        case ATHBT_MODIFY_CONTROL_ACTION_REPLACE:
                /* remove any existing replacements or append operations */
            CleanupModifiedControlActionDescChain(pDescHead);
                /* ignore the first entry's action string */
            pDescHead->pActionString = NULL;
                /* add new replacement */
            pDescHead->pNext = pNewDesc;
            break;

        default:
            A_FREE(pNewDesc);
            break;
    }


    return A_OK;
}
Ejemplo n.º 12
0
static A_STATUS
GetAdapterInfo(ABF_WLAN_INFO *pAbfWlanInfo)
{
    A_STATUS status;
    struct ar6000_version *revinfo;

    revinfo = (struct ar6000_version *)A_MALLOC(sizeof(struct ar6000_version));

    if (revinfo == NULL) {
        A_ERR("[%s] Failed to alloc WLAN revision info\n", __FUNCTION__);
        return A_ERROR;    
    }

 
    /* Get the revision info */
    status = Abf_WlanDispatchIO(pAbfWlanInfo->pInfo, AR6000_IOCTL_WMI_GETREV, 
                                (void *)revinfo, sizeof(struct ar6000_version));
    if (A_FAILED(status)) {
        A_ERR("[%s] Failed to get WLAN revision\n", __FUNCTION__);
        return A_ERROR;
    }

    pAbfWlanInfo->HostVersion = revinfo->host_ver;
    pAbfWlanInfo->TargetVersion = revinfo->target_ver;
    A_INFO("Host Rev: 0x%x(%u.%u.%u.%u), Target Rev: 0x%x(%u.%u.%u.%u)\n",
           revinfo->host_ver,
           ((revinfo->host_ver)&0xf0000000)>>28,
           ((revinfo->host_ver)&0x0f000000)>>24,
           ((revinfo->host_ver)&0x00ff0000)>>16,
           ((revinfo->host_ver)&0x0000ffff),
           revinfo->target_ver,
           ((revinfo->target_ver)&0xf0000000)>>28,
           ((revinfo->target_ver)&0x0f000000)>>24,
           ((revinfo->target_ver)&0x00ff0000)>>16,
           ((revinfo->target_ver)&0x0000ffff));

    A_FREE(revinfo);

    return A_OK;
}
Ejemplo n.º 13
0
/* APIs visible to the driver */
void
BMIInit(void)
{
    bmiDone = FALSE;


    /*
     * On some platforms, it's not possible to DMA to a static variable
     * in a device driver (e.g. Linux loadable driver module).
     * So we need to A_MALLOC space for "command credits" and for commands.
     *
     * Note: implicitly relies on A_MALLOC to provide a buffer that is
     * suitable for DMA (or PIO).  This buffer will be passed down the
     * bus stack.
     */

    if (!pBMICmdBuf) {
        pBMICmdBuf = (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ);
        A_ASSERT(pBMICmdBuf);
    }

    A_REGISTER_MODULE_DEBUG_INFO(bmi);
}
Ejemplo n.º 14
0
static A_STATUS RecvHCIEvent(AR3K_CONFIG_INFO *pConfig,
                             A_UINT8          *pBuffer,
                             int              *pLength)
{
    A_STATUS    status = A_OK;
    HTC_PACKET  *pRecvPacket = NULL;

    do {

        pRecvPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
        if (NULL == pRecvPacket) {
            status = A_NO_MEMORY;
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
            break;
        }

        A_MEMZERO(pRecvPacket,sizeof(HTC_PACKET));

        SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);

        status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
                                               pRecvPacket,
                                               HCI_EVENT_RESP_TIMEOUTMS);
        if (A_FAILED(status)) {
            break;
        }

        *pLength = pRecvPacket->ActualLength;

    } while (FALSE);

    if (pRecvPacket != NULL) {
        A_FREE(pRecvPacket);
    }

    return status;
}
Ejemplo n.º 15
0
static int RecvHCIEvent(struct ar3k_config_info *pConfig,
                             u8 *pBuffer,
                             int              *pLength)
{
    int    status = 0;
    struct htc_packet  *pRecvPacket = NULL;
    
    do {
                 
        pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
        if (NULL == pRecvPacket) {
            status = A_NO_MEMORY;
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
            break;    
        }     
        
        A_MEMZERO(pRecvPacket,sizeof(struct htc_packet)); 
         
        SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);
        
        status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
                                               pRecvPacket,
                                               HCI_EVENT_RESP_TIMEOUTMS);
        if (status) {
            break;    
        }

        *pLength = pRecvPacket->ActualLength;
        
    } while (false);
       
    if (pRecvPacket != NULL) {
        kfree(pRecvPacket);    
    }
    
    return status;
} 
Ejemplo n.º 16
0
void *
a_netbuf_alloc (A_UINT32 len)
{
    void            *buff = NULL;
    ndis_mini_buf_t *pb = NULL;

    pb = A_MALLOC (sizeof(ndis_mini_buf_t)  + \
                   len + AR6000_DATA_OFFSET + \
                   DataBufferAlignmentBytes + DataBufferPadBytes);

    if (pb == NULL) {
        return NULL;
    }

    memset(pb, 0, sizeof(ndis_mini_buf_t));
    buff = (void *) ((A_UINT8 *)pb + sizeof(ndis_mini_buf_t));

    //
        // check buffer alignment
    //
        if ((DWORD)buff & DataBufferAlignmentMask)
    {
        //
            // not aligned, adjust buffer
        //
            (DWORD)buff += DataBufferAlignmentBytes;
            buff = (PUCHAR)((DWORD)buff & ~DataBufferAlignmentMask);
        }

    pb->buf = buff;
    pb->buf_len = len + AR6000_DATA_OFFSET;

    // Reserve headroom
    pb->buf_dat = pb->buf + AR6000_DATA_OFFSET;
    pb->buf_dat_len = 0;
    return pb;
}
Ejemplo n.º 17
0
static void
WirelessEvent(ATH_BT_FILTER_INSTANCE *pInstance, char *data, int len)
{
    A_STATUS status = A_OK;
    struct iw_event iwe_buf, *iwe = &iwe_buf;
    char *pos, *end, *custom, *buf;

    pos = data;
    end = data + len;

    while ((pos + IW_EV_LCP_PK_LEN <= end) && (status == A_OK)) {
        /* Event data may be unaligned, so make a local, aligned copy
         * before processing. */
        A_MEMCPY(&iwe_buf, pos, IW_EV_LCP_LEN);
        if (iwe->len <= IW_EV_LCP_LEN) {
            status = A_ERROR;
            break;
        }

        custom = pos + IW_EV_POINT_LEN;
        if (WIRELESS_EXT > 18 &&
            (iwe->cmd == IWEVMICHAELMICFAILURE ||
             iwe->cmd == IWEVCUSTOM ||
             iwe->cmd == IWEVASSOCREQIE ||
             iwe->cmd == IWEVASSOCRESPIE ||
             iwe->cmd == IWEVPMKIDCAND ||
             iwe->cmd == IWEVGENIE)) {
            /* WE-19 removed the pointer from struct iw_point */
            char *dpos = (char *) &iwe_buf.u.data.length;
            int dlen = dpos - (char *) &iwe_buf;
            A_MEMCPY(dpos, pos + IW_EV_LCP_LEN,
                   sizeof(struct iw_event) - dlen);
        } else {
            A_MEMCPY(&iwe_buf, pos, sizeof(struct iw_event));
            custom += IW_EV_POINT_OFF;
        }

        switch (iwe->cmd) {
        case SIOCGIWAP:
            break;
        case IWEVCUSTOM:
            if (custom + iwe->u.data.length > end) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            buf = A_MALLOC(iwe->u.data.length + 1);
            if (buf == NULL) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            A_MEMCPY(buf, custom, iwe->u.data.length);
            status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length);
            A_FREE(buf);
            break;
        case SIOCGIWSCAN:
            break;
        case SIOCSIWESSID:
            break;
        case IWEVGENIE:
            if (custom + iwe->u.data.length > end || (iwe->u.data.length < 2)) {
                A_ERR("event = IWEVGENIE with wrong length %d remain %d\n", 
                                      iwe->u.data.length, (end-custom));
                status = A_ERROR;
                break;
            }
            buf = A_MALLOC(iwe->u.data.length + 1);
            if (buf == NULL) {
                A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__);
                status = A_ERROR;
                break;
            }
            A_MEMCPY(buf, custom, iwe->u.data.length);
            status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length);
            A_FREE(buf);
            break;
        default:
            break;
        }

        pos += iwe->len;
    }
}
Ejemplo n.º 18
0
int PSSendOps(void *arg) 
{
    int i;
    int ps_index;
    int status = 0;
    PSCmdPacket *HciCmdList; /* List storing the commands */
    const struct firmware* firmware;
    A_UINT32 numCmds;
    A_UINT8 *event;
    A_UINT8 *bufferToFree;
    struct hci_dev *device;
    A_UCHAR *buffer;
    A_UINT32 len;
    A_UINT32 DevType;
    A_UCHAR *PsFileName;
    A_UCHAR *patchFileName;
    A_UCHAR patch_loc[40];
    A_UCHAR *path = NULL;
    A_UCHAR *config_path = NULL;
    A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
    AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg;
    struct device *firmwareDev = NULL;
    A_UINT8 cFlags = 0;
    A_UINT8 bit7 = 0;

    status = 0;
    HciCmdList = NULL;
#ifdef HCI_TRANSPORT_SDIO
    device = hdev->pBtStackHCIDev; 
    firmwareDev = device->parent;
#else 
    device = hdev;
    firmwareDev = &device->dev;
    AthEnableSyncCommandOp(TRUE);    
#endif /* HCI_TRANSPORT_SDIO */
    /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
     */

    path =(A_UCHAR *)A_MALLOC(MAX_FW_PATH_LEN);
    if(path == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
        goto complete;
    }
    config_path = (A_UCHAR *) A_MALLOC(MAX_FW_PATH_LEN);
    if(config_path == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
        goto complete;
    }

    if(A_ERROR == getDeviceType(hdev,&DevType)) {
        status = 1;
        goto complete;
    }
    if(A_ERROR == ReadVersionInfo(hdev)) {
        status = 1;
        goto complete;
    }

    patchFileName = PATCH_FILE;
    snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
    if(DevType){
        if(DevType == 0xdeadc0de){
	        PsFileName =  PS_ASIC_FILE;
	    } else{
    		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x  \n",Rom_Version,Build_Version));
                if((Rom_Version == 0x99999999) && (Build_Version == 1)){
                        
    			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
    			patchFileName = NULL;
		}
	        PsFileName =  PS_FPGA_FILE;
	    }
    }
    else{
	    PsFileName =  PS_ASIC_FILE;
    }

    snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
    /* Read the PS file to a dynamically allocated buffer */
    if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        status = 1;
        goto complete;

    }
    if(NULL == firmware || firmware->size == 0) {
        status = 1;
        goto complete;
    }
    buffer = (A_UCHAR *)A_MALLOC(firmware->size);
    if(buffer != NULL) {
    /* Copy the read file to a local Dynamic buffer */
        memcpy(buffer,firmware->data,firmware->size);
        len = firmware->size;
        A_RELEASE_FIRMWARE(firmware);
        /* Parse the PS buffer to a global variable */
        status = AthDoParsePS(buffer,len);
        A_FREE(buffer);
    } else {
        A_RELEASE_FIRMWARE(firmware);
    }


    /* Read the patch file to a dynamically allocated buffer */
	if(patchFileName != NULL)
                snprintf(config_path,
                         MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
	else {
        	status = 0;
	}
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
    if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        /* 
         *  It is not necessary that Patch file be available, continue with PS Operations if.
         *  failed.
         */
        status = 0;

    } else {
        if(NULL == firmware || firmware->size == 0) {
            status = 0;
        } else {
            buffer = (A_UCHAR *)A_MALLOC(firmware->size);
            if(buffer != NULL) {
                /* Copy the read file to a local Dynamic buffer */
                memcpy(buffer,firmware->data,firmware->size);
                len = firmware->size;
                A_RELEASE_FIRMWARE(firmware);
                /* parse and store the Patch file contents to a global variables */
				patch_loc[0] = '\0';
                status = AthDoParsePatch(buffer,len, patch_loc);
		
                A_FREE(buffer);
            } else {
                A_RELEASE_FIRMWARE(firmware);
            }
        }
    }

    /* Create an HCI command list from the parsed PS and patch information */
    AthCreateCommandList(&HciCmdList,&numCmds);
#define CONFIG_PLATFORM 0x21
#define CONFIG_TLPM 0x23
#define PLATFORM_CONFIG_BIT 0x01
#define TLPM_CONFIG_BIT 0x02
#define IDLE_TIMEOUT_OFFSET 12
#define WAKEUP_TIMEOUT_OFFSET 8
#define IDLE_TIMEOUT_DEFAULT_VAL 1000
#define WAKEUP_TIMEOUT_DEFAULT_VAL 10

    hdev->IdleTimeout = IDLE_TIMEOUT_DEFAULT_VAL;
    hdev->WakeupTimeout = WAKEUP_TIMEOUT_DEFAULT_VAL;
    hdev->PwrMgmtEnabled = 0;

	ps_index = 2; /* CRC + PS Reset */
	if (Patch_Count)
		ps_index += Patch_Count + 1; /* Patches + Enable patch Cmd */

    for(i = ps_index; i <numCmds; i++) {

	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Check PS ID %x\n", HciCmdList[i].Hcipacket[4]));
        /* search for Platform config and TLPM tags */
        if((HciCmdList[i].Hcipacket[4] == CONFIG_PLATFORM) &&
            (HciCmdList[i].Hcipacket[5] == 0)) {
            cFlags |= PLATFORM_CONFIG_BIT;
            bit7 = (HciCmdList[i].Hcipacket[7]) & (1<<7);
            if(bit7) {
                hdev->PwrMgmtEnabled = 1;
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("CONFIG PLATFORM present and Pwr Manage %x\n", hdev->PwrMgmtEnabled));
		}
        }
        else if((HciCmdList[i].Hcipacket[4] == CONFIG_TLPM) &&
                (HciCmdList[i].Hcipacket[5] == 0)) {
            cFlags |= TLPM_CONFIG_BIT;
            hdev->IdleTimeout = *((A_UINT32 *)&HciCmdList[i].Hcipacket[IDLE_TIMEOUT_OFFSET + 7]);
            hdev->WakeupTimeout = *((A_UINT16 *)&HciCmdList[i].Hcipacket[WAKEUP_TIMEOUT_OFFSET + 7]);
		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("hdev->idletimeout %d hdev->WakeupTimeout %d",hdev->IdleTimeout, hdev->WakeupTimeout));
        }
    }


    /* Form the parameter for PSSendOps() API */
 

    /*
     * First Send the CRC packet, 
     * We have to continue with the PS operations only if the CRC packet has been replied with 
     * a Command complete event with status Error.
     */

    if(SendHCICommandWaitCommandComplete
    (hdev,
    HciCmdList[0].Hcipacket,
    HciCmdList[0].packetLen,
    &event,
    &bufferToFree) == A_OK) {
        if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */
            if(bufferToFree != NULL) {
                A_FREE(bufferToFree);
                }
#ifndef HCI_TRANSPORT_SDIO
			if(bdaddr && bdaddr[0] !='\0') {
				write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
			}
#endif 
               status = 1;
               goto complete;
        }
        if(bufferToFree != NULL) {
               A_FREE(bufferToFree);
        }
    } else {
        status = 0;
        goto complete;
    }
	/* Set Patch location */ 
	if(patch_loc[0] != '\0') {
    	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Setting Patch Location  %s\n", patch_loc));
		set_patch_ram(hdev,patch_loc,sizeof(patch_loc));
	}
    for(i = 1; i <numCmds; i++) {
    	Hci_log("PS/Patch Write -->",HciCmdList[i].Hcipacket,HciCmdList[i].packetLen);
        if(SendHCICommandWaitCommandComplete
        (hdev,
        HciCmdList[i].Hcipacket,
        HciCmdList[i].packetLen,
        &event,
        &bufferToFree) == A_OK) {
            if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
                if(bufferToFree != NULL) {
                    A_FREE(bufferToFree);
                    }
                   status = 1;
                    goto complete;
            }
            if(bufferToFree != NULL) {
                   A_FREE(bufferToFree);
            }
        } else {
            status = 0;
            goto complete;
        }
    }
#ifdef HCI_TRANSPORT_SDIO
	if(BDADDR == FALSE)
		if(hdev->bdaddr[0] !=0x00 ||
		   hdev->bdaddr[1] !=0x00 ||
		   hdev->bdaddr[2] !=0x00 ||
		   hdev->bdaddr[3] !=0x00 ||
		   hdev->bdaddr[4] !=0x00 ||
		   hdev->bdaddr[5] !=0x00)
			write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);


	/* if Platform config is present and TLPM is not available
	 * write HCI command for TLPM with default timeout values */
	if(bit7 && !(cFlags & TLPM_CONFIG_BIT)) {
		A_UCHAR TLPMHciCmd[] = {0x0b, 0xfc, 0x1c, 0x01, 0x23, 0x00, 0x18, 
			0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x0a, 0x00, 0x0a, 0x00, 0xe8, 0x03,
			0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xe8,
			0x03, 0x00, 0x00 };
		int CmdLen = sizeof(TLPMHciCmd);

		*((A_UINT32 *)&TLPMHciCmd[IDLE_TIMEOUT_OFFSET + 7]) = hdev->IdleTimeout;
		*((A_UINT16 *)&TLPMHciCmd[WAKEUP_TIMEOUT_OFFSET + 7]) = hdev->WakeupTimeout;

		if(SendHCICommandWaitCommandComplete
				(hdev,
				 TLPMHciCmd,
				 CmdLen,
				 &event,
				 &bufferToFree) == A_OK) {
			if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
				if(bufferToFree != NULL) {
					A_FREE(bufferToFree);
				}
				status = 1;
				goto complete;
			}
			if(bufferToFree != NULL) {
				A_FREE(bufferToFree);
			}
		} else {
			status = 0;
			goto complete;
		}
	}

#ifndef HCI_TRANSPORT_SDIO

	if(bdaddr && bdaddr[0] != '\0') {
		write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
	} else
#endif /* HCI_TRANSPORT_SDIO */
    /* Write BDADDR Read from OTP here */



#endif

	{
		 /* Read Contents of BDADDR file if user has not provided any option */
        snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
    	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR File Name %s\n", config_path));
    	if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
        	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        	goto complete;
    	}
    	if(NULL == firmware || firmware->size == 0) {
        	goto complete;
    	}
        len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size;
	memcpy(config_bdaddr, firmware->data,len);
	config_bdaddr[len] = '\0';
	write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
       	A_RELEASE_FIRMWARE(firmware);
	}
complete:
#ifndef HCI_TRANSPORT_SDIO
    AthEnableSyncCommandOp(FALSE);    
    PSTagMode = FALSE;
    wake_up_interruptible(&PsCompleteEvent);
#endif /* HCI_TRANSPORT_SDIO */
    if(NULL != HciCmdList) {
        AthFreeCommandList(&HciCmdList,numCmds);
    }
    if(path) {
        A_FREE(path);
    }
    if(config_path) {
        A_FREE(config_path);
    }
    return status;
}
Ejemplo n.º 19
0
A_STATUS
htcTargetInsertedHandler(HIF_DEVICE *device)
{
    HTC_TARGET *target;
    HTC_ENDPOINT *endPoint;
    A_UINT8 count1, count2;
    HTC_EVENT_INFO eventInfo;
    HTC_REG_BUFFER *regBuffer;
    HTC_QUEUE_ELEMENT *element;
    HTC_MBOX_BUFFER *mboxBuffer;
    HTC_REG_REQUEST_LIST *regList;
    HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue;
	HIF_REQUEST request;
	A_STATUS status;
    A_UINT32 address;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcTargetInserted - Enter\n");

    /* Initialize the locks */
    A_MUTEX_INIT(&instanceCS);
    A_MUTEX_INIT(&creditCS);
    A_MUTEX_INIT(&counterCS);
    A_MUTEX_INIT(&txCS);

    /* Allocate target memory */
    if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
        HTC_DEBUG_PRINTF(ATH_LOG_ERR, "Unable to allocate memory\n");
        return A_ERROR;
    }
    A_MEMZERO(target, sizeof(HTC_TARGET));
    target->device = device;
    target->ready = FALSE;

    /* Initialize the endpoints, mbox queues, event table */
    for (count1 = ENDPOINT1; count1 <= ENDPOINT4; count1 ++) {
        endPoint = &target->endPoint[count1];
        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "endPoint[%d]: %p\n", count1, endPoint);
        A_MEMZERO(endPoint->txCreditsAvailable, HTC_TX_CREDITS_NUM_MAX);
        endPoint->txCreditsConsumed = 0;
        endPoint->txCreditsIntrEnable = FALSE;
        endPoint->rxLengthPending = 0;
        endPoint->target = target;
        endPoint->enabled = FALSE;
        for (count2 = 0; count2<HTC_DATA_REQUEST_RING_BUFFER_SIZE; count2 ++) {
            /* Send Queue */
            sendQueue = &endPoint->sendQueue;
            sendQueue->head = sendQueue->size = 0;
            element = &sendQueue->element[count2];
            A_MEMZERO(element, sizeof(HTC_DATA_REQUEST_ELEMENT));
            element->buffer.free = TRUE;
            element->completionCB = htcTxCompletionCB;
            mboxBuffer = GET_MBOX_BUFFER(element);
            mboxBuffer->endPoint = endPoint;

            /* Receive Queue */
            recvQueue = &endPoint->recvQueue;
            recvQueue->head = recvQueue->size = 0;
            element = &recvQueue->element[count2];
            A_MEMZERO(element, sizeof(HTC_DATA_REQUEST_ELEMENT));
            element->buffer.free = TRUE;
            element->completionCB = htcRxCompletionCB;
            mboxBuffer = GET_MBOX_BUFFER(element);
            mboxBuffer->endPoint = endPoint;
        }
        A_MEMZERO(&target->endPoint[count1].eventTable, 
                  sizeof(HTC_ENDPOINT_EVENT_TABLE));
    }

    /* Populate the block size for each of the end points */
    endPoint = &target->endPoint[ENDPOINT1];
    endPoint->blockSize = HIF_MBOX0_BLOCK_SIZE;
    endPoint = &target->endPoint[ENDPOINT2];
    endPoint->blockSize = HIF_MBOX1_BLOCK_SIZE;
    endPoint = &target->endPoint[ENDPOINT3];
    endPoint->blockSize = HIF_MBOX2_BLOCK_SIZE;
    endPoint = &target->endPoint[ENDPOINT4];
    endPoint->blockSize = HIF_MBOX3_BLOCK_SIZE;

    /* Initialize the shadow copy of the target register table */
    A_MEMZERO(&target->table, sizeof(HTC_REGISTER_TABLE));

    /* Initialize the register request list */
    regList = &target->regList;
    for (count1 = 0; count1 < HTC_REG_REQUEST_LIST_SIZE; count1 ++) {
        element = &regList->element[count1];
        A_MEMZERO(element, sizeof(HTC_REG_REQUEST_ELEMENT));
        element->buffer.free = TRUE;
        element->completionCB = htcRegCompletionCB;
        regBuffer = GET_REG_BUFFER(element);
        regBuffer->target = target;
    }

    /* Add the target instance to the global list */
    addTargetInstance(target);

    /* Disable all the dragon interrupts */
    target->table.int_status_enable = 0;
    target->table.cpu_int_status_enable = 0;
    target->table.error_status_enable = 0;
    target->table.counter_int_status_enable = 0;
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          &target->table.int_status_enable, 4, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);

    /* 
     * Frame a TARGET_AVAILABLE event and send it to the host. Return the
     * HIF_DEVICE handle as a parameter with the event.
     */
    FRAME_EVENT(eventInfo, (A_UCHAR *)device, sizeof(HIF_DEVICE *), 
                sizeof(HIF_DEVICE *), A_OK, NULL);
    dispatchEvent(target, ENDPOINT_UNUSED, HTC_TARGET_AVAILABLE, &eventInfo);

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcTargetInserted - Exit\n");

    return A_OK;
}
Ejemplo n.º 20
0
int PSSendOps(void *arg) 
{
    int i;
    int status = 0;
    PSCmdPacket *HciCmdList; /* List storing the commands */
    const struct firmware* firmware;
    A_UINT32 numCmds;
    A_UINT8 *event;
    A_UINT8 *bufferToFree;
    struct hci_dev *device;
    A_UCHAR *buffer;
    A_UINT32 len;
    A_UINT32 DevType;
    A_UCHAR *PsFileName;
    A_UCHAR *patchFileName;
    AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg;
    struct device *firmwareDev = NULL;
    status = 0;
    HciCmdList = NULL;
#ifdef HCI_TRANSPORT_SDIO
    device = hdev->pBtStackHCIDev; 
    firmwareDev = device->parent;
#else 
    device = hdev;
    firmwareDev = &device->dev;
    AthEnableSyncCommandOp(TRUE);    
#endif /* HCI_TRANSPORT_SDIO */
    /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
     */ 
    if(A_ERROR == getDeviceType(hdev,&DevType)) {
        status = 1;
        goto complete;
    }
    if(A_ERROR == ReadVersionInfo(hdev)) {
        status = 1;
        goto complete;
    }
    patchFileName = PATCH_FILE;
    if(DevType){
        if(DevType == 0xdeadc0de){
	        PsFileName =  PS_ASIC_FILE;
	    } else{
    		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x  \n",Rom_Version,Build_Version));
                if((Rom_Version == 0x99999999) && (Build_Version == 1)){
                        
    			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
    			patchFileName = NULL;
		}
	        PsFileName =  PS_FPGA_FILE;
	    }
    }
    else{
	    PsFileName =  PS_ASIC_FILE;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,PsFileName));
    /* Read the PS file to a dynamically allocated buffer */
    if(request_firmware(&firmware,PsFileName,firmwareDev) < 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        status = 1;
        goto complete;

    }
    if(NULL == firmware || firmware->size == 0) {
        status = 1;
        goto complete;
    }
    buffer = (A_UCHAR *)A_MALLOC(firmware->size);
    if(buffer != NULL) {
    /* Copy the read file to a local Dynamic buffer */
        memcpy(buffer,firmware->data,firmware->size);
        len = firmware->size;
        release_firmware(firmware);
        /* Parse the PS buffer to a global variable */
        status = AthDoParsePS(buffer,len);
        A_FREE(buffer);
    } else {
        release_firmware(firmware);
    }


    /* Read the patch file to a dynamically allocated buffer */
    if((patchFileName == NULL) || (request_firmware(&firmware,patchFileName,firmwareDev) < 0)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        /* 
         *  It is not necessary that Patch file be available, continue with PS Operations if.
         *  failed.
         */
        status = 0;

    } else {
        if(NULL == firmware || firmware->size == 0) {
            status = 0;
        } else {
            buffer = (A_UCHAR *)A_MALLOC(firmware->size);
            if(buffer != NULL) {
                /* Copy the read file to a local Dynamic buffer */
                memcpy(buffer,firmware->data,firmware->size);
                len = firmware->size;
                release_firmware(firmware);
                /* parse and store the Patch file contents to a global variables */
                status = AthDoParsePatch(buffer,len);
                A_FREE(buffer);
            } else {
                release_firmware(firmware);
            }
        }
    }

    /* Create an HCI command list from the parsed PS and patch information */
    AthCreateCommandList(&HciCmdList,&numCmds);

    /* Form the parameter for PSSendOps() API */
 

    /*
     * First Send the CRC packet, 
     * We have to continue with the PS operations only if the CRC packet has been replied with 
     * a Command complete event with status Error.
     */

    if(SendHCICommandWaitCommandComplete
    (hdev,
    HciCmdList[0].Hcipacket,
    HciCmdList[0].packetLen,
    &event,
    &bufferToFree) == A_OK) {
        if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */
            if(bufferToFree != NULL) {
                A_FREE(bufferToFree);
                }
#ifndef HCI_TRANSPORT_SDIO
				if(bdaddr[0] !='\0') {
					write_bdaddr(hdev,bdaddr);
				}
#endif 
               status = 1;
               goto complete;
        }
        if(bufferToFree != NULL) {
               A_FREE(bufferToFree);
        }
    } else {
        status = 0;
        goto complete;
    }
 
    for(i = 1; i <numCmds; i++) {
    
        if(SendHCICommandWaitCommandComplete
        (hdev,
        HciCmdList[i].Hcipacket,
        HciCmdList[i].packetLen,
        &event,
        &bufferToFree) == A_OK) {
            if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
                if(bufferToFree != NULL) {
                    A_FREE(bufferToFree);
                    }
                   status = 1;
                    goto complete;
            }
            if(bufferToFree != NULL) {
                   A_FREE(bufferToFree);
            }
        } else {
            status = 0;
            goto complete;
        }
    }
#ifndef HCI_TRANSPORT_SDIO
	if(bdaddr[0] != '\0') {
		write_bdaddr(hdev,bdaddr);
	} else
#endif /* HCI_TRANSPORT_SDIO */
	{
		 /* Read Contents of BDADDR file if user has not provided any option */
    	if(request_firmware(&firmware,BDADDR_FILE,firmwareDev) < 0) {
        	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        	status = 1;
        	goto complete;
    	}
    	if(NULL == firmware || firmware->size == 0) {
        	status = 1;
        	goto complete;
    	}
		write_bdaddr(hdev,(A_UCHAR *)firmware->data);
       	release_firmware(firmware);
	}
complete:
#ifndef HCI_TRANSPORT_SDIO
    AthEnableSyncCommandOp(FALSE);    
    PSTagMode = FALSE;
    wake_up_interruptible(&PsCompleteEvent);
#endif /* HCI_TRANSPORT_SDIO */
    if(NULL != HciCmdList) {
        AthFreeCommandList(&HciCmdList,numCmds);
    }
    return status;
}
Ejemplo n.º 21
0
A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
                                           A_UINT8          *pHCICommand,
                                           int              CmdLength,
                                           A_UINT8          **ppEventBuffer,
                                           A_UINT8          **ppBufferToFree)
{
    A_STATUS    status = A_OK;
    A_UINT8     *pBuffer = NULL;
    A_UINT8     *pTemp;
    int         length;
    A_BOOL      commandComplete = FALSE;
    A_UINT8     opCodeBytes[2];

    do {

        length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
        length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
        length += pConfig->pHCIProps->IOBlockPad;

        pBuffer = (A_UINT8 *)A_MALLOC(length);
        if (NULL == pBuffer) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n"));
            status = A_NO_MEMORY;
            break;
        }

            /* get the opcodes to check the command complete event */
        opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET];
        opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET];

            /* copy HCI command */
        A_MEMCPY(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);
            /* send command */
        status = SendHCICommand(pConfig,
                                pBuffer + pConfig->pHCIProps->HeadRoom,
                                CmdLength);
        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status));
            AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
            break;
        }

            /* reuse buffer to capture command complete event */
        A_MEMZERO(pBuffer,length);
        status = RecvHCIEvent(pConfig,pBuffer,&length);
        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n"));
            AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
            break;
        }

        pTemp = pBuffer + pConfig->pHCIProps->HeadRoom;
        if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) {
            if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) &&
                (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) {
                commandComplete = TRUE;
            }
        }

        if (!commandComplete) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0]));
            AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event");
            status = A_ECOMM;
            break;
        }

        if (ppEventBuffer != NULL) {
                /* caller wants to look at the event */
            *ppEventBuffer = pTemp;
            if (ppBufferToFree == NULL) {
                status = A_EINVAL;
                break;
            }
                /* caller must free the buffer */
            *ppBufferToFree = pBuffer;
            pBuffer = NULL;
        }

    } while (FALSE);

    if (pBuffer != NULL) {
        A_FREE(pBuffer);
    }

    return status;
}
Ejemplo n.º 22
0
A_STATUS download_binary (HIF_DEVICE *hifDevice,
                          A_UINT32 address,
                          wchar_t *fileName,
                          wchar_t *fileRoot,
                          A_BOOL  bCompressed,
                          AR6K_BIN_CACHE_INFO *pBinCache)
{
    A_STATUS status = A_OK;
    A_UCHAR  *buffer = NULL;
    A_UINT32 length = 0;
    A_UINT32 fileSize = 0;
    A_UINT32 next_address=0;
    A_INT32 file_left = 0;
    size_t nSize;
    wchar_t filePath[128];
    HANDLE fd = NULL;
    BY_HANDLE_FILE_INFORMATION finfo;
    A_BOOL  fillCache = FALSE;

    A_MEMZERO(&finfo, sizeof(finfo));
    if ( wcslen(fileName) + wcslen(fileRoot) > 127 )
    {
         ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Name Very Long :: ====>");
         return A_ERROR;
    }

    wcscpy(filePath,fileRoot);
    wcscat(filePath,fileName);


    ATHR_DISPLAY_MSG (L"file %s \n",filePath);
    do
    {
        if (pBinCache->Valid) {

                /* binary cache is valid */
            if (bCompressed) {
                status = BMILZStreamStart (hifDevice, address);
                if (A_FAILED(status)) {
                    break;
                }
            }

            if (bCompressed) {
                A_UINT32  lastWord = 0;
                A_UINT32  lastWordOffset = pBinCache->ActualLength & ~0x3;
                A_UINT32  unalignedBytes = pBinCache->ActualLength & 0x3;

                if (unalignedBytes) {
                        /* copy the last word into a zero padded buffer */
                    A_MEMCPY(&lastWord,
                             &pBinCache->pData[lastWordOffset],
                             unalignedBytes);
                }

                status = BMILZData(hifDevice,
                                   pBinCache->pData,
                                   lastWordOffset);

                if (A_FAILED(status)) {
                    break;
                }

                if (unalignedBytes) {
                    status = BMILZData(hifDevice,
                                       (A_UINT8 *)&lastWord,
                                       4);
                }

            } else {
                status = BMIWriteMemory(hifDevice,
                                        address,
                                        pBinCache->pData,
                                        A_ROUND_UP(pBinCache->ActualLength,4));
            }

            if (bCompressed && A_SUCCESS(status)) {
                //
                // Close compressed stream and open a new (fake) one.  This serves mainly to flush Target caches.
                //
                status = BMILZStreamStart (hifDevice, 0x00);
                if (A_FAILED(status)) {
                    break;
                }
            }

                /* all done */
            break;
        }

        //Determine the length of the file
        if ( (fd = CreateFile (filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
        {
            status = A_ERROR;
            ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Not Found :: ====> %s", filePath);
            break;
        }

        if (!GetFileInformationByHandle(fd, &finfo))
        {
            ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Size Error :: ====> %s", filePath);
            status = A_ERROR;
            break;
        }
        fileSize = finfo.nFileSizeLow;
        file_left = fileSize;

        if ((pBinCache->pData != NULL) && (!pBinCache->Static)) {
            /* binary caching is supported */
            A_ASSERT(!pBinCache->Valid);

            if (fileSize <= pBinCache->MaxLength) {
                    /* size if good, flag to cache this binary when read from the filesystem */
                fillCache = TRUE;
                pBinCache->ActualLength = 0; /* reset */
            } else {
                    /* cache is not big enough to hold data */
                A_ASSERT(FALSE);
                ATHR_DISPLAY_MSG (L"AR6K::WARNING!!!! :: File :%s (%d bytes) too big for cache (max=%d)",
                         filePath, fileSize, pBinCache->MaxLength);
            }
        }

        //
        // zero data buffer and init length
        //
        buffer = (A_UCHAR *)A_MALLOC(MAX_BUF);
        if (NULL == buffer)
        {
            status = A_ERROR;
            break;
        }

        if (bCompressed)
        {
            status = BMILZStreamStart (hifDevice, address);
            if (status != A_OK)
            {
                break;
            }
        }


        while (file_left)
        {
            length  = (file_left < (MAX_BUF)) ? file_left : MAX_BUF;
            if (bCompressed)
            {
                //
                // 0 pad last word of data to avoid messy uncompression
                //
                ((A_UINT32 *)buffer)[((length-1)/4)] = 0;
            }

            if (!ReadFile( fd, buffer, length, &nSize, NULL) || nSize != length)
            {
                ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: ReadFile Error :: ====>");
                status = A_ERROR;
                break;
            }
            next_address = address + fileSize - file_left;

            //
            // We round up the requested length because some SDIO Host controllers can't handle other lengths.
            // This generally isn't a problem for users, but it's something to be aware of.
            //
            length = A_ROUND_UP(length, 4);

            if (bCompressed)
            {
                status = BMILZData(hifDevice, buffer, length);
            }
            else
            {
                status = BMIWriteMemory(hifDevice, next_address, buffer, length);
            }

            if (status != A_OK)
            {
               break;
            }

            if (fillCache) {
                CopyChunkToBinCache(pBinCache, buffer, length);
            }

            if (file_left >= MAX_BUF)
            {
                file_left = file_left - MAX_BUF;
            }
            else
            {
                file_left = 0;
            }

        };

        if (status != A_OK)
        {
            break;
        }

        if (fillCache) {
                /* cache was filled, mark it valid */
            pBinCache->Valid = TRUE;
        }

        if (bCompressed)
        {
            //
            // Close compressed stream and open a new (fake) one.  This serves mainly to flush Target caches.
            //
            status = BMILZStreamStart (hifDevice, 0x00);
            if (status != A_OK)
            {
                break;
            }
        }

    } while (FALSE);

    if (buffer)
    {
        free (buffer);
        buffer = NULL;
    }
    if (fd)
    {
        CloseHandle (fd);
    }

    return status;
}
Ejemplo n.º 23
0
A_STATUS apply_patch (HIF_DEVICE *hifDevice,
                      A_UINT32 TargetVersion,
                      wchar_t *patchFile,
                      wchar_t *fileRoot,
                      AR6K_BIN_CACHE_INFO *pRomCache)
{
    A_STATUS status = A_OK;
    HANDLE fd = INVALID_HANDLE_VALUE;
    wchar_t filePath[128];
    A_UINT32 ret = 0;
    A_UINT32 id = 0;
    A_UINT32 tpid = 0;
    A_UINT32 chkSum = 0;
    A_UINT32 count = 0;
    A_UINT32 max = 0;
    A_UINT32 cmd = 0;
    A_UINT32 romAddr = 0;
    A_UINT32 ramAddr = 0;
    A_UINT32 reMapSz = 0;
    A_UCHAR  *buffer = NULL;
    A_UINT32 length = 0;
    A_UINT32 i = 0;
    BY_HANDLE_FILE_INFORMATION finfo;
    A_UINT32 fileSize = 0;

    do
    {
        if (pRomCache->Valid) {
            buffer = pRomCache->pData;
            fileSize = pRomCache->ActualLength;
        } else {
            if ( wcslen(patchFile) + wcslen(fileRoot) > 127 )
            {
                 ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Name Very Long :: ====>");
                return A_ERROR;
            }

            wcscpy(filePath,fileRoot);
            wcscat(filePath,patchFile);

            ATHR_DISPLAY_MSG (L"file %s \n",filePath);
            //Read the patch distribution file
            if ( (fd = CreateFile (filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
            {
                ATHR_DISPLAY_MSG (L"CAR6K:: No Patch File :: ====> %s", filePath);
                break;
            }

            if (!GetFileInformationByHandle(fd, &finfo))
            {
                ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Size Error :: ====> %s", filePath);
                status = A_ERROR;
                break;
            }
            fileSize = finfo.nFileSizeLow;
            if ((buffer=A_MALLOC(fileSize)) == NULL)
            {
                ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable allocated memory :: ====> %d",fileSize);
                status = A_ERROR;
                break;
            }
            if ( !ReadFile(fd, buffer, fileSize, &ret, NULL) || (ret != fileSize))
            {
                ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable to read rpdf ID from :: ====> %s",filePath);
                status = A_ERROR;
                break;
            }
            if (pRomCache->Static)
            {
                pRomCache->Valid = TRUE;
                pRomCache->pData = buffer;
                pRomCache->ActualLength = fileSize;
                pRomCache->MaxLength = fileSize;
            }
        }
        id = *((A_UINT32 *)buffer);
        buffer += sizeof(id);

        chkSum = *((A_UINT32 *)buffer);
        buffer += sizeof(chkSum);

        count = *((A_UINT32 *)buffer);
        buffer += sizeof(count);

        if ( TargetVersion == AR6002_VERSION_REV2 )
        {
             max = AR6002_REV2_MAX_PATCHES;
        }

        if (count > max)
        {
            ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Maximum patches supported :: %d ====> %d",max,count);
            status = A_ERROR;
            break;
        }

        for (; count; count--)
        {
            cmd = 0;
            romAddr = 0;
            ramAddr = 0;
            reMapSz = 0;
            length = 0;
            tpid = 0;

            cmd = *((A_UINT32 *)buffer);
            buffer += sizeof(cmd);

            if ( cmd != RPDF_CMD_INSTALL && cmd != RPDF_CMD_INST_ACT )
            {
                ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unknown command in patch specification :: ====> %d",cmd);
                status = A_ERROR;
                break;
            }

            reMapSz= *((A_UINT32 *)buffer);
            buffer += sizeof(reMapSz);

            if ( reMapSz == 0 || reMapSz & (reMapSz-1) )
            {
                ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Invalid remap size :: ====> 0x%x",reMapSz);
                status = A_ERROR;
                break;
            }

            romAddr= *((A_UINT32 *)buffer);
            buffer += sizeof(romAddr);

            ramAddr= *((A_UINT32 *)buffer);
            buffer += sizeof(ramAddr);

            length= *((A_UINT32 *)buffer);
            buffer += sizeof(length);

            if (length > 0)
            {
                status = BMIWriteMemory(hifDevice, ramAddr, buffer, length);
                if (status != A_OK)
                {
                    ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable write patch to target :: ====> ");
                    break;
                }

                buffer += length;
            }

            if (cmd == RPDF_CMD_INST_ACT || cmd == RPDF_CMD_INSTALL)
            {
                status = BMIrompatchInstall(hifDevice, romAddr, ramAddr, reMapSz, 0, &tpid);
                if (status != A_OK)
                {
                    ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable write patch registers in target :: ====> ");
                    break;
                }

                InstalledPatches[NumPatches++] = tpid;
            }

            if (cmd == RPDF_CMD_INST_ACT && NumPatches)
            {
                status = BMIrompatchActivate(hifDevice, NumPatches, InstalledPatches);
                if (status != A_OK)
                {
                    ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable activate patch in target :: ====> ");
                    break;
                }
            }
        }
    } while (FALSE);

    if ((!pRomCache->Valid) && (buffer))
    {
       A_FREE(buffer);
    }

    if (fd)
    {
       CloseHandle (fd);
    }
    NumPatches = 0;

    return status;
}
Ejemplo n.º 24
0
int ar6000_htc_raw_open(AR_SOFTC_T *ar)
{
    A_STATUS status;
    int streamID, endPt, count2;
    raw_htc_buffer *buffer;
    HTC_SERVICE_ID servicepriority;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;
    if (!arRaw) {
        arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
        if (arRaw) {
            A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
        }
    }
    A_ASSERT(ar->arHtcTarget != NULL);
    if (!arRaw) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
        return -ENOMEM;
    }
    /* wait for target */
    status = HTCWaitTarget(ar->arHtcTarget);

    if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
        return -ENODEV;
    }

    for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
        arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
    }

    for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
        /* Initialize the data structures */
        init_MUTEX(&arRaw->raw_htc_read_sem[streamID]);
        init_MUTEX(&arRaw->raw_htc_write_sem[streamID]);
        init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
        init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);

        /* try to connect to the raw service */
        status = ar6000_connect_raw_service(ar,streamID);

        if (A_FAILED(status)) {
            break;
        }

        if (arRawStream2EndpointID(ar,streamID) == 0) {
            break;
        }

        for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
            /* Initialize the receive buffers */
            buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
            memset(buffer, 0, sizeof(raw_htc_buffer));
            buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
            memset(buffer, 0, sizeof(raw_htc_buffer));

            SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
                                          buffer,
                                          buffer->data,
                                          HTC_RAW_BUFFER_SIZE,
                                          arRawStream2EndpointID(ar,streamID));

            /* Queue buffers to HTC for receive */
            if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK)
            {
                BMIInit();
                return -EIO;
            }
        }

        for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
            /* Initialize the receive buffers */
            buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
            memset(buffer, 0, sizeof(raw_htc_buffer));
        }

        arRaw->read_buffer_available[streamID] = FALSE;
        arRaw->write_buffer_available[streamID] = TRUE;
    }

    if (A_FAILED(status)) {
        return -EIO;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));

    servicepriority = HTC_RAW_STREAMS_SVC;  /* only 1 */

    /* set callbacks and priority list */
    HTCSetCreditDistribution(ar->arHtcTarget,
                             ar,
                             NULL,  /* use default */
                             NULL,  /* use default */
                             &servicepriority,
                             1);

    /* Start the HTC component */
    if ((status = HTCStart(ar->arHtcTarget)) != A_OK) {
        BMIInit();
        return -EIO;
    }

    (ar)->arRawIfInit = TRUE;

    return 0;
}
Ejemplo n.º 25
0
int PSSendOps(void *arg) 
{
    int i;
    int status = 0;
    struct ps_cmd_packet *HciCmdList; /* List storing the commands */
    const struct firmware* firmware;
    u32 numCmds;
    u8 *event;
    u8 *bufferToFree;
    struct hci_dev *device;
    u8 *buffer;
    u32 len;
    u32 DevType;
    u8 *PsFileName;
    u8 *patchFileName;
    u8 *path = NULL;
    u8 *config_path = NULL;
    u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
    struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg;
    struct device *firmwareDev = NULL;
    status = 0;
    HciCmdList = NULL;
#ifdef HCI_TRANSPORT_SDIO
    device = hdev->pBtStackHCIDev; 
    firmwareDev = device->parent;
#else 
    device = hdev;
    firmwareDev = &device->dev;
    AthEnableSyncCommandOp(true);
#endif /* HCI_TRANSPORT_SDIO */
    /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
     */

    path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN);
    if(path == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
        goto complete;
    }
    config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN);
    if(config_path == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
        goto complete;
    }

    if(A_ERROR == getDeviceType(hdev,&DevType)) {
        status = 1;
        goto complete;
    }
    if(A_ERROR == ReadVersionInfo(hdev)) {
        status = 1;
        goto complete;
    }

    patchFileName = PATCH_FILE;
    snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
    if(DevType){
        if(DevType == 0xdeadc0de){
	        PsFileName =  PS_ASIC_FILE;
	    } else{
    		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x  \n",Rom_Version,Build_Version));
                if((Rom_Version == 0x99999999) && (Build_Version == 1)){
                        
    			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
    			patchFileName = NULL;
		}
	        PsFileName =  PS_FPGA_FILE;
	    }
    }
    else{
	    PsFileName =  PS_ASIC_FILE;
    }

    snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
    /* Read the PS file to a dynamically allocated buffer */
    if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        status = 1;
        goto complete;

    }
    if(NULL == firmware || firmware->size == 0) {
        status = 1;
        goto complete;
    }
    buffer = (u8 *)A_MALLOC(firmware->size);
    if(buffer != NULL) {
    /* Copy the read file to a local Dynamic buffer */
        memcpy(buffer,firmware->data,firmware->size);
        len = firmware->size;
        A_RELEASE_FIRMWARE(firmware);
        /* Parse the PS buffer to a global variable */
        status = AthDoParsePS(buffer,len);
        kfree(buffer);
    } else {
        A_RELEASE_FIRMWARE(firmware);
    }


    /* Read the patch file to a dynamically allocated buffer */
	if(patchFileName != NULL)
                snprintf(config_path,
                         MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
	else {
        	status = 0;
	}
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
    if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        /* 
         *  It is not necessary that Patch file be available, continue with PS Operations if.
         *  failed.
         */
        status = 0;

    } else {
        if(NULL == firmware || firmware->size == 0) {
            status = 0;
        } else {
            buffer = (u8 *)A_MALLOC(firmware->size);
            if(buffer != NULL) {
                /* Copy the read file to a local Dynamic buffer */
                memcpy(buffer,firmware->data,firmware->size);
                len = firmware->size;
                A_RELEASE_FIRMWARE(firmware);
                /* parse and store the Patch file contents to a global variables */
                status = AthDoParsePatch(buffer,len);
                kfree(buffer);
            } else {
                A_RELEASE_FIRMWARE(firmware);
            }
        }
    }

    /* Create an HCI command list from the parsed PS and patch information */
    AthCreateCommandList(&HciCmdList,&numCmds);

    /* Form the parameter for PSSendOps() API */
 

    /*
     * First Send the CRC packet, 
     * We have to continue with the PS operations only if the CRC packet has been replied with 
     * a Command complete event with status Error.
     */

    if(SendHCICommandWaitCommandComplete
    (hdev,
    HciCmdList[0].Hcipacket,
    HciCmdList[0].packetLen,
    &event,
    &bufferToFree) == 0) {
        if(ReadPSEvent(event) == 0) { /* Exit if the status is success */
            if(bufferToFree != NULL) {
                kfree(bufferToFree);
                }
	
#ifndef HCI_TRANSPORT_SDIO
			if(bdaddr && bdaddr[0] !='\0') {
				write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
			}
#endif 
               status = 1;
               goto complete;
        }
        if(bufferToFree != NULL) {
               kfree(bufferToFree);
        }
    } else {
        status = 0;
        goto complete;
    }
 
    for(i = 1; i <numCmds; i++) {
    
        if(SendHCICommandWaitCommandComplete
        (hdev,
        HciCmdList[i].Hcipacket,
        HciCmdList[i].packetLen,
        &event,
        &bufferToFree) == 0) {
            if(ReadPSEvent(event) != 0) { /* Exit if the status is success */
                if(bufferToFree != NULL) {
                    kfree(bufferToFree);
                    }
                   status = 1;
                    goto complete;
            }
            if(bufferToFree != NULL) {
                   kfree(bufferToFree);
            }
        } else {
            status = 0;
            goto complete;
        }
    }
#ifdef HCI_TRANSPORT_SDIO
	if(BDADDR == false)
		if(hdev->bdaddr[0] !=0x00 ||
		   hdev->bdaddr[1] !=0x00 ||
		   hdev->bdaddr[2] !=0x00 ||
		   hdev->bdaddr[3] !=0x00 ||
		   hdev->bdaddr[4] !=0x00 ||
		   hdev->bdaddr[5] !=0x00)
			write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);

#ifndef HCI_TRANSPORT_SDIO

	if(bdaddr && bdaddr[0] != '\0') {
		write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
	} else
#endif /* HCI_TRANSPORT_SDIO */
    /* Write BDADDR Read from OTP here */



#endif

	{
		 /* Read Contents of BDADDR file if user has not provided any option */
        snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
    	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
    	if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
        	AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
        	status = 1;
        	goto complete;
    	}
    	if(NULL == firmware || firmware->size == 0) {
        	status = 1;
        	goto complete;
    	}
	len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1);
	memcpy(config_bdaddr, firmware->data, len);
	config_bdaddr[len] = '\0';
	write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
       	A_RELEASE_FIRMWARE(firmware);
	}
complete:
#ifndef HCI_TRANSPORT_SDIO
    AthEnableSyncCommandOp(false);
    PSTagMode = false;
    wake_up_interruptible(&PsCompleteEvent);
#endif /* HCI_TRANSPORT_SDIO */
    if(NULL != HciCmdList) {
        AthFreeCommandList(&HciCmdList,numCmds);
    }
    if(path) {
        kfree(path);
    }
    if(config_path) {
        kfree(config_path);
    }
    return status;
}
Ejemplo n.º 26
0
NDIS_STATUS
busDriverInit (NDIS_HANDLE miniportHandle, 
               NDIS_HANDLE wrapperConfigurationContext, 
               A_UINT32   sysIntr,
               BUS_DRIVER_HANDLE *busDriverHandle)
{
    PNDIS_RESOURCE_LIST pNdisResourceList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR pResourceDesc;
    NDIS_PHYSICAL_ADDRESS           physicalAddress;
    A_UINT32						bufferSize;
    A_UINT32						dwResourceCount;
    NDIS_STATUS                     status=NDIS_STATUS_FAILURE;
    A_UINT32						addressSpace;

    *busDriverHandle = NULL;
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
                        "ar6000CFBusInit: Enter \n");

    cfDevice = A_MALLOC(sizeof(CF_DEVICE));
    if (cfDevice == NULL) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,
            "ar6000CFBusInit: Allocate Memory for CF_DEVICE failed\n");
        return status; 
	}
    A_MEMZERO(cfDevice,sizeof(CF_DEVICE));

    cfDevice->miniportHandle = miniportHandle;
    cfDevice->wrapperConfigurationContext=wrapperConfigurationContext;

	pNdisResourceList = NULL;
	bufferSize = 0;

	//	First call is just to determine buffer size
    NdisMQueryAdapterResources(
            &status,
            wrapperConfigurationContext,
            pNdisResourceList,
            &bufferSize);

    pNdisResourceList = A_MALLOC(bufferSize);

    if (pNdisResourceList == NULL) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR, 
            "ar6000CFBusInit: AllocateMemory for NDIS_RESOURCE_LIST failed\n");
        A_FREE(cfDevice);
        return NDIS_STATUS_FAILURE;
    }

    NdisMQueryAdapterResources(
            &status,
            wrapperConfigurationContext,
            pNdisResourceList,
            &bufferSize);

    if (status != NDIS_STATUS_SUCCESS) {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR, 
            "ar6000CFBusInit: NdisMQueryAdapterResources failed \n");
        A_FREE(pNdisResourceList);
        A_FREE(cfDevice);
        return status; 
    }

    /* Search for I/O address and IRQ in assigned resources. */
    
    dwResourceCount = pNdisResourceList->Count;
    pResourceDesc = &(pNdisResourceList->PartialDescriptors[0]);

    while (dwResourceCount--) {
        switch(pResourceDesc->Type) {
            case CmResourceTypeInterrupt:
                cfDevice->interruptNumber = 
                    pResourceDesc->u.Interrupt.Vector;
                HIF_DEBUG_PRINTF(ATH_LOG_INF,
                    "ar6000CFBusInit: Interrupt Number = %u\n", cfDevice->interruptNumber);
                break;

            case CmResourceTypeMemory:
                cfDevice->memLen = pResourceDesc->u.Memory.Length;
                cfDevice->deviceMemBase = pResourceDesc->u.Memory.Start.LowPart;
                HIF_DEBUG_PRINTF(ATH_LOG_INF,
				    "ar6000CFBusInit: Physical Address = %x Length = %x\n", 
                        cfDevice->deviceMemBase,cfDevice->memLen);
                break;
        
            default:
                HIF_DEBUG_PRINTF(ATH_LOG_ERR,
                    "ar6000CFBusInit: Unexpected assigned resource type %u\n", 
                    pResourceDesc->Type);
                break;
        }
        pResourceDesc++;
    }

    A_FREE(pNdisResourceList);

    cfDevice->sysIntr =  sysIntr;
    HIF_DEBUG_PRINTF(ATH_LOG_INF,
        "ar6000CFBusInit: sysIntr = %u\n", cfDevice->sysIntr);
    
    NdisSetPhysicalAddressLow(physicalAddress, cfDevice->deviceMemBase);
    NdisSetPhysicalAddressHigh(physicalAddress, 0);

    cfDevice->ndisMapped = 1;
    status = NdisMMapIoSpace((PVOID *)&cfDevice->mappedMemBase,
                            cfDevice->miniportHandle,
                            physicalAddress,
                            cfDevice->memLen);
    if (status != NDIS_STATUS_SUCCESS) {
		HIF_DEBUG_PRINTF(ATH_LOG_ERR,
				"ar6000CFBusInit: NdisMmapIoSpace failed.. Trying MmMapIoSpace \n");
        /* NdisMmapIoSpace fails sometimes in WINCE, type MmMapIoSpace */
	    cfDevice->mappedMemBase = (A_UINT32) MmMapIoSpace(physicalAddress,
                                                          cfDevice->memLen,
                                                          FALSE);
        if (!cfDevice->mappedMemBase) {
            HIF_DEBUG_PRINTF(ATH_LOG_ERR,
                "ar6000CFBusInit: MmMapIoSpace failed \n");
            A_FREE(cfDevice);
            return NDIS_STATUS_FAILURE;
        } 
        cfDevice->ndisMapped = 0;
    } 

	 addressSpace = 0;
#ifdef SHARED_INTERRUPTS
#if (UNDER_CE==600) 
	giisrMappedAddress = (PVOID)cfDevice->mappedMemBase;
#else
    if (!TransBusAddrToStatic(PCIBus,
						 0,
						 physicalAddress,
						 cfDevice->memLen,
						 &addressSpace,
						 &giisrMappedAddress)) 
    {
        HIF_DEBUG_PRINTF(ATH_LOG_ERR,
                "ar6000CFBusInit : TransBusAddrToStatic failed \n");
        A_FREE(cfDevice);
        return NDIS_STATUS_FAILURE;
    }
#endif //UNDER_CE
#endif //SHARED_INTERRUPTS

    *busDriverHandle = (BUS_DRIVER_HANDLE)cfDevice;
    
    HIF_DEBUG_PRINTF(ATH_LOG_TRC,
                        "ar6000CFBusInit: Exit \n");
    return NDIS_STATUS_SUCCESS;
}
Ejemplo n.º 27
0
/* registered target arrival callback from the HIF layer */
HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo)
{
    HTC_TARGET              *target = NULL;
    A_STATUS                 status = A_OK;
    int                      i;
    A_UINT32                 ctrl_bufsz;
    A_UINT32                 blocksizes[HTC_MAILBOX_NUM_MAX];

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n"));
	printk("HTCCreate !!\n");

    do {

            /* allocate target memory */
        if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) 
		{
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
            status = A_ERROR;
            break;
        }

        A_MEMZERO(target, sizeof(HTC_TARGET));
        A_MUTEX_INIT(&target->HTCLock);
        A_MUTEX_INIT(&target->HTCRxLock);
        A_MUTEX_INIT(&target->HTCTxLock);
        INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);
        INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList);

            /* give device layer the hif device handle */
        target->Device.HIFDevice = hif_handle;
            /* give the device layer our context (for event processing)
             * the device layer will register it's own context with HIF
             * so we need to set this so we can fetch it in the target remove handler */
        target->Device.HTCContext = target;
            /* set device layer target failure callback */
        target->Device.TargetFailureCallback = HTCReportFailure;
            /* set device layer recv message pending callback */
        target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler;
        target->EpWaitingForBuffers = ENDPOINT_MAX;

        A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
          
            /* setup device layer */
        status = DevSetup(&target->Device);

        if (A_FAILED(status)) {
            break;
        }


        /* get the block sizes */
        status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
                                    blocksizes, sizeof(blocksizes));
        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n"));
            break;
        }

        /* Set the control buffer size based on the block size */
        if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) 
		{
            ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH;
        } 
		else 
		{
            ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH;
        }

		
        for (i = 0;i < NUM_CONTROL_BUFFERS;i++) 
		{
            target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz);	
            if (target->HTCControlBuffers[i].Buffer == NULL) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
                status = A_ERROR;
                break;
            }
        }

        if (A_FAILED(status)) {
            break;
        }

            /* carve up buffers/packets for control messages */
        for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
            HTC_PACKET *pControlPacket;
            pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
            SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket,
                                          target,
                                          target->HTCControlBuffers[i].Buffer,
                                          ctrl_bufsz,
                                          ENDPOINT_0);
            HTC_FREE_CONTROL_RX(target,pControlPacket);
        }

        for (;i < NUM_CONTROL_BUFFERS;i++) {
             HTC_PACKET *pControlPacket;
             pControlPacket = &target->HTCControlBuffers[i].HtcPacket;
             INIT_HTC_PACKET_INFO(pControlPacket,
                                  target->HTCControlBuffers[i].Buffer,
                                  ctrl_bufsz);
             HTC_FREE_CONTROL_TX(target,pControlPacket);
        }

    } while (FALSE);

    if (A_FAILED(status)) {
        if (target != NULL) {
            HTCCleanup(target);
            target = NULL;
        }
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));

    return target;
}
Ejemplo n.º 28
0
    /* setup of HIF scatter resources */
A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
{
    A_STATUS              status = A_ERROR;   
    int                   i;
    HIF_SCATTER_REQ_PRIV *pReqPriv;
    BUS_REQUEST          *busrequest;
        
    do {
        
            /* check if host supports scatter requests and it meets our requirements */
        if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
                    device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ));
            status = A_ENOTSUP;
            break;    
        }
                    
        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n",
                MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); 
        
        for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {    
                /* allocate the private request blob */
            pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV));
            if (NULL == pReqPriv) {
                break;    
            }
            A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV));
                /* save the device instance*/
            pReqPriv->device = device;      
                /* allocate the scatter request */
            pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + 
                                         (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM))); 
           
            if (NULL == pReqPriv->pHifScatterReq) {
                A_FREE(pReqPriv);
                break;      
            }           
                /* just zero the main part of the scatter request */
            A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ));
                /* back pointer to the private struct */
            pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv;
                /* allocate a bus request for this scatter request */
            busrequest = hifAllocateBusRequest(device);
            if (NULL == busrequest) {
                A_FREE(pReqPriv->pHifScatterReq);
                A_FREE(pReqPriv);
                break;    
            }
                /* assign the scatter request to this bus request */
            busrequest->pScatterReq = pReqPriv;
                /* point back to the request */
            pReqPriv->busrequest = busrequest;                           
                /* add it to the scatter pool */
            FreeScatterReq(device,pReqPriv->pHifScatterReq);
        }
        
        if (i != MAX_SCATTER_REQUESTS) {
            status = A_NO_MEMORY;
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n"));
            break;    
        }
        
            /* set scatter function pointers */
        pInfo->pAllocateReqFunc = AllocScatterReq;
        pInfo->pFreeReqFunc = FreeScatterReq;
        pInfo->pReadWriteScatterFunc = HifReadWriteScatter;   
        pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ;
        pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE;
     
        status = A_OK;
        
    } while (FALSE);
    
    if (A_FAILED(status)) {
        CleanupHIFScatterResources(device);   
    }
    
    return status;
}
Ejemplo n.º 29
0
Archivo: htc.c Proyecto: KHATEEBNSIT/AP
/* registered target arrival callback from the HIF layer */
HTC_HANDLE HTCCreate(void *hHIF, HTC_INIT_INFO *pInfo, adf_os_device_t osdev)
{
    MSG_BASED_HIF_CALLBACKS htcCallbacks;
    HTC_ENDPOINT            *pEndpoint=NULL;
    HTC_TARGET              *target = NULL;
    int                     i;

    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("+HTCCreate ..  HIF :%p \n",hHIF));

    A_REGISTER_MODULE_DEBUG_INFO(htc);

    if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC : Unable to allocate memory\n"));
        return NULL;
    }

    A_MEMZERO(target, sizeof(HTC_TARGET));

    adf_os_spinlock_init(&target->HTCLock);
    adf_os_spinlock_init(&target->HTCRxLock);
    adf_os_spinlock_init(&target->HTCTxLock);

    do {
        A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
        target->host_handle = pInfo->pContext;
		target->osdev = osdev;

        ResetEndpointStates(target);

        INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList);

        for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) {
            HTC_PACKET *pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
            if (pPacket != NULL) {
                A_MEMZERO(pPacket,sizeof(HTC_PACKET));
                FreeHTCPacketContainer(target,pPacket);
            }
        }

#ifdef TODO_FIXME
        for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) {
            pPacket = BuildHTCTxCtrlPacket();
            if (NULL == pPacket) {
                break;
            }
            HTCFreeControlTxPacket(target,pPacket);
        }
#endif

        /* setup HIF layer callbacks */
        A_MEMZERO(&htcCallbacks, sizeof(MSG_BASED_HIF_CALLBACKS));
        htcCallbacks.Context = target;
        htcCallbacks.rxCompletionHandler = HTCRxCompletionHandler;
        htcCallbacks.txCompletionHandler = HTCTxCompletionHandler;
        htcCallbacks.txResourceAvailHandler = HTCTxResourceAvailHandler;
        htcCallbacks.fwEventHandler = HTCFwEventHandler;
        target->hif_dev = hHIF;

        /* Get HIF default pipe for HTC message exchange */
        pEndpoint = &target->EndPoint[ENDPOINT_0];

        HIFPostInit(hHIF, target, &htcCallbacks);
        HIFGetDefaultPipe(hHIF, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID);

    } while (FALSE);

    HTCRecvInit(target);

    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("-HTCCreate (0x%p) \n", target));

    return (HTC_HANDLE)target;
}
A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar)
#endif
{
    HCI_TRANSPORT_CONFIG_INFO config;
    A_STATUS                  status = A_OK;
    int                       i;
    HTC_PACKET                *pPacket;
    AR6K_HCI_BRIDGE_INFO      *pHcidevInfo;
        
       
    do {
        
        pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO));
        
        if (NULL == pHcidevInfo) {
            status = A_NO_MEMORY;
            break;    
        }
        
        A_MEMZERO(pHcidevInfo, sizeof(AR6K_HCI_BRIDGE_INFO));
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
        g_pHcidevInfo = pHcidevInfo;
        pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar;
#else
        ar->hcidev_info = pHcidevInfo;
        pHcidevInfo->ar = ar;
#endif
        spin_lock_init(&pHcidevInfo->BridgeLock);
        INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);

        ar->exitCallback = AR3KConfigureExit;
    
        status = bt_setup_hci(pHcidevInfo);
        if (A_FAILED(status)) {
            break;    
        }
        
        if (pHcidevInfo->HciNormalMode) {      
            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));    
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));     
        }
        
        pHcidevInfo->pHTCStructAlloc = (A_UINT8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS);
        
        if (NULL == pHcidevInfo->pHTCStructAlloc) {
            status = A_NO_MEMORY;
            break;    
        }
        
        pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc;
        for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
            FreeHTCStruct(pHcidevInfo,pPacket);                
        }
        
        A_MEMZERO(&config,sizeof(HCI_TRANSPORT_CONFIG_INFO));        
        config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2;
        config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2;
        config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH;
        config.pContext = pHcidevInfo;    
        config.TransportFailure = ar6000_hci_transport_failure;
        config.TransportReady = ar6000_hci_transport_ready;
        config.TransportRemoved = ar6000_hci_transport_removed;
        config.pHCISendComplete = ar6000_hci_send_complete;
        config.pHCIPktRecv = ar6000_hci_pkt_recv;
        config.pHCIPktRecvRefill = ar6000_hci_pkt_refill;
        config.pHCISendFull = ar6000_hci_pkt_send_full;
       
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
        pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
#else
        pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
#endif

        if (NULL == pHcidevInfo->pHCIDev) {
            status = A_ERROR;      
        }
    
    } while (FALSE);
    
    if (A_FAILED(status)) {
        if (pHcidevInfo != NULL) {
            if (NULL == pHcidevInfo->pHCIDev) {
                /* GMBOX may not be present in older chips */
                /* just return success */ 
                status = A_OK;
            }
        }
        ar6000_cleanup_hci(ar);    
    }
    
    return status;
}