static bool device_alloc_bufs(struct vnt_private *pDevice) { struct vnt_usb_send_context *pTxContext; struct vnt_rcb *pRCB; int ii; for (ii = 0; ii < pDevice->cbTD; ii++) { pTxContext = kmalloc(sizeof(struct vnt_usb_send_context), GFP_KERNEL); if (pTxContext == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name); goto free_tx; } pDevice->apTD[ii] = pTxContext; pTxContext->pDevice = (void *) pDevice; /* allocate URBs */ pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC); if (pTxContext->pUrb == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n"); goto free_tx; } pTxContext->bBoolInUse = false; } /* allocate RCB mem */ pDevice->pRCBMem = kzalloc((sizeof(struct vnt_rcb) * pDevice->cbRD), GFP_KERNEL); if (pDevice->pRCBMem == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name); goto free_tx; } pDevice->FirstRecvFreeList = NULL; pDevice->LastRecvFreeList = NULL; pDevice->FirstRecvMngList = NULL; pDevice->LastRecvMngList = NULL; pDevice->NumRecvFreeList = 0; pRCB = (struct vnt_rcb *)pDevice->pRCBMem; for (ii = 0; ii < pDevice->cbRD; ii++) { pDevice->apRCB[ii] = pRCB; pRCB->pDevice = (void *) pDevice; /* allocate URBs */ pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC); if (pRCB->pUrb == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n"); goto free_rx_tx; } pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); if (pRCB->skb == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n"); goto free_rx_tx; } pRCB->skb->dev = pDevice->dev; pRCB->bBoolInUse = false; EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB); pDevice->NumRecvFreeList++; pRCB++; } pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC); if (pDevice->pInterruptURB == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n"); goto free_rx_tx; } pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL); if (pDevice->intBuf.pDataBuf == NULL) { DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n"); usb_free_urb(pDevice->pInterruptURB); goto free_rx_tx; } return true; free_rx_tx: device_free_rx_bufs(pDevice); free_tx: device_free_tx_bufs(pDevice); return false; }
int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB, unsigned long BytesToIndicate) { struct net_device_stats *pStats = &pDevice->stats; struct sk_buff *skb; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; struct vnt_rx_mgmt *pRxPacket = &pMgmt->sRxPacket; struct ieee80211_hdr *p802_11Header; u8 *pbyRsr, *pbyNewRsr, *pbyRSSI, *pbyFrame; u64 *pqwTSFTime; u32 bDeFragRx = false; u32 cbHeaderOffset, cbIVOffset; u32 FrameSize; u16 wEtherType = 0; s32 iSANodeIndex = -1; int ii; u8 *pbyRxSts, *pbyRxRate, *pbySQ, *pby3SQ; u32 cbHeaderSize; PSKeyItem pKey = NULL; u16 wRxTSC15_0 = 0; u32 dwRxTSC47_16 = 0; /* signed long ldBm = 0; */ int bIsWEP = false; int bExtIV = false; u32 dwWbkStatus; struct vnt_rcb *pRCBIndicate = pRCB; u8 *pbyDAddress; u16 *pwPLCP_Length; u8 abyVaildRate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; u16 wPLCPwithPadding; struct ieee80211_hdr *pMACHeader; int bRxeapol_key = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n"); skb = pRCB->skb; /* [31:16]RcvByteCount ( not include 4-byte Status ) */ dwWbkStatus = *((u32 *)(skb->data)); FrameSize = dwWbkStatus >> 16; FrameSize += 4; if (BytesToIndicate != FrameSize) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n"); pStats->rx_frame_errors++; return false; } if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) { // Frame Size error drop this packet. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n"); pStats->rx_frame_errors++; return false; } pbyDAddress = (u8 *)(skb->data); pbyRxSts = pbyDAddress+4; pbyRxRate = pbyDAddress+5; //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding //if SQ3 the range is 24~27, if no SQ3 the range is 20~23 //real Frame size in PLCPLength field. pwPLCP_Length = (u16 *) (pbyDAddress + 6); //Fix hardware bug => PLCP_Length error if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) || ((BytesToIndicate - (*pwPLCP_Length)) < 24) || (BytesToIndicate < (*pwPLCP_Length)) ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length); pStats->rx_frame_errors++; return false; } for ( ii=RATE_1M;ii<MAX_RATE;ii++) { if ( *pbyRxRate == abyVaildRate[ii] ) { break; } } if ( ii==MAX_RATE ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate); return false; } wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4; pqwTSFTime = (u64 *)(pbyDAddress + 8 + wPLCPwithPadding); if(pDevice->byBBType == BB_TYPE_11G) { pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12; pbySQ = pby3SQ; } else { pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8; pby3SQ = pbySQ; } pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9; pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10; pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11; FrameSize = *pwPLCP_Length; pbyFrame = pbyDAddress + 8; pMACHeader = (struct ieee80211_hdr *) pbyFrame; //mike add: to judge if current AP is activated? if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) || (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) { if (pMgmt->sNodeDBTable[0].bActive) { if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) { if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) pMgmt->sNodeDBTable[0].uInActiveCount = 0; } } } if (!is_multicast_ether_addr(pMACHeader->addr1)) { if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (struct ieee80211_hdr *) pbyFrame)) { return false; } if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) { return false; } } // Use for TKIP MIC s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader); if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source, pDevice->abyCurrentNetAddr)) return false; if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) { if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) { p802_11Header = (struct ieee80211_hdr *) (pbyFrame); // get SA NodeIndex if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->addr2), &iSANodeIndex)) { pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; } } } if (IS_FC_WEP(pbyFrame)) { bool bRxDecryOK = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n"); bIsWEP = true; bRxDecryOK = s_bHandleRxEncryption(pDevice, pbyFrame, FrameSize, pbyRsr, pbyNewRsr, &pKey, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16); if (bRxDecryOK) { if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n"); if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { } return false; } } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n"); return false; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) FrameSize -= 8; // Message Integrity Code else FrameSize -= 4; // 4 is ICV } // // RX OK // /* remove the FCS/CRC length */ FrameSize -= ETH_FCS_LEN; if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address (IS_FRAGMENT_PKT((pbyFrame))) ) { // defragment bDeFragRx = WCTLbHandleFragment(pDevice, (struct ieee80211_hdr *) (pbyFrame), FrameSize, bIsWEP, bExtIV); if (bDeFragRx) { // defrag complete // TODO skb, pbyFrame skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; pbyFrame = skb->data + 8; } else { return false; } } // // Management & Control frame Handle // if ((IS_TYPE_DATA((pbyFrame))) == false) { // Handle Control & Manage Frame if (IS_TYPE_MGMT((pbyFrame))) { u8 * pbyData1; u8 * pbyData2; pRxPacket = &(pRCB->sMngPacket); pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame); pRxPacket->cbMPDULen = FrameSize; pRxPacket->uRSSI = *pbyRSSI; pRxPacket->bySQ = *pbySQ; pRxPacket->qwLocalTSF = cpu_to_le64(*pqwTSFTime); if (bIsWEP) { // strip IV pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame); pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4; for (ii = 0; ii < (FrameSize - 4); ii++) { *pbyData1 = *pbyData2; pbyData1++; pbyData2++; } } pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); if ( *pbyRxSts == 0 ) { //Discard beacon packet which channel is 0 if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) || (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) { return false; } } pRxPacket->byRxChannel = (*pbyRxSts) >> 2; // // Insert the RCB in the Recv Mng list // EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate); pDevice->NumRecvMngList++; if ( bDeFragRx == false) { pRCB->Ref++; } if (pDevice->bIsRxMngWorkItemQueued == false) { pDevice->bIsRxMngWorkItemQueued = true; schedule_work(&pDevice->rx_mng_work_item); } } else { // Control Frame };