void SwAntennaDiversity(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bSwCheckSS = false; if (bSwCheckSS) { priv->AdTickCount++; printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod); printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold); } if (priv->ieee80211->state != IEEE80211_LINKED) { priv->bAdSwitchedChecking = false; SwitchAntenna(dev); } else if (priv->AdRxOkCnt == 0) { priv->bAdSwitchedChecking = false; SwitchAntenna(dev); } else if (priv->bAdSwitchedChecking == true) { priv->bAdSwitchedChecking = false; priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) { priv->AdCheckPeriod *= 2; if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod) priv->AdCheckPeriod = priv->AdMaxCheckPeriod; SwitchAntenna(dev); } else { priv->AdCheckPeriod = priv->AdMinCheckPeriod; } } else { priv->AdTickCount = 0; if ((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)) { SwitchAntenna(dev); priv->bHWAdSwitched = true; } else if ((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)) { SwitchAntenna(dev); priv->bHWAdSwitched = true; } else { priv->bHWAdSwitched = false; } if ((!priv->bHWAdSwitched) && (bSwCheckSS)) { if (priv->AdRxSignalStrength < priv->AdRxSsThreshold) { priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; priv->bAdSwitchedChecking = true; SwitchAntenna(dev); } else { priv->bAdSwitchedChecking = false; if ((priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; } if (priv->AdCheckPeriod > priv->AdMinCheckPeriod) priv->AdCheckPeriod /= 2; } } } priv->AdRxOkCnt = 0; priv->AdMainAntennaRxOkCnt = 0; priv->AdAuxAntennaRxOkCnt = 0; }
// // Description: // Engine of SW Antenna Diversity mechanism. // Since 8187 has no Tx part information, // this implementation is only dependend on Rx part information. // // 2006.04.17, by rcnjko. // void SwAntennaDiversity( struct net_device *dev ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bSwCheckSS=false; // printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex); // printk("AdTickCount is %d\n",priv->AdTickCount); //by amy 080312 if(bSwCheckSS) { priv->AdTickCount++; printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod); printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold); } // priv->AdTickCount++;//-by amy 080312 // Case 1. No Link. if(priv->ieee80211->state != IEEE80211_LINKED) { // printk("SwAntennaDiversity(): Case 1. No Link.\n"); priv->bAdSwitchedChecking = false; // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. SwitchAntenna(dev); } // Case 2. Linked but no packet received. else if(priv->AdRxOkCnt == 0) { // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n"); priv->bAdSwitchedChecking = false; SwitchAntenna(dev); } // Case 3. Evaluate last antenna switch action and undo it if necessary. else if(priv->bAdSwitchedChecking == true) { // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n"); priv->bAdSwitchedChecking = false; // Adjust Rx signal strength threshold. priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) { // Rx signal strength is not improved after we swtiched antenna. => Swich back. // printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n", // priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched); //by amy 080312 // Increase Antenna Diversity checking period due to bad decision. priv->AdCheckPeriod *= 2; //by amy 080312 // Increase Antenna Diversity checking period. if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod) priv->AdCheckPeriod = priv->AdMaxCheckPeriod; // Wrong deceision => switch back. SwitchAntenna(dev); } else { // Rx Signal Strength is improved. // printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n", // priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched); // Reset Antenna Diversity checking period to its min value. priv->AdCheckPeriod = priv->AdMinCheckPeriod; } // printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n", // priv->AdRxSsThreshold, priv->AdCheckPeriod); } // Case 4. Evaluate if we shall switch antenna now. // Cause Table Speed is very fast in TRC Dell Lab, we check it every time. else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312 { // printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n"); priv->AdTickCount = 0; // // <Roger_Notes> We evaluate RxOk counts for each antenna first and than // evaluate signal strength. // The following operation can overcome the disability of CCA on both two antennas // When signal strength was extremely low or high. // 2008.01.30. // // // Evaluate RxOk count from each antenna if we shall switch default antenna now. // Added by Roger, 2008.02.21. //{by amy 080312 if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)) { // We set Main antenna as default but RxOk count was less than Aux ones. // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); // Switch to Aux antenna. SwitchAntenna(dev); priv->bHWAdSwitched = true; } else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)) { // We set Aux antenna as default but RxOk count was less than Main ones. // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); // Switch to Main antenna. SwitchAntenna(dev); priv->bHWAdSwitched = true; } else {// Default antenna is better. // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); // Still need to check current signal strength. priv->bHWAdSwitched = false; } // // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna // didn't changed by HW evaluation. // 2008.02.27. // // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 // For example, Throughput of aux is better than main antenna(about 10M v.s 2M), // but AdRxSignalStrength is less than main. // Our guess is that main antenna have lower throughput and get many change // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength. // if( (!priv->bHWAdSwitched) && (bSwCheckSS)) { //by amy 080312} // Evaluate Rx signal strength if we shall switch antenna now. if(priv->AdRxSignalStrength < priv->AdRxSsThreshold) { // Rx signal strength is weak => Switch Antenna. // printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n", // priv->AdRxSignalStrength, priv->AdRxSsThreshold); priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; priv->bAdSwitchedChecking = true; SwitchAntenna(dev); } else { // Rx signal strength is OK. // printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n", // priv->AdRxSignalStrength, priv->AdRxSsThreshold); priv->bAdSwitchedChecking = false; // Increase Rx signal strength threshold if necessary. if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit. { priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312 } // Reduce Antenna Diversity checking period if possible. if( priv->AdCheckPeriod > priv->AdMinCheckPeriod ) { priv->AdCheckPeriod /= 2; } } } } //by amy 080312 // Reset antenna diversity Rx related statistics. priv->AdRxOkCnt = 0; priv->AdMainAntennaRxOkCnt = 0; priv->AdAuxAntennaRxOkCnt = 0; //by amy 080312 // priv->AdRxOkCnt = 0;//-by amy 080312 // printk("-SwAntennaDiversity()\n"); }
/* * Engine of SW Antenna Diversity mechanism. * Since 8187 has no Tx part information, * this implementation is only dependend on Rx part information. */ void SwAntennaDiversity(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bSwCheckSS = false; if (bSwCheckSS) { priv->AdTickCount++; printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", priv->AdTickCount, priv->AdCheckPeriod); printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", priv->AdRxSignalStrength, priv->AdRxSsThreshold); } /* Case 1. No Link. */ if (priv->ieee80211->state != IEEE80211_LINKED) { priv->bAdSwitchedChecking = false; /* I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. */ SwitchAntenna(dev); /* Case 2. Linked but no packet receive.d */ } else if (priv->AdRxOkCnt == 0) { priv->bAdSwitchedChecking = false; SwitchAntenna(dev); /* Case 3. Evaluate last antenna switch action and undo it if necessary. */ } else if (priv->bAdSwitchedChecking == true) { priv->bAdSwitchedChecking = false; /* Adjust Rx signal strength threshold. */ priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold; if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) { /* Rx signal strength is not improved after we swtiched antenna. => Swich back. */ /* Increase Antenna Diversity checking period due to bad decision. */ priv->AdCheckPeriod *= 2; /* Increase Antenna Diversity checking period. */ if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod) priv->AdCheckPeriod = priv->AdMaxCheckPeriod; /* Wrong decision => switch back. */ SwitchAntenna(dev); } else { /* Rx Signal Strength is improved. */ /* Reset Antenna Diversity checking period to its min value. */ priv->AdCheckPeriod = priv->AdMinCheckPeriod; } } /* Case 4. Evaluate if we shall switch antenna now. */ /* Cause Table Speed is very fast in TRC Dell Lab, we check it every time. */ else { priv->AdTickCount = 0; /* * <Roger_Notes> We evaluate RxOk counts for each antenna first and than * evaluate signal strength. * The following operation can overcome the disability of CCA on both two antennas * When signal strength was extremely low or high. * 2008.01.30. */ /* * Evaluate RxOk count from each antenna if we shall switch default antenna now. */ if ((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)) { /* We set Main antenna as default but RxOk count was less than Aux ones. */ /* Switch to Aux antenna. */ SwitchAntenna(dev); priv->bHWAdSwitched = true; } else if ((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)) { /* We set Aux antenna as default but RxOk count was less than Main ones. */ /* Switch to Main antenna. */ SwitchAntenna(dev); priv->bHWAdSwitched = true; } else { /* Default antenna is better. */ /* Still need to check current signal strength. */ priv->bHWAdSwitched = false; } /* * <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna * didn't change by HW evaluation. * 2008.02.27. * * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 * For example, Throughput of aux is better than main antenna(about 10M v.s 2M), * but AdRxSignalStrength is less than main. * Our guess is that main antenna have lower throughput and get many change * to receive more CCK packets(ex.Beacon) which have stronger SignalStrength. */ if ((!priv->bHWAdSwitched) && (bSwCheckSS)) { /* Evaluate Rx signal strength if we shall switch antenna now. */ if (priv->AdRxSignalStrength < priv->AdRxSsThreshold) { /* Rx signal strength is weak => Switch Antenna. */ priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; priv->bAdSwitchedChecking = true; SwitchAntenna(dev); } else { /* Rx signal strength is OK. */ priv->bAdSwitchedChecking = false; /* Increase Rx signal strength threshold if necessary. */ if ((priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && /* Signal is much stronger than current threshold */ priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { /* Current threhold is not yet reach upper limit. */ priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */ } /* Reduce Antenna Diversity checking period if possible. */ if (priv->AdCheckPeriod > priv->AdMinCheckPeriod) priv->AdCheckPeriod /= 2; } } } /* Reset antenna diversity Rx related statistics. */ priv->AdRxOkCnt = 0; priv->AdMainAntennaRxOkCnt = 0; priv->AdAuxAntennaRxOkCnt = 0; }
void rtl8180_hw_dig_wq (struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq); struct net_device *dev = ieee->dev; #else void rtl8180_hw_dig_wq(struct net_device *dev) { #endif struct r8180_priv *priv = ieee80211_priv(dev); if(priv->card_8187_Bversion == VERSION_8187B_B) { priv->FalseAlarmRegValue = (u32)read_nic_byte(dev, (OFDM_FALSE_ALARM+1)); } else { priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM); } if(priv->bDigMechanism) { DynamicInitGain(dev); } if(priv->card_8187 == NIC_8187B) { if(priv->bCCKThMechanism) { DynamicCCKThreshold(dev); } } } void SetTxPowerLevel8187(struct net_device *dev, short chan) { struct r8180_priv *priv = ieee80211_priv(dev); switch(priv->rf_chip) { case RF_ZEBRA: rtl8225_SetTXPowerLevel(dev,chan); break; case RF_ZEBRA2: rtl8225z2_SetTXPowerLevel(dev,chan); break; } } void DoRxHighPower(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); TR_SWITCH_STATE TrSwState; u16 HiPwrUpperTh = 0; u16 HiPwrLowerTh = 0; u16 RSSIHiPwrUpperTh = 0; u16 RSSIHiPwrLowerTh = 0; if((priv->card_8187 == NIC_8187B)||(priv->card_8187 == NIC_8187)) { TrSwState = priv->TrSwitchState; switch(priv->rf_chip) { case RF_ZEBRA: HiPwrUpperTh = Z1_HIPWR_UPPER_TH; HiPwrLowerTh = Z1_HIPWR_LOWER_TH; break; case RF_ZEBRA2: if((priv->card_8187 == NIC_8187)) { HiPwrUpperTh = Z2_HIPWR_UPPER_TH; HiPwrLowerTh = Z2_HIPWR_LOWER_TH; } else { HiPwrUpperTh = priv->Z2HiPwrUpperTh; HiPwrLowerTh = priv->Z2HiPwrLowerTh; HiPwrUpperTh = HiPwrUpperTh * 10; HiPwrLowerTh = HiPwrLowerTh * 10; RSSIHiPwrUpperTh = priv->Z2RSSIHiPwrUpperTh; RSSIHiPwrLowerTh = priv->Z2RSSIHiPwrLowerTh; } break; default: return; break; } if((priv->card_8187 == NIC_8187)) { if (priv->UndecoratedSmoothedSS > HiPwrUpperTh) { if( priv->TrSwitchState == TR_HW_CONTROLLED ) { write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect | TR_SW_MASK_8187 )); write_nic_byte(dev, RFPinsOutput, (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187)); priv->TrSwitchState = TR_SW_TX; priv->bToUpdateTxPwr = true; } } else if (priv->UndecoratedSmoothedSS < HiPwrLowerTh) { if( priv->TrSwitchState == TR_SW_TX) { write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput)); write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect)); priv->TrSwitchState = TR_HW_CONTROLLED; priv->bToUpdateTxPwr = true; } } }else { if(TrSwState == TR_HW_CONTROLLED) { if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) || (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) { write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect|TR_SW_MASK_8187 )); write_nic_byte(dev, RFPinsOutput, (u8)((priv->wMacRegRfPinsOutput&(~TR_SW_MASK_8187))|TR_SW_MASK_TX_8187)); priv->TrSwitchState = TR_SW_TX; priv->bToUpdateTxPwr = true; } } else { if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) && (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) { write_nic_byte(dev, RFPinsOutput, (u8)(priv->wMacRegRfPinsOutput)); write_nic_byte(dev, RFPinsSelect, (u8)(priv->wMacRegRfPinsSelect)); priv->TrSwitchState = TR_HW_CONTROLLED; priv->bToUpdateTxPwr = true; } } } } } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void rtl8180_tx_pw_wq (struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq); struct net_device *dev = ieee->dev; #else void rtl8180_tx_pw_wq(struct net_device *dev) { #endif struct r8180_priv *priv = ieee80211_priv(dev); if(priv->bToUpdateTxPwr) { priv->bToUpdateTxPwr = false; SetTxPowerLevel8187(dev, priv->chan); } DoRxHighPower(dev); } bool CheckHighPower(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; if(!priv->bRegHighPowerMechanism) { return false; } if((ieee->state == IEEE80211_LINKED_SCANNING)) { return false; } return true; } #ifdef SW_ANTE_DIVERSITY #define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 void SwAntennaDiversityRxOk8185( struct net_device *dev, u8 SignalStrength ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); priv->AdRxOkCnt++; if( priv->AdRxSignalStrength != -1) { priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10; } else { priv->AdRxSignalStrength = SignalStrength; } if( priv->LastRxPktAntenna ) priv->AdMainAntennaRxOkCnt++; else priv->AdAuxAntennaRxOkCnt++; } bool SetAntenna8185( struct net_device *dev, u8 u1bAntennaIndex ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bAntennaSwitched = false; switch(u1bAntennaIndex) { case 0: switch(priv->rf_chip) { case RF_ZEBRA: case RF_ZEBRA2: write_nic_byte(dev, 0x7f, ((0x01009b90 & 0xff000000) >> 24)); write_nic_byte(dev, 0x7e, ((0x01009b90 & 0x00ff0000) >> 16)); write_nic_byte(dev, 0x7d, ((0x01009b90 & 0x0000ff00) >> 8)); write_nic_byte(dev, 0x7c, ((0x01009b90 & 0x000000ff) >> 0)); write_nic_byte(dev, 0x7f, ((0x000090a6 & 0xff000000) >> 24)); write_nic_byte(dev, 0x7e, ((0x000090a6 & 0x00ff0000) >> 16)); write_nic_byte(dev, 0x7d, ((0x000090a6 & 0x0000ff00) >> 8)); write_nic_byte(dev, 0x7c, ((0x000090a6 & 0x000000ff) >> 0)); write_nic_byte(dev, ANTSEL, 0x03); bAntennaSwitched = true; break; default: printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip); break; } break; case 1: switch(priv->rf_chip) { case RF_ZEBRA: case RF_ZEBRA2: write_nic_byte(dev, 0x7f, ((0x0100db90 & 0xff000000) >> 24)); write_nic_byte(dev, 0x7e, ((0x0100db90 & 0x00ff0000) >> 16)); write_nic_byte(dev, 0x7d, ((0x0100db90 & 0x0000ff00) >> 8)); write_nic_byte(dev, 0x7c, ((0x0100db90 & 0x000000ff) >> 0)); write_nic_byte(dev, 0x7f, ((0x000010a6 & 0xff000000) >> 24)); write_nic_byte(dev, 0x7e, ((0x000010a6 & 0x00ff0000) >> 16)); write_nic_byte(dev, 0x7d, ((0x000010a6 & 0x0000ff00) >> 8)); write_nic_byte(dev, 0x7c, ((0x000010a6 & 0x000000ff) >> 0)); write_nic_byte(dev, ANTSEL, 0x00); bAntennaSwitched = true; break; default: printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip); break; } break; default: printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex); break; } if(bAntennaSwitched) { priv->CurrAntennaIndex = u1bAntennaIndex; } return bAntennaSwitched; } bool SwitchAntenna( struct net_device *dev ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bResult = false; if(priv->CurrAntennaIndex == 0) { bResult = SetAntenna8185(dev, 1); if(priv->ieee80211->state == IEEE80211_LINKED) printk("To aux antenna 1......\n"); } else { bResult = SetAntenna8185(dev, 0); if(priv->ieee80211->state == IEEE80211_LINKED) printk("To main antenna 0......\n"); } return bResult; } void SwAntennaDiversity( struct net_device *dev ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bSwCheckSS=true; if(bSwCheckSS) { priv->AdTickCount++; } if(priv->ieee80211->state != IEEE80211_LINKED) { priv->bAdSwitchedChecking = false; SwitchAntenna(dev); } else if(priv->AdRxOkCnt == 0) { priv->bAdSwitchedChecking = false; SwitchAntenna(dev); } else if(priv->bAdSwitchedChecking == true) { priv->bAdSwitchedChecking = false; priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) { priv->AdCheckPeriod *= 2; if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod) priv->AdCheckPeriod = priv->AdMaxCheckPeriod; SwitchAntenna(dev); } else { priv->AdCheckPeriod = priv->AdMinCheckPeriod; } } else { priv->AdTickCount = 0; if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) && (priv->CurrAntennaIndex == 0)) { SwitchAntenna(dev); priv->bHWAdSwitched = true; } else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) && (priv->CurrAntennaIndex == 1)) { SwitchAntenna(dev); priv->bHWAdSwitched = true; } else { priv->bHWAdSwitched = false; } if( (!priv->bHWAdSwitched) && (bSwCheckSS)) { if(priv->AdRxSignalStrength < priv->AdRxSsThreshold) { priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; priv->bAdSwitchedChecking = true; SwitchAntenna(dev); } else { priv->bAdSwitchedChecking = false; if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; } if( priv->AdCheckPeriod > priv->AdMinCheckPeriod ) { priv->AdCheckPeriod /= 2; } } } } priv->AdRxOkCnt = 0; priv->AdMainAntennaRxOkCnt = 0; priv->AdAuxAntennaRxOkCnt = 0; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) void SwAntennaWorkItemCallback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,SwAntennaWorkItem); struct net_device *dev = ieee->dev; #else void SwAntennaWorkItemCallback(struct net_device *dev) { #endif SwAntennaDiversity(dev); } void SwAntennaDiversityTimerCallback( struct net_device *dev ) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; rtState = priv->eRFPowerState; do{ if (rtState == eRfOff) { break; } else if (rtState == eRfSleep) { break; } #ifdef SW_ANTE_DIVERSITY #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->SwAntennaWorkItem,0); #elif LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) queue_work(priv->ieee80211->wq,(void *)&priv->ieee80211->SwAntennaWorkItem); #else schedule_task(&priv->ieee80211->SwAntennaWorkItem); #endif #endif }while(false); if(priv->up) { mod_timer(&priv->SwAntennaDiversityTimer, jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD)); } }