예제 #1
0
void ar6000_dtimexpiry_event(void *dev)
{
	
#if 0 //bluebird
    A_BOOL isMcastQueued = FALSE;
    struct sk_buff *skb = NULL;

    /* If there are no associated STAs, ignore the DTIM expiry event.
     * There can be potential race conditions where the last associated
     * STA may disconnect & before the host could clear the 'Indicate DTIM'
     * request to the firmware, the firmware would have just indicated a DTIM
     * expiry event. The race is between 'clear DTIM expiry cmd' going
     * from the host to the firmware & the DTIM expiry event happening from
     * the firmware to the host.
     */
    if (ar->sta_list_index == 0) {
        return;
    }

    A_MUTEX_LOCK(&ar->mcastpsqLock);
    isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq);
    A_MUTEX_UNLOCK(&ar->mcastpsqLock);

    A_ASSERT(isMcastQueued == FALSE);

    /* Flush the mcast psq to the target */
    /* Set the STA flag to DTIMExpired, so that the frame will go out */
    ar->DTIMExpired = TRUE;

    A_MUTEX_LOCK(&ar->mcastpsqLock);
    while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
        skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
        A_MUTEX_UNLOCK(&ar->mcastpsqLock);

        ar6000_data_tx(skb, ar->arNetDev);

        A_MUTEX_LOCK(&ar->mcastpsqLock);
    }
    A_MUTEX_UNLOCK(&ar->mcastpsqLock);

    /* Reset the DTIMExpired flag back to 0 */
    ar->DTIMExpired = FALSE;

    /* Clear the LSB of the BitMapCtl field of the TIM IE */
    wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0);
#else
	NDIS_DEBUG_PRINTF(DBG_TRACE, " %s() is not ready yet~ \r\n", __FUNCTION__);
#endif

}
예제 #2
0
	bool CAsyncIOConnection::Connect(const ASOCK_ADDR& sa)
	{
		bool bRet;

		A_MUTEX_LOCK(&m_mtxLock);

		ZION_ASSERT(!m_pSendBuf);
		ZION_ASSERT(!m_hConn);
		ZION_ASSERT(!m_bConnecting);
		if(m_hConn || m_bConnecting)
		{
			bRet = false;
		}
		else
		{
			m_pSendBuf = NULL;
			m_bConnecting = true;
			bRet = Zion::Connect(sa, g_client_handler, CAsyncIOInit::Get().m_iopool, CAsyncIOInit::Get().m_workers, this);
			if(!bRet) m_bConnecting = false;
		}

		A_MUTEX_UNLOCK(&m_mtxLock);

		return bRet;
	}
예제 #3
0
	void CStressManager::DisconnectAll()
	{	
		Zion::Map<_U32, CStressClient*>::iterator i;
		_U32 count = 1;
		while(count>0)
		{
			count = 0;
			A_MUTEX_LOCK(&m_mtxLocker);
			for(i=m_mapClients.begin(); i!=m_mapClients.end(); i++)
			{
				i->second->Logout();
				if(i->second->GetClient()->GetState()!=CClient::STATE_NA && i->second->GetClient()->GetState()!=CClient::STATE_FAILED) count++;
			}
			A_MUTEX_UNLOCK(&m_mtxLocker);
			SwitchToThread();

			if(!CClientApp::GetDefault()->IsThread())
			{
				CClientApp::GetDefault()->Tick();
			}
		}

		for(i=m_mapClients.begin(); i!=m_mapClients.end(); i++)
		{
			delete i->second;
		}
		m_mapClients.clear();
	}
