⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zdhci.c

📁 ZD1211 source code, based on linux 2.44 or linux 2.
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -