コード例 #1
0
ファイル: ar3kconfig.c プロジェクト: burstlam/AR6kSDK.3.1
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;
}
コード例 #2
0
LOCAL void _HTC_Ready(htc_handle_t htcHandle)
{
	adf_nbuf_t pBuffer;
	HTC_READY_MSG *pReady;
	a_uint8_t *addr;
	HTC_CONTEXT *pHTC = (HTC_CONTEXT *)htcHandle;
    
	pBuffer = HTCAllocMsgBuffer(pHTC);
       
	/* an optimization... the header length is chosen to
	 * be aligned on a 16 bit bounday, the fields in the message are designed to
	 * be aligned */
	addr = adf_nbuf_put_tail(pBuffer, sizeof(HTC_READY_MSG));       
	pReady = (HTC_READY_MSG *)addr;     
	A_MEMZERO(pReady,sizeof(HTC_READY_MSG));  
	pReady->MessageID = adf_os_htons(HTC_MSG_READY_ID);
	pReady->CreditSize = adf_os_htons((A_UINT16)pHTC->RecvBufferSize);
	pReady->CreditCount = adf_os_htons((A_UINT16)pHTC->TotalCredits);
	pReady->MaxEndpoints = ENDPOINT_MAX;
       
	/* send out the message */
	HTC_SendMsg(pHTC, ENDPOINT0, pBuffer);
	/* now we need to wait for service connection requests */
}
コード例 #3
0
ファイル: htc.c プロジェクト: S5-APQ8084/qcacld-3.0
A_STATUS htc_start(HTC_HANDLE HTCHandle)
{
	cdf_nbuf_t netbuf;
	A_STATUS status = A_OK;
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_SETUP_COMPLETE_EX_MSG *pSetupComp;
	HTC_PACKET *pSendPacket;

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Enter\n"));

	do {

		htc_config_target_hif_pipe(target);

		/* allocate a buffer to send */
		pSendPacket = htc_alloc_control_tx_packet(target);
		if (NULL == pSendPacket) {
			AR_DEBUG_ASSERT(false);
			cdf_print("%s: allocControlTxPacket failed\n",
				  __func__);
			status = A_NO_MEMORY;
			break;
		}

		netbuf =
			(cdf_nbuf_t) GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket);
		/* assemble setup complete message */
		cdf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
		pSetupComp =
			(HTC_SETUP_COMPLETE_EX_MSG *) cdf_nbuf_data(netbuf);
		A_MEMZERO(pSetupComp, sizeof(HTC_SETUP_COMPLETE_EX_MSG));

		HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG,
			      MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID);

		if (!htc_credit_flow) {
			AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
					("HTC will not use TX credit flow control\n"));
			pSetupComp->SetupFlags |=
				HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW;
		} else {
			AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
					("HTC using TX credit flow control\n"));
		}

#ifdef HIF_SDIO
#if ENABLE_BUNDLE_RX
		if (HTC_ENABLE_BUNDLE(target))
			pSetupComp->SetupFlags |=
				HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV;
#endif /* ENABLE_BUNDLE_RX */
#endif /* HIF_SDIO */

		SET_HTC_PACKET_INFO_TX(pSendPacket,
				       NULL,
				       (A_UINT8 *) pSetupComp,
				       sizeof(HTC_SETUP_COMPLETE_EX_MSG),
				       ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);

		status = htc_send_pkt((HTC_HANDLE) target, pSendPacket);
		if (A_FAILED(status)) {
			break;
		}

	} while (false);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_start Exit\n"));
	return status;
}
コード例 #4
0
A_STATUS HTCConnectService(HTC_HANDLE               HTCHandle,
                           HTC_SERVICE_CONNECT_REQ  *pConnectReq,
                           HTC_SERVICE_CONNECT_RESP *pConnectResp)
{
    HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    A_STATUS                            status = A_OK;
    HTC_PACKET                          *pRecvPacket = NULL;
    HTC_PACKET                          *pSendPacket = NULL;
    HTC_CONNECT_SERVICE_RESPONSE_MSG    *pResponseMsg;
    HTC_CONNECT_SERVICE_MSG             *pConnectMsg;
    HTC_ENDPOINT_ID                     assignedEndpoint = ENDPOINT_MAX;
    HTC_ENDPOINT                        *pEndpoint;
    unsigned int                        maxMsgSize = 0;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%X SvcID:0x%X \n",
               (A_UINT32)target, pConnectReq->ServiceID));

    do {

        AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0);

        if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) {
                /* special case for pseudo control service */
            assignedEndpoint = ENDPOINT_0;
            maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH;
        } else {
                /* allocate a packet to send to the target */
            pSendPacket = HTC_ALLOC_CONTROL_TX(target);

            if (NULL == pSendPacket) {
                AR_DEBUG_ASSERT(FALSE);
                status = A_NO_MEMORY;
                break;
            }
                /* assemble connect service message */
            pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer;
            AR_DEBUG_ASSERT(pConnectMsg != NULL);
            A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG));
            pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID;
            pConnectMsg->ServiceID = pConnectReq->ServiceID;
            pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags;
                /* check caller if it wants to transfer meta data */
            if ((pConnectReq->pMetaData != NULL) &&
                (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
                    /* copy meta data into message buffer (after header ) */
                A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
                         pConnectReq->pMetaData,
                         pConnectReq->MetaDataLength);
                pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
            }

            SET_HTC_PACKET_INFO_TX(pSendPacket,
                                   NULL,
                                   (A_UINT8 *)pConnectMsg,
                                   sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength,
                                   ENDPOINT_0,
                                   HTC_SERVICE_TX_PACKET_TAG);

                /* we want synchronous operation */
            pSendPacket->Completion = NULL;
            HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
            status = HTCIssueSend(target,pSendPacket);

            if (A_FAILED(status)) {
                break;
            }

                /* wait for response */
            status = HTCWaitforControlMessage(target, &pRecvPacket);

            if (A_FAILED(status)) {
                break;
            }
                /* we controlled the buffer creation so it has to be properly aligned */
            pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer;

            if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) ||
                (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) {
                    /* this message is not valid */
                AR_DEBUG_ASSERT(FALSE);
                status = A_EPROTO;
                break;
            }

            pConnectResp->ConnectRespCode = pResponseMsg->Status;
                /* check response status */
            if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                    (" Target failed service 0x%X connect request (status:%d)\n",
                                pResponseMsg->ServiceID, pResponseMsg->Status));
                status = A_EPROTO;
                break;
            }

            assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID;
            maxMsgSize = pResponseMsg->MaxMsgSize;

            if ((pConnectResp->pMetaData != NULL) &&
                (pResponseMsg->ServiceMetaLength > 0) &&
                (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) {
                    /* caller supplied a buffer and the target responded with data */
                int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength);
                    /* copy the meta data */
                A_MEMCPY(pConnectResp->pMetaData,
                         ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG),
                         copyLength);
                pConnectResp->ActualLength = copyLength;
            }

        }

            /* the rest of these are parameter checks so set the error status */
        status = A_EPROTO;

        if (assignedEndpoint >= ENDPOINT_MAX) {
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

        if (0 == maxMsgSize) {
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

        pEndpoint = &target->EndPoint[assignedEndpoint];
        pEndpoint->Id = assignedEndpoint;
        if (pEndpoint->ServiceID != 0) {
            /* endpoint already in use! */
            AR_DEBUG_ASSERT(FALSE);
            break;
        }

            /* return assigned endpoint to caller */
        pConnectResp->Endpoint = assignedEndpoint;
        pConnectResp->MaxMsgLength = maxMsgSize;

            /* setup the endpoint */
        pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */
        pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth;
        pEndpoint->MaxMsgLength = maxMsgSize;
            /* copy all the callbacks */
        pEndpoint->EpCallBacks = pConnectReq->EpCallbacks;
            /* set the credit distribution info for this endpoint, this information is
             * passed back to the credit distribution callback function */
        pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID;
        pEndpoint->CreditDist.pHTCReserved = pEndpoint;
        pEndpoint->CreditDist.Endpoint = assignedEndpoint;
        pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize;
        
        if (pConnectReq->MaxSendMsgSize != 0) {
                /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications
                 * since the host will actually issue smaller messages in the Send path */
            if (pConnectReq->MaxSendMsgSize > maxMsgSize) {
                    /* can't be larger than the maximum the target can support */
                AR_DEBUG_ASSERT(FALSE);
                break;       
            }
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize;
        } else {
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize;
        }
        
        if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) {
            pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1;
        }
        
            /* save local connection flags */
        pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags;
        
        status = A_OK;

    } while (FALSE);

    if (pSendPacket != NULL) {
        HTC_FREE_CONTROL_TX(target,pSendPacket);
    }

    if (pRecvPacket != NULL) {
        HTC_FREE_CONTROL_RX(target,pRecvPacket);
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n"));

    return status;
}
コード例 #5
0
ファイル: hif.c プロジェクト: AvalueAES/rev-sa01
static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
{
    int ret;
    HIF_DEVICE * device;
    int count;
    struct task_struct* startup_task_struct;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
		    ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n",
		     func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize));

    addHifDevice(func);
    device = getHifDevice(func);

    spin_lock_init(&device->lock);

    spin_lock_init(&device->asynclock);
    
    DL_LIST_INIT(&device->ScatterReqHead);
    
    if (!nohifscattersupport) {
            /* try to allow scatter operation on all instances,
             * unless globally overridden */
        device->scatter_enabled = TRUE;
    }
    
        /* enable the SDIO function */
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: claim\n"));
    sdio_claim_host(func);
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: enable\n"));

    if ((id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) {
        /* enable 4-bit ASYNC interrupt on AR6003 or later devices */    
        ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
        if (ret) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));    
            sdio_release_host(func);
            return ret;
        }
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));   
    }
    
    
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
    /* give us some time to enable, in ms */
    func->enable_timeout = 100;
#endif
    ret = sdio_enable_func(func);
    if (ret) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
					  __FUNCTION__, ret)); 
        sdio_release_host(func);
        return ret;
    }
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: set block size 0x%X\n", HIF_MBOX_BLOCK_SIZE));
    ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
    sdio_release_host(func);
    if (ret) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x  AR6K: 0x%X\n",
					  __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
        return ret;
    }
    /* Initialize the bus requests to be used later */
    A_MEMZERO(device->busRequest, sizeof(device->busRequest));
    for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
        sema_init(&device->busRequest[count].sem_req, 0);
        hifFreeBusRequest(device, &device->busRequest[count]);
    }

    /* create async I/O thread */
    device->async_shutdown = 0;
    device->async_task = kthread_create(async_task,
                                       (void *)device,
                                       "AR6K Async");
    if (IS_ERR(device->async_task)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
        return A_ERROR;
    }
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
    sema_init(&device->sem_async, 0);
    wake_up_process(device->async_task );

    /* create startup thread */
    startup_task_struct = kthread_create(startup_task,
                                  (void *)device,
                                  "AR6K startup");
    if (IS_ERR(startup_task_struct)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create startup task\n", __FUNCTION__));
        return A_ERROR;
    }
    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start startup task\n"));
    wake_up_process(startup_task_struct);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: return %d\n", ret));
    return ret;
}
コード例 #6
0
ファイル: abtfilt_wlan.c プロジェクト: Ar3kkusu/AR6kSDK.3.1
/* Internal functions */
static void *
WlanEventThread(void *arg)
{
    int left, ret, sd;
    struct timeval tv;
    socklen_t fromlen;
    struct nlmsghdr *h;
    fd_set readfds, tempfds;
    char buf[WLAN_EVENT_SIZE_MAX];
    struct sockaddr_nl from, local;
    ABF_WLAN_INFO *pAbfWlanInfo = (ABF_WLAN_INFO *)arg;
    ATHBT_FILTER_INFO *pInfo = pAbfWlanInfo->pInfo;
    ATH_BT_FILTER_INSTANCE *pInstance = pInfo->pInstance;
    A_STATUS status;
    
    A_INFO("Starting the WLAN Event Handler task\n");

    A_INFO("Checking WLAN adapter on startup .. \n");

    if (!pInstance->pWlanAdapterName) {
        Abf_WlanCheckSettings(pAbfWlanInfo->IfName, NULL);
        if (pAbfWlanInfo->IfName[0]) {
            pAbfWlanInfo->IfIndex = if_nametoindex(pAbfWlanInfo->IfName);
        }
    }
    status = AcquireWlanAdapter(pAbfWlanInfo);
 
    if (A_FAILED(status)) {
        A_INFO("No WLAN adapter on startup (OKAY) \n");
    }else {
        /* Communicate this to the Filter task */
        HandleAdapterEvent(pInfo, ATH_ADAPTER_ARRIVED);
        A_INFO("WLAN Adapter Added\n");
    }


    do {
        sd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
        if (sd < 0) {
            A_ERR("[%s] socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE): %d\n", 
                  __FUNCTION__, sd);
            break;
        }

        A_MEMZERO(&local, sizeof(struct sockaddr_nl));
        local.nl_family = AF_NETLINK;
        local.nl_groups = RTMGRP_LINK;
        if ((ret = bind(sd, (struct sockaddr *) &local, sizeof(local))) < 0) {
            A_ERR("[%s] bind(netlink): %d\n", __FUNCTION__, ret);
            close(sd);
            break;
        }

        FD_ZERO(&readfds);
        FD_SET(sd, &readfds);
        while (pAbfWlanInfo->Loop) {
            A_MEMCPY(&tempfds, &readfds, sizeof(fd_set));
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            ret = select(sd+1, &tempfds, NULL, NULL, &tv);
            if ((ret < 0) && (errno != EINTR)) {
                A_ERR("[%s] select failed: %d\n", __FUNCTION__, ret);
                break;
            } else if ((ret > 0) && (FD_ISSET(sd, &tempfds))) {
                fromlen = sizeof(from);
                do {
                    left = recvfrom(sd, buf, sizeof(buf), 0,
                                    (struct sockaddr *) &from, &fromlen);
                } while (left == -1 && errno == EINTR);

                if (left < 0) {
                    A_ERR("[%s] recvfrom(netlink)\n", __FUNCTION__);
                    continue;
                 //   break;
                }

                h = (struct nlmsghdr *) buf;
                while (left >= sizeof(*h)) {
                    int len, plen;

                    len = h->nlmsg_len;
                    plen = len - sizeof(*h);
                    if (len > left || plen < 0) {
                        A_ERR("[%s] malformed netlink message\n", __FUNCTION__);
                        continue;
                    }

                    //A_DEBUG("RTM Message Type: %s\n", 
                    //        ((h->nlmsg_type == RTM_NEWLINK) ? 
                    //         "RTM_NEWLINK" : ((h->nlmsg_type == RTM_DELLINK) ? 
                    //         "RTM_DELLINK" : "RTM_OTHER")));
                    switch (h->nlmsg_type) {
                    case RTM_NEWLINK:
                        NewLinkEvent(pInstance, h, plen);
                        break;
                    case RTM_DELLINK:
                        DelLinkEvent(pInstance, h, plen);
                        break;
                    default:
                        break;
                    }

                    len = NLMSG_ALIGN(len);
                    left -= len;
                    h = (struct nlmsghdr *) ((char *) h + len);
                }
            }
        }

        close(sd);
    } while (FALSE);

    /* Clean up the resources allocated in this task */
    A_INFO("Terminating the WLAN Event Handler task\n");
    A_MUTEX_LOCK(&pAbfWlanInfo->hWaitEventLock);
    pAbfWlanInfo->Loop = FALSE;
    A_COND_SIGNAL(&pAbfWlanInfo->hWaitEvent);
    A_MUTEX_UNLOCK(&pAbfWlanInfo->hWaitEventLock);

    return NULL;
}
コード例 #7
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;
}
コード例 #8
0
ファイル: ar6000_android.c プロジェクト: burstlam/AR6kSDK.3.1
int android_ioctl_siwpriv(struct net_device *dev,
              struct iw_request_info *__info,
              struct iw_point *data, char *__extra)
{
    char cmd[384]; /* assume that android command will not excess 384 */
    char buf[512];
    int len = sizeof(cmd)-1;
    AR_SOFTC_DEV_T *arPriv = (AR_SOFTC_DEV_T *)ar6k_priv(dev);
    AR_SOFTC_STA_T *arSta = &arPriv->arSta;

    if (!data->pointer) {
        return -EOPNOTSUPP;
    }
    if (data->length < len) {
        len = data->length;
    }
    if (copy_from_user(cmd, data->pointer, len)) {
        return -EIO;
    }
    cmd[len] = 0;

    if (strcasecmp(cmd, "RSSI")==0 || strcasecmp(cmd, "RSSI-APPROX") == 0) {
        int rssi = -200;
        struct iw_statistics *iwStats;
        struct iw_statistics* (*get_iwstats)(struct net_device *);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
        get_iwstats = dev->get_wireless_stats;
#else
        get_iwstats = dev->wireless_handlers->get_wireless_stats;
#endif
        if (get_iwstats && arPriv->arConnected) {
            iwStats = get_iwstats(dev);
            if (iwStats) {
                rssi = iwStats->qual.qual;          
                if (rssi == 255)
                    rssi = -200;
                else
                    rssi += (161 - 256);                
            }
        }
        len = snprintf(buf, data->length, "SSID rssi %d\n", rssi) + 1;
        return (copy_to_user(data->pointer, buf, len)==0) ? len : -1;
    } else if (strcasecmp(cmd, "LINKSPEED")==0) {
        /* We skip to use SIOCGIWRATE since Android always asked LINKSPEED just after RSSI*/
        unsigned int speed_mbps;
        if (arPriv->arConnected) {
            speed_mbps = arPriv->arTargetStats.tx_unicast_rate / 1000;
        } else {
            speed_mbps = 1;
        }
        len = snprintf(buf, data->length, "LinkSpeed %u\n", speed_mbps) + 1;
        return (copy_to_user(data->pointer, buf, len)==0) ? len : -1;
    } else if (memcmp(cmd, "CSCAN S\x01\x00\x00S\x00", 12)==0) {
        int iocmd = SIOCSIWSCAN - SIOCSIWCOMMIT;
        const iw_handler setScan = dev->wireless_handlers->standard[iocmd];
        A_INT32 home_dwell=0, pas_dwell=0, act_dwell=0;
        A_UCHAR ssid[IW_ESSID_MAX_SIZE+1] = { 0 };       
        A_INT32 ssid_len = 0, ie_len;
        A_UINT8 index = 1; /* reserve index 0 for wext */
        A_INT32 ch = 0;
        A_CHAR nprobe, scantype;
        struct iw_freq chList[IW_MAX_FREQUENCIES];
        A_UCHAR *scanBuf = (A_UCHAR*)(cmd + 12);
        A_UCHAR *scanEnd = (A_UCHAR*)(cmd + len);
        A_BOOL broadcastSsid = FALSE;

        while ( scanBuf < scanEnd ) {
            A_UCHAR *sp = scanBuf;
            switch (*scanBuf) {
            case 'S': /* SSID section */
                if (ssid_len > 0 && index < MAX_PROBED_SSID_INDEX) {
                    /* setup the last parsed ssid, reserve index 0 for wext */
                    if (wmi_probedSsid_cmd(arPriv->arWmi, index,
                                           SPECIFIC_SSID_FLAG, ssid_len, ssid) == A_OK) {
                        ++index;
                        if (arSta->scanSpecificSsid<index) {
                            arSta->scanSpecificSsid = index;
                        }
                    }
                }
                ie_len = ((scanBuf + 1) < scanEnd) ? ((A_INT32)*(scanBuf+1) + 1) : 0;
                if ((scanBuf+ie_len) < scanEnd ) {
                    ssid_len = *(scanBuf+1);
                    if (ssid_len == 0) {
                        broadcastSsid = TRUE;
                    } else {
                        A_MEMCPY(ssid, scanBuf+2, ssid_len);
                        ssid[ssid_len] = '\0';
                    }
                }
                scanBuf += 1 + ie_len;
                break;
            case 'C': /* Channel section */
                if (scanBuf+1 < scanEnd) {
                    int value = *(scanBuf+1);
                    if (value == 0) {
                        ch = 0; /* scan for all channels */
                    } else if (ch < IW_MAX_FREQUENCIES) {
                        if (value>1000) {
                            chList[ch].e = 1;
                            chList[ch].m = value * 100000;
                        } else {
                            chList[ch].e = 0;
                            chList[ch].m = value;
                        }
                        ++ch;
                    }
                }
                scanBuf += 2;
                break;
            case 'P': /* Passive dwell section */
                if (scanBuf+2 < scanEnd) {
                    pas_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8);
                }
                scanBuf += 3;
                break;
            case 'H': /* Home dwell section */
                if (scanBuf+2 < scanEnd) {
                    home_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8);
                }
                scanBuf += 3;
                break;
            case 'N': /* Number of probe section */
                if (scanBuf+1 < scanEnd) {
                    nprobe = *(scanBuf+1);
                }
                scanBuf += 2;
                break;
            case 'A': /* Active dwell section */
                if (scanBuf+2 < scanEnd) {
                    act_dwell = *(scanBuf+1) + (*(scanBuf+2) << 8);
                }
                scanBuf += 3;
                break;
            case 'T': /* Scan active type section */
                if (scanBuf+1 < scanEnd) {
                    scantype = *(scanBuf+1);
                }
                scanBuf += 2;
                break;
            default:
                break;
            }
            if (sp == scanBuf) {
                return -1; /* parsing error */
            }
        }

        if (ssid_len>0) {
            A_UINT8 idx; /* Clean up the last specific scan items */
            for (idx=index; idx<arSta->scanSpecificSsid; ++idx) {
                wmi_probedSsid_cmd(arPriv->arWmi, idx, DISABLE_SSID_FLAG, 0, NULL);
            }
            arSta->scanSpecificSsid = index;
            /* 
             * There is no way to know when we need to send broadcast probe in current Android wpa_supplicant_6 
             * combo scan implemenation. Always force to sent it here uniti future Android version will set
             * the broadcast flags for combo scan.
             */
#if 0
            if (broadcastSsid)
#endif
            {
                /* setup the last index as broadcast SSID for combo scan */
                ++arSta->scanSpecificSsid;
                wmi_probedSsid_cmd(arPriv->arWmi, index, ANY_SSID_FLAG, 0, NULL);
            }
        }

        if (pas_dwell>0) {
            /* TODO: Should we change our passive dwell? There may be some impact for bt-coex */
        }

        if (home_dwell>0) {
            /* TODO: Should we adjust home_dwell? How to pass it to wext handler? */
        }

        if (setScan) {
            union iwreq_data miwr;
            struct iw_request_info minfo;
            struct iw_scan_req scanreq, *pScanReq = NULL;
            A_MEMZERO(&minfo, sizeof(minfo));
            A_MEMZERO(&miwr, sizeof(miwr));            
            A_MEMZERO(&scanreq, sizeof(scanreq));
            if (ssid_len > 0) {
                pScanReq = &scanreq;
                memcpy(scanreq.essid, ssid, ssid_len);
                scanreq.essid_len = ssid_len;
                miwr.data.flags |= IW_SCAN_THIS_ESSID;
            }
            if (ch > 0) {
                pScanReq = &scanreq;
                scanreq.num_channels = ch;
                memcpy(scanreq.channel_list, chList, ch * sizeof(chList[0]));
                miwr.data.flags |= IW_SCAN_THIS_FREQ;
            }
            if (pScanReq) {
                miwr.data.pointer = (__force void __user *)&scanreq;
                miwr.data.length = sizeof(scanreq);
            }
            minfo.cmd = SIOCSIWSCAN;
            return setScan(dev, &minfo, &miwr, (char*)pScanReq);
        }
        return -1;
    } else if (strcasecmp(cmd, "MACADDR")==0) {
        /* reply comes back in the form "Macaddr = XX:XX:XX:XX:XX:XX" where XX */
        A_UCHAR *mac = dev->dev_addr;
        len = snprintf(buf, data->length, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
                        mac[0], mac[1], mac[2],
                        mac[3], mac[4], mac[5]) + 1;
        return (copy_to_user(data->pointer, buf, len)==0) ? len : -1;
    } else if (strcasecmp(cmd, "SCAN-ACTIVE")==0) {
        return 0; /* unsupport function. Suppress the error */
    } else if (strcasecmp(cmd, "SCAN-PASSIVE")==0) {
        return 0; /* unsupport function. Suppress the error */
    } else if (strcasecmp(cmd, "START")==0 || strcasecmp(cmd, "STOP")==0) {
        struct ifreq ifr;
        char userBuf[16];
        int ex_arg = (strcasecmp(cmd, "START")==0) ? WLAN_ENABLED : WLAN_DISABLED;
        int ret;
        A_MEMZERO(userBuf, sizeof(userBuf));
        ((int *)userBuf)[0] = AR6000_XIOCTRL_WMI_SET_WLAN_STATE;
        ((int *)userBuf)[1] = ex_arg;
        ret = android_do_ioctl_direct(dev, AR6000_IOCTL_EXTENDED, &ifr, userBuf);
        if (ret==0) {
            /* Send wireless event which need by android supplicant */
            union iwreq_data wrqu;
            A_MEMZERO(&wrqu, sizeof(wrqu));
            wrqu.data.length = strlen(cmd);
            wireless_send_event(dev, IWEVCUSTOM, &wrqu, cmd);
        }
        return ret;
    } else if (strncasecmp(cmd, "POWERMODE ", 10)==0) {
        int mode;
        if (sscanf(cmd, "%*s %d", &mode) == 1) {
            int iocmd = SIOCSIWPOWER - SIOCSIWCOMMIT;
            iw_handler setPower = dev->wireless_handlers->standard[iocmd];
            if (setPower) {
                union iwreq_data miwr;
                struct iw_request_info minfo;
                A_MEMZERO(&minfo, sizeof(minfo));
                A_MEMZERO(&miwr, sizeof(miwr));
                minfo.cmd = SIOCSIWPOWER;
                if (mode == 0 /* auto */)
                    miwr.power.disabled = 0;
                else if (mode == 1 /* active */)
                    miwr.power.disabled = 1;
                else
                    return -1;
                return setPower(dev, &minfo, &miwr, NULL);
            }
        }
        return -1;
    } else if (strcasecmp(cmd, "GETPOWER")==0) {
        struct ifreq ifr;
        int userBuf[2];
        A_MEMZERO(userBuf, sizeof(userBuf));
        ((int *)userBuf)[0] = AR6000_XIOCTRL_WMI_GET_POWER_MODE;
        if (android_do_ioctl_direct(dev, AR6000_IOCTL_EXTENDED, &ifr, userBuf)>=0) {
            WMI_POWER_MODE_CMD *getPowerMode = (WMI_POWER_MODE_CMD *)userBuf;
            len = snprintf(buf, data->length, "powermode = %u\n", 
                           (getPowerMode->powerMode==MAX_PERF_POWER) ? 1/*active*/ : 0/*auto*/) + 1;
            return (copy_to_user(data->pointer, buf, len)==0) ? len : -1;        
        }
        return -1;
    } else if (strncasecmp(cmd, "SETSUSPENDOPT ", 14)==0) {
        int enable;
        if (sscanf(cmd, "%*s %d", &enable)==1) {
            /* 
             * We set our suspend mode by wlan_config.h now. 
             * Should we follow Android command?? TODO
             */
            return 0;
        }
        return -1;
    } else if (strcasecmp(cmd, "SCAN-CHANNELS")==0) {
        // reply comes back in the form "Scan-Channels = X" where X is the number of channels        
        int iocmd = SIOCGIWRANGE - SIOCSIWCOMMIT;
        iw_handler getRange = dev->wireless_handlers->standard[iocmd];            
        if (getRange) {
            union iwreq_data miwr;
            struct iw_request_info minfo;
            struct iw_range range;
            A_MEMZERO(&minfo, sizeof(minfo));
            A_MEMZERO(&miwr, sizeof(miwr));
            A_MEMZERO(&range, sizeof(range));
            minfo.cmd = SIOCGIWRANGE;
            miwr.data.pointer = (__force void __user *) &range;
            miwr.data.length = sizeof(range);
            getRange(dev, &minfo, &miwr, (char*)&range);
        }
        if (arSta->arNumChannels!=-1) {
            len = snprintf(buf, data->length, "Scan-Channels = %d\n", arSta->arNumChannels) + 1;
            return (copy_to_user(data->pointer, buf, len)==0) ? len : -1;
        }
        return -1;
    } else if (strncasecmp(cmd, "SCAN-CHANNELS ", 14)==0 || 
               strncasecmp(cmd, "COUNTRY ", 8)==0) {
        /* 
         * Set the available channels with WMI_SET_CHANNELPARAMS cmd
         * However, the channels will be limited by the eeprom regulator domain
         * Try to use a regulator domain which will not limited the channels range.
         */
        int i;
        int chan = 0;
        A_UINT16 *clist;
        struct ifreq ifr; 
        char ioBuf[256];
        WMI_CHANNEL_PARAMS_CMD *chParamCmd = (WMI_CHANNEL_PARAMS_CMD *)ioBuf;
        if (strncasecmp(cmd, "COUNTRY ", 8)==0) {
            char *country = cmd + 8;
            if (strcasecmp(country, "US")==0) {
                chan = 11;
            } else if (strcasecmp(country, "JP")==0) {
                chan = 14;
            } else if (strcasecmp(country, "EU")==0) {
                chan = 13;
            }
        } else if (sscanf(cmd, "%*s %d", &chan) != 1) {
            return -1;
        }
        if ( (chan != 11) && (chan != 13) && (chan != 14)) {
            return -1;
        }
        if (arPriv->arNextMode == AP_NETWORK) {
            return -1;
        }
        A_MEMZERO(&ifr, sizeof(ifr));
        A_MEMZERO(ioBuf, sizeof(ioBuf));

        chParamCmd->phyMode = WMI_11G_MODE;
        clist = chParamCmd->channelList;
        chParamCmd->numChannels = chan;
        chParamCmd->scanParam = 1;        
        for (i = 0; i < chan; i++) {
            clist[i] = wlan_ieee2freq(i + 1);
        }
        
        return android_do_ioctl_direct(dev, AR6000_IOCTL_WMI_SET_CHANNELPARAMS, &ifr, ioBuf);
    } else if (strncasecmp(cmd, "BTCOEXMODE ", 11)==0) {
        int mode;
        if (sscanf(cmd, "%*s %d", &mode)==1) {
            /* 
            * Android disable BT-COEX when obtaining dhcp packet except there is headset is connected 
             * It enable the BT-COEX after dhcp process is finished
             * We ignore since we have our way to do bt-coex during dhcp obtaining.
             */
            switch (mode) {
            case 1: /* Disable*/
                break;
            case 0: /* Enable */
                /* fall through */
            case 2: /* Sense*/
                /* fall through */
            default:
                break;
            }
            return 0; /* ignore it */
        }
        return -1;
    } else if (strcasecmp(cmd, "BTCOEXSCAN-START")==0) {
        /* Android enable or disable Bluetooth coexistence scan mode. When this mode is on,
         * some of the low-level scan parameters used by the driver are changed to
         * reduce interference with A2DP streaming.
         */
        return 0; /* ignore it since we have btfilter  */
    } else if (strcasecmp(cmd, "BTCOEXSCAN-STOP")==0) {
        return 0; /* ignore it since we have btfilter  */
    } else if (strncasecmp(cmd, "RXFILTER-ADD ", 13)==0) {
        return 0; /* ignore it */
    } else if (strncasecmp(cmd, "RXFILTER-REMOVE ", 16)==0) {
        return 0; /* ignoret it */
    } else if (strcasecmp(cmd, "RXFILTER-START")==0 || strcasecmp(cmd, "RXFILTER-STOP")==0) {
        unsigned int flags = dev->flags;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
        int mc_count = dev->mc_count;   
#else
        int mc_count = netdev_mc_count(dev);
#endif
        if (strcasecmp(cmd, "RXFILTER-START")==0) {
            if (mc_count > 0 || (flags & IFF_MULTICAST) ) {
                flags &= ~IFF_MULTICAST;
            }
        } else {
            flags |= IFF_MULTICAST;
        }
        if (flags != dev->flags) {
            dev_change_flags(dev, flags);
        }
        return 0;
    }

    return -EOPNOTSUPP;
}
コード例 #9
0
ファイル: ar6k_gmbox.c プロジェクト: CSCLOG/beaglebone
int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS)
{
    int status = 0;
    int      i;
    u8 buffer[4];
    
    A_MEMZERO(buffer, sizeof(buffer));
    
    do {
        
        if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) {
            status = A_EINVAL;
            break;    
        }
        
            /* set the last buffer to do the actual signal trigger */
        buffer[3] = (1 << Signal);
        
        status = HIFReadWrite(pDev->HIFDevice,
                              INT_WLAN_ADDRESS,
                              buffer,
                              sizeof(buffer),
                              HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
                              NULL);    
                          
        if (status) {
            break;    
        }
        
    } while (false);
    
    
    if (!status) {
            /* now read back the register to see if the bit cleared */
        while (AckTimeoutMS) {        
            status = HIFReadWrite(pDev->HIFDevice,
                                  INT_WLAN_ADDRESS,
                                  buffer,
                                  sizeof(buffer),
                                  HIF_RD_SYNC_BYTE_FIX,
                                  NULL);    
                          
            if (status) {
                break;    
            }
                            
            for (i = 0; i < sizeof(buffer); i++) {
                if (buffer[i] & (1 << Signal)) {
                    /* bit is still set */
                    break;    
                }   
            }
            
            if (i >= sizeof(buffer)) {
                /* done */
                break;    
            }
            
            AckTimeoutMS--;
            A_MDELAY(1);  
        }
        
        if (0 == AckTimeoutMS) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal));
            status = A_ERROR;    
        }        
    }
    
    return status;
    
}
コード例 #10
0
ファイル: ar6k_gmbox.c プロジェクト: CSCLOG/beaglebone
int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits)
{
    int    status = 0;
    struct htc_packet  *pIOPacket = NULL;  
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC"));
                                            
    do {
        
        pIOPacket = AR6KAllocIOPacket(pDev);

        if (NULL == pIOPacket) {
            status = A_NO_MEMORY;
            A_ASSERT(false);
            break;
        }
        
        A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
      
        if (AsyncMode) {   
                /* stick in our completion routine when the I/O operation completes */
            pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
            pIOPacket->pContext = pDev;
                /* read registers asynchronously */
            HIFReadWrite(pDev->HIFDevice,
                         AR6K_GMBOX_CREDIT_DEC_ADDRESS,
                         pIOPacket->pBuffer,
                         AR6K_REG_IO_BUFFER_SIZE,  /* hit the register multiple times */
                         HIF_RD_ASYNC_BYTE_FIX,
                         pIOPacket);
            pIOPacket = NULL;
            break;
        } 

        pIOPacket->Completion = NULL;
            /* if we get here we are doing it synchronously */
        status = HIFReadWrite(pDev->HIFDevice,
                              AR6K_GMBOX_CREDIT_DEC_ADDRESS,
                              pIOPacket->pBuffer,
                              AR6K_REG_IO_BUFFER_SIZE,
                              HIF_RD_SYNC_BYTE_FIX,
                              NULL);    
    } while (false);
    
    if (status) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                (" DevGMboxReadCreditCounter failed! status:%d \n", status));          
    }
    
    if (pIOPacket != NULL) {
        if (!status) {
                /* sync mode processing */
            *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE);     
        }
        AR6KFreeIOPacket(pDev,pIOPacket);
    }
    
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n", 
            AsyncMode ? "ASYNC" : "SYNC", status));
    
    return status;
}
コード例 #11
0
ファイル: u_wmi.c プロジェクト: NemProjects/WLAN
A_STATUS wmi_control_rx(A_UINT8 *pBuffer, int Length)
{
    WMI_CMD_HDR *cmd;
    A_UINT16 id;
    A_UINT8 *datap;
    A_UINT32 len;
    A_STATUS status = A_OK;
    A_CHAR *pWmiDumpStr = "WMI message payload";

    if (Length < sizeof(WMI_CMD_HDR)) { 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 
               ("WMI: invalid length: %d \n",Length));
        return A_ERROR;
    }

    cmd = (WMI_CMD_HDR *)pBuffer;
    id = cmd->commandId;
    datap = pBuffer + sizeof(WMI_CMD_HDR);
    len = Length - sizeof(WMI_CMD_HDR);
    
    AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("---- WMI recv, MsgNo %d, Event ID: 0x%X (%d) ---------------------------\n", 
            cmdRecvNum, id , id));
            
    cmdRecvNum++;
    
    switch (id) {
   
        case (WMI_READY_EVENTID):
            {
                WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
                AR_DEBUG_PRINTF(ATH_DEBUG_WMI,("WMI_READY_EVENTID\n"));
                if (len < sizeof(WMI_READY_EVENT)) {
                    return A_EINVAL;
                }
                A_MEMCPY(g_MACAddress, ev->macaddr, ATH_MAC_LEN);          
                ar6000_ready_event(ev->macaddr, ev->phyCapability);

            }
            break;
     
        case (WMI_CONNECT_EVENTID):
            {
                WMI_CONNECT_EVENT *ev;
                
                AR_DEBUG_PRINTF(ATH_DEBUG_WMI,("WMI_CONNECT_EVENTID \n"));
                
                if (len < sizeof(WMI_CONNECT_EVENT)) {
                    return A_EINVAL;
                }
                ev = (WMI_CONNECT_EVENT *)datap;
                            
                A_MEMCPY(g_bssid, ev->bssid, ATH_MAC_LEN);
            
                ar6000_connect_event(ev->channel, ev->bssid,
                                     ev->listenInterval, ev->beaconInterval,
                                     ev->networkType, ev->beaconIeLen,
                                     ev->assocReqLen, ev->assocRespLen,
                                     ev->assocInfo);
            }                         
            break;
     
        case (WMI_DISCONNECT_EVENTID):
            {
                WMI_DISCONNECT_EVENT *ev;
            
                if (len < sizeof(WMI_DISCONNECT_EVENT)) {
                    return A_EINVAL;
                }
            
                ev = (WMI_DISCONNECT_EVENT *)datap;
            
                A_MEMZERO(g_bssid, ATH_MAC_LEN);
            
                ar6000_disconnect_event(ev->disconnectReason, ev->bssid,
                                        ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
            }
            break;
       
        case (WMI_REGDOMAIN_EVENTID):  
            {
                WMI_REG_DOMAIN_EVENT *ev;

                AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI_REGDOMAIN_EVENTID\n"));      
                
                if (len < sizeof(*ev)) {
                    return A_EINVAL;
                }
                ev = (WMI_REG_DOMAIN_EVENT *)datap;
            
                ar6000_regDomain_event(ev->regDomain);
            }            
            
            break;
     
        case (WMI_EXTENSION_EVENTID):
            {
                A_UINT16 extId = datap[0] | ((A_UINT16)datap[1]) << 8;
                
                datap += sizeof(WMIX_CMD_HDR);
                len -= sizeof(WMIX_CMD_HDR);
                
                AR_DEBUG_PRINTF(ATH_DEBUG_WMI, 
                    ("WMI_EXTENSION_EVENTID - id: 0x%X (%d) length:%d \n",extId, extId, len));
                pWmiDumpStr = "WMI Extended Message payload";
            }
            break;
        
        case (WMI_REPORT_STATISTICS_EVENTID) :
            {
                WMI_TARGET_STATS *reply;

                AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI_EXTENSION_EVENTID\n"));     
                                
                if (len < sizeof(*reply)) {
                    return A_EINVAL;
                }
                
                reply = (WMI_TARGET_STATS *)datap;
        
                ar6000_targetStats_event(reply);   
            }
                     
        default:
            AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("UNHANDLED WMI EVENT : 0x%X (%d) \n",id,id));
            break;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_WMI, 
      ("------------------------------------------------------------------------------------\n"));
        
    if (g_WMIloggingReq) {
        DebugDumpBytes(datap, len, pWmiDumpStr);  
    }
    
    return status;
}
コード例 #12
0
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;
}
コード例 #13
0
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; 
}
コード例 #14
0
ファイル: ar6000_cf.c プロジェクト: NemProjects/WLAN
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;
}
コード例 #15
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;
}
コード例 #16
0
ファイル: hci_bridge.c プロジェクト: CSCLOG/beaglebone
static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE     HCIHandle,
                                           struct hci_transport_properties *pProps, 
                                           void                     *pContext)
{
    struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext;
    int              status;
    u32 address, hci_uart_pwr_mgmt_params;
//    struct ar3k_config_info      ar3kconfig;
    
    pHcidevInfo->pHCIDev = HCIHandle;
    
    memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
    
    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", 
            (unsigned long)HCIHandle, 
            pHcidevInfo->HCIProps.HeadRoom, 
            pHcidevInfo->HCIProps.TailRoom,
            pHcidevInfo->HCIProps.IOBlockPad));
    
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
#else
    A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
#endif
                             
        /* provide buffers */
    RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
    RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
   
    do {
            /* start transport */
        status = HCI_TransportStart(pHcidevInfo->pHCIDev);
         
        if (status) {
            break;    
        }
        
        if (!pHcidevInfo->HciNormalMode) {
                /* in test mode, no need to go any further */
            break;    
        }

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

        /* Make sure both AR6K and AR3K have power management enabled */
        if (ar3kconfig.PwrMgmtEnabled) {
            status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
            if (status) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
            }
        }
        
        status = bt_register_hci(pHcidevInfo);
        
    } while (false);
コード例 #17
0
static void
ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket)
{
    AR_SOFTC_T        *ar = (AR_SOFTC_T *)Context;
    raw_htc_buffer    *busy;
    HTC_RAW_STREAM_ID streamID;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;

    busy = (raw_htc_buffer *)pPacket->pPktContext;
    A_ASSERT(busy != NULL);

    if (pPacket->Status == A_ECANCELED) {
        /*
         * HTC provides A_ECANCELED status when it doesn't want to be refilled
         * (probably due to a shutdown)
         */
        return;
    }

    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
    if(streamID == HTC_RAW_STREAM_NOT_MAPPED) {
        return; /* in case panic_on_assert==0 */
    }

#ifdef CF
    if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
#else
    if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
#endif /* CF */
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
    }

    A_ASSERT((pPacket->Status != A_OK) ||
             (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));

    busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
    busy->currPtr = HTC_HEADER_LEN;
    arRaw->read_buffer_available[streamID] = TRUE;
    //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb:  0x%X 0x%X \n", busy->currPtr,busy->length);
    up(&arRaw->raw_htc_read_sem[streamID]);

    /* Signal the waiting process */
    AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
    wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
}

static void
ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket)
{
    AR_SOFTC_T          *ar = (AR_SOFTC_T  *)Context;
    raw_htc_buffer      *free;
    HTC_RAW_STREAM_ID   streamID;
    AR_RAW_HTC_T *arRaw = ar->arRawHtc;

    free = (raw_htc_buffer *)pPacket->pPktContext;
    A_ASSERT(free != NULL);

    if (pPacket->Status == A_ECANCELED) {
        /*
         * HTC provides A_ECANCELED status when it doesn't want to be refilled
         * (probably due to a shutdown)
         */
        return;
    }

    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
    if(streamID == HTC_RAW_STREAM_NOT_MAPPED) {
        return; /* in case panic_on_assert==0 */
    }
#ifdef CF
    if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
#else
    if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
#endif
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
    }

    A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));

    free->length = 0;
    arRaw->write_buffer_available[streamID] = TRUE;
    up(&arRaw->raw_htc_write_sem[streamID]);

    /* Signal the waiting process */
    AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
    wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
}

/* connect to a service */
static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T        *ar,
        HTC_RAW_STREAM_ID StreamID)
{
    A_STATUS                 status;
    HTC_SERVICE_CONNECT_RESP response;
    A_UINT8                  streamNo;
    HTC_SERVICE_CONNECT_REQ  connect;

    do {

        A_MEMZERO(&connect,sizeof(connect));
        /* pass the stream ID as meta data to the RAW streams service */
        streamNo = (A_UINT8)StreamID;
        connect.pMetaData = &streamNo;
        connect.MetaDataLength = sizeof(A_UINT8);
        /* these fields are the same for all endpoints */
        connect.EpCallbacks.pContext = ar;
        connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
        connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
        /* simple interface, we don't need these optional callbacks */
        connect.EpCallbacks.EpRecvRefill = NULL;
        connect.EpCallbacks.EpSendFull = NULL;
        connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;

        /* connect to the raw streams service, we may be able to get 1 or more
         * connections, depending on WHAT is running on the target */
        connect.ServiceID = HTC_RAW_STREAMS_SVC;

        A_MEMZERO(&response,sizeof(response));

        /* try to connect to the raw stream, it is okay if this fails with
         * status HTC_SERVICE_NO_MORE_EP */
        status = HTCConnectService(ar->arHtcTarget,
                                   &connect,
                                   &response);

        if (A_FAILED(status)) {
            if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
                status = A_OK;
            }
            break;
        }

        /* set endpoint mapping for the RAW HTC streams */
        arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);

        AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n",
                                           StreamID, arRawStream2EndpointID(ar,StreamID)));

    } while (FALSE);

    return status;
}
コード例 #18
0
ファイル: htc.c プロジェクト: NemProjects/WLAN
/* wait for the target to arrive (sends HTC Ready message)
 * this operation is fully synchronous and the message is polled for */
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
{
    HTC_TARGET              *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    A_STATUS                 status;
    HTC_PACKET              *pPacket = NULL;
    HTC_READY_MSG           *pRdyMsg;
    HTC_SERVICE_CONNECT_REQ  connect;
    HTC_SERVICE_CONNECT_RESP resp;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%X) \n", (A_UINT32)target));


    do {

#ifdef MBOXHW_UNIT_TEST

        status = DoMboxHWTest(&target->Device);

        if (status != A_OK) {
            break;
        }

#endif

		/* we should be getting 1 control message that the target is ready */
        status = HTCWaitforControlMessage(target, &pPacket);

        if (A_FAILED(status)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n"));
            break;
        }

		/* we controlled the buffer creation so it has to be properly aligned */
        pRdyMsg = (HTC_READY_MSG *)pPacket->pBuffer;

        if ((pRdyMsg->MessageID != HTC_MSG_READY_ID) ||
            (pPacket->ActualLength < sizeof(HTC_READY_MSG))) {
                /* this message is not valid */
            AR_DEBUG_ASSERT(FALSE);
            status = A_EPROTO;
            break;
        }

        if (pRdyMsg->CreditCount == 0 || pRdyMsg->CreditSize == 0) {
              /* this message is not valid */
            AR_DEBUG_ASSERT(FALSE);
            status = A_EPROTO;
            break;
        }

        target->TargetCredits = pRdyMsg->CreditCount;
        target->TargetCreditSize = pRdyMsg->CreditSize;

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Target Ready: credits: %d credit size: %d\n",
                target->TargetCredits, target->TargetCreditSize));

		printk(" Target Ready: credits: %d credit size: %d\n",target->TargetCredits, target->TargetCreditSize);
			

            /* setup our pseudo HTC control endpoint connection */
        A_MEMZERO(&connect,sizeof(connect));
        A_MEMZERO(&resp,sizeof(resp));
        connect.EpCallbacks.pContext = target;
        connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
        connect.EpCallbacks.EpRecv = HTCControlRecv;
        connect.EpCallbacks.EpRecvRefill = NULL;  /* not needed */
        connect.EpCallbacks.EpSendFull = NULL;    /* not nedded */
        connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS;
        connect.ServiceID = HTC_CTRL_RSVD_SVC;

            /* connect fake service */
        status = HTCConnectService((HTC_HANDLE)target,
                                   &connect,
                                   &resp);

        if (!A_FAILED(status)) {
            break;
        }

    } while (FALSE);

    if (pPacket != NULL) {
        HTC_FREE_CONTROL_RX(target,pPacket);
    }

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

    return status;
}
コード例 #19
0
ファイル: hif_scatter.c プロジェクト: ANFS/ANFS-kernel
    /* 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;
}
コード例 #20
0
ファイル: htc.c プロジェクト: NemProjects/WLAN
/* 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;
}
コード例 #21
0
ファイル: ar6k.c プロジェクト: ANFS/ANFS-kernel
A_STATUS DevSetup(AR6K_DEVICE *pDev)
{
    A_UINT32 blocksizes[AR6K_MAILBOXES];
    A_STATUS status = A_OK;
    int      i;
    HTC_CALLBACKS htcCallbacks;

    do {

        DL_LIST_INIT(&pDev->ScatterReqHead);
           /* initialize our free list of IO packets */
        INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList);
        A_MUTEX_INIT(&pDev->Lock);

        A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
            /* the device layer handles these */
        htcCallbacks.rwCompletionHandler = DevRWCompletionHandler;
        htcCallbacks.dsrHandler = DevDsrHandler;
        htcCallbacks.context = pDev;

        status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks);

        if (A_FAILED(status)) {
            break;
        }

        pDev->HifAttached = TRUE;

            /* get the addresses for all 4 mailboxes */
        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR,
                                    &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo));

        if (status != A_OK) {
            A_ASSERT(FALSE);
            break;
        }

            /* carve up register I/O packets (these are for ASYNC register I/O ) */
        for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) {
            HTC_PACKET *pIOPacket;
            pIOPacket = &pDev->RegIOBuffers[i].HtcPacket;
            SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket,
                                          pDev,
                                          pDev->RegIOBuffers[i].Buffer,
                                          AR6K_REG_IO_BUFFER_SIZE,
                                          0); /* don't care */
            AR6KFreeIOPacket(pDev,pIOPacket);
        }

            /* get the block sizes */
        status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
                                    blocksizes, sizeof(blocksizes));

        if (status != A_OK) {
            A_ASSERT(FALSE);
            break;
        }

            /* note: we actually get the block size of a mailbox other than 0, for SDIO the block
             * size on mailbox 0 is artificially set to 1.  So we use the block size that is set
             * for the other 3 mailboxes */
        pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
            /* must be a power of 2 */
        A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0);

            /* assemble mask, used for padding to a block */
        pDev->BlockMask = pDev->BlockSize - 1;

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n",
                    pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]));

        pDev->GetPendingEventsFunc = NULL;
            /* see if the HIF layer implements the get pending events function  */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
                           &pDev->GetPendingEventsFunc,
                           sizeof(pDev->GetPendingEventsFunc));

            /* assume we can process HIF interrupt events asynchronously */
        pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC;

            /* see if the HIF layer overrides this assumption */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_IRQ_PROC_MODE,
                           &pDev->HifIRQProcessingMode,
                           sizeof(pDev->HifIRQProcessingMode));

        switch (pDev->HifIRQProcessingMode) {
            case HIF_DEVICE_IRQ_SYNC_ONLY:
                AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n"));
                    /* see if HIF layer wants HTC to yield */
                HIFConfigureDevice(pDev->HIFDevice,
                                   HIF_DEVICE_GET_IRQ_YIELD_PARAMS,
                                   &pDev->HifIRQYieldParams,
                                   sizeof(pDev->HifIRQYieldParams));

                if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) {
                    AR_DEBUG_PRINTF(ATH_DEBUG_WARN,
                        ("HIF requests that DSR yield per %d RECV packets \n",
                        pDev->HifIRQYieldParams.RecvPacketYieldCount));
                    pDev->DSRCanYield = TRUE;
                }
                break;
            case HIF_DEVICE_IRQ_ASYNC_SYNC:
                AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n"));
                break;
            default:
                A_ASSERT(FALSE);
        }

        pDev->HifMaskUmaskRecvEvent = NULL;

            /* see if the HIF layer implements the mask/unmask recv events function  */
        HIFConfigureDevice(pDev->HIFDevice,
                           HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,
                           &pDev->HifMaskUmaskRecvEvent,
                           sizeof(pDev->HifMaskUmaskRecvEvent));

        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n",
                 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent));

        status = DevDisableInterrupts(pDev);

        if (A_FAILED(status)) {
            break;
        }

        status = DevSetupGMbox(pDev);

    } while (FALSE);

    if (A_FAILED(status)) {
        if (pDev->HifAttached) {
            HIFDetachHTC(pDev->HIFDevice);
            pDev->HifAttached = FALSE;
        }
    }

    return status;

}
コード例 #22
0
ファイル: htc.c プロジェクト: NemProjects/WLAN
void
HTCStop(HTC_TARGET *target)
{
    A_UINT32 count;
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    A_UINT32 window_data;
    HTC_ENDPOINT *endPoint;
    HTC_REG_REQUEST_LIST *regList;
    HTC_REG_REQUEST_ELEMENT *element;
    HTC_DATA_REQUEST_QUEUE *sendQueue;
    HTC_DATA_REQUEST_QUEUE *recvQueue;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStop: Enter");

    /* 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);

    /* Disable the host controller interrupts */
    HIFMaskInterrupt(target->device);

    /* Flush all the queues and return the buffers to their owner */
    for (count = ENDPOINT1; count <= ENDPOINT4; count ++) {
        endPoint = &target->endPoint[count];

        /* Decrement the number of credits consumed */
        if (endPoint->txCreditsConsumed) {
            HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, 
                              HIF_SYNCHRONOUS, HIF_BYTE_BASIS, 
                              HIF_FIXED_ADDRESS);
            address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, count);
#ifdef ONLY_16BIT
            status = HIFReadWrite(target->device, address, 
                                  (A_UCHAR *)endPoint->txCreditsAvailable, 
                                  endPoint->txCreditsConsumed * 2, &request, NULL);
#else
            status = HIFReadWrite(target->device, address, 
                                  endPoint->txCreditsAvailable, 
                                  endPoint->txCreditsConsumed, &request, NULL);
#endif
            AR_DEBUG_ASSERT(status == A_OK);
        }

        SET_TX_CREDITS_AVAILABLE(endPoint, 0);
        SET_TX_CREDITS_CONSUMED(endPoint, 0);

#ifdef DEBUG
        txcreditsavailable[count] = GET_TX_CREDITS_AVAILABLE(endPoint);
        txcreditsconsumed[count] = GET_TX_CREDITS_CONSUMED(endPoint);
#endif

        endPoint->txCreditsIntrEnable = FALSE;
        endPoint->rxLengthPending = 0;
        endPoint->enabled = FALSE;

        /* Flush the Pending Receive Queue */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "Flushing the recv queue & returning the buffers\n");

        recvQueue = &endPoint->recvQueue;
        flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED);

        /* Flush the Pending Send Queue */
        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "Flushing the send queue & returning the buffers\n");
        sendQueue = &endPoint->sendQueue;
        flushMboxQueue(endPoint, sendQueue, HTC_BUFFER_SENT);
    }

    /* Clear the tx counters */
    memset(tx_attempt, 0, sizeof(tx_attempt));
    memset(tx_post, 0, sizeof(tx_post));
    memset(tx_complete, 0, sizeof(tx_complete));

    /* Attempting a force reset of the target */
    window_data = RESET_CONTROL_COLD_RST_MASK;
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
    address = getRegAddr(WINDOW_DATA_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, (A_UCHAR *)&window_data, 
                          4, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);
    
    _WRITE_WINDOW_ADDR(target, WINDOW_WRITE_ADDR_REG, RESET_CONTROL_ADDRESS);

    /* 
     * Read back the RESET CAUSE register to ensure that the cold reset 
     * went through.
     */
    A_MDELAY(2000); /* 2 Second delay to allow dragon to settle down */
    _WRITE_WINDOW_ADDR(target, WINDOW_READ_ADDR_REG, RESET_CAUSE_ADDRESS);
    window_data = 0;
    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
    address = getRegAddr(WINDOW_DATA_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, (A_UCHAR *)&window_data, 
                          4, &request, NULL);
    AR_DEBUG_ASSERT(status == A_OK);     
    HTC_DEBUG_PRINTF(ATH_LOG_INF, "window data: %d\n", window_data);
    window_data &= RESET_CAUSE_LAST_MASK;

    if (window_data != 2) {
        HTC_DEBUG_PRINTF(ATH_LOG_ERR, "Unable to cold reset the target\n");
    }

    /* 
     * Ensure that all the pending asynchronous register read/writes have 
     * been finished.
     */
    regList = &target->regList;
    for (count = 0; count < HTC_REG_REQUEST_LIST_SIZE; count ++) {
        element = &regList->element[count];
        AR_DEBUG_ASSERT(IS_ELEMENT_FREE(element));
    }

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

    HTC_DEBUG_PRINTF(ATH_LOG_TRC, "HTCStop: Exit");
}
コード例 #23
0
/* called in response to the arrival of a service connection message */
LOCAL void HTCProcessConnectMsg(HTC_CONTEXT *pHTC, HTC_CONNECT_SERVICE_MSG *pMsg)
{
	HTC_SERVICE *pService = pHTC->pServiceList;
	A_UINT8 connectStatus = HTC_SERVICE_NOT_FOUND;
	adf_nbuf_t pBuffer;
	HTC_CONNECT_SERVICE_RESPONSE_MSG *pRspMsg;
	int metaDataOutLen = 0;
	A_UINT16 serviceId = adf_os_ntohs(pMsg->ServiceID);
    
	pBuffer = HTCAllocMsgBuffer(pHTC);
	/* note : this will be aligned */
	pRspMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)
                adf_nbuf_put_tail(pBuffer, sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG));
                                 
	A_MEMZERO(pRspMsg,sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG));
	pRspMsg->MessageID = adf_os_htons(HTC_MSG_CONNECT_SERVICE_RESPONSE_ID);
	/* reflect the service ID for this connect attempt */
	pRspMsg->ServiceID = adf_os_htons(serviceId);

	while (pService) {
        
		if (pHTC->CurrentEpIndex >= ENDPOINT_MAX) {
			/* no more endpoints */
			connectStatus = HTC_SERVICE_NO_RESOURCES;
			break;    
		}

		if (serviceId == pService->ServiceID) {
			/* we found a match */             
			A_UINT8 *pMetaDataIN = NULL; 
			A_UINT8 *pMetaDataOut;
            
			/* outgoing meta data resides in the space after the response message */
			pMetaDataOut = ((A_UINT8 *)pRspMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG);
            
			if (pMsg->ServiceMetaLength != 0) {
				/* the meta data follows the connect service message */
				pMetaDataIN = ((A_UINT8 *)pMsg) + sizeof(HTC_CONNECT_SERVICE_MSG);
			}

			/* call the connect callback with the endpoint to use and pointers to meta data */
			connectStatus = pService->ProcessConnect(pService,
								 pHTC->CurrentEpIndex,
								 pMetaDataIN,
								 pMsg->ServiceMetaLength,
								 pMetaDataOut,
								 &metaDataOutLen);
            
			/* check if the service accepted this connection request */
			if (HTC_SERVICE_SUCCESS == connectStatus) {
				/* set the length of the response meta data going back to the host */
				pRspMsg->ServiceMetaLength = (A_UINT8)metaDataOutLen;
				/* set the endpoint ID the host will now communicate over */
				pRspMsg->EndpointID = pHTC->CurrentEpIndex;
				/* return the maximum message size for this service */
				pRspMsg->MaxMsgSize = adf_os_htons((A_UINT16)pService->MaxSvcMsgSize);
				/* assign this endpoint to this service, this will be used in routing messages */
				pHTC->Endpoints[pHTC->CurrentEpIndex].pService = pService;
				/* set connection flags */
				pHTC->Endpoints[pHTC->CurrentEpIndex].ConnectionFlags = pMsg->ConnectionFlags;
                
				pHTC->Endpoints[pHTC->CurrentEpIndex].DownLinkPipeID = pMsg->DownLinkPipeID;
				pHTC->Endpoints[pHTC->CurrentEpIndex].UpLinkPipeID = pMsg->UpLinkPipeID;
                
				/* mark that we are now connected */
				pService->ServiceFlags |= HTC_SERVICE_FLAGS_CONNECTED;
				/* bump up our index, this EP is now in use */
				pHTC->CurrentEpIndex++;   
			}

			break;
		}       
        
		pService = pService->pNext;   
	}
                   
	pRspMsg->Status = connectStatus;    
    
	/* send out the response message */
	HTC_SendMsg(pHTC, ENDPOINT0, pBuffer); 
}
コード例 #24
0
ファイル: htc.c プロジェクト: 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;
}
コード例 #25
0
ファイル: abtfilt_wlan.c プロジェクト: Ar3kkusu/AR6kSDK.3.1
void Abf_WlanCheckSettings(A_CHAR *wifname, A_UINT32 *btfiltFlags)
{
    int sd;
    A_CHAR ifname[IFNAMSIZ];
#ifdef ANDROID 
    char ifprop[PROPERTY_VALUE_MAX];
    if (wifname[0] == '\0' && property_get("wifi.interface", ifprop, NULL)) {
        strcpy(wifname, ifprop);
    }
#endif

    {
        A_BOOL found = FALSE;
        A_CHAR linebuf[1024];
        FILE *f = fopen("/proc/net/wireless", "r");
        if (f) {
            while(fgets(linebuf, sizeof(linebuf)-1, f)) {
                if (strchr(linebuf, ':')) {
                    char *dest = ifname;
                    char *p = linebuf;
                    while(*p && isspace(*p)) ++p;
                    while (*p && *p != ':')
                        *dest++ = *p++;
                    *dest = '\0';
                    if (strcmp(wifname, ifname)==0) {
                        found = TRUE;
                        break;
                    }
                }
            }
            if (!found && ifname[0]!='\0') {                
                strcpy(wifname, ifname);
            }
            fclose(f);
        }
    }
    A_DEBUG("%s : wlan: %s\n", __FUNCTION__, wifname);
    if (wifname[0] == '\0' || !btfiltFlags) {
        return;
    }

    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        A_ERR("[%s] Error creating socket: %d\n", __FUNCTION__, sd);
        return;
    }

    do {
        A_UINT32 flags = *btfiltFlags;
        struct ifreq ifr;
        struct ar6000_version revinfo;
        A_MEMZERO(&revinfo, sizeof(revinfo));
        strncpy(ifr.ifr_name, wifname, sizeof(ifr.ifr_name));
        ifr.ifr_data = (void *)&revinfo;
        if (ioctl(sd, AR6000_IOCTL_WMI_GETREV, &ifr) < 0) {
            break;              
        }                       
        if ( (revinfo.target_ver & 0xf0000000)==0x30000000) {
            *btfiltFlags |= ABF_WIFI_CHIP_IS_VENUS;
        } else {
            *btfiltFlags &= ~ABF_WIFI_CHIP_IS_VENUS;
        }
        if (*btfiltFlags != flags) {
            A_DEBUG("Change btfilt flags from %u to %u isVenus %d\n", flags, *btfiltFlags, 
                        (*btfiltFlags & ABF_WIFI_CHIP_IS_VENUS) ? "yes" : "no");
        }
    } while (0);
    close(sd);
}
コード例 #26
0
ファイル: htc.c プロジェクト: KHATEEBNSIT/AP
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
{
    A_STATUS                status = A_OK;
    HTC_TARGET              *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
    HTC_READY_EX_MSG        *pReadyMsg;
    HTC_SERVICE_CONNECT_REQ  connect;
    HTC_SERVICE_CONNECT_RESP resp;
    HTC_READY_MSG *rdy_msg;
    A_UINT16 htc_rdy_msg_id;

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%p) \n", HTCHandle));
    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n"));

    do {

        status = HIFStart(target->hif_dev);
        if (A_FAILED(status)) {
            break;
        }

        status = HTCWaitRecvCtrlMessage(target);

        if (A_FAILED(status)) {
            break;
        }

        if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg Len:%d! \n",target->CtrlResponseLength));
            status = A_ECOMM;
            break;
        }

        pReadyMsg = (HTC_READY_EX_MSG *)target->CtrlResponseBuffer;

        rdy_msg = &pReadyMsg->Version2_0_Info;
        htc_rdy_msg_id = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
        if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                        ("Invalid HTC Ready Msg : 0x%X ! \n",htc_rdy_msg_id));
            status = A_ECOMM;
            break;
        }

        target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT);
        target->TargetCreditSize = (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);

        AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("Target Ready! : transmit resources : %d size:%d\n",
                target->TotalTransmitCredits, target->TargetCreditSize));

        if ((0 == target->TotalTransmitCredits) || (0 == target->TargetCreditSize)) {
            status = A_ECOMM;
            break;
        }
            /* done processing */
        target->CtrlResponseProcessing = FALSE;

        HTCSetupTargetBufferAssignments(target);

            /* setup our pseudo HTC control endpoint connection */
        A_MEMZERO(&connect,sizeof(connect));
        A_MEMZERO(&resp,sizeof(resp));
        connect.EpCallbacks.pContext = target;
        connect.EpCallbacks.EpTxComplete = HTCControlTxComplete;
        connect.EpCallbacks.EpRecv = HTCControlRxComplete;
        connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
        connect.ServiceID = HTC_CTRL_RSVD_SVC;

            /* connect fake service */
        status = HTCConnectService((HTC_HANDLE)target,
                                   &connect,
                                   &resp);

    } while (FALSE);

    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit (%d)\n",status));
    AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n"));
    return status;
}
コード例 #27
0
ファイル: hif.c プロジェクト: AvalueAES/rev-sa01
void HIFDetachHTC(HIF_DEVICE *device)
{
    A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks));
}
コード例 #28
0
ファイル: abtfilt_main.c プロジェクト: burstlam/AR6kSDK.3.1
int
main(int argc, char *argv[])
{
    int ret;
    char *config_file = NULL;
    int opt = 0, daemonize = 1, debug = 0, console_output=0;
    progname = argv[0];
    A_STATUS status;
    struct sigaction sa;
    ATHBT_FILTER_INFO *pInfo;
    A_UINT32 btfiltFlags = 0;

    A_MEMZERO(&g_AthBtFilterInstance, sizeof(ATH_BT_FILTER_INSTANCE));

    /*
     * Keep an option to specify the wireless extension. By default,
     * assume it to be equal to WIRELESS_EXT TODO
     */

    /* Get user specified options */
    while ((opt = getopt(argc, argv, "bsvandczxf:w:")) != EOF) {
        switch (opt) {
        case 'n':
            daemonize = 0;
            break;

        case 'd':
            debug = 1;
            break;

        case 'f':
            if (optarg) {
                config_file = strdup(optarg);
            }
            break;
        case 'c':
            console_output = 1;
            break;
        case 'a':
            btfiltFlags |= ABF_ENABLE_AFH_CHANNEL_CLASSIFICATION;
            break;
        case 'z':
            btfiltFlags |= ABF_USE_HCI_FILTER_FOR_HEADSET_PROFILE;
            break;
        case 'v':
            btfiltFlags |= ABF_WIFI_CHIP_IS_VENUS ;
            A_DEBUG("wifi chip is venus\n");
            break;
        case 'x':
            btfiltFlags |= ABF_BT_CHIP_IS_ATHEROS ;
            A_DEBUG("bt chip is atheros\n");
            break;
        case 's':
            btfiltFlags |= ABF_FE_ANT_IS_SA ;
            A_DEBUG("Front End Antenna Configuration is single antenna \n");
            break;
        case 'w':
            memset(wifname, '\0', IFNAMSIZ);
            strcpy(wifname, optarg);
            g_AthBtFilterInstance.pWlanAdapterName = (A_CHAR *)&wifname;
            break;
	case 'b':
	    btfiltFlags |= ABF_USE_ONLY_DBUS_FILTERING;
	    break;
        default:
            usage();
            exit(1);
        }
    }

    /* Launch the daemon if desired */
    if (daemonize && daemon(0, console_output ? 1 : 0)) {
        printf("Can't daemonize: %s\n", strerror(errno));
        exit(1);
    }

    /* Initialize the debug infrastructure */
    A_DBG_INIT("ATHBT", "Ath BT Filter Daemon");
    if (debug) {
        if (console_output) {
            A_DBG_SET_OUTPUT_TO_CONSOLE();
        }
       // setlogmask(LOG_INFO | LOG_DEBUG | LOG_ERR);
        A_INFO("Enabling Debug Information\n");
        A_SET_DEBUG(1);
    }

    if (config_file) {
        A_DEBUG("Config file: %s\n", config_file);
        if (!(gConfigFile = fopen(config_file, "r")))
        {
            A_ERR("[%s] fopen failed\n", __FUNCTION__);
        }
    }

    A_MEMZERO(&sa, sizeof(struct sigaction));
    sa.sa_flags = SA_NOCLDSTOP;
    sa.sa_handler = Abf_SigTerm;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT,  &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sa, NULL);

    Abf_HciLibInit(&btfiltFlags);

    /* Initialize the Filter core */
    do {
        Abf_WlanCheckSettings(wifname, &btfiltFlags);
        ret = AthBtFilter_Attach(&g_AthBtFilterInstance, btfiltFlags );
        if (ret) {
            A_ERR("Filter initialization failed\n");
            break;
        }

        /* Initialize the WLAN notification mechanism */
        status = Abf_WlanStackNotificationInit(&g_AthBtFilterInstance, btfiltFlags );
        if (A_FAILED(status)) {
            AthBtFilter_Detach(&g_AthBtFilterInstance);
            A_ERR("WLAN stack notification init failed\n");
            break;
        }

        /* Initialize the BT notification mechanism */
        status = Abf_BtStackNotificationInit(&g_AthBtFilterInstance,btfiltFlags);
        if (A_FAILED(status)) {
            Abf_WlanStackNotificationDeInit(&g_AthBtFilterInstance);
            AthBtFilter_Detach(&g_AthBtFilterInstance);
            A_ERR("BT stack notification init failed\n");
            break;
        }

        /* Check for errors on the return value TODO */
        pInfo = g_AthBtFilterInstance.pContext;
        GpInfo = pInfo;

        A_DEBUG("Service running, waiting for termination .... \n");

            /* wait for termination signal */
        while (!terminated) {
            sleep(1);
        }
    } while(FALSE);

    /* Initiate the shutdown sequence */
    if(GpInfo != NULL) {
        AthBtFilter_State_Off(GpInfo);
    }
    Abf_ShutDown();

    Abf_HciLibDeInit();
    /* Shutdown */
    if (gConfigFile) {
        fclose(gConfigFile);
    }

    if (config_file) {
        A_FREE(config_file);
    }

    A_DEBUG("Service terminated \n");
    A_MEMZERO(&g_AthBtFilterInstance, sizeof(ATH_BT_FILTER_INSTANCE));
    A_DBG_DEINIT();

    return 0;
}
コード例 #29
0
A_STATUS HTCSendSetupComplete(HTC_TARGET *target)
{
    HTC_PACKET             *pSendPacket = NULL;
    A_STATUS                status;

    do {
           /* allocate a packet to send to the target */
        pSendPacket = HTC_ALLOC_CONTROL_TX(target);

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

        if (target->HTCTargetVersion >= HTC_VERSION_2P1) {
            HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx;
            A_UINT32                  setupFlags = 0;
                   
            pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer;
            A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG));
            pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID;   
            if (target->MaxMsgPerBundle > 0) {
                    /* host can do HTC bundling, indicate this to the target */
                setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV; 
                pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle;
            }    
            A_MEMCPY(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags));            
            SET_HTC_PACKET_INFO_TX(pSendPacket,
                                   NULL,
                                   (A_UINT8 *)pSetupCompleteEx,
                                   sizeof(HTC_SETUP_COMPLETE_EX_MSG),
                                   ENDPOINT_0,
                                   HTC_SERVICE_TX_PACKET_TAG);
      
        }  else {            
            HTC_SETUP_COMPLETE_MSG *pSetupComplete;
                /* assemble setup complete message */
            pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer;
            A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG));
            pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID;   
            SET_HTC_PACKET_INFO_TX(pSendPacket,
                                   NULL,
                                   (A_UINT8 *)pSetupComplete,
                                   sizeof(HTC_SETUP_COMPLETE_MSG),
                                   ENDPOINT_0,
                                   HTC_SERVICE_TX_PACKET_TAG);
        }

            /* we want synchronous operation */
        pSendPacket->Completion = NULL;
        HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0);
            /* send the message */
        status = HTCIssueSend(target,pSendPacket);

    } while (FALSE);

    if (pSendPacket != NULL) {
        HTC_FREE_CONTROL_TX(target,pSendPacket);
    }

    return status;
}
コード例 #30
0
ファイル: htc.c プロジェクト: S5-APQ8084/qcacld-3.0
A_STATUS htc_wait_target(HTC_HANDLE HTCHandle)
{
	A_STATUS status = A_OK;
	HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
	HTC_READY_EX_MSG *pReadyMsg;
	HTC_SERVICE_CONNECT_REQ connect;
	HTC_SERVICE_CONNECT_RESP resp;
	HTC_READY_MSG *rdy_msg;
	A_UINT16 htc_rdy_msg_id;

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
			("htc_wait_target - Enter (target:0x%p) \n", HTCHandle));
	AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n"));

	do {

		status = hif_start(target->hif_dev);
		if (A_FAILED(status)) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("hif_start failed\n"));
			break;
		}

		status = htc_wait_recv_ctrl_message(target);

		if (A_FAILED(status)) {
			break;
		}

		if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("Invalid HTC Ready Msg Len:%d! \n",
					 target->CtrlResponseLength));
			status = A_ECOMM;
			break;
		}

		pReadyMsg = (HTC_READY_EX_MSG *) target->CtrlResponseBuffer;

		rdy_msg = &pReadyMsg->Version2_0_Info;
		htc_rdy_msg_id =
			HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID);
		if (htc_rdy_msg_id != HTC_MSG_READY_ID) {
			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
					("Invalid HTC Ready Msg : 0x%X ! \n",
					 htc_rdy_msg_id));
			status = A_ECOMM;
			break;
		}

		target->TotalTransmitCredits =
			HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT);
		target->TargetCreditSize =
			(int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE);
		target->MaxMsgsPerHTCBundle =
			(A_UINT8) pReadyMsg->MaxMsgsPerHTCBundle;
		/* for old fw this value is set to 0. But the minimum value should be 1,
		 * i.e., no bundling */
		if (target->MaxMsgsPerHTCBundle < 1)
			target->MaxMsgsPerHTCBundle = 1;

		AR_DEBUG_PRINTF(ATH_DEBUG_INIT,
				("Target Ready! : transmit resources : %d size:%d, MaxMsgsPerHTCBundle = %d\n",
				 target->TotalTransmitCredits,
				 target->TargetCreditSize,
				 target->MaxMsgsPerHTCBundle));

		if ((0 == target->TotalTransmitCredits)
		    || (0 == target->TargetCreditSize)) {
			status = A_ECOMM;
			break;
		}
		/* done processing */
		target->CtrlResponseProcessing = false;

		htc_setup_target_buffer_assignments(target);

		/* setup our pseudo HTC control endpoint connection */
		A_MEMZERO(&connect, sizeof(connect));
		A_MEMZERO(&resp, sizeof(resp));
		connect.EpCallbacks.pContext = target;
		connect.EpCallbacks.EpTxComplete = htc_control_tx_complete;
		connect.EpCallbacks.EpRecv = htc_control_rx_complete;
		connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS;
		connect.ServiceID = HTC_CTRL_RSVD_SVC;

		/* connect fake service */
		status = htc_connect_service((HTC_HANDLE) target,
					     &connect, &resp);

	} while (false);

	AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Exit (%d)\n", status));
	AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n"));
	return status;
}