예제 #4
0
void a_module_debug_support_cleanup(void)
{
    ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
    ATH_DEBUG_MODULE_DBG_INFO *pCur;

    if (!g_ModuleDebugInit) {
        return;
    }

    g_ModuleDebugInit = FALSE;

    A_MUTEX_LOCK(&g_ModuleListLock);

    while (pInfo != NULL) {
        pCur = pInfo;
        pInfo = pInfo->pNext;
        pCur->pNext = NULL;
            /* clear registered flag */
        pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED;
    }

    A_MUTEX_UNLOCK(&g_ModuleListLock);

    A_MUTEX_DELETE(&g_ModuleListLock);
    g_pModuleInfoHead = NULL;
}
예제 #5
0
void
Abf_WlanStackNotificationDeInit(ATH_BT_FILTER_INSTANCE *pInstance)
{
    ATHBT_FILTER_INFO *pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext;
    ABF_WLAN_INFO *pAbfWlanInfo = pInfo->pWlanInfo;

    if (!pAbfWlanInfo) return;

    /* Terminate and wait for the WLAN Event Handler task to finish */
    A_MUTEX_LOCK(&pAbfWlanInfo->hWaitEventLock);
    if (pAbfWlanInfo->Loop) {
        pAbfWlanInfo->Loop = FALSE;
        A_COND_WAIT(&pAbfWlanInfo->hWaitEvent, &pAbfWlanInfo->hWaitEventLock, 
                    WAITFOREVER);
    }
    A_MUTEX_UNLOCK(&pAbfWlanInfo->hWaitEventLock);

    /* Flush all the BT actions from the filter core */
    HandleAdapterEvent(pInfo, ATH_ADAPTER_REMOVED);
    pInfo->pWlanInfo = NULL;
    A_MUTEX_DEINIT(&pAbfWlanInfo->hWaitEventLock);
    A_COND_DEINIT(&pAbfWlanInfo->hWaitEvent);
    A_MEMZERO(pAbfWlanInfo, sizeof(ABF_WLAN_INFO));
    A_FREE(pAbfWlanInfo);

    A_INFO("WLAN Stack Notification de-init complete\n");
}
예제 #6
0
	const Zion::String CStressClient::GetInfo()
	{
		Zion::String ret;
		A_MUTEX_LOCK(&m_pClient->m_mtxClient);
		ret = m_Info;
		A_MUTEX_UNLOCK(&m_pClient->m_mtxClient);
		return ret;
	}
예제 #7
0
	bool CClientApp::Tick(_U32 nTime)
	{
		if(m_bThread) return false;

		bool bQuit = false, bRet = false;
		CLIENTAPP_ITEM i;
		while(!bQuit)
		{
			A_MUTEX_LOCK(&m_mtxQueue);
			if(m_Queue.size()==0)
			{
				bQuit = true;
				A_MUTEX_UNLOCK(&m_mtxQueue);
				break;
			}
			i = m_Queue.front();
			m_Queue.pop_front();
			bRet = true;
			A_MUTEX_UNLOCK(&m_mtxQueue);

			switch(i.nCode)
			{
			case 0:
				i.pClient->OnLoginDone();
				break;
			case 1:
				i.pClient->OnLoginFailed();
				break;
			case 2:
				i.pClient->OnDisconnected();
				break;
			case 3:
				i.pClient->OnData(i.iid, i.fid, i.len, i.data);
				ZION_FREE(i.data);
				break;
			}
		}

		Zion::Set<CClient*>::iterator it;
		for(it=m_Clients.begin(); it!=m_Clients.end(); it++)
		{
			(*it)->Tick();
		}

		return bRet;
	}
예제 #8
0
	void CClientApp::QueueTask(CClient* pClient, CClientTask* pTask)
	{
		ZION_ASSERT(!m_bThread);

		CLIENTAPP_ITEM i = { 4, pClient, 0, 0, 0, NULL };
		A_MUTEX_LOCK(&m_mtxQueue);
		m_Queue.push_back(i);
		A_MUTEX_UNLOCK(&m_mtxQueue);
	}
예제 #9
0
	_U32 CStressManager::NewClient()
	{
		_U32 index = A_ATOM_INC(&m_nIDSeq);
		CStressClient* pClient = ZION_NEW CStressClient(index, CClientApp::GetDefault()->NewClient());
		A_MUTEX_LOCK(&m_mtxLocker);
		m_mapClients[index] = pClient;
		A_MUTEX_UNLOCK(&m_mtxLocker);
		return index;
	}
예제 #10
0
void ar6000_pspoll_event(void *dev,A_UINT8 aid)
{
	
#if 0 //bluebird
    sta_t *conn=NULL;
    A_BOOL isPsqEmpty = FALSE;

    conn = ieee80211_find_conn_for_aid(ar, aid);

    /* If the PS q for this STA is not empty, dequeue and send a pkt from
     * the head of the q. Also update the More data bit in the WMI_DATA_HDR
     * if there are more pkts for this STA in the PS q. If there are no more
     * pkts for this STA, update the PVB for this STA.
     */
    A_MUTEX_LOCK(&conn->psqLock);
    isPsqEmpty  = A_NETBUF_QUEUE_EMPTY(&conn->psq);
    A_MUTEX_UNLOCK(&conn->psqLock);

    if (isPsqEmpty) {
        /* TODO:No buffered pkts for this STA. Send out a NULL data frame */
    } else {
        struct sk_buff *skb = NULL;

        A_MUTEX_LOCK(&conn->psqLock);
        skb = A_NETBUF_DEQUEUE(&conn->psq);
        A_MUTEX_UNLOCK(&conn->psqLock);
        /* Set the STA flag to PSPolled, so that the frame will go out */
        STA_SET_PS_POLLED(conn);
        ar6000_data_tx(skb, ar->arNetDev);
        STA_CLR_PS_POLLED(conn);

        /* Clear the PVB for this STA if the queue has become empty */
        A_MUTEX_LOCK(&conn->psqLock);
        isPsqEmpty  = A_NETBUF_QUEUE_EMPTY(&conn->psq);
        A_MUTEX_UNLOCK(&conn->psqLock);

        if (isPsqEmpty) {
            wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0);
        }
    }
#else
	NDIS_DEBUG_PRINTF(DBG_TRACE, " %s() is not ready yet~ \r\n", __FUNCTION__);
#endif //bluebird
}
예제 #11
0
	CStressClient* CStressManager::GetClient(_U32 id)
	{
		CStressClient* pClient;
		Zion::Map<_U32, CStressClient*>::iterator i;
		A_MUTEX_LOCK(&m_mtxLocker);
		i = m_mapClients.find(id);
		pClient = (i==m_mapClients.end()?NULL:i->second);
		A_MUTEX_UNLOCK(&m_mtxLocker);
		return pClient;
	}
예제 #12
0
	void CAsyncIOConnection::OnRawConnected(HCONNECT hConn)
	{
		A_MUTEX_LOCK(&m_mtxLock);
		ZION_ASSERT(!m_hConn);
		m_hConn = hConn;
		m_bConnecting = false;
		A_MUTEX_UNLOCK(&m_mtxLock);

		CClientConnection::OnRawConnected();
	}
예제 #13
0
	void CStressManager::GetClients(Zion::Array<_U32>& clients)
	{
		clients.clear();
		Zion::Map<_U32, CStressClient*>::iterator i;
		A_MUTEX_LOCK(&m_mtxLocker);
		for(i=m_mapClients.begin(); i!=m_mapClients.end(); i++)
		{
			clients.push_back(i->first);
		}
		A_MUTEX_UNLOCK(&m_mtxLocker);
	}
예제 #14
0
	void CStressClient::Tick()
	{
		A_MUTEX_LOCK(&m_pClient->m_mtxClient);

		Zion::Map<Zion::String, CStressCase*>::iterator i;
		for(i=m_Cases.begin(); i!=m_Cases.end(); i++)
		{
			i->second->OnTick();
		}

		A_MUTEX_UNLOCK(&m_pClient->m_mtxClient);
	}
예제 #15
0
	void CAsyncIOConnection::OnRawDisconnected()
	{
		A_MUTEX_LOCK(&m_mtxLock);
		if(m_pSendBuf)
		{
			UnlockIoBuffer(m_pSendBuf);
			m_pSendBuf = NULL;
		}
		m_hConn = NULL;
		A_MUTEX_UNLOCK(&m_mtxLock);

		CClientConnection::OnRawDisconnected();
	}
예제 #16
0
	void CStressManager::UpdateAll()
	{
		A_MUTEX_LOCK(&m_mtxLocker);
		
		Zion::Map<_U32, CStressClient*>::iterator it = m_mapClients.begin();
		while(it != m_mapClients.end())
		{
			it->second->Tick();
			++it;
		}

		A_MUTEX_UNLOCK(&m_mtxLocker);
	}
예제 #17
0
	void CClientApp::QueueDisconnected(CClient* pClient)
	{
		if(m_bThread)
		{
			pClient->OnDisconnected();
			return;
		}

		CLIENTAPP_ITEM i = { 2, pClient, 0, 0, 0, NULL };
		A_MUTEX_LOCK(&m_mtxQueue);
		m_Queue.push_back(i);
		A_MUTEX_UNLOCK(&m_mtxQueue);
	}
예제 #18
0
	void CClientApp::QueueLoginDone(CClient* pClient)
	{
		if(m_bThread)
		{
			pClient->OnLoginDone();
			return;
		}

		CLIENTAPP_ITEM i = { 0, pClient, 0, 0, 0, NULL };
		A_MUTEX_LOCK(&m_mtxQueue);
		m_Queue.push_back(i);
		A_MUTEX_UNLOCK(&m_mtxQueue);
	}
예제 #19
0
	void CClientApp::QueueData(CClient* pClient, _U16 iid, _U16 fid, _U32 len, const _U8* data)
	{
		if(m_bThread)
		{
			pClient->OnData(iid, fid, len, data);
			return;
		}

		CLIENTAPP_ITEM i = { 3, pClient, iid, fid, len, NULL };
		i.data = (_U8*)ZION_ALLOC(len);
		memcpy(i.data, data, len);
		A_MUTEX_LOCK(&m_mtxQueue);
		m_Queue.push_back(i);
		A_MUTEX_UNLOCK(&m_mtxQueue);
	}
예제 #20
0
void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
{
    if (!g_ModuleDebugInit) {
        return;
    }

    A_MUTEX_LOCK(&g_ModuleListLock);

    if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) {
        if (g_pModuleInfoHead == NULL) {
            g_pModuleInfoHead = pInfo;
        } else {
           pInfo->pNext = g_pModuleInfoHead;
           g_pModuleInfoHead = pInfo;
        }
        pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED;
    }

    A_MUTEX_UNLOCK(&g_ModuleListLock);
}
예제 #21
0
	CStressCase* CStressClient::NewStressCase(const char* name)
	{
		CStressCase* pCase = NULL;

		A_MUTEX_LOCK(&m_pClient->m_mtxClient);

		Zion::Map<Zion::String, CStressCase*>::iterator i;
		i = m_Cases.find(name);
		if(i==m_Cases.end())
		{
			pCase = CStressManager::Get().CreateCase(name);
			if(pCase)
			{
				CaseAttach(pCase);
			}
		}

		A_MUTEX_UNLOCK(&m_pClient->m_mtxClient);

		return pCase;
	}
예제 #22
0
	void CAsyncIOConnection::SendData(_U32 len, const _U8* data, bool bPending)
	{
		A_MUTEX_LOCK(&m_mtxLock);

		HIOPOOL pool = HIOPoolOf(m_hConn);
		_U32 blen = GetIoBufferSize(pool);
		_U32 dolen;
		while(len>0)
		{
			if(!m_pSendBuf)
			{
				m_pSendBuf = LockIoBuffer(pool);
				m_nSendBufLen = 0;
			}

			dolen = (len>blen-m_nSendBufLen)?blen-m_nSendBufLen:len;

			memcpy(m_pSendBuf+m_nSendBufLen, data, dolen);
			len -= dolen;
			data += dolen;
			m_nSendBufLen += dolen;
			if(m_nSendBufLen==blen)
			{
				Send(m_hConn, m_nSendBufLen, m_pSendBuf);
				m_pSendBuf = NULL;
			}
		}

		if(!bPending && m_pSendBuf!=NULL && m_nSendBufLen>0)
		{
			Send(m_hConn, m_nSendBufLen, m_pSendBuf);
			m_pSendBuf = NULL;
		}

		A_MUTEX_UNLOCK(&m_mtxLock);
	}
예제 #23
0
void
htcEnableCreditCounterInterrupt(HTC_TARGET *target, 
                                HTC_ENDPOINT_ID endPointId)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_REG_REQUEST_ELEMENT *element;
#ifdef ONLY_16BIT
	A_UINT16 counter_int_enable16;
#endif
	A_UCHAR	counter_int_enable;


    endPoint = &target->endPoint[endPointId];
    AR_DEBUG_ASSERT(endPoint != NULL);

    A_MUTEX_LOCK(&counterCS);

    endPoint->txCreditsIntrEnable = TRUE;
    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, 
                      HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, 
                      HIF_FIXED_ADDRESS);
    element = allocateRegRequestElement(target);
    AR_DEBUG_ASSERT(element != NULL);

    counter_int_enable = ((target->endPoint[0].txCreditsIntrEnable << (4)) |
                         (target->endPoint[1].txCreditsIntrEnable << (5)) |
                         (target->endPoint[2].txCreditsIntrEnable << (6)) |
                         (target->endPoint[3].txCreditsIntrEnable << (7)) |
                         0x0F);
	

#ifdef ONLY_16BIT
    counter_int_enable16 = (counter_int_enable << 8) | target->table.error_status_enable;

    FILL_REG_BUFFER(element, NULL, 2, COUNTER_INT_STATUS_ENABLE_REG, counter_int_enable16);
	address = getRegAddr(ERROR_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          2, &request, element);
#else
    FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_ENABLE_REG, counter_int_enable);
    address = getRegAddr(COUNTER_INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          1, &request, element);
#endif

#ifndef HTC_SYNC
    AR_DEBUG_ASSERT(status == A_OK);
#else
    AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
    if (status == A_OK) { 
        element->completionCB(element, status);
    }
#endif

    A_MUTEX_UNLOCK(&counterCS);
}
예제 #24
0
/* 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;
}
예제 #25
0
A_STATUS
htcRegCompletionCB(HTC_REG_REQUEST_ELEMENT *element,
                   A_STATUS status) 
{
    A_STATUS ret;
    HTC_TARGET *target;
    HTC_ENDPOINT *endPoint;
    HTC_REG_BUFFER *regBuffer;
#ifdef ONLY_16BIT
    A_UINT16 txCreditsConsumed;
    A_UINT16 txCreditsAvailable;
#else
    A_UINT8 txCreditsConsumed;
    A_UINT8 txCreditsAvailable;
#endif
    HTC_ENDPOINT_ID endPointId;

    HTC_DEBUG_PRINTF(ATH_LOG_TRC | ATH_LOG_SEND | ATH_LOG_RECV, 
                    "htcRegCompletion - Enter\n");
    AR_DEBUG_ASSERT(status == A_OK);

    /* Get the context */
    AR_DEBUG_ASSERT(element != NULL);
    regBuffer = GET_REG_BUFFER(element);
    AR_DEBUG_ASSERT(regBuffer != NULL);
    target = regBuffer->target;
    AR_DEBUG_ASSERT(target != NULL);

    /* Identify the register and the operation responsible for the callback */
    ret = A_OK;
    switch(regBuffer->base) {
    case TX_CREDIT_COUNTER_DECREMENT_REG:
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "TX_CREDIT_COUNTER_DECREMENT_REG\n");
        endPointId = regBuffer->offset;
        endPoint = &target->endPoint[endPointId];

        HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                        "Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__);
        A_MUTEX_LOCK(&creditCS);

        /* Calculate the number of credits available */
#ifdef ONLY_16BIT
        AR_DEBUG_ASSERT((GET_TX_CREDITS_CONSUMED(endPoint)*2) == regBuffer->length);
#else
       	AR_DEBUG_ASSERT(GET_TX_CREDITS_CONSUMED(endPoint) == regBuffer->length);
#endif
        AR_DEBUG_ASSERT(regBuffer->buffer[0] >= 
                        GET_TX_CREDITS_CONSUMED(endPoint));
        SET_TX_CREDITS_AVAILABLE(endPoint, regBuffer->buffer[0] - 
                                 GET_TX_CREDITS_CONSUMED(endPoint));
        SET_TX_CREDITS_CONSUMED(endPoint, 0);
        txCreditsAvailable = GET_TX_CREDITS_AVAILABLE(endPoint);
        txCreditsConsumed = GET_TX_CREDITS_CONSUMED(endPoint);
        HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                        "Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
        A_MUTEX_UNLOCK(&creditCS);

        HTC_DEBUG_PRINTF(ATH_LOG_INF | ATH_LOG_SEND, 
                        "Pulling %d tx credits from the target\n", 
                        txCreditsAvailable);

#ifdef DEBUG
        txcreditsavailable[endPointId] = txCreditsAvailable;
        txcreditsconsumed[endPointId] = txCreditsConsumed;
#endif /* DEBUG */

        if (txCreditsAvailable) {
            htcSendFrame(endPoint);
        } else {
            /* 
             * Enable the Tx credit counter interrupt so that we can get the
             * credits posted by the target.
             */

            htcEnableCreditCounterInterrupt(target, endPointId);

#ifdef DEBUG
            txcreditintrenable[endPointId] += 1;
            txcreditintrenableaggregate[endPointId] += 1;
#endif /* DEBUG */
        }
        break;

    case TX_CREDIT_COUNTER_RESET_REG:
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "TX_CREDIT_COUNTER_RESET_REG\n");
        endPointId = regBuffer->offset;

        /* 
         * Enable the Tx credit counter interrupt so that we can get the
         * credits posted by the target.
         */
        htcEnableCreditCounterInterrupt(target, endPointId);

#ifdef DEBUG
        txcreditintrenable[endPointId] += 1;
        txcreditintrenableaggregate[endPointId] += 1;
#endif /* DEBUG */
        break;

    case COUNTER_INT_STATUS_ENABLE_REG:
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "COUNTER_INT_STATUS_ENABLE: 0x%x\n",
                        target->table.counter_int_status_enable);
        break;

    case COUNTER_INT_STATUS_DISABLE_REG:
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "COUNTER_INT_STATUS_DISABLE:0x%x\n",
                        target->table.counter_int_status_enable);
		
        HIFAckInterrupt(target->device);
        HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcDSRHandler - ACK\n");
        break;


    case INT_WLAN_REG:
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "INT_WLAN: 0x%x\n",
                        target->table.int_wlan);
        target->table.int_wlan = 0;

        /* Mark the target state as ready and signal the waiting sem */
        target->ready = TRUE;
        A_WAKE_UP(&htcEvent);
        break;

	case INT_STATUS_ENABLE_REG:
        HTC_DEBUG_PRINTF(ATH_LOG_INF, "INT_STATUS_ENABLE: 0x%x\n",
                        target->table.int_status_enable);
        break;


    default:
        HTC_DEBUG_PRINTF(ATH_LOG_ERR, 
                        "Invalid register address: %d\n", regBuffer->base);
    }

    /* Free the register request structure */
    freeRegRequestElement(element);

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

    return ret;
}
예제 #26
0
	void CAsyncIOConnection::Disconnect()
	{
		A_MUTEX_LOCK(&m_mtxLock);
		if(m_hConn) Zion::Disconnect(m_hConn);
		A_MUTEX_UNLOCK(&m_mtxLock);
	}
예제 #27
0
void
htcDisableCreditCounterInterrupt(HTC_TARGET *target, 
                                 HTC_ENDPOINT_ID unused)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_ENDPOINT_ID endPointId;
    A_UINT8 update_credit_int_status;
    HTC_REG_REQUEST_ELEMENT *element;
#ifdef ONLY_16BIT
	A_UINT16 counter_int_enable16;
#endif
	A_UCHAR	counter_int_enable;

    A_MUTEX_LOCK(&counterCS);

    /* The Tx credit counter update bits are reflected in the upper nibble */
    update_credit_int_status = target->table.counter_int_status & 0xF0;

    while(update_credit_int_status) {
        endPointId = htcGetBitNumSet(update_credit_int_status) - 
                     HTC_MAILBOX_NUM_MAX;
        endPoint = &target->endPoint[endPointId];
        AR_DEBUG_ASSERT(endPoint != NULL);

        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "endPoint(%d): %p\n", endPointId, endPoint);

        /* Disable the tx credit interrupt */
        endPoint->txCreditsIntrEnable = FALSE;

        update_credit_int_status &= 
            ~(1 << htcGetBitNumSet(update_credit_int_status));
    }


    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS, 
                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);

    element = allocateRegRequestElement(target);
    AR_DEBUG_ASSERT(element != NULL);

    counter_int_enable = ((target->endPoint[0].txCreditsIntrEnable << (4)) |
						 (target->endPoint[1].txCreditsIntrEnable << (5)) |
						 (target->endPoint[2].txCreditsIntrEnable << (6)) |
                         (target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);

#ifdef ONLY_16BIT
    counter_int_enable16 = (counter_int_enable << 8) | target->table.error_status_enable;

    FILL_REG_BUFFER(element, NULL, 2, COUNTER_INT_STATUS_DISABLE_REG, 
					counter_int_enable16);
	address = getRegAddr(ERROR_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          2, &request, element);
#else
    FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_DISABLE_REG, 
					counter_int_enable);
	address = getRegAddr(COUNTER_INT_STATUS_DISABLE_REG, ENDPOINT_UNUSED);
    status = HIFReadWrite(target->device, address, 
                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
                          1, &request, element);
#endif

#ifndef HTC_SYNC
    AR_DEBUG_ASSERT(status == A_OK);
#else
    AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
	if ( status == A_OK ) {
		element->completionCB(element, status);
	}
#endif

    A_MUTEX_UNLOCK(&counterCS);
}
예제 #28
0
void
htcServiceCounterInterrupt(HTC_TARGET *target)
{
    A_STATUS status;
    A_UINT32 address;
    HIF_REQUEST request;
    HTC_ENDPOINT *endPoint;
    HTC_ENDPOINT_ID endPointId;
    A_UINT8 counter_int_status;
    A_UINT8 reset_credit_int_status;
    A_UINT8 update_credit_int_status;
    HTC_REG_REQUEST_ELEMENT *element;

    HTC_DEBUG_PRINTF(ATH_LOG_INF, "Counter Interrupt\n");

    counter_int_status = target->table.counter_int_status &
                         target->table.counter_int_status_enable;
    AR_DEBUG_ASSERT(counter_int_status);
    HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                    "Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
                    counter_int_status);

    /* Service the reset credit counter interrupt */
    reset_credit_int_status = (counter_int_status & 0x0F);
    while(reset_credit_int_status) {
        endPointId = htcGetBitNumSet(reset_credit_int_status);
        endPoint = &target->endPoint[endPointId];
        AR_DEBUG_ASSERT(endPoint != NULL);

        HTC_DEBUG_PRINTF(ATH_LOG_INF, 
                        "endPoint(%d): %p\n", endPointId, endPoint);

        /* Initialize the number of credits available to zero */
	    HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                   "Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_LOCK(&creditCS);
        SET_TX_CREDITS_AVAILABLE(endPoint, 0);
	    HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                  "Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_UNLOCK(&creditCS);

        /* Clear the interrupt */
        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, 
                          HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
        address = getRegAddr(TX_CREDIT_COUNTER_RESET_REG, endPointId);
        element = allocateRegRequestElement(target);
        AR_DEBUG_ASSERT(element != NULL);
        FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1], sizeof(endPoint->txCreditsAvailable[1]),
                        TX_CREDIT_COUNTER_RESET_REG, endPointId);
        status = HIFReadWrite(target->device, address, 
                              (A_UCHAR *)&endPoint->txCreditsAvailable[1],
                              sizeof(endPoint->txCreditsAvailable[1]), &request, element);

#ifndef HTC_SYNC
        AR_DEBUG_ASSERT(status == A_OK);
#else
        AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
		if (status == A_OK) {
        	/* Enable the Tx credit counter interrupt so that we can get the
             * credits posted by the target */
        	htcEnableCreditCounterInterrupt(target, endPointId);
		}
#endif
        reset_credit_int_status &= 
            ~(1 << htcGetBitNumSet(reset_credit_int_status));
    }

    /* Disable the credit counter interrupt */
    htcDisableCreditCounterInterrupt(target, ENDPOINT_UNUSED);

    /* Service the credit counter interrupt */
    update_credit_int_status = counter_int_status & 0xF0;
    while(update_credit_int_status) {
        endPointId = htcGetBitNumSet(update_credit_int_status) - 
                     HTC_MAILBOX_NUM_MAX;
        endPoint = &target->endPoint[endPointId];
        AR_DEBUG_ASSERT(endPoint != NULL);

        /* This is the minimum number of credits that we would have got */
        AR_DEBUG_ASSERT(GET_TX_CREDITS_AVAILABLE(endPoint) == 0);
	    HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                   "Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_LOCK(&creditCS);
        SET_TX_CREDITS_AVAILABLE(endPoint, 1);
		HTC_DEBUG_PRINTF(ATH_LOG_SYNC,
                   "Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__);
		A_MUTEX_UNLOCK(&creditCS);


#ifdef DEBUG
        txcreditsavailable[endPointId] = GET_TX_CREDITS_AVAILABLE(endPoint);
        txcreditintrenable[endPointId] -= 1;
#endif /* DEBUG */

        HTC_DEBUG_PRINTF(ATH_LOG_INF, "Tx Credits Available: %d\n", 
                                        GET_TX_CREDITS_AVAILABLE(endPoint));

        if (!target->ready) {
            htcSendBlkSize(endPoint);
        } else {
            htcSendFrame(endPoint);
        }

        update_credit_int_status &= 
            ~(1 << htcGetBitNumSet(update_credit_int_status));
    }
}