📄 zd1205.c
字号:
if (!dot11Obj.bDeviceInSleep)
zd_writel(phyAddr, ZD_PCI_TxAddr_p1);
}
void zd1205_start_upload(u32 phyAddr)
{
#ifdef HOST_IF_USB
return;
#endif
if (!dot11Obj.bDeviceInSleep){
zd_writel(phyAddr, ZD_PCI_RxAddr_p1);
zd_writel(0, ZD_PCI_RxAddr_p2);
}
}
static void zd1205_action(unsigned long parm)
{
zd_SigProcess(); //process management frame queue in mgtQ
}
#if ZDCONF_AP_SUPPORT == 1
static void zd1205_ps_action(unsigned long parm)
{
zd_CleanupAwakeQ();
}
#endif
static void zd1205_tx_action(unsigned long parm)
{
zd_CleanupTxQ();
}
#ifndef HOST_IF_USB
u8 zd1205_RateAdaption(u16 aid, u8 CurrentRate, u8 gear)
{
u8 NewRate;
RATEDEBUG("***** zd1205_RateAdaption");
RATEDEBUG_V("aid", aid);
RATEDEBUG_V("CurrentRate", CurrentRate);
if (gear == FALL_RATE){
if (CurrentRate >= RATE_2M){
NewRate = CurrentRate - 1;
zd_EventNotify(EVENT_UPDATE_TX_RATE, (U32)NewRate, (U32)aid, 0);
}
else{
NewRate = CurrentRate;
}
return (NewRate);
}
return 0;
}
#endif
void zd1205_ClearTupleCache(struct zd1205_private *macp)
{
int i;
tuple_Cache_t *pCache = &macp->cache;
pCache->freeTpi = 0;
for (i=0; i<TUPLE_CACHE_SIZE; i++){
pCache->cache[i].full = 0;
}
}
u8 zd1205_SearchTupleCache(struct zd1205_private *macp, u8 *pAddr, u16 seq, u8 frag)
{
int k;
tuple_Cache_t *pCache = &macp->cache;
for (k=0; k<TUPLE_CACHE_SIZE; k++){
if ((memcmp((char *)&pCache->cache[k].ta[0], (char *)pAddr, 6) == 0)
&& (pCache->cache[k].sn == seq) && (pCache->cache[k].fn == frag)
&& (pCache->cache[k].full))
return 1;
}
return 0;
}
void zd1205_UpdateTupleCache(struct zd1205_private *macp, u8 *pAddr, u16 seq ,u8 frag)
{
int k;
tuple_Cache_t *pCache = &macp->cache;
for (k=0; k<TUPLE_CACHE_SIZE; k++){
if (pCache->cache[k].full){
if ((memcmp((char *)&pCache->cache[k].ta[0], (char *)pAddr, 6) == 0)
&& (pCache->cache[k].sn == seq) ){
pCache->cache[k].fn = frag;
return;
}
}
}
pCache->freeTpi &= (TUPLE_CACHE_SIZE-1);
memcpy(&pCache->cache[pCache->freeTpi].ta[0], (char *)pAddr, 6);
pCache->cache[pCache->freeTpi].sn = seq;
pCache->cache[pCache->freeTpi].fn = frag;
pCache->cache[pCache->freeTpi].full = 1;
pCache->freeTpi++;
}
void zd1205_ArReset(struct zd1205_private *macp)
{
u8 i;
defrag_Array_t *pArray = &macp->defragArray;
for (i=0; i<MAX_DEFRAG_NUM; i++)
pArray->mpdu[i].inUse = 0;
}
void zd1205_ArAge(struct zd1205_private *macp, u32 age)
{
u8 i;
defrag_Array_t *pArray = &macp->defragArray;
for (i=0; i<MAX_DEFRAG_NUM; i++){
if (pArray->mpdu[i].inUse){
if ((age - pArray->mpdu[i].eol) > MAX_RX_TIMEOUT){
DFDEBUG("***** zd1205_ArAged");
macp->ArAgedCnt++;
dot11Obj.ReleaseBuffer(pArray->mpdu[i].buf);
pArray->mpdu[i].inUse = 0;
}
}
}
}
int zd1205_ArFree(struct zd1205_private *macp)
{
u8 i;
defrag_Array_t *pArray = &macp->defragArray;
for (i=0; i<MAX_DEFRAG_NUM; i++){
if (!pArray->mpdu[i].inUse)
return i;
}
macp->ArFreeFailCnt++;
return -1;
}
int zd1205_ArSearch(struct zd1205_private *macp, u8 *pAddr, u16 seq, u8 frag)
{
u8 i;
defrag_Array_t *pArray = &macp->defragArray;
defrag_Mpdu_t *pDeMpdu;
for (i=0; i<MAX_DEFRAG_NUM; i++){
pDeMpdu = &pArray->mpdu[i];
if (pDeMpdu->inUse){
if ((memcmp((char *)&pDeMpdu->ta[0], pAddr, 6) == 0)
&& (pDeMpdu->sn == seq)){
if (pDeMpdu->fn == (frag-1)){
return i;
}
else {
dot11Obj.ReleaseBuffer(pDeMpdu->buf);
pDeMpdu->inUse = 0;
return -1;
}
}
}
}
return -1;
}
void zd1205_ArUpdate(struct zd1205_private *macp, u8 *pAddr, u16 seq, u8 frag, int i)
{
defrag_Array_t *pArray = &macp->defragArray;
pArray->mpdu[i].inUse = 1;
memcpy(&pArray->mpdu[i].ta[0], (char*)pAddr, 6);
pArray->mpdu[i].sn = seq;
pArray->mpdu[i].fn = frag;
pArray->mpdu[i].eol = nowT();
}
void zd1205_IncreaseTxPower(struct zd1205_private *macp, u8 TxPwrType)
{
u8 *pTxGain;
#if fTX_GAIN_OFDM
if (TxPwrType != cTX_OFDM)
pTxGain = &(dot11Obj.TxGainSetting);
else
pTxGain = &(dot11Obj.TxGainSetting2);
#else
pTxGain = &(dot11Obj.TxGainSetting);
#endif
switch(macp->RF_Mode){
case MAXIM_NEW_RF:
if (*pTxGain < MAXIM2_MAX_TX_PWR_SET)
(*pTxGain)++;
break;
case RFMD_RF:
if (*pTxGain < RFMD_MAX_TX_PWR_SET)
(*pTxGain) ++;
break;
case AL2230_RF:
case AL2230S_RF:
case AL7230B_RF:
if (*pTxGain < AL2230_MAX_TX_PWR_SET)
(*pTxGain) += 2;
break;
default:
break;
}
HW_Write_TxGain2(&dot11Obj, TxPwrType);
}
void zd1205_DecreaseTxPower(struct zd1205_private *macp, u8 TxPwrType)
{
u8 *pTxGain;
#if fTX_GAIN_OFDM
if (TxPwrType != cTX_OFDM)
pTxGain = &(dot11Obj.TxGainSetting);
else
pTxGain = &(dot11Obj.TxGainSetting2);
#else
pTxGain = &(dot11Obj.TxGainSetting);
#endif
switch(macp->RF_Mode){
case MAXIM_NEW_RF:
if (*pTxGain > MAXIM2_MIN_TX_PWR_SET)
(*pTxGain)--;
break;
case RFMD_RF:
if (*pTxGain > RFMD_MIN_TX_PWR_SET)
(*pTxGain) --;
break;
case AL2230_RF:
case AL2230S_RF:
case AL7230B_RF:
if (*pTxGain > AL2230_MIN_TX_PWR_SET)
(*pTxGain) -= 2;
break;
default:
break;
}
HW_Write_TxGain2(&dot11Obj, TxPwrType);
}
#if ZDCONF_STA_PSM == 1
int
zd1205_AnyActivity(struct zd1205_private *macp)
{
unsigned long flags;
// Any frame wait for transmission.
spin_lock_irqsave(&macp->q_lock, flags);
if (macp->activeTxQ->count){
spin_unlock_irqrestore(&macp->q_lock, flags);
return 1;
}
spin_unlock_irqrestore(&macp->q_lock, flags);
if ((dot11Obj.QueueFlag & MGT_QUEUE_SET) || (dot11Obj.QueueFlag & TX_QUEUE_SET))
return 1;
if (macp->bAnyActivity)
return 1;
// No any activity.
return 0;
}
#endif
void zd1205_connect_mon(struct zd1205_private *macp)
{
static u16 IdleLoop_Under_Seq1 = 0;
zd_ConnectMon();
// if (dot11Obj.bDeviceInSleep)
// printk(KERN_ERR "mon\n");
#if ZDCONF_STA_PSM == 1
if ((macp->cardSetting.BssType == INFRASTRUCTURE_BSS) && (macp->bPSMSupported)){
if ((!dot11Obj.bChScanning) && (macp->PwrState) && (!dot11Obj.bDeviceInSleep) && (macp->bAssoc)){
// Solve Sequence number duplication problem after wakeup.
if (!zd1205_AnyActivity(macp)){
if ((macp->SequenceNum != 1) || (IdleLoop_Under_Seq1 > 20)){
//zd1205_sleep_reset(macp);
IdleLoop_Under_Seq1 = 0;
// Avoid accessing Registers to save computation power.
}
else{
IdleLoop_Under_Seq1++;
}
//ZD1211DEBUG(2, "IdleLoop_Under_Seq1= %d\n", IdleLoop_Under_Seq1);
}
}
}
#endif
}
void zd1205_mgt_mon_cb(struct net_device *dev)
{
struct zd1205_private *macp = dev->priv;
#ifdef HOST_IF_USB
defer_kevent(macp, KEVENT_MGT_MON_TIMEOUT);
mod_timer(&(macp->tm_mgt_id), jiffies+ (1*HZ)/50); //20ms
#else
zd1205_connect_mon(macp);
mod_timer(&(macp->tm_mgt_id), jiffies+ (1*HZ)/50); //20ms
#endif
}
void zd1205_SwAntennaDiv(struct zd1205_private *macp)
{
#if fANT_DIVERSITY
static u32 loop = 0;
loop++;
// Software Antenna Diversity Mechanism
if (macp->bEnableSwAntennaDiv){
switch(AccState){
case ACC_1:
if ((loop % macp->Ant_MonitorDur1) == 0){
if (macp->Acc_Num_OFDM)
Avg1_SQ_OFDM = macp->Acc_SQ_OFDM / macp->Acc_Num_OFDM;
else {
Avg1_SQ_OFDM = 0;
if (macp->Acc_Num)
Avg1_SQ = macp->Acc_SQ / macp->Acc_Num;
else
Avg1_SQ = 0;
}
// Higher SQ is better
if (((Avg1_SQ_OFDM < macp->NiceSQThr_OFDM) && (Avg1_SQ_OFDM > 0))
|| ((Avg1_SQ_OFDM == 0)
&& ((Avg1_SQ < macp->NiceSQThr) && (Avg1_SQ > 0)))
|| (!macp->bAssoc)){ // disconnected
SwitchAntenna(macp);
AccState = ACC_2;
}
macp->Acc_SQ = 0;
macp->Acc_Num = 0;
macp->Acc_SQ_OFDM = 0;
macp->Acc_Num_OFDM = 0;
}
break;
case ACC_2:
if ((loop % macp->Ant_MonitorDur2) == 0)
{
if (macp->Acc_Num_OFDM)
Avg2_SQ_OFDM = macp->Acc_SQ_OFDM / macp->Acc_Num_OFDM;
else {
Avg2_SQ_OFDM = 0;
if (macp->Acc_Num)
Avg2_SQ = macp->Acc_SQ / macp->Acc_Num;
else
Avg2_SQ = 0;
}
// Higher SQ is better
if ((Avg2_SQ_OFDM < Avg1_SQ_OFDM)
|| (((Avg2_SQ_OFDM == 0) && (Avg1_SQ_OFDM == 0))
&& (Avg2_SQ < Avg1_SQ))
|| (!macp->bAssoc)){ // disconnected
SwitchAntenna(macp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -