Пример #1
0
void rtl8225_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;
	int eifs_addr;
	
	if(NIC_8187 == priv->card_8187) {
		eifs_addr = EIFS_8187;
	} else {
		eifs_addr = EIFS_8187B;
	}	

	
	rtl8225_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_addr,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_addr,91 - 0x24); // EIFS: 91 (0x5B)
		write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
		//DMESG("using B net params");
	}


}
Пример #2
0
void rtl8225_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;

	rtl8225_SetTXPowerLevel(dev, ch);

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

	force_pci_posting(dev);
	mdelay(10);

	// A mode sifs 0x44, difs 34-14, slot 9, eifs 23, cwm 3, cwM 7, ctstoself 0x10
	if(gset){
		write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
		write_nic_byte(dev,DIFS,0x14); //DIFS: 20
		//write_nic_byte(dev,DIFS,20); //DIFS: 20
	}else{
		write_nic_byte(dev,SIFS,0x44);// SIFS: 0x22
		write_nic_byte(dev,DIFS,50 - 14); //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,81);//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,81); // EIFS: 91 (0x5B)
		write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
		//DMESG("using B net params");
	}


}
Пример #3
0
static void rtl8225_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;

	rtl8225_SetTXPowerLevel(dev, ch);

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

	force_pci_posting(dev);
	mdelay(10);

	if (gset) {
		write_nic_byte(dev, SIFS, 0x22);
		write_nic_byte(dev, DIFS, 0x14);
	} else {
		write_nic_byte(dev, SIFS, 0x44);
		write_nic_byte(dev, DIFS, 0x24);
	}

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

	if (gset) {
		write_nic_byte(dev, EIFS, 81);
		write_nic_byte(dev, CW_VAL, 0x73);
	} else {
		write_nic_byte(dev, EIFS, 81);
		write_nic_byte(dev, CW_VAL, 0xa5);
	}
}
Пример #4
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));
    }

}