📄 zdhci.c
字号:
}
BOOLEAN zd_ChooseAP(BOOLEAN bUseBssid)
{
U8 i;
U16 cap;
U16 quality = 10000;
BOOLEAN found = FALSE;
mBssIndex = 0xff;
for (i=0; i<mBssCnt; i++)
{
if (bUseBssid)
{
if (memcmp(&dot11DesiredBssid, &mBssInfo[i].bssid.mac[0], ETH_ALEN) == 0 && memcmp(&dot11DesiredBssid, zeroMacAddress, ETH_ALEN)!=0)
{
//ZD1211DEBUG(0, "zd_ChooseAP: Bssid" MACSTR "matched to index:%d\n",MAC2STR(dot11DesiredBssid), i);
mBssIndex = i;
break;
}
}
cap = mBssInfo[i].cap;
if ((memcmp(&dot11DesiredSsid, &mBssInfo[i].ssid, dot11DesiredSsid.buf[1]+2) == 0)
|| (!mProbeWithSsid) ) {
if(1)
;
else if ((mMacMode == PURE_B_MODE) && (mBssInfo[i].apMode == PURE_G_AP))
continue;
else if ((mMacMode == PURE_B_MODE) && (mBssInfo[i].apMode == PURE_A_AP))
continue;
else if ((mMacMode == PURE_G_MODE) && (mBssInfo[i].apMode == PURE_B_AP))
continue;
else if ((mMacMode == PURE_G_MODE) && (mBssInfo[i].apMode == PURE_A_AP))
continue;
else if ((mMacMode == PURE_A_MODE) && (mBssInfo[i].apMode != PURE_A_AP))
continue;
else if ((mMacMode == MIXED_MODE) && (mBssInfo[i].apMode == PURE_A_AP))
continue;
//check capability ...
if (cap & CAP_PRIVACY){
if (!mPrivacyInvoked)
continue;
}
else {
if (mPrivacyInvoked)
continue;
}
if (!pdot11Obj->IsUSB2_0){ //host is usb 1.1
if (mBssInfo[i].apMode == PURE_G_AP)
continue;
}
if (cap & CAP_ESS){
if (mBssInfo[i].signalQuality < quality ){
quality = mBssInfo[i].signalQuality;
mBssIndex = i;
//FPRINT_V("cap", cap);
}
}
//break;
}
}
if (mBssIndex< mBssCnt){
found = TRUE;
//FPRINT_V("Desired AP Found, Bss Index", mBssIndex);
if (pdot11Obj->ConfigFlag & SCAN_AND_CONNECT_SET){
//printk("zd_ChooseAP: set mRequestFlag.BSS_CONNECT_SET\n");
mRequestFlag |= BSS_CONNECT_SET;
pdot11Obj->ConfigFlag &= ~SCAN_AND_CONNECT_SET;
}
}
else{
//printk(" \n");
//printk(KERN_ERR "****** Can't find desiredSSID:");
//for (i=0; i<dot11DesiredSsid.buf[1]; i++) {
// printk("%c", dot11DesiredSsid.buf[2+i]);
//}
//printk(" \n");
}
// int j;
// if(0xff != mBssIndex) {
// for(j=0;j<mBssInfo[mBssIndex].ssid.buf[1];j++)
// printk("%c",mBssInfo[mBssIndex].ssid.buf[2+j]);
// printk(" ChooseAP(Mac=%d,Ch:%d)\n",mBssInfo[mBssIndex].apMode,mBssInfo[mBssIndex].Phpm.buf[2]);
// }
return found;
}
BOOLEAN zd_InfraConnect(U8 index)
{
Signal_t *signal;
struct zd1205_private *macp = (struct zd1205_private *)g_dev->priv;
MacAddr_t *pBssid;
Element *pSsid = NULL;
U32 tmpvalue;
BOOLEAN bChooseAPResult;
void *reg = pdot11Obj->reg;
//FPRINT("zd_InfraConnect");
if (mBssNum == 0)
return FALSE;
if ((signal = allocSignal()) == NULL)
return FALSE;
if(mCounterMeasureState) {
mRequestFlag &= ~BSS_CONNECT_SET;
return FALSE;
}
// look up global scan result table according to desired ssid,
// because mBssInfo order may be different from macp->BSSInfo[].
/*if (mBssCnt)
{
U8 ssidLength;
for(i=0; i<mBssCnt; i++)
{
ssidLength=dot11DesiredSsid.buf[1]+2;
if (mBssInfo[i].cap & CAP_ESS)
{
if (memcmp((U8*)&dot11DesiredSsid,(U8*)&mBssInfo[i].ssid,ssidLength)==0)
{
break;
}
}
}
} */
// Use zd_ChooseAP instead of above code
bChooseAPResult=zd_ChooseAP(0);
if (!bChooseAPResult || 1)
{// dot11DesiredSsid can't be found in table mBssInfo[]
if ((index+1) <= mBssCnt)
{
//printk(KERN_ERR "Desired SSID can't be found in current table\n");
mBssIndex=index; // Can't found in the latest scan result table, use the old index.
}
else
{
return FALSE; // The index exceed mBssInfo[].
}
}
else
{
//printk(KERN_ERR "Desired SSID found in location %d\n",mBssIndex);
}
//Disable IBSS mode
tmpvalue = pdot11Obj->GetReg(reg, ZD_BCNInterval);
tmpvalue &= ~BIT_25;
pdot11Obj->SetReg(reg, ZD_BCNInterval, tmpvalue);
mCap |= BIT_0;
mCap &= ~BIT_1;
// For IBSS Connect
if (mBssInfo[index].cap & CAP_IBSS)
{
}
//mBssIndex = index;
//update beacon interval
HW_UpdateBcnInterval(pdot11Obj, mBssInfo[mBssIndex].bcnInterval);
pSsid = &mBssInfo[mBssIndex].ssid;
memcpy((U8 *)&mSsid, (U8 *)pSsid, pSsid->buf[1]+2);
pBssid = &mBssInfo[mBssIndex].bssid;
memcpy((U8 *)&mBssId, (U8 *)pBssid, 6);
//update Bssid
pdot11Obj->SetReg(reg, ZD_BSSID_P1, zd_cpu_to_le32(*(U32 *)&mBssId.mac[0]));
pdot11Obj->SetReg(reg, ZD_BSSID_P2, zd_cpu_to_le32(*(U32 *)&mBssId.mac[4]));
// Update channel number contained in the DS Parameter Set element of the received probe response or beacon frame.
mRfChannel = mBssInfo[mBssIndex].Phpm.buf[2];
if(PURE_A_AP == mBssInfo[mBssIndex].apMode) {
ChangeMacMode(PURE_A_MODE,mRfChannel);
zd_UpdateCardSetting(&(macp->cardSetting));
pdot11Obj->DelayUs(1000);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, PURE_A_MODE);
}
else {
if(PURE_A_MODE == mMacMode)
mMacMode = MIXED_MODE;
ChangeMacMode(mMacMode,mRfChannel);
zd_UpdateCardSetting(&(macp->cardSetting));
pdot11Obj->DelayUs(1000);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, MIXED_MODE);
}
signal->id = SIG_AUTH_REQ;
signal->block = BLOCK_AUTH_REQ;
memcpy(&signal->frmInfo.Sta, (U8 *)&mBssId, 6);
sigEnque(pMgtQ, (signal));
if (mRequestFlag & CONNECT_TOUT_SET)
mRequestFlag &= ~CONNECT_TOUT_SET;
if (mRequestFlag & BSS_CONNECT_SET)
mRequestFlag &= ~BSS_CONNECT_SET;
return TRUE;
}
BOOLEAN zd_IbssConnect(void)
{
struct zd1205_private *macp=g_dev->priv;
int i;
U8 Length;
BOOLEAN bBSSFound = FALSE;
MacAddr_t *pBssid;
BssInfo_t *pBssInfo;
void *reg = pdot11Obj->reg;
U32 tmpvalue;
//FPRINT("zd_IbssConnect");
#if defined(OFDM)
pdot11Obj->SetReg(reg, ZD_CWmin_CWmax, CW_NORMAL_SLOT);
// not to use short slot time
mCap &= ~BIT_10;
pdot11Obj->ConfigFlag &= ~SHORT_SLOT_TIME_SET;
if (mMacMode == PURE_G_MODE){
// not use protection mechanism
pdot11Obj->ConfigFlag &= ~ENABLE_PROTECTION_SET;
}
else if(mMacMode != PURE_A_MODE) {
// force use protection mechanism
pdot11Obj->ConfigFlag |= ENABLE_PROTECTION_SET;
}
#endif
// Recover the EIFS to 0x200.
// We need not use SleepResetDevice. In IBSS mode, we can easily
// get others traffic. (not less of Rx-Frame)
pdot11Obj->SetReg(reg, ZD_IFS_Value, 0x5200032);
if (mATIMWindow != 0){
// Do not set macp->PwrState = PSM, otherwise
// throughput with Cirrus card (in PS mode) will down.
//macp->PwrState = PSM;
// PwrMgt = 1
tmpvalue = pdot11Obj->GetReg(reg, ZD_BCNInterval);
tmpvalue |= BIT_26;
pdot11Obj->SetReg(reg, ZD_BCNInterval, tmpvalue);
}
else{
//macp->PwrState = CAM;
// PwrMgt = 0;
tmpvalue = pdot11Obj->GetReg(reg, ZD_BCNInterval);
tmpvalue &= ~BIT_26;
pdot11Obj->SetReg(reg, ZD_BCNInterval, tmpvalue);
}
mCap &= ~BIT_0;
mCap |= BIT_1;
if (mBssCnt){ // IBSS found
for (i=0; i<mBssCnt; i++){
Length = dot11DesiredSsid.buf[1]+2;
if (mBssInfo[i].cap & CAP_IBSS){
if (memcmp((U8 *)&dot11DesiredSsid, (U8 *)&mBssInfo[i].ssid, Length) == 0){
break;
}
}
}
if (i < mBssCnt){
bBSSFound = TRUE;
mBssIndex = i;
//FPRINT("IBSS found, joint it !!!");
//FPRINT_V("mBssIndex", mBssIndex);
if (mMacMode==PURE_B_MODE) {
if ((mBssInfo[i].cap & CAP_SHORT_PREAMBLE)==0)
mCap &= ~CAP_SHORT_PREAMBLE;
}
pBssInfo = &mBssInfo[mBssIndex];
// Update channel number contained in the DS Parameter Set element of the received probe response or beacon frame.
macp->cardSetting.Channel = mRfChannel = pBssInfo->Phpm.buf[2];
mPhpm.buf[2]=mRfChannel;
if(PURE_A_AP == mBssInfo[mBssIndex].apMode) {
ChangeMacMode(PURE_A_MODE, mRfChannel);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, PURE_A_MODE);
}
else {
ChangeMacMode(MIXED_MODE,mRfChannel);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, MIXED_MODE);
}
//FPRINT_V("mRfChannel", mRfChannel);
pBssid = &pBssInfo->bssid;
memcpy((U8 *)&mBssId, (U8 *)pBssid, 6);
//zd1205_dump_data("mBssId = ", (U8 *)&mBssId, 6);
//update Bssid
pdot11Obj->SetReg(reg, ZD_BSSID_P1, zd_cpu_to_le32(*(U32 *)&mBssId.mac[0]));
pdot11Obj->SetReg(reg, ZD_BSSID_P2, zd_cpu_to_le32(*(U32 *)&mBssId.mac[4]));
//update beacon interval
mBeaconPeriod = pBssInfo->bcnInterval;
HW_UpdateBcnInterval(pdot11Obj, mBeaconPeriod);
//FPRINT_V("mBeaconPeriod", mBeaconPeriod);
//update supported rated
memcpy((U8 *)&mBrates, (U8 *)&pBssInfo->supRates, pBssInfo->supRates.buf[1]+2);
HW_SetSupportedRate(pdot11Obj, (U8 *)&mBrates);
//zd1205_dump_data("mBrates = ", (U8 *)&mBrates, mBrates.buf[1]+2);
#if defined(OFDM)
if (mMacMode != PURE_B_MODE && mMacMode != PURE_A_MODE){
if (pBssInfo->extRates.buf[0] == EID_EXT_RATES){
memcpy((U8 *)&mExtRates, (U8 *)&pBssInfo->extRates, pBssInfo->extRates.buf[1]+2);
HW_SetSupportedRate(pdot11Obj, (U8 *)&mExtRates);
//zd1205_dump_data("mExtRates = ", (U8 *)&mExtRates, mExtRates.buf[1]+2);
}
}
#endif
//update ATIM Window
mATIMWindow = pBssInfo->IbssParms.buf[2] + (((U16)pBssInfo->IbssParms.buf[3]) << 8);
memcpy((U8 *)&mIbssParms, (U8 *)&pBssInfo->IbssParms, pBssInfo->IbssParms.buf[1]+2);
HW_UpdateATIMWindow(pdot11Obj, mATIMWindow);
//FPRINT_V("mATIMWindow", mATIMWindow);
ConfigBcnFIFO();
HW_EnableBeacon(pdot11Obj, mBeaconPeriod, 0, INDEPENDENT_BSS);
HW_RadioOnOff(pdot11Obj, mRadioOn);
mRequestFlag &= ~IBSS_CONNECT_SET;
//Modified for Continuous Reconnect to an existing IBSS
//When use a existing IBSS SSID
mRequestFlag &= ~CHANNEL_SCAN_SET;
mAssoc = TRUE;
memcpy(&pdot11Obj->CurrSsid[0], (U8 *)&mSsid, mSsid.buf[1]+2);
pdot11Obj->StatusNotify(STA_ASSOCIATED, (U8 *)&mBssId);
return TRUE;
}
}
else{
if (!(pdot11Obj->ConfigFlag & IBSS_CHANNEL_SCAN_SET)){
pdot11Obj->ConfigFlag |= IBSS_CHANNEL_SCAN_SET;
zd_CmdProbeReq(1);
}
return FALSE;
}
if (!bBSSFound){
//FPRINT("IBSS not found, create it !!!");
/****************************************************/
/* We generate an IBSS */
/****************************************************/
U32 seed = pdot11Obj->GetReg(reg, ZD_TSF_LowPart);
mBssIndex = 0xff;
//generate random BSSID
mBssId.mac[0] = (U8)((pdot11Obj->Rand(seed) & ~0x3) | 0x2); // I/G = 0, U/L = 1
mBssId.mac[1] = (U8)pdot11Obj->Rand(seed);
mBssId.mac[2] = (U8)pdot11Obj->Rand(seed);
mBssId.mac[3] = (U8)pdot11Obj->Rand(seed);
mBssId.mac[4] = (U8)pdot11Obj->Rand(seed);
mBssId.mac[5] = (U8)pdot11Obj->Rand(seed);
//zd1205_dump_data("mBssId = ", (U8 *)&mBssId, 6);
//update Bssid
pdot11Obj->SetReg(reg, ZD_BSSID_P1, zd_cpu_to_le32(*(U32 *)&mBssId.mac[0]));
pdot11Obj->SetReg(reg, ZD_BSSID_P2, zd_cpu_to_le32(*(U32 *)&mBssId.mac[4]));
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, mMacMode);
//FPRINT_V("mRfChannel", mRfChannel);
//update beacon interval
HW_UpdateBcnInterval(pdot11Obj, mBeaconPeriod);
//FPRINT_V("mBeaconPeriod", mBeaconPeriod);
//update supported rated
HW_SetSupportedRate(pdot11Obj, (U8 *)&mBrates);
//zd1205_dump_data("mBrates = ", (U8 *)&mBrates, mBrates.buf[1]+2);
#if defined(OFDM)
if(mMacMode != PURE_A_MODE && mMacMode != PURE_B_MODE)
if (pdot11Obj->IsUSB2_0)
HW_SetSupportedRate(pdot11Obj, (U8 *)&mExtRates);
//zd1205_dump_data("mExtRates = ", (U8 *)&mExtRates, mExtRates.buf[1]+2);
#endif
//update ATIM Window
HW_UpdateATIMWindow(pdot11Obj, mATIMWindow);
//FPRINT_V("mATIMWindow", mATIMWindow);
ConfigBcnFIFO();
HW_EnableBeacon(pdot11Obj, mBeaconPeriod, 0, INDEPENDENT_BSS);
HW_RadioOnOff(pdot11Obj, mRadioOn);
mRequestFlag &= ~IBSS_CONNECT_SET;
mAssoc = TRUE;
memcpy(&pdot11Obj->CurrSsid[0], (U8 *)&mSsid, mSsid.buf[1]+2);
pdot11Obj->StatusNotify(STA_ASSOCIATED, (U8 *)&mBssId);
return TRUE;
}
return FALSE;
}
void zd_ResetDevice(void)
{
U16 BeaconInterval = 0x2;
U32 tmpvalue;
void *reg = pdot11Obj->reg;
// Device will reset after 1ms
HW_UpdateBcnInterval(pdot11Obj, BeaconInterval);
pdot11Obj->SetReg(reg, ZD_Pre_TBTT, 0x1);
//++ Ensure the following is an atomic operation.
#ifndef HOST_IF_USB
i_state = pdot11Obj->EnterCS();
#endif
tmpvalue = pdot11Obj->GetReg(reg, ZD_PS_Ctrl);
pdot11Obj->SetReg(reg, ZD_PS_Ctrl, (tmpvalue | BIT_0));
pdot11Obj->bDeviceInSleep = 1;
#ifndef HOST_IF_USB
pdot11Obj->ExitCS(i_state);
// Delay 1ms to ensure device had been reset
pdot11Obj->DelayUs(1000);
#endif
}
BOOLEAN zd_PseudoIbssConnect(void)
{
void *reg = pdot11Obj->reg;
U8 IBSS_BSSID[6];
memset(IBSS_BSSID, 0, 6);
//++
// Set EIFS=0x32 to prevent chamber low Tx-throughput (sometimes)
// problem. In chamber environment, almost no Rx-frame, once
// we detect a CRC16/CRC32 error frame, we adopt EIFS, because of
// less of RX-frame, it's less posibility to change EIFS to DIFS
// by FA (Frame Analyzer), and therefore damage the Tx-Throughput.
// We must use SleepResetDevice to trigger FA to adpot 0x32.
pdot11Obj->SetReg(reg, ZD_IFS_Value, 0x5032032);
zd_ResetDevice();
//update Bssid
pdot11Obj->SetReg(reg, ZD_BSSID_P1, zd_cpu_to_le32(*(U32 *)&IBSS_BSSID[0]));
pdot11Obj->SetReg(reg, ZD_BSSID_P2, zd_cpu_to_le32(*(U32 *)&IBSS_BSSID[4]));
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, mMacMode);
mAssoc = TRUE;
pdot11Obj->StatusNotify(STA_ASSOCIATED, (U8 *)IBSS_BSSID);
return TRUE;
}
BOOLEAN zd_CmdConnect(U8 index, U8 bssType)
{
if (bssType == INFRASTRUCTURE_BSS)
{
//printk(KERN_ERR "Build Infra-Type BSS\n");
return zd_InfraConnect(index-1);
}
else if (bssType==INDEPENDENT_BSS)
{
//printk(KERN_ERR "Build IBSS\n");
return zd_IbssConnect();
}
else if (bssType == PSEUDO_IBSS)
return zd_PseudoIbssConnect();
return TRUE;
}
BOOLEAN zd_CmdDisConnect(void)
{
mAssoc = FALSE;
mRequestFlag |= DIS_CONNECT_SET;
return TRUE;
}
BOOLEAN zd_CmdRoaming(void)
{
if ((mRequestFlag & ROAMING_SET) || pdot11Obj->bChScanning || (pdot11Obj->ConfigFlag & SCAN_AND_CONNECT_SET))
return FALSE;
mAssoc = FALSE;
mRequestFlag |= ROAMING_SET;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -