/* * Description: * get each stations encryption key * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_get_encryption(PSDevice pDevice, struct viawget_hostapd_param *param, int param_len) { PSMgmtObject pMgmt = pDevice->pMgmt; int ret = 0; int ii; int iNodeIndex =0; param->u.crypt.err = 0; if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { iNodeIndex = 0; } else { if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); memset(param->u.crypt.seq, 0, 8); for (ii = 0 ; ii < 8 ; ii++) { param->u.crypt.seq[ii] = (unsigned char)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8); } return ret; }
/*+ * * Description: * Update Tx attemps, Tx failure counter in Node DB * * In: * Out: * none * * Return Value: none * -*/ VOID VNTWIFIvUpdateNodeTxCounter( IN PVOID pMgmtHandle, IN PBYTE pbyDestAddress, IN BOOL bTxOk, IN WORD wRate, IN PBYTE pbyTxFailCount ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; UINT uNodeIndex = 0; UINT ii; if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == FALSE) { return; } } pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; if (bTxOk == TRUE) { // transmit success, TxAttempts at least plus one pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; } else { pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; } pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE]; for(ii=0;ii<MAX_RATE;ii++) { pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii]; } return; }
/*+ * * Description: * Update Tx attemps, Tx failure counter in Node DB * * In: * Out: * none * * Return Value: none * -*/ void VNTWIFIvUpdateNodeTxCounter( void *pMgmtHandle, unsigned char *pbyDestAddress, bool bTxOk, unsigned short wRate, unsigned char *pbyTxFailCount ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; unsigned int uNodeIndex = 0; unsigned int ii; if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex) == false) { return; } } pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++; if (bTxOk == true) { // transmit success, TxAttempts at least plus one pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++; } else { pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++; } pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE]; for(ii=0;ii<MAX_RATE;ii++) { pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii]; } return; }
/* * Description: * remove station function supported for hostap deamon * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_remove_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { unsigned int uNodeIndex; if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, param->sta_addr, &uNodeIndex)) { BSSvRemoveOneNode(pDevice, uNodeIndex); } else { return -ENOENT; } return 0; }
static int hostap_get_info_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex; if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { param->u.get_info_sta.inactive_sec = (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ; } else { return -ENOENT; } return 0; }
/* * Description: * set station flag * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_set_flags_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex; if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n", (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); } else { return -ENOENT; } return 0; }
/* * Description: * add a station from hostap deamon * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_add_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex; if (!BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) { BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); } memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability; // TODO listenInterval // pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1; pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = false; pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates; // set max tx rate pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate; // set max basic rate pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M; // Todo: check sta preamble, if ap can't support, set status code pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo); pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)param->u.add_sta.aid; pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n", param->sta_addr[0], param->sta_addr[1], param->sta_addr[2], param->sta_addr[3], param->sta_addr[4], param->sta_addr[5] ) ; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n", pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); return 0; }
VOID VNTWIFIvGetTxRate( IN PVOID pMgmtHandle, IN PBYTE pbyDestAddress, OUT PWORD pwTxDataRate, OUT PBYTE pbyACKRate, OUT PBYTE pbyCCKBasicRate, OUT PBYTE pbyOFDMBasicRate ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; UINT uNodeIndex = 0; WORD wTxDataRate = RATE_1M; BYTE byACKRate = RATE_1M; BYTE byCCKBasicRate = RATE_1M; BYTE byOFDMBasicRate = RATE_24M; PWLAN_IE_SUPP_RATES pSupportRateIEs = NULL; PWLAN_IE_SUPP_RATES pExtSupportRateIEs = NULL; if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { // Adhoc Tx rate decided from node DB if(BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) { wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate); pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates); pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrExtSuppRates); } else { if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) { wTxDataRate = RATE_2M; } else { wTxDataRate = RATE_24M; } pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; } } else { // Infrastructure: rate decided from AP Node, index = 0 wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate); #ifdef PLICE_DEBUG printk("GetTxRate:AP MAC is %02x:%02x:%02x:%02x:%02x:%02x,TxRate is %d\n", pMgmt->sNodeDBTable[0].abyMACAddr[0],pMgmt->sNodeDBTable[0].abyMACAddr[1], pMgmt->sNodeDBTable[0].abyMACAddr[2],pMgmt->sNodeDBTable[0].abyMACAddr[3], pMgmt->sNodeDBTable[0].abyMACAddr[4],pMgmt->sNodeDBTable[0].abyMACAddr[5],wTxDataRate); #endif pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates; pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates; } byACKRate = VNTWIFIbyGetACKTxRate( (BYTE) wTxDataRate, pSupportRateIEs, pExtSupportRateIEs ); if (byACKRate > (BYTE) wTxDataRate) { byACKRate = (BYTE) wTxDataRate; } byCCKBasicRate = VNTWIFIbyGetACKTxRate( RATE_11M, pSupportRateIEs, pExtSupportRateIEs ); byOFDMBasicRate = VNTWIFIbyGetACKTxRate(RATE_54M, pSupportRateIEs, pExtSupportRateIEs ); *pwTxDataRate = wTxDataRate; *pbyACKRate = byACKRate; *pbyCCKBasicRate = byCCKBasicRate; *pbyOFDMBasicRate = byOFDMBasicRate; return; }
/* * Description: * set each stations encryption key * * Parameters: * In: * pDevice - * param - * Out: * * Return Value: * */ static int hostap_set_encryption(PSDevice pDevice, struct viawget_hostapd_param *param, int param_len) { PSMgmtObject pMgmt = pDevice->pMgmt; unsigned long dwKeyIndex = 0; unsigned char abyKey[MAX_KEY_LEN]; unsigned char abySeq[MAX_KEY_LEN]; NDIS_802_11_KEY_RSC KeyRSC; unsigned char byKeyDecMode = KEY_CTL_WEP; int ret = 0; int iNodeIndex = -1; int ii; bool bKeyTableFull = false; unsigned short wKeyCtl = 0; param->u.crypt.err = 0; /* if (param_len != (int) ((char *) param->u.crypt.key - (char *) param) + param->u.crypt.key_len) return -EINVAL; */ if (param->u.crypt.alg > WPA_ALG_CCMP) return -EINVAL; if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); return -EINVAL; } if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { if (param->u.crypt.idx >= MAX_GROUP_KEY) return -EINVAL; iNodeIndex = 0; } else { if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg); if (param->u.crypt.alg == WPA_ALG_NONE) { if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == true) { if (KeybRemoveKey(&(pDevice->sKey), param->sta_addr, pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, pDevice->PortOffset) == false) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n"); } pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; } pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0; pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0; pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0; pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0; memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], 0, MAX_KEY_LEN ); return ret; } memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len); // copy to node key tbl pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx; pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len; memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], param->u.crypt.key, param->u.crypt.key_len ); dwKeyIndex = (unsigned long)(param->u.crypt.idx); if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { pDevice->byKeyIndex = (unsigned char)dwKeyIndex; pDevice->bTransmitKey = true; dwKeyIndex |= (1 << 31); } if (param->u.crypt.alg == WPA_ALG_WEP) { if ((pDevice->bEnable8021x == false) || (iNodeIndex == 0)) { KeybSetDefaultKey(&(pDevice->sKey), dwKeyIndex & ~(BIT30 | USE_KEYRSC), param->u.crypt.key_len, NULL, abyKey, KEY_CTL_WEP, pDevice->PortOffset, pDevice->byLocalID); } else { // 8021x enable, individual key dwKeyIndex |= (1 << 30); // set pairwise key if (KeybSetKey(&(pDevice->sKey), ¶m->sta_addr[0], dwKeyIndex & ~(USE_KEYRSC), param->u.crypt.key_len, (PQWORD) &(KeyRSC), (unsigned char *)abyKey, KEY_CTL_WEP, pDevice->PortOffset, pDevice->byLocalID) == true) { pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { // Key Table Full pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; bKeyTableFull = true; } } pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; pDevice->bEncryptionEnable = true; pMgmt->byCSSPK = KEY_CTL_WEP; pMgmt->byCSSGK = KEY_CTL_WEP; pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP; pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; return ret; } if (param->u.crypt.seq) { memcpy(&abySeq, param->u.crypt.seq, 8); for (ii = 0 ; ii < 8 ; ii++) { KeyRSC |= (abySeq[ii] << (ii * 8)); } dwKeyIndex |= 1 << 29; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; } if (param->u.crypt.alg == WPA_ALG_TKIP) { if (param->u.crypt.key_len != MAX_KEY_LEN) return -EINVAL; pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; byKeyDecMode = KEY_CTL_TKIP; pMgmt->byCSSPK = KEY_CTL_TKIP; pMgmt->byCSSGK = KEY_CTL_TKIP; } if (param->u.crypt.alg == WPA_ALG_CCMP) { if ((param->u.crypt.key_len != AES_KEY_LEN) || (pDevice->byLocalID <= REV_ID_VT3253_A1)) return -EINVAL; pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; byKeyDecMode = KEY_CTL_CCMP; pMgmt->byCSSPK = KEY_CTL_CCMP; pMgmt->byCSSGK = KEY_CTL_CCMP; } if (iNodeIndex == 0) { KeybSetDefaultKey(&(pDevice->sKey), dwKeyIndex, param->u.crypt.key_len, (PQWORD) &(KeyRSC), abyKey, byKeyDecMode, pDevice->PortOffset, pDevice->byLocalID); pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { dwKeyIndex |= (1 << 30); // set pairwise key if (KeybSetKey(&(pDevice->sKey), ¶m->sta_addr[0], dwKeyIndex, param->u.crypt.key_len, (PQWORD) &(KeyRSC), (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, pDevice->byLocalID) == true) { pMgmt->sNodeDBTable[iNodeIndex].bOnFly = true; } else { // Key Table Full pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; bKeyTableFull = true; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); } } if (bKeyTableFull == true) { wKeyCtl &= 0x7F00; // clear all key control filed wKeyCtl |= (byKeyDecMode << 4); wKeyCtl |= (byKeyDecMode); wKeyCtl |= 0x0044; // use group key for all address wKeyCtl |= 0x4000; // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx, param->u.crypt.key_len ); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n", pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3], pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4] ); // set wep key pDevice->bEncryptionEnable = true; pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode; pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex; pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0; pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0; return ret; }
bool device_receive_frame( PSDevice pDevice, PSRxDesc pCurrRD ) { PDEVICE_RD_INFO pRDInfo = pCurrRD->pRDInfo; struct net_device_stats *pStats = &pDevice->stats; struct sk_buff *skb; PSMgmtObject pMgmt = pDevice->pMgmt; PSRxMgmtPacket pRxPacket = &(pDevice->pMgmt->sRxPacket); PS802_11Header p802_11Header; unsigned char *pbyRsr; unsigned char *pbyNewRsr; unsigned char *pbyRSSI; PQWORD pqwTSFTime; unsigned short *pwFrameSize; unsigned char *pbyFrame; bool bDeFragRx = false; bool bIsWEP = false; unsigned int cbHeaderOffset; unsigned int FrameSize; unsigned short wEtherType = 0; int iSANodeIndex = -1; int iDANodeIndex = -1; unsigned int ii; unsigned int cbIVOffset; bool bExtIV = false; unsigned char *pbyRxSts; unsigned char *pbyRxRate; unsigned char *pbySQ; unsigned int cbHeaderSize; PSKeyItem pKey = NULL; unsigned short wRxTSC15_0 = 0; unsigned long dwRxTSC47_16 = 0; SKeyItem STempKey; // 802.11h RPI unsigned long dwDuration = 0; long ldBm = 0; long ldBmThreshold = 0; PS802_11Header pMACHeader; bool bRxeapol_key = false; skb = pRDInfo->skb; //PLICE_DEBUG-> pci_unmap_single(pDevice->pcid, pRDInfo->skb_dma, pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE); //PLICE_DEBUG<- pwFrameSize = (unsigned short *)(skb->data + 2); FrameSize = cpu_to_le16(pCurrRD->m_rd1RD1.wReqCount) - cpu_to_le16(pCurrRD->m_rd0RD0.wResCount); // Max: 2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR if ((FrameSize > 2364) || (FrameSize <= 32)) { // Frame Size error drop this packet. DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 1\n"); return false; } pbyRxSts = (unsigned char *)(skb->data); pbyRxRate = (unsigned char *)(skb->data + 1); pbyRsr = (unsigned char *)(skb->data + FrameSize - 1); pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2); pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3); pbySQ = (unsigned char *)(skb->data + FrameSize - 4); pqwTSFTime = (PQWORD)(skb->data + FrameSize - 12); pbyFrame = (unsigned char *)(skb->data + 4); // get packet size FrameSize = cpu_to_le16(*pwFrameSize); if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC // Min: 14 bytes ACK DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n"); return false; } //PLICE_DEBUG-> // update receive statistic counter STAvUpdateRDStatCounter(&pDevice->scStatistic, *pbyRsr, *pbyNewRsr, *pbyRxRate, pbyFrame, FrameSize); pMACHeader = (PS802_11Header)((unsigned char *)(skb->data) + 8); //PLICE_DEBUG<- if (pDevice->bMeasureInProgress) { if ((*pbyRsr & RSR_CRCOK) != 0) pDevice->byBasicMap |= 0x01; dwDuration = (FrameSize << 4); dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE]; if (*pbyRxRate <= RATE_11M) { if (*pbyRxSts & 0x01) { // long preamble dwDuration += 192; } else { // short preamble dwDuration += 96; } } else { dwDuration += 16; } RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm); ldBmThreshold = -57; for (ii = 7; ii > 0;) { if (ldBm > ldBmThreshold) break; ldBmThreshold -= 5; ii--; } pDevice->dwRPIs[ii] += dwDuration; return false; } if (!is_multicast_ether_addr(pbyFrame)) { if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header)(skb->data + 4))) { pDevice->s802_11Counter.FrameDuplicateCount++; return false; } } // Use for TKIP MIC s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader); // filter packet send from myself if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr, 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 = (PS802_11Header)(pbyFrame); // get SA NodeIndex if (BSSDBbIsSTAInNodeDB(pMgmt, (unsigned char *)(p802_11Header->abyAddr2), &iSANodeIndex)) { pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies; pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0; } } } if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex)) return false; } if (IS_FC_WEP(pbyFrame)) { bool bRxDecryOK = false; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx WEP pkt\n"); bIsWEP = true; if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { pKey = &STempKey; pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite; pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex; pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength; pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16; pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0; memcpy(pKey->abyKey, &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0], pKey->uKeyLength ); bRxDecryOK = s_bHostWepRxEncryption(pDevice, pbyFrame, FrameSize, pbyRsr, pMgmt->sNodeDBTable[iSANodeIndex].bOnFly, pKey, pbyNewRsr, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16); } else { 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 ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) pDevice->s802_11Counter.TKIPICVErrors++; else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) pDevice->s802_11Counter.CCMPDecryptErrors++; } 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 CRC length FrameSize -= ETH_FCS_LEN; if ((!(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address (IS_FRAGMENT_PKT((skb->data+4))) ) { // defragment bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header)(skb->data+4), FrameSize, bIsWEP, bExtIV); pDevice->s802_11Counter.ReceivedFragmentCount++; if (bDeFragRx) { // defrag complete skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb; FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength; } else { return false; } } // Management & Control frame Handle if ((IS_TYPE_DATA((skb->data+4))) == false) { // Handle Control & Manage Frame if (IS_TYPE_MGMT((skb->data+4))) { unsigned char *pbyData1; unsigned char *pbyData2; pRxPacket->p80211Header = (PUWLAN_80211HDR)(skb->data+4); pRxPacket->cbMPDULen = FrameSize; pRxPacket->uRSSI = *pbyRSSI; pRxPacket->bySQ = *pbySQ; HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime)); LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime)); if (bIsWEP) { // strip IV pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); pbyData2 = WLAN_HDR_A3_DATA_PTR(skb->data+4) + 4; for (ii = 0; ii < (FrameSize - 4); ii++) { *pbyData1 = *pbyData2; pbyData1++; pbyData2++; } } pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate); pRxPacket->byRxChannel = (*pbyRxSts) >> 2; vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); // hostap Deamon handle 802.11 management if (pDevice->bEnableHostapd) { skb->dev = pDevice->apdev; skb->data += 4; skb->tail += 4; skb_put(skb, FrameSize); skb_reset_mac_header(skb); skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_802_2); memset(skb->cb, 0, sizeof(skb->cb)); netif_rx(skb); return true; } } return false; } else {