Example #1
0
//
//	Description:
//		Tx Power tracking mechanism routine on 87SE.
// 	Created by Roger, 2007.12.11.
//
void
TxPwrTracking87SE(
	struct net_device *dev
)
{
	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
	u8	tmpu1Byte, CurrentThermal, Idx;
	char	CckTxPwrIdx, OfdmTxPwrIdx;
	//u32	u4bRfReg;

	tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
	CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
	CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826

	//printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);

	if( CurrentThermal != priv->ThermalMeter)
	{
//		printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");

		// Update Tx Power level on each channel.
		for(Idx = 1; Idx<15; Idx++)
		{
			CckTxPwrIdx = priv->chtxpwr[Idx];
			OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];

			if( CurrentThermal > priv->ThermalMeter )
			{ // higher thermal meter.
				CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
				OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;

				if(CckTxPwrIdx >35)
					CckTxPwrIdx = 35; // Force TxPower to maximal index.
				if(OfdmTxPwrIdx >35)
					OfdmTxPwrIdx = 35;
			}
			else
			{ // lower thermal meter.
				CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
				OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;

				if(CckTxPwrIdx <0)
					CckTxPwrIdx = 0;
				if(OfdmTxPwrIdx <0)
					OfdmTxPwrIdx = 0;
			}

			// Update TxPower level on CCK and OFDM resp.
			priv->chtxpwr[Idx] = CckTxPwrIdx;
			priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
		}

		// Update TxPower level immediately.
		rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
	}
	priv->ThermalMeter = CurrentThermal;
}
Example #2
0
void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
{
	rtl8225z2_SetTXPowerLevel(dev, ch);

	RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);

	if ((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
		RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);

	mdelay(1);

	force_pci_posting(dev);
	mdelay(10);
}
Example #3
0
void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
{
/*
	short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
		ieee80211_is_54g(priv->ieee80211->current_network)) ||
		priv->ieee80211->iw_mode == IW_MODE_MONITOR;
*/
	rtl8225z2_SetTXPowerLevel(dev, ch);

	RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);

	//YJ,add,080828, if set channel failed, write again
	if((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
	{
		RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
	}

	mdelay(1);

	force_pci_posting(dev);
	mdelay(10);
//deleted by David : 2006/8/9
#if 0
	write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22

	if(gset)
		write_nic_byte(dev,DIFS,20); //DIFS: 20
	else
		write_nic_byte(dev,DIFS,0x24); //DIFS: 36

	if(priv->ieee80211->state == IEEE80211_LINKED &&
		ieee80211_is_shortslot(priv->ieee80211->current_network))
		write_nic_byte(dev,SLOT,0x9); //SLOT: 9

	else
		write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)


	if(gset){
		write_nic_byte(dev,EIFS,91 - 20); // EIFS: 91 (0x5B)
		write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
		//DMESG("using G net params");
	}else{
		write_nic_byte(dev,EIFS,91 - 0x24); // EIFS: 91 (0x5B)
		write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
		//DMESG("using B net params");
	}
#endif

}
void TxPwrTracking87SE(struct net_device *dev)
{
	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
	u8	tmpu1Byte, CurrentThermal, Idx;
	char	CckTxPwrIdx, OfdmTxPwrIdx;

	tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
	CurrentThermal = (tmpu1Byte & 0xf0) >> 4; 
	CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c:CurrentThermal;

	if (CurrentThermal != priv->ThermalMeter) {
		
		for (Idx = 1; Idx < 15; Idx++) {
			CckTxPwrIdx = priv->chtxpwr[Idx];
			OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];

			if (CurrentThermal > priv->ThermalMeter) {
				
				CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
				OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;

				if (CckTxPwrIdx > 35)
					CckTxPwrIdx = 35; 
				if (OfdmTxPwrIdx > 35)
					OfdmTxPwrIdx = 35;
			} else {
				
				CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
				OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;

				if (CckTxPwrIdx < 0)
					CckTxPwrIdx = 0;
				if (OfdmTxPwrIdx < 0)
					OfdmTxPwrIdx = 0;
			}

			
			priv->chtxpwr[Idx] = CckTxPwrIdx;
			priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
		}

		
		rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
	}
	priv->ThermalMeter = CurrentThermal;
}
/*
 *	Description:
 *		Tx Power tracking mechanism routine on 87SE.
 */
void TxPwrTracking87SE(struct net_device *dev)
{
	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
	u8	tmpu1Byte, CurrentThermal, Idx;
	char	CckTxPwrIdx, OfdmTxPwrIdx;

	tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
	CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */
	CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c:CurrentThermal;

	if (CurrentThermal != priv->ThermalMeter) {
		/* Update Tx Power level on each channel. */
		for (Idx = 1; Idx < 15; Idx++) {
			CckTxPwrIdx = priv->chtxpwr[Idx];
			OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];

			if (CurrentThermal > priv->ThermalMeter) {
				/* higher thermal meter. */
				CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
				OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;

				if (CckTxPwrIdx > 35)
					CckTxPwrIdx = 35; /* Force TxPower to maximal index. */
				if (OfdmTxPwrIdx > 35)
					OfdmTxPwrIdx = 35;
			} else {
				/* lower thermal meter. */
				CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
				OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;

				if (CckTxPwrIdx < 0)
					CckTxPwrIdx = 0;
				if (OfdmTxPwrIdx < 0)
					OfdmTxPwrIdx = 0;
			}

			/* Update TxPower level on CCK and OFDM resp. */
			priv->chtxpwr[Idx] = CckTxPwrIdx;
			priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
		}

		/* Update TxPower level immediately. */
		rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
	}
	priv->ThermalMeter = CurrentThermal;
}
Example #6
0
void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
{
	struct r8180_priv *priv = ieee80211_priv(dev);
	short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
		ieee80211_is_54g(priv->ieee80211->current_network)) ||
		priv->ieee80211->iw_mode == IW_MODE_MONITOR;
	
	rtl8225z2_SetTXPowerLevel(dev, ch);
	
	write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
	
	force_pci_posting(dev);
	mdelay(10);
	
	write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
	
	if(gset)
		write_nic_byte(dev,DIFS,20); //DIFS: 20 
	else
		write_nic_byte(dev,DIFS,0x24); //DIFS: 36 
	
	if(priv->ieee80211->state == IEEE80211_LINKED &&
		ieee80211_is_shortslot(priv->ieee80211->current_network))
		write_nic_byte(dev,SLOT,0x9); //SLOT: 9
		
	else
		write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
		
	
	if(gset){
		write_nic_byte(dev,EIFS,91 - 20); // EIFS: 91 (0x5B)
		write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
		//DMESG("using G net params");
	}else{
		write_nic_byte(dev,EIFS,91 - 0x24); // EIFS: 91 (0x5B)
		write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
		//DMESG("using B net params");
	}


}
Example #7
0
void rtl8225z2_rf_init(struct net_device *dev)
{
	struct r8180_priv *priv = ieee80211_priv(dev);
	int i;
	short channel = 1;
	u16	brsr;
	u32	data, addr;

	priv->chan = channel;

	rtl8225_host_pci_init(dev);

	write_nic_dword(dev, RF_TIMING, 0x000a8008);

	brsr = read_nic_word(dev, BRSR);

	write_nic_word(dev, BRSR, 0xffff);

	write_nic_dword(dev, RF_PARA, 0x100044);

	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
	write_nic_byte(dev, CONFIG3, 0x44);
	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);

	rtl8185_rf_pins_enable(dev);

	write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
	write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
	write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
	write_rtl8225(dev, 0x3, 0x441); mdelay(1);
	write_rtl8225(dev, 0x4, 0x8c3); mdelay(1);
	write_rtl8225(dev, 0x5, 0xc72); mdelay(1);
	write_rtl8225(dev, 0x6, 0xe6);  mdelay(1);
	write_rtl8225(dev, 0x7, rtl8225_chan[channel]);  mdelay(1);
	write_rtl8225(dev, 0x8, 0x3f);  mdelay(1);
	write_rtl8225(dev, 0x9, 0x335); mdelay(1);
	write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
	write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
	write_rtl8225(dev, 0xc, 0x850); mdelay(1);
	write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
	write_rtl8225(dev, 0xe, 0x2b);  mdelay(1);
	write_rtl8225(dev, 0xf, 0x114);

	mdelay(100);

	write_rtl8225(dev, 0x0, 0x1b7);

	for (i = 0; i < 95; i++) {
		write_rtl8225(dev, 0x1, (u8)(i + 1));
		write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
	}

	write_rtl8225(dev, 0x3, 0x80);
	write_rtl8225(dev, 0x5, 0x4);

	write_rtl8225(dev, 0x0, 0xb7);

	write_rtl8225(dev, 0x2, 0xc4d);

	/* FIXME!! rtl8187 we have to check if calibrarion
	 * is successful and eventually cal. again (repeat
	 * the two write on reg 2)
	 */
	data = read_rtl8225(dev, 6);
	if (!(data & 0x00000080)) {
		write_rtl8225(dev, 0x02, 0x0c4d);
		force_pci_posting(dev); mdelay(200);
		write_rtl8225(dev, 0x02, 0x044d);
		force_pci_posting(dev); mdelay(100);
		data = read_rtl8225(dev, 6);
		if (!(data & 0x00000080))
			DMESGW("RF Calibration Failed!!!!\n");
	}

	mdelay(200);

	write_rtl8225(dev, 0x0, 0x2bf);

	for (i = 0; i < 128; i++) {
		data = rtl8225_agc[i];

		addr = i + 0x80; /* enable writing AGC table */
		write_phy_ofdm(dev, 0xb, data);
		mdelay(1);

		write_phy_ofdm(dev, 0xa, addr);
		mdelay(1);
	}

	force_pci_posting(dev);
	mdelay(1);

	write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
	write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
	write_phy_ofdm(dev, 0x02, 0x62); mdelay(1);
	write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x06, 0x40); mdelay(1);
	write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x08, 0x40); mdelay(1);
	write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
	write_phy_ofdm(dev, 0x0a, 0x08); mdelay(1);
	write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
	write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
	write_phy_ofdm(dev, 0x0d, 0x43);
	write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
	write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
	write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
	write_phy_ofdm(dev, 0x11, 0x07); mdelay(1);
	write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
	write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
	write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
	write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
	write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
	write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
	write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
	write_phy_ofdm(dev, 0x1b, 0x15); mdelay(1);
	write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
	write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
	write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1);
	write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
	write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
	write_phy_ofdm(dev, 0x21, 0x17); mdelay(1);
	write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
	write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME maybe not needed */
	write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
	write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
	write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);

	rtl8225z2_set_gain(dev, 4);

	write_phy_cck(dev, 0x0, 0x98); mdelay(1);
	write_phy_cck(dev, 0x3, 0x20); mdelay(1);
	write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
	write_phy_cck(dev, 0x5, 0x12); mdelay(1);
	write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
	write_phy_cck(dev, 0x7, 0x78); mdelay(1);
	write_phy_cck(dev, 0x8, 0x2e); mdelay(1);
	write_phy_cck(dev, 0x10, 0x93); mdelay(1);
	write_phy_cck(dev, 0x11, 0x88); mdelay(1);
	write_phy_cck(dev, 0x12, 0x47); mdelay(1);
	write_phy_cck(dev, 0x13, 0xd0);
	write_phy_cck(dev, 0x19, 0x00);
	write_phy_cck(dev, 0x1a, 0xa0);
	write_phy_cck(dev, 0x1b, 0x08);
	write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
	write_phy_cck(dev, 0x41, 0x8d); mdelay(1);
	write_phy_cck(dev, 0x42, 0x15); mdelay(1);
	write_phy_cck(dev, 0x43, 0x18); mdelay(1);
	write_phy_cck(dev, 0x44, 0x36); mdelay(1);
	write_phy_cck(dev, 0x45, 0x35); mdelay(1);
	write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
	write_phy_cck(dev, 0x47, 0x25); mdelay(1);
	write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
	write_phy_cck(dev, 0x49, 0x12); mdelay(1);
	write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
	write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
	write_phy_cck(dev, 0x4c, 0x05); mdelay(1);

	write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);

	rtl8225z2_SetTXPowerLevel(dev, channel);

	/* RX antenna default to A */
	write_phy_cck(dev, 0x11, 0x9b); mdelay(1);		/* B: 0xDB */
	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);		/* B: 0x10 */

	rtl8185_tx_antenna(dev, 0x03);				/* B: 0x00 */

	/* switch to high-speed 3-wire
	 * last digit. 2 for both cck and ofdm
	 */
	write_nic_dword(dev, 0x94, 0x15c00002);
	rtl8185_rf_pins_enable(dev);

	rtl8225_rf_set_chan(dev, priv->chan);
}
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));
    }

}