📄 zdhci.c
字号:
U8 mode;
void *bcBuf;
U8 *pBcData;
Hash_t *pHash;
U8 vapId = 0;
U8 rate = pRxInfo->rate;
U8 bDataFrm = pRxInfo->bDataFrm;
U8 SaIndex = pRxInfo->SaIndex;
#if ZDCONF_SIGNAL_INFO == 1
U8 signalStrength = pRxInfo->signalStrength;
U8 signalQuality = pRxInfo->signalQuality;
#endif
U8 bSwCheckMIC = pRxInfo->bSwCheckMIC;
U32 LP_MAP = 0;
#if ZDCONF_LP_SUPPORT == 1
// ####### FOR A-MSDU ########
U16 wCnt;
struct sk_buff *skb = NULL;
Signal_t *signal;
FrmDesc_t *pfrmDesc;
Frame_t *frame;
U16 dataOff = 0;
U16 idx, pktLen,idx2;
int j=0;
Hash_t *sHash = NULL;
U8 HDR[24];
U8 *pBody2;
U32 len2;
// ###########################
if(LP)
{
LP_MAP = 0xFFFFFFFF;
}
#endif
ZDEBUG("zd_ReceivePkt");
if (mBssType == INFRASTRUCTURE_BSS){
pDa = (MacAddr_t *)&pHdr[4]; //A1 will be my MAC
//pSa = (MacAddr_t *)&pHdr[16]; //A3
pSa = (MacAddr_t *)&pHdr[10]; //A2 for Asoc status check
pHash = sstByAid[0];
}
#if ZDCONF_AP_SUPPORT == 1
else if (mBssType == AP_BSS){
pDa = (MacAddr_t *)&pHdr[16]; //A3
pSa = (MacAddr_t *)&pHdr[10]; //A2
if (bDataFrm){
//don't care PS Bit in authenticate, (Re)assoicate and Probe Reguest frame
psm = (PsMode)((pHdr[1] & PW_SAVE_BIT) ? PSMODE_POWER_SAVE : PSMODE_STA_ACTIVE);
}
if (SaIndex == 0)
pHash = RxInfoIndicate(pSa, psm, rate); //12us update ps and rate information
else {
pHash = sstByAid[SaIndex];
if (pHash)
RxInfoUpdate(pHash, psm, rate);
}
}
#endif
#if ZDCONF_ADHOC_SUPPORT == 1 || ZDCONF_PSEUDO_SUPPORT == 1
else{ // INDEPENDENT_BSS or PSEUDO_IBSS
pDa = (MacAddr_t *)&pHdr[4]; //A1
pSa = (MacAddr_t *)&pHdr[10]; //A2
pHash = RxInfoIndicate(pSa, 0, rate);
}
#endif
#if ZDCONF_LP_SUPPORT == 1
if(pHash) pHash->LP_CAP = LP;
#endif
if (bDataFrm){
if (!bodyLen)
goto rx_release;
if (!pHash){
zd_SendClass2ErrorFrame(pSa, vapId);
goto rx_release;
}
else {
sas = pHash->asoc;
#if ZDCONF_AP_SUPPORT == 1
if ((sas != STATION_STATE_ASOC) && (mBssType == AP_BSS)){
//if (sas != STATION_STATE_ASOC){
zd_SendClass3ErrorFrame(pSa, vapId);
printk(KERN_ERR "Class3ErrFrm:%02X %02X %02X %02X %02X %02X\n",pSa->mac[0],pSa->mac[1],pSa->mac[2],pSa->mac[3],pSa->mac[4],pSa->mac[5]);
goto rx_release;
}
#endif
}
if (sas == STATION_STATE_ASOC)
{ //association station
#if ZDCONF_AP_SUPPORT == 1
if (mBssType == AP_BSS)
{
if (isGroup(pDa))
{
if (pHash->keyLength == 32)
{
if (!pHash->pkInstalled)
goto rx_release;
else if (!mGkInstalled)
goto rx_release;
else if ((pHdr[1] & WEP_BIT) && (hdrLen == 32))
{
if (bSwCheckMIC)
{
#if ZDCONF_MIC_CHECK == 1
if (!zd_CheckMic(pHdr, pBody, bodyLen, pHash, pEthHdr))
{
goto rx_release;
}
else
#endif
{
bodyLen -= MIC_LNG; //remove MIC
}
}
}
}
#if ZDCONF_DRV_FORWARD == 1
if (mCurrConnUser > 1)
{
mode = BC_FORWARD;
bcBuf = pdot11Obj->AllocBuffer(bodyLen, &pBcData);
if (bcBuf)
{
memcpy(pBcData, pBody, bodyLen);
zd_WirelessForward(pHdr, pBcData, bodyLen, bcBuf, mode, NULL, pEthHdr);
}
}
#endif
goto rx_ind;
}
else
{
#if ZDCONF_DRV_FORWARD == 1
void *pTxHash = NULL;
if (mBlockBSS)
{ //discard IntraBSS packet
goto rx_release;
}
zd_QueryStaTable((U8 *)pDa, &pTxHash); //Automatic wireless forwarding
if (pTxHash)
{
if (bSwCheckMIC)
{
if ((pHash->keyLength==32) && (pHdr[1] & WEP_BIT) && (hdrLen == 32))
{
#if ZDCONF_MIC_CHECK == 1
if (!zd_CheckMic(pHdr, pBody, bodyLen, pHash, pEthHdr))
{
goto rx_release;
}
#endif
else
bodyLen -= MIC_LNG; //remove MIC
}
}
mode = BSS_FORWARD;
zd_WirelessForward(pHdr, pBody, bodyLen, buf, mode, pTxHash, pEthHdr);
return;
}
#endif
}
}
#endif //ZDCONF_AP_SUPPORT == 1
// mic check
if (bSwCheckMIC) // For TKIP, always use sw-mic check.
{
//if ((pHash->keyLength==32) && (pHdr[1] & WEP_BIT) && (hdrLen == 32))
{
#if ZDCONF_MIC_CHECK == 1
if (!zd_CheckMic(pHdr, pBody, bodyLen, pHash, pEthHdr))
{// sw-mic check failed, discard this packet.
goto rx_release;
}
else
#endif
{// sw-mic check ok, remove MIC
bodyLen -= MIC_LNG;
}
}
}
rx_ind:
if(LP)
{
#if ZDCONF_LP_SUPPORT == 1
pData = pBody;
dataLen = bodyLen;
#endif
}
//If Typelen field is not used for len
else if(memcmp(pBody,zd_Snap_Apple_AARP,8)==0 || memcmp(pBody,zd_Snap_Apple_Type,8)==0) {
pData = pBody - 14;
dataLen = bodyLen + 14; /* Plus DA, SA and TypeLen */
pData[12] = (bodyLen>>8) & 0xFF;
pData[13] = bodyLen & 0xFF;
}
else if ((bodyLen > 5 ) && (memcmp(pBody, zd_Snap_Header, 6) == 0
|| memcmp(pBody, zd_SnapBridgeTunnel, 6) == 0)){
pData = pBody - 6;
dataLen = bodyLen + 6; /* Plus DA, SA*/
}
/* 24 6 2 n
*---------------*------*-----*------------------------*
| WLAN HDR | SNAP | LEN | DATA |
*---------------*------*-----*------------------------*
*/
else{
pData = pBody - 14;
dataLen = bodyLen + 14; /* Plus DA, SA and TypeLen */
pData[12] = (bodyLen>>8) & 0xFF;
pData[13] = bodyLen & 0xFF;
}
/* 24 6
*---------------*------------------------*
| WLAN HDR | DATA |
*---------------*------------------------*
*/
if(!LP)
{
memcpy(pData, pEthHdr, 6); /* Set DA */
memcpy(pData+6, pEthHdr+6, 6); /* Set SA */
}
//if (Type == 0x888e)
//zd1205_dump_data("pData = ", pData, dataLen);
pdot11Obj->RxInd(pData, dataLen, buf, LP_MAP);
return;
}
}
else { //Mgt Frame
pRxSignal = allocSignal();
if (!pRxSignal){
FPRINT("zd_ReceivePkt out of signal");
FPRINT_V("freeSignalCount", freeSignalCount);
goto rx_release;
}
pRxFdesc = allocFdesc();
if (!pRxFdesc){
FPRINT("zd_ReceivePkt out of description");
FPRINT_V("freeFdescCount", freeFdescCount);
freeSignal(pRxSignal);
goto rx_release;
}
else{
//pRxFdesc->bDataFrm = bDataFrm;
#if ZDCONF_SIGNAL_INFO == 1
pRxFdesc->signalStrength = signalStrength;
pRxFdesc->signalQuality = signalQuality;
#endif
pRxFrame = pRxFdesc->mpdu;
pRxFrame->HdrLen = hdrLen;
pRxFrame->bodyLen = bodyLen;
memcpy(pRxFrame->header, pHdr, hdrLen);
pRxFrame->body = pBody;
pRxSignal->buf = buf;
pRxSignal->vapId = vapId;
pRxSignal->frmInfo.frmDesc = pRxFdesc;
if (!RxMgtMpdu(pRxSignal)){
freeSignal(pRxSignal);
freeFdesc(pRxFdesc);
pdot11Obj->ReleaseBuffer(buf);
}
return;
}
}
rx_release:
pdot11Obj->ReleaseBuffer(buf);
return;
}
void zd_InitWepData(void)
{
memset(mWepIv,0, sizeof(mWepIv));
memset(mBcIv,0,sizeof(mBcIv));
#if 0
mWepIv[0] = 0;
mWepIv[1] = 0;
mWepIv[2] = 0;
mWepIv[3] = 0;
mBcIv[0] = 0;
mBcIv[1] = 0;
mBcIv[2] = 0;
mBcIv[3] = 0;
#endif
}
void zd_Release_80211_Buffer(void)
{
releaseSignalBuf();
releaseFdescBuf();
}
//Cmd Functions
BOOLEAN zd_Reset80211(zd_80211Obj_t * pObj)
{
pdot11Obj = pObj;
initSignalBuf();
initFdescBuf();
ResetPSMonitor();
ResetPMFilter();
zd_InitWepData();
mBssCnt=0;
return TRUE;
}
#if ZDCONF_AP_SUPPORT == 1
BOOLEAN zd_HandlePsPoll(U8 *pHdr)
{
Frame_t psPollFrame;
//PSDEBUG("zd_HandlePsPoll");
psPollFrame.HdrLen = 16;
psPollFrame.bodyLen = 0;
memcpy(&psPollFrame.header[0], pHdr, 16);
RxPsPoll(&psPollFrame);
return TRUE;
}
#endif
#if ZDCONF_AP_SUPPORT == 1
BOOLEAN zd_StartAP(void)
{
void *reg = pdot11Obj->reg;
HW_SetRfChannel(pdot11Obj, mRfChannel, 0, mMacMode);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, mMacMode);
#if defined(AMAC)
pdot11Obj->SetReg(reg, ZD_BasicRateTbl, 0);
#endif
HW_SetSupportedRate(pdot11Obj, (U8 *)&mBrates);
#if defined(OFDM)
if(PURE_A_MODE != mMacMode)
HW_SetSupportedRate(pdot11Obj, (U8 *)&mExtRates);
#endif
/* Set CAM_MODE to AP Mode */
pdot11Obj->SetReg(reg, ZD_CAM_MODE, CAM_AP);
ConfigBcnFIFO();
HW_EnableBeacon(pdot11Obj, mBeaconPeriod, mDtimPeriod, AP_BSS);
HW_RadioOnOff(pdot11Obj, mRadioOn);
return TRUE;
}
#endif
BOOLEAN zd_ProbeReq(void)
{
Signal_t *signal;
//FPRINT("zd_ProbeReq");
if ((signal = allocSignal()) == NULL){
return FALSE;
}
signal->vapId=0;
signal->id = SIG_PROBE_REQ;
signal->block = BLOCK_SYNCH;
sigEnque(pMgtQ, (signal));
zd_SigProcess();
return TRUE;
}
BOOLEAN zd_ScanReq(void)
{
Signal_t *signal;
if ((signal = allocSignal()) == NULL){
return FALSE;
}
signal->vapId=0x12; //This member is not used in zd1211, we can use it to carry additional information, 0x1234 indicates we don't want to start a scantimer after sending a Probe Request frame.
signal->id = SIG_PROBE_REQ;
signal->block = BLOCK_SYNCH;
sigEnque(pMgtQ, (signal));
zd_SigProcess();
return TRUE;
}
#if 0
void zd_ScanEnd()
{
void *reg=pdot11Obj->reg;
if (mBssType == AP_BSS)
pdot11Obj->SetReg(reg, ZD_Rx_Filter, AP_RX_FILTER);
else
pdot11Obj->SetReg(reg, ZD_Rx_Filter, STA_RX_FILTER);
if (mAssoc) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1,mMacMode);
}
mBssCnt=mBssNum;
pdot11Obj->ConfigFlag &= ((~ACTIVE_CHANNEL_SCAN_SET) & (~JUST_CHANNEL_SCAN));
}
void zd_ScanBegin()
{
void *reg=pdot11Obj->reg;
mBssNum=0;
pdot11Obj->ConfigFlag |= (ACTIVE_CHANNEL_SCAN_SET | JUST_CHANNEL_SCAN);
pdot11Obj->SetReg(reg, ZD_Rx_Filter, (BIT_5|BIT_8));
}
void zd_CmdScanReq(u16 channel)
{
if(mMacMode != PURE_A_MODE) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, channel, 1,mMacMode);
}
else {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj,dot11A_Channel[channel-1],1 ,mMacMode);
}
zd_ScanReq();
return;
}
#endif
BOOLEAN zd_CmdProbeReq(U8 bWithSSID)
{
void *reg = pdot11Obj->reg;
U32 tempValue;
//FPRINT("zd_CmdProbeReq");
if (pdot11Obj->bChScanning){
FPRINT("Channel is under scanning....");
if (mRequestFlag & CHANNEL_SCAN_SET)
mRequestFlag &= ~CHANNEL_SCAN_SET;
return FALSE;
}
pdot11Obj->bChScanning=1;
if(pdot11Obj->bDeviceInSleep)
{
printk("In SLEEP @ %s\n", __FUNCTION__);
return 0;
}
tempValue = pdot11Obj->GetReg(reg, ZD_BCNInterval);
tempValue &= ~BIT_25; // disable IBSS Beacon transmission temporarily.
pdot11Obj->SetReg(reg, ZD_BCNInterval, tempValue);
pdot11Obj->SetReg(reg, ZD_Rx_Filter, (BIT_5|BIT_8)); //only accept beacon and ProbeRsp frame
pdot11Obj->ConfigFlag |= ACTIVE_CHANNEL_SCAN_SET;
mBssNum = 0;
if(mMacMode != PURE_A_MODE) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, CurrScanCH, 1,mMacMode);
}
#if ZDCONF_80211A_SUPPORT == 1
else {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, dot11A_Channel[CurrScanCH-1], 1,mMacMode);
}
#endif
zd_ProbeReq();
if (mRequestFlag & CHANNEL_SCAN_SET)
mRequestFlag &= ~CHANNEL_SCAN_SET;
//pdot11Obj->bChScanning = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -