Esempio n. 1
0
/*
 *	service()
 *	called periodically by RPC server idle timeout
 */
void panelsim_service(void)
{
#define MSECS(tv) ((uint64_t)((tv).tv_sec)*1000 + (tv).tv_usec / 1000 )
	struct timeval current_time_tv;
	int curchr;

	// scan for key press, first char into buffer
	// !!! Works not in Eclipse condole !!!
//	set_conio_terminal_mode();
	curchr = os_kbhit();
	if (curchr) {
//		user_input_in_progress = 1;
		//curchr = getch();
		//if (curchr < 0)
		//{
		//	fprintf(stderr, "Error %d on input!\n", curchr);
		//}
		//else
		//{
		// if CR or buffer full: process input
		if (curchr == '\n' || user_input_chars + 1 >= sizeof(user_input_buffer)) {
			printf("Processing \"%s\"\n", user_input_buffer);
			user_input_buffer[user_input_chars] = '\0';
			panelsim_userinput(user_input_buffer);
			update_needed = 1; // panel state changed
			user_input_buffer[0] = '\0'; // empty buffer
			user_input_chars = 0;
		} else {
			// just save & echo input character
			user_input_buffer[user_input_chars++] = curchr;
			user_input_buffer[user_input_chars] = '\0'; // terminate
		}
		//}
	}
//	reset_terminal_mode();

	gettimeofday(&current_time_tv, NULL);

	// do not update more often then every MIN_UPDATE_INTERVALL_US usecs
	if ((MSECS(update_last_time_tv) + MIN_UPDATE_INTERVALL_MS < MSECS(current_time_tv))
			&& update_needed /*&& !user_input_in_progress*/) {
		update_last_time_tv = current_time_tv;
		update_needed = 0;
		panelsim_show();
		printf(" q)  quit\n");
		printf("\nSet input by entering \"<nr> <value>\"\n");
		// re-print current user input
		printf(">>> %s", user_input_buffer);
	}
}
Esempio n. 2
0
void rtl_ips_nic_off(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	queue_delayed_work(rtlpriv->works.rtl_wq,
			   &rtlpriv->works.ips_nic_off_wq, MSECS(100));
}
Esempio n. 3
0
void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	u8 sleep_intv;

	if (!rtlpriv->psc.sw_ps_enabled)
		return;

	if ((rtlpriv->sec.being_setkey) ||
	    (mac->opmode == NL80211_IFTYPE_ADHOC))
		return;

	/*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
	if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
		return;

	if (rtlpriv->link_info.busytraffic)
		return;

	mutex_lock(&rtlpriv->locks.ps_mutex);
	rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
	mutex_unlock(&rtlpriv->locks.ps_mutex);

	if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
		!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
		rtlpriv->intf_ops->enable_aspm(hw);
		RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
	}

	/* here is power save alg, when this beacon is DTIM
	 * we will set sleep time to dtim_period * n;
	 * when this beacon is not DTIM, we will set sleep
	 * time to sleep_intv = rtlpriv->psc.dtim_counter or
	 * MAX_SW_LPS_SLEEP_INTV(default set to 5) */

	if (rtlpriv->psc.dtim_counter == 0) {
		if (hw->conf.ps_dtim_period == 1)
			sleep_intv = hw->conf.ps_dtim_period * 2;
		else
			sleep_intv = hw->conf.ps_dtim_period;
	} else {
		sleep_intv = rtlpriv->psc.dtim_counter;
	}

	if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
		sleep_intv = MAX_SW_LPS_SLEEP_INTV;

	/* this print should always be dtim_conter = 0 &
	 * sleep  = dtim_period, that meaons, we should
	 * awake before every dtim */
	RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
		 "dtim_counter:%x will sleep :%d beacon_intv\n",
		 rtlpriv->psc.dtim_counter, sleep_intv);

	/* we tested that 40ms is enough for sw & hw sw delay */
	queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
			MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
}
Esempio n. 4
0
static void ActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA,
			    u16 Time)
{
	pBA->bValid = true;
	if (Time != 0)
		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
}
Esempio n. 5
0
static bool CPUcheck_firmware_ready(struct net_device *dev)
{

	bool	rt_status = true;
	u32	CPU_status = 0;
	unsigned long timeout;

	timeout = jiffies + MSECS(20);
	while (time_before(jiffies, timeout)) {
		CPU_status = read_nic_dword(dev, CPU_GEN);
		if (CPU_status&CPU_GEN_FIRM_RDY)
			break;
		mdelay(2);
	}

	if (!(CPU_status&CPU_GEN_FIRM_RDY))
		goto CPUCheckFirmwareReady_Fail;
	else
		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");

	return rt_status;

CPUCheckFirmwareReady_Fail:
	RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
	rt_status = false;
	return rt_status;

}
Esempio n. 6
0
static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
{
	bool		rt_status = true;
	u32		CPU_status = 0;
	unsigned long   timeout;

	timeout = jiffies + MSECS(200);
	while (time_before(jiffies, timeout)) {
		CPU_status = read_nic_dword(dev, CPU_GEN);
		if (CPU_status & CPU_GEN_PUT_CODE_OK)
			break;
		mdelay(2);
	}

	if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
		RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
	} else {
		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
	}

	CPU_status = read_nic_dword(dev, CPU_GEN);
	write_nic_byte(dev, CPU_GEN,
		       (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
	mdelay(1);

	timeout = jiffies + MSECS(200);
	while (time_before(jiffies, timeout)) {
		CPU_status = read_nic_dword(dev, CPU_GEN);
		if (CPU_status&CPU_GEN_BOOT_RDY)
			break;
		mdelay(2);
	}

	if (!(CPU_status&CPU_GEN_BOOT_RDY))
		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
	else
		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");

	return rt_status;

CPUCheckMainCodeOKAndTurnOnCPU_Fail:
	RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
	rt_status = false;
	return rt_status;
}
Esempio n. 7
0
void AdmitTS(struct rtllib_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
{
	del_timer_sync(&pTsCommonInfo->SetupTimer);
	del_timer_sync(&pTsCommonInfo->InactTimer);

	if(InactTime!=0)
		mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
}
Esempio n. 8
0
void SwLedControlMode4(struct net_device *dev, LED_CTL_MODE LedAction)
{
	struct r8192_priv *priv = rtllib_priv(dev);
	PLED_8190 pLed0 = &(priv->SwLed0);
	PLED_8190 pLed1 = &(priv->SwLed1);
	
	switch(LedAction)
	{
	case LED_CTL_POWER_ON:
		pLed1->CurrLedState = LED_ON;
		SwLedOn(dev, pLed1);
		pLed0->CurrLedState = LED_OFF;
		SwLedOff(dev, pLed0);
		break;
		
	case LED_CTL_TX:
	case LED_CTL_RX:
		if( pLed0->bLedBlinkInProgress == false )
		{
			pLed0->bLedBlinkInProgress = true;

			pLed0->CurrLedState = LED_BLINK_RUNTOP;
			pLed0->BlinkTimes = 2;
		
			if( pLed0->bLedOn )
				pLed0->BlinkingLedState = LED_OFF; 
			else
				pLed0->BlinkingLedState = LED_ON; 
			
			mod_timer(&(pLed0->BlinkTimer), jiffies + MSECS(LED_RunTop_BLINK_INTERVAL));
		}
		break;

	case LED_CTL_POWER_OFF:
		pLed0->CurrLedState = LED_OFF;
		pLed1->CurrLedState = LED_OFF;
		if(pLed0->bLedBlinkInProgress)
		{
			del_timer_sync(&(pLed0->BlinkTimer));
			pLed0->bLedBlinkInProgress = false;
		}
		if(pLed1->bLedBlinkInProgress)
		{
			del_timer_sync(&(pLed1->BlinkTimer));
			pLed1->bLedBlinkInProgress = false;
		}
		SwLedOff(dev, pLed0);
		SwLedOff(dev, pLed1);
		break;

	default:
		break;
	}
	
	RT_TRACE(COMP_LED, "Led0 %d, Led1 %d \n", pLed0->CurrLedState, pLed1->CurrLedState);
}
Esempio n. 9
0
void rtl_watch_dog_timer_callback(unsigned long data)
{
	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	queue_delayed_work(rtlpriv->works.rtl_wq,
			   &rtlpriv->works.watchdog_wq, 0);

	mod_timer(&rtlpriv->works.watchdog_timer,
		  jiffies + MSECS(RTL_WATCH_DOG_TIME));
}
Esempio n. 10
0
void rtl_ips_nic_off(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	/* because when link with ap, mac80211 will ask us
	 * to disable nic quickly after scan before linking,
	 * this will cause link failed, so we delay 100ms here
	 */
	queue_delayed_work(rtlpriv->works.rtl_wq,
			   &rtlpriv->works.ips_nic_off_wq, MSECS(100));
}
Esempio n. 11
0
void rtl8192_hw_wakeup(struct net_device* dev)
{
	struct r8192_priv *priv = rtllib_priv(dev);
	unsigned long flags = 0;
	u8 queue_index = 0;
	unsigned long queue_len = 0;
	struct sk_buff* skb = NULL;
#ifdef CONFIG_ASPM_OR_D3
	PRT_POWER_SAVE_CONTROL	pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->rtllib->PowerSaveControl));
#endif	
	spin_lock_irqsave(&priv->rf_ps_lock,flags);
	if (priv->RFChangeInProgress) {
		spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
		RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
		printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
		queue_delayed_work_rsl(priv->rtllib->wq,&priv->rtllib->hw_wakeup_wq,MSECS(10));
		return;
	}
	spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
#ifdef CONFIG_ASPM_OR_D3
	if (pPSC->RegRfPsLevel & RT_RF_LPS_LEVEL_ASPM) {
		RT_DISABLE_ASPM(dev);
		RT_CLEAR_PS_LEVEL(pPSC, RT_RF_LPS_LEVEL_ASPM);
	}
#endif
	RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__);
	MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS,false);
	for (queue_index=0; queue_index<=VO_QUEUE; queue_index++){
		
		queue_len = skb_queue_len(&priv->rtllib->skb_waitQ[queue_index]);
		
		if (queue_len) {
			printk("=====>%s(): no need to ps,wake up!! %d queue is not empty\n",
				__FUNCTION__,queue_index);
			skb = skb_dequeue(&priv->rtllib->skb_waitQ[queue_index]);
			if (skb == NULL) {
				RT_TRACE(COMP_ERR,"rtl8192_hw_wakeup():skb is NULL\n");
				return;
			}
			if ((priv->rtllib->b4ac_Uapsd & 0x0f) !=0) {
				if ( IsMgntQosData(skb->data) || IsMgntQosNull(skb->data) ) { 
					if(!priv->rtllib->bin_service_period && get_qos_queueID_maskAPSD(queue_index, priv->rtllib->b4ac_Uapsd))
					{
						RT_TRACE(COMP_PS, "rtl8192_hw_wakeup(): >>>>>>>>>> Enter APSD service period >>>>>>>>>>\n");
						printk("rtl8192_hw_wakeup(): >>>>>>>>>> Enter APSD service period >>>>>>>>>>\n");
						priv->rtllib->bin_service_period = true;
					}
				}
			}
			priv->rtllib->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
		}
	}
}
Esempio n. 12
0
void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	u8 sleep_intv;

	if (!rtlpriv->psc.sw_ps_enabled)
		return;

	if ((rtlpriv->sec.being_setkey) ||
	    (mac->opmode == NL80211_IFTYPE_ADHOC))
		return;

	
	if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
		return;

	if (rtlpriv->link_info.busytraffic)
		return;

	mutex_lock(&rtlpriv->locks.ps_mutex);
	rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
	mutex_unlock(&rtlpriv->locks.ps_mutex);

	if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
		!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
		rtlpriv->intf_ops->enable_aspm(hw);
		RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
	}


	if (rtlpriv->psc.dtim_counter == 0) {
		if (hw->conf.ps_dtim_period == 1)
			sleep_intv = hw->conf.ps_dtim_period * 2;
		else
			sleep_intv = hw->conf.ps_dtim_period;
	} else {
		sleep_intv = rtlpriv->psc.dtim_counter;
	}

	if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
		sleep_intv = MAX_SW_LPS_SLEEP_INTV;

	RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
		 "dtim_counter:%x will sleep :%d beacon_intv\n",
		 rtlpriv->psc.dtim_counter, sleep_intv);

	
	queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
			MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
}
void timer_rate_adaptive(unsigned long data)
{
	struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
	if (!priv->up) {
		return;
	}
	if ((priv->ieee80211->iw_mode != IW_MODE_MASTER)
			&& (priv->ieee80211->state == IEEE80211_LINKED) &&
			(priv->ForcedDataRate == 0)) {
		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
	}
	priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
	add_timer(&priv->rateadapter_timer);
}
Esempio n. 14
0
void timer_rate_adaptive(unsigned long data)
{
	struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
	//DMESG("---->timer_rate_adaptive()\n");
	if(!priv->up)
	{
//		DMESG("<----timer_rate_adaptive():driver is not up!\n");
		return;
	}
	if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
			&& (priv->ieee80211->state == IEEE80211_LINKED) &&
			(priv->ForcedDataRate == 0) )
	{
//	DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
//		StaRateAdaptive87SE((struct net_device *)data);
	}
	priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
	add_timer(&priv->rateadapter_timer);
	//DMESG("<----timer_rate_adaptive()\n");
}
Esempio n. 15
0
//
//	Description:
//		Timer callback function of SW Antenna Diversity.
//
void
SwAntennaDiversityTimerCallback(
	struct net_device *dev
	)
{
	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
	RT_RF_POWER_STATE rtState;

	//printk("+SwAntennaDiversityTimerCallback()\n");

	//
	// We do NOT need to switch antenna while RF is off.
	// 2007.05.09, added by Roger.
	//
	rtState = priv->eRFPowerState;
	do{
		if (rtState == eRfOff)
		{
//			printk("SwAntennaDiversityTimer - RF is OFF.\n");
			break;
		}
		else if (rtState == eRfSleep)
		{
			// Don't access BB/RF under Disable PLL situation.
			//RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
			break;
		}
		SwAntennaDiversity(dev);

	}while(false);

	if(priv->up)
	{
		priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
		add_timer(&priv->SwAntennaDiversityTimer);
	}

	//printk("-SwAntennaDiversityTimerCallback()\n");
}
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;
		}
		SwAntennaDiversity(dev);

	} while (false);

	if (priv->up) {
		priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
		add_timer(&priv->SwAntennaDiversityTimer);
	}
}
Esempio n. 17
0
/*	Timer callback function of SW Antenna Diversity. */
void SwAntennaDiversityTimerCallback(struct net_device *dev)
{
    struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
    RT_RF_POWER_STATE rtState;

    /* We do NOT need to switch antenna while RF is off. */
    rtState = priv->eRFPowerState;
    do {
        if (rtState == eRfOff) {
            break;
        } else if (rtState == eRfSleep) {
            /* Don't access BB/RF under Disable PLL situation. */
            break;
        }
        SwAntennaDiversity(dev);

    } while (false);

    if (priv->up) {
        priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
        add_timer(&priv->SwAntennaDiversityTimer);
    }
}
void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
{
	pBA->bValid = true;
	if(Time != 0)
		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
}
Esempio n. 19
0
void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct ieee80211_hdr *hdr = (void *) data;
	struct ieee80211_tim_ie *tim_ie;
	u8 *tim;
	u8 tim_len;
	bool u_buffed;
	bool m_buffed;

	if (mac->opmode != NL80211_IFTYPE_STATION)
		return;

	if (!rtlpriv->psc.swctrl_lps)
		return;

	if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
		return;

	if (!rtlpriv->psc.sw_ps_enabled)
		return;

	if (rtlpriv->psc.fwctrl_lps)
		return;

	if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
		return;

	
	if (!ieee80211_is_beacon(hdr->frame_control))
		return;

	
	if (len <= 40 + FCS_LEN)
		return;

	
	if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
		return;

	rtlpriv->psc.last_beacon = jiffies;

	tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
	if (!tim)
		return;

	if (tim[1] < sizeof(*tim_ie))
		return;

	tim_len = tim[1];
	tim_ie = (struct ieee80211_tim_ie *) &tim[2];

	if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
		rtlpriv->psc.dtim_counter = tim_ie->dtim_count;

	

	
	u_buffed = ieee80211_check_tim(tim_ie, tim_len,
				       rtlpriv->mac80211.assoc_id);

	
	m_buffed = tim_ie->bitmap_ctrl & 0x01;
	rtlpriv->psc.multi_buffered = m_buffed;

	if (!m_buffed) {
		queue_delayed_work(rtlpriv->works.rtl_wq,
				&rtlpriv->works.ps_work, MSECS(5));
	} else {
		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
			 "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
	}
}
Esempio n. 20
0
void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
{
#ifdef _RTL8192_EXT_PATCH_
	struct r8192_priv *priv = rtllib_priv(dev);
	u32 rb = jiffies, sleep_cost = MSECS(8+16+7), delta = 0;
	unsigned long flags;

	if((tl > rb) && (th > 0))
		return;

	spin_lock_irqsave(&priv->ps_lock,flags);

	if (tl >= sleep_cost)
		tl -= sleep_cost;
	else if (th > 0) {
		tl = 0xffffffff - sleep_cost + tl;  
		th--;
	} else {
		spin_unlock_irqrestore(&priv->ps_lock,flags);
		return;
	}

	if (tl > rb) {
		delta = tl - rb;
	} else if (th > 0) {
		delta = 0xffffffff - rb + tl;
		th --;
	} else {
		spin_unlock_irqrestore(&priv->ps_lock,flags);
		return;
	}

	if (delta <= MSECS(MIN_SLEEP_TIME)) {
		spin_unlock_irqrestore(&priv->ps_lock,flags);
		printk("too short to sleep::%x, %x, %lx\n",tl, rb,  MSECS(MIN_SLEEP_TIME));
		return;
	}	

	if(delta > MSECS(MAX_SLEEP_TIME)) {
		spin_unlock_irqrestore(&priv->ps_lock,flags);
		printk("========>too long to sleep:%x, %x, %lx\n", tl, rb,  MSECS(MAX_SLEEP_TIME));
		return;
	}

	RT_TRACE(COMP_LPS, "==============>%s(): wake up time is %d,%d\n",__FUNCTION__,delta,jiffies_to_msecs(delta));
	queue_delayed_work_rsl(priv->rtllib->wq,&priv->rtllib->hw_wakeup_wq,delta); 
	queue_delayed_work_rsl(priv->rtllib->wq, (void *)&priv->rtllib->hw_sleep_wq,0);

	spin_unlock_irqrestore(&priv->ps_lock,flags);
#else
	struct r8192_priv *priv = rtllib_priv(dev);

	u32 rb = jiffies;
	unsigned long flags;

	spin_lock_irqsave(&priv->ps_lock,flags);

	tl -= MSECS(8+16+7);

	if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
			||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
		spin_unlock_irqrestore(&priv->ps_lock,flags);
		printk("too short to sleep::%x, %x, %lx\n",tl, rb,  MSECS(MIN_SLEEP_TIME));
		return;
	}	

	if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
			((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
			((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
		printk("========>too long to sleep:%x, %x, %lx\n", tl, rb,  MSECS(MAX_SLEEP_TIME));
		spin_unlock_irqrestore(&priv->ps_lock,flags);
		return;
	}
	{
		u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
		queue_delayed_work_rsl(priv->rtllib->wq,
				&priv->rtllib->hw_wakeup_wq,tmp); 
	}
	queue_delayed_work_rsl(priv->rtllib->wq, 
			(void *)&priv->rtllib->hw_sleep_wq,0);
	spin_unlock_irqrestore(&priv->ps_lock,flags);
#endif
}
Esempio n. 21
0
/* For sw LPS*/
void rtl92e_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct ieee80211_hdr *hdr = (void *)data;
	struct ieee80211_tim_ie *tim_ie;
	u8 *tim;
	u8 tim_len;
	bool u_buffed;
	bool m_buffed;

	if (mac->opmode != NL80211_IFTYPE_STATION)
		return;

	if (!rtlpriv->psc.b_swctrl_lps)
		return;

	if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
		return;

	if (!rtlpriv->psc.sw_ps_enabled)
		return;

	if (rtlpriv->psc.b_fwctrl_lps)
		return;

	if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
		return;

	/* check if this really is a beacon */
	if (!ieee80211_is_beacon(hdr->frame_control))
		return;

	/* min. beacon length + FCS_LEN */
	if (len <= 40 + FCS_LEN)
		return;

	/* and only beacons from the associated BSSID, please */
	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
		return;

	rtlpriv->psc.last_beacon = jiffies;

	tim = rtl92e_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
	if (!tim)
		return;

	if (tim[1] < sizeof(*tim_ie))
		return;

	tim_len = tim[1];
	tim_ie = (struct ieee80211_tim_ie *)&tim[2];

	if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
		rtlpriv->psc.dtim_counter = tim_ie->dtim_count;

	/* Check whenever the PHY can be turned off again. */

	/* 1. What about buffered unicast traffic for our AID? */
	u_buffed = ieee80211_check_tim(tim_ie, tim_len,
				       rtlpriv->mac80211.assoc_id);

	/* 2. Maybe the AP wants to send multicast/broadcast data? */
	m_buffed = tim_ie->bitmap_ctrl & 0x01;
	rtlpriv->psc.multi_buffered = m_buffed;

	/* unicast will process by mac80211 through
	 * set ~IEEE80211_CONF_PS, So we just check
	 * multicast frames here */
	if (!m_buffed) {/*&&) { !rtlpriv->psc.tx_doing) { */
		/* back to low-power land. and delay is
		 * prevent null power save frame tx fail */
		queue_delayed_work(rtlpriv->works.rtl_wq,
				   &rtlpriv->works.ps_work, MSECS(5));
	} else {
		RT_TRACE(COMP_POWER, DBG_DMESG,
			 ("u_bufferd: %x, m_buffered: %x\n",
			  u_buffed, m_buffed));
	}
}
Esempio n. 22
0
static int rtl_op_add_interface(struct ieee80211_hw *hw,
		struct ieee80211_vif *vif)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	int err = 0;

	if (mac->vif) {
		RT_TRACE(COMP_ERR, DBG_WARNING,
			 ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
		return -EOPNOTSUPP;
	}

/*This flag is not defined before kernel 3.4*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
#endif

	rtl_ips_nic_on(hw);

	mutex_lock(&rtlpriv->locks.conf_mutex);
/*<delete in kernel start>*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
	switch (ieee80211_vif_type_p2p(vif)) {	
	case NL80211_IFTYPE_P2P_CLIENT:
		mac->p2p = P2P_ROLE_CLIENT;
		/*fall through*/
#else
/*<delete in kernel end>*/
	switch (vif->type) {
/*<delete in kernel start>*/	
#endif
/*<delete in kernel end>*/
	case NL80211_IFTYPE_STATION:
		if (mac->beacon_enabled == 1) {
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("NL80211_IFTYPE_STATION \n"));
			mac->beacon_enabled = 0;
			rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
					rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
		}
		break;
	case NL80211_IFTYPE_ADHOC:
		RT_TRACE(COMP_MAC80211, DBG_LOUD,
			 ("NL80211_IFTYPE_ADHOC \n"));

		mac->link_state = MAC80211_LINKED;
		rtlpriv->cfg->ops->set_bcn_reg(hw);
		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
			mac->basic_rates = 0xfff;
		else
			mac->basic_rates = 0xff0;
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
				(u8 *) (&mac->basic_rates));

		break;
/*<delete in kernel start>*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
	case NL80211_IFTYPE_P2P_GO:
		mac->p2p = P2P_ROLE_GO;
		/*fall through*/
#endif
/*<delete in kernel end>*/
	case NL80211_IFTYPE_AP:
		RT_TRACE(COMP_MAC80211, DBG_LOUD,
			 ("NL80211_IFTYPE_AP \n"));

		mac->link_state = MAC80211_LINKED;
		rtlpriv->cfg->ops->set_bcn_reg(hw);
		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
			mac->basic_rates = 0xfff;
		else
			mac->basic_rates = 0xff0;
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
					      (u8 *) (&mac->basic_rates));
		break;
	case NL80211_IFTYPE_MESH_POINT:
		RT_TRACE(COMP_MAC80211, DBG_LOUD,
			 ("NL80211_IFTYPE_MESH_POINT \n"));
	
		mac->link_state = MAC80211_LINKED;
		rtlpriv->cfg->ops->set_bcn_reg(hw);
		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
			mac->basic_rates = 0xfff;
		else
			mac->basic_rates = 0xff0;
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
				(u8 *) (&mac->basic_rates));
		break;
	default:
		RT_TRACE(COMP_ERR, DBG_EMERG,
			 ("operation mode %d is not support!\n", vif->type));
		err = -EOPNOTSUPP;
		goto out;
	}

#ifdef VIF_TODO
	if (!rtl_set_vif_info(hw, vif))
		goto out;
#endif

	if (mac->p2p) {
		RT_TRACE(COMP_MAC80211, DBG_LOUD,
			 ("p2p role %x \n",vif->type));		
		mac->basic_rates = 0xff0;/*disable cck rate for p2p*/
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
				(u8 *) (&mac->basic_rates));		
	}
	mac->vif = vif;
	mac->opmode = vif->type;
	rtlpriv->cfg->ops->set_network_type(hw, vif->type);
	memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);

out:
	mutex_unlock(&rtlpriv->locks.conf_mutex);
	return err;
}

static void rtl_op_remove_interface(struct ieee80211_hw *hw,
		struct ieee80211_vif *vif)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));

	mutex_lock(&rtlpriv->locks.conf_mutex);

	/* Free beacon resources */
	if ((vif->type == NL80211_IFTYPE_AP) ||
	    (vif->type == NL80211_IFTYPE_ADHOC) ||
	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
		if (mac->beacon_enabled == 1) {
			mac->beacon_enabled = 0;
			rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
					rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]);
		}
	}

	/*
	 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
	 *NO LINK for our hardware.
	 */
	mac->p2p = 0; 
	mac->vif = NULL;
	mac->link_state = MAC80211_NOLINK;
	memset(mac->bssid, 0, 6);
	mac->vendor = PEER_UNKNOWN;
	mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
	rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);

	mutex_unlock(&rtlpriv->locks.conf_mutex);
}
/*<delete in kernel start>*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
/*<delete in kernel end>*/	
static int rtl_op_change_interface(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   enum nl80211_iftype new_type, bool p2p)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	int ret;
	rtl_op_remove_interface(hw, vif);

	vif->type = new_type;
	vif->p2p = p2p;
	ret = rtl_op_add_interface(hw, vif);
	RT_TRACE(COMP_MAC80211, DBG_LOUD,
		 (" p2p  %x\n",p2p));
	return ret;
}
/*<delete in kernel start>*/
#endif
/*<delete in kernel end>*/	
static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	struct ieee80211_conf *conf = &hw->conf;
	
	if (mac->skip_scan)
		return 1;
	
	mutex_lock(&rtlpriv->locks.conf_mutex);	
	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {	/* BIT(2) */
		RT_TRACE(COMP_MAC80211, DBG_LOUD,
			 ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
	}

	/*For IPS */
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
		if (hw->conf.flags & IEEE80211_CONF_IDLE)
			rtl_ips_nic_off(hw);
		else
			rtl_ips_nic_on(hw);
	} else {
		/*
		 *although rfoff may not cause by ips, but we will
		 *check the reason in set_rf_power_state function
		 */
		if (unlikely(ppsc->rfpwr_state == ERFOFF))
			rtl_ips_nic_on(hw);
	}

	/*For LPS */
	if (changed & IEEE80211_CONF_CHANGE_PS) {
		cancel_delayed_work(&rtlpriv->works.ps_work);
		cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
		if (conf->flags & IEEE80211_CONF_PS) {
			rtlpriv->psc.sw_ps_enabled = true;
			/* sleep here is must, or we may recv the beacon and
			 * cause mac80211 into wrong ps state, this will cause
			 * power save nullfunc send fail, and further cause
			 * pkt loss, So sleep must quickly but not immediatly
			 * because that will cause nullfunc send by mac80211
			 * fail, and cause pkt loss, we have tested that 5mA
			 * is worked very well */
			if (!rtlpriv->psc.multi_buffered)
				queue_delayed_work(rtlpriv->works.rtl_wq,
						   &rtlpriv->works.ps_work, 
						   MSECS(5));
		} else {
			rtl_swlps_rf_awake(hw);
			rtlpriv->psc.sw_ps_enabled = false;
		}
	}

	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
		RT_TRACE(COMP_MAC80211, DBG_LOUD,
			 ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
			  hw->conf.long_frame_max_tx_count));
		mac->retry_long = hw->conf.long_frame_max_tx_count;
		mac->retry_short = hw->conf.long_frame_max_tx_count;
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
				(u8 *) (&hw->conf.long_frame_max_tx_count));
	}

	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
		struct ieee80211_channel *channel = hw->conf.chandef.chan;
		enum nl80211_channel_type channel_type = 
				cfg80211_get_chandef_type(&(hw->conf.chandef)); 
#else
		struct ieee80211_channel *channel = hw->conf.channel;
		enum nl80211_channel_type channel_type = hw->conf.channel_type;
#endif
		u8 wide_chan = (u8) channel->hw_value;

		if (mac->act_scanning)
			mac->n_channels++;

		if (rtlpriv->dm.supp_phymode_switch &&
			mac->link_state < MAC80211_LINKED &&
			!mac->act_scanning) {
			if (rtlpriv->cfg->ops->check_switch_to_dmdp)
				rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
		}

		/*
		 *because we should back channel to
		 *current_network.chan in in scanning,
		 *So if set_chan == current_network.chan
		 *we should set it.
		 *because mac80211 tell us wrong bw40
		 *info for cisco1253 bw20, so we modify
		 *it here based on UPPER & LOWER
		 */
		switch (channel_type) {
			case NL80211_CHAN_HT20:
			case NL80211_CHAN_NO_HT:
				/* SC */
				mac->cur_40_prime_sc =
					PRIME_CHNL_OFFSET_DONT_CARE;
				rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
				mac->bw_40 = false;
				break;
			case NL80211_CHAN_HT40MINUS:
				/* SC */
				mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
				rtlphy->current_chan_bw =
					HT_CHANNEL_WIDTH_20_40;
				mac->bw_40 = true;

				/*wide channel */
				wide_chan -= 2;

				break;
			case NL80211_CHAN_HT40PLUS:
				/* SC */
				mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
				rtlphy->current_chan_bw =
					HT_CHANNEL_WIDTH_20_40;
				mac->bw_40 = true;

				/*wide channel */
				wide_chan += 2;

				break;
			default:
				mac->bw_40 = false;
				RT_TRACE(COMP_ERR, DBG_EMERG,
					 ("switch case not processed \n"));
				break;
		}

		if (wide_chan <= 0)
			wide_chan = 1;

		/* in scanning, when before we offchannel we may send a ps=1
		 * null to AP, and then we may send a ps = 0 null to AP quickly,
		 * but first null have cause AP's put lots of packet to hw tx
		 * buffer, these packet must be tx before off channel so we must
		 * delay more time to let AP flush these packets before
		 * offchannel, or dis-association or delete BA will happen by AP
		 */
		if (rtlpriv->mac80211.offchan_deley) {
			rtlpriv->mac80211.offchan_deley = false;
			mdelay(50);
		}

		rtlphy->current_channel = wide_chan;

		rtlpriv->cfg->ops->switch_channel(hw);
		rtlpriv->cfg->ops->set_channel_access(hw);
		rtlpriv->cfg->ops->set_bw_mode(hw,
			channel_type);
	}

	mutex_unlock(&rtlpriv->locks.conf_mutex);

	return 0;
}

static void rtl_op_configure_filter(struct ieee80211_hw *hw,
				    unsigned int changed_flags,
				    unsigned int *new_flags, u64 multicast)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));

	*new_flags &= RTL_SUPPORTED_FILTERS;
	if (0 == changed_flags)
		return;

	/*TODO: we disable broadcase now, so enable here */
	if (changed_flags & FIF_ALLMULTI) {
		if (*new_flags & FIF_ALLMULTI) {
			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
			    rtlpriv->cfg->maps[MAC_RCR_AB];
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Enable receive multicast frame.\n"));
		} else {
			mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
					  rtlpriv->cfg->maps[MAC_RCR_AB]);
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Disable receive multicast frame.\n"));
		}
	}

	if (changed_flags & FIF_FCSFAIL) {
		if (*new_flags & FIF_FCSFAIL) {
			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Enable receive FCS error frame.\n"));
		} else {
			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Disable receive FCS error frame.\n"));
		}
	}

	/* if ssid not set to hw don't check bssid
	 * here just used for linked scanning, & linked
	 * and nolink check bssid is set in set network_type */
	if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
		(mac->link_state >= MAC80211_LINKED)) {
		if (mac->opmode != NL80211_IFTYPE_AP &&
			mac->opmode != NL80211_IFTYPE_MESH_POINT) {
			if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
				rtlpriv->cfg->ops->set_chk_bssid(hw, false);
			} else {
				rtlpriv->cfg->ops->set_chk_bssid(hw, true);
			}
		}
	}

	if (changed_flags & FIF_CONTROL) {
		if (*new_flags & FIF_CONTROL) {
			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];

			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Enable receive control frame.\n"));
		} else {
			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Disable receive control frame.\n"));
		}
	}

	if (changed_flags & FIF_OTHER_BSS) {
		if (*new_flags & FIF_OTHER_BSS) {
			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Enable receive other BSS's frame.\n"));
		} else {
			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
			RT_TRACE(COMP_MAC80211, DBG_LOUD,
				 ("Disable receive other BSS's frame.\n"));
		}
	}
}
static int rtl_op_sta_add(struct ieee80211_hw *hw,
			 struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal= rtl_hal(rtl_priv(hw));
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));	
	struct rtl_sta_info *sta_entry;

	if (sta) {
		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
		spin_lock_bh(&rtlpriv->locks.entry_list_lock);		
		list_add_tail(&sta_entry->list, &rtlpriv->entry_list);
		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
			sta_entry->wireless_mode = WIRELESS_MODE_G;
			if (sta->supp_rates[0] <= 0xf)
				sta_entry->wireless_mode = WIRELESS_MODE_B;
			if (sta->ht_cap.ht_supported == true)
				sta_entry->wireless_mode = WIRELESS_MODE_N_24G;

			if (vif->type == NL80211_IFTYPE_ADHOC)
				sta_entry->wireless_mode = WIRELESS_MODE_G;
		} else if (rtlhal->current_bandtype == BAND_ON_5G) {
			sta_entry->wireless_mode = WIRELESS_MODE_A;
			if (sta->ht_cap.ht_supported == true)
				sta_entry->wireless_mode = WIRELESS_MODE_N_24G;

			if (vif->type == NL80211_IFTYPE_ADHOC)
				sta_entry->wireless_mode = WIRELESS_MODE_A;
		}
		/*disable cck rate for p2p*/
		if (mac->p2p)
			sta->supp_rates[0] &= 0xfffffff0;
		
		memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
		RT_TRACE(COMP_MAC80211, DBG_DMESG,
			("Add sta addr is %pM\n",sta->addr));
		rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
	}

	return 0;
}

static int rtl_op_sta_remove(struct ieee80211_hw *hw,
				struct ieee80211_vif *vif,
				struct ieee80211_sta *sta)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_sta_info *sta_entry;
	if (sta) {
		RT_TRACE(COMP_MAC80211, DBG_DMESG,
			("Remove sta addr is %pM\n",sta->addr));
		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
		sta_entry->wireless_mode = 0;
		sta_entry->ratr_index = 0;
		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
		list_del(&sta_entry->list);
		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
	}
	return 0;
}
static int _rtl_get_hal_qnum(u16 queue)
{
	int qnum;

	switch (queue) {
	case 0:
		qnum = AC3_VO;
		break;
	case 1:
		qnum = AC2_VI;
		break;
	case 2:
		qnum = AC0_BE;
		break;
	case 3:
		qnum = AC1_BK;
		break;
	default:
		qnum = AC0_BE;
		break;
	}
	return qnum;
}
Esempio n. 23
0
void SwLedBlink(PLED_8190 pLed)
{
	struct net_device *dev = (struct net_device *)pLed->dev;
	struct r8192_priv *priv = rtllib_priv(dev);
	bool bStopBlinking = false;
	
	if( pLed->BlinkingLedState == LED_ON ) 
	{
		SwLedOn(dev, pLed);
		RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
	}	
	else 
	{
		SwLedOff(dev, pLed);
		RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
	}

	pLed->BlinkTimes--;
	switch(pLed->CurrLedState)
	{
	case LED_BLINK_NORMAL: 
	case LED_BLINK_TXRX:
	case LED_BLINK_RUNTOP:
		if(pLed->BlinkTimes == 0)
		{
			bStopBlinking = true;
		}
		break;

	case LED_SCAN_BLINK:
		if( (priv->rtllib->state == RTLLIB_LINKED) &&  
			(!rtllib_act_scanning(priv->rtllib,true))&& 
			(pLed->BlinkTimes % 2 == 0)) 
		{
			bStopBlinking = true;
		}
		break;

	case LED_NO_LINK_BLINK:
	case LED_BLINK_StartToBlink:	
		if( (priv->rtllib->state == RTLLIB_LINKED) && (priv->rtllib->iw_mode == IW_MODE_INFRA)) 
		{
			bStopBlinking = true;
		}
		else if((priv->rtllib->state == RTLLIB_LINKED) && (priv->rtllib->iw_mode == IW_MODE_ADHOC))
		{
			bStopBlinking = true;
		}
		else if(pLed->BlinkTimes == 0)
		{
			bStopBlinking = true;
		}
		break;
		
	case LED_BLINK_CAMEO:
		if((priv->rtllib->state == RTLLIB_LINKED) && (priv->rtllib->iw_mode == IW_MODE_INFRA)) 
		{
			bStopBlinking = true;
		}
		else if((priv->rtllib->state == RTLLIB_LINKED) && (priv->rtllib->iw_mode == IW_MODE_ADHOC) )
		{
			bStopBlinking = true;
		}
		break;
		
	default:
		bStopBlinking = true;
		break;
	}

	if(bStopBlinking)
	{
		if( priv->rtllib->eRFPowerState != eRfOn )
		{
			SwLedOff(dev, pLed);
		}
		else if(pLed->CurrLedState == LED_BLINK_TXRX)
		{
			SwLedOff(dev, pLed);
		}
		else if(pLed->CurrLedState == LED_BLINK_RUNTOP)
		{
			SwLedOff(dev, pLed);
		}
		else if( (priv->rtllib->state == RTLLIB_LINKED) && (pLed->bLedOn == false))
		{
			SwLedOn(dev, pLed);
		}
		else if( (priv->rtllib->state != RTLLIB_LINKED) &&  pLed->bLedOn == true)
		{
			SwLedOff(dev, pLed);
		}

		pLed->BlinkTimes = 0;
		pLed->bLedBlinkInProgress = false;	
	}
	else
	{
		if( pLed->BlinkingLedState == LED_ON ) 
			pLed->BlinkingLedState = LED_OFF;
		else 
			pLed->BlinkingLedState = LED_ON;

		switch( pLed->CurrLedState )
		{
		case LED_BLINK_NORMAL:
		case LED_BLINK_TXRX:
		case LED_BLINK_StartToBlink:
			mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
			break;

		case LED_BLINK_SLOWLY:
			mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
			break;

		case LED_SCAN_BLINK:
		case LED_NO_LINK_BLINK:
			if( pLed->bLedOn )
				mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
			else
				mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
			break;
			
		case LED_BLINK_RUNTOP:
			mod_timer(&(pLed->BlinkTimer),jiffies + MSECS(LED_RunTop_BLINK_INTERVAL));
			break;
			
		case LED_BLINK_CAMEO:
			mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL_PORNET));
			break;
			
		default:
			RT_TRACE(COMP_ERR, "SwLedCm2Blink(): unexpected state!\n");
			mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL));
			break;
		}		
	}
}
Esempio n. 24
0
void SwLedBlink6(PLED_8190 pLed)
{
	struct net_device *dev = (struct net_device *)pLed->dev;
	struct r8192_priv *priv = rtllib_priv(dev);
	bool bStopBlinking = false;

	if( pLed->BlinkingLedState == LED_ON ) 
	{
		SwLedOn(dev, pLed);
		RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes);
	}	
	else 
	{
		SwLedOff(dev, pLed);
		RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes);
	}
	
	switch(pLed->CurrLedState)
	{
		case LED_OFF:
			SwLedOff(dev, pLed);
			break;

		case LED_BLINK_SLOWLY:
			if( pLed->bLedOn )
				pLed->BlinkingLedState = LED_OFF; 
			else
				pLed->BlinkingLedState = LED_ON; 
			mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL_PORNET));
			break;

		case LED_BLINK_NORMAL:
			pLed->BlinkTimes--;
			if( pLed->BlinkTimes == 0 )
			{
				bStopBlinking = true;
			}
			if(bStopBlinking)
			{
				if( priv->rtllib->eRFPowerState != eRfOn )
				{
					SwLedOff(dev, pLed);
				}
				else 
				{
					pLed->bLedSlowBlinkInProgress = true;
					pLed->CurrLedState = LED_BLINK_SLOWLY;
					if( pLed->bLedOn )
						pLed->BlinkingLedState = LED_OFF; 
					else
						pLed->BlinkingLedState = LED_ON; 
					mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL_PORNET));
				}
				pLed->BlinkTimes = 0;
				pLed->bLedBlinkInProgress = false;	
			}
			else
			{
				if( priv->rtllib->eRFPowerState != eRfOn )
				{
					SwLedOff(dev, pLed);
				}
				else
				{
					if( pLed->bLedOn )
						pLed->BlinkingLedState = LED_OFF; 
					else
						pLed->BlinkingLedState = LED_ON; 

					mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL_PORNET));
				}
			}
			break;
			
		default:
			break;	
		}
	
}
Esempio n. 25
0
void SwLedControlMode1(struct net_device *dev, LED_CTL_MODE LedAction)
{
	struct r8192_priv *priv = rtllib_priv(dev);
	PLED_8190	pLed = &(priv->SwLed1);
	
	switch(LedAction)
	{
	case LED_CTL_TX:
	case LED_CTL_RX:
		if( pLed->bLedBlinkInProgress == false )
		{
			pLed->bLedBlinkInProgress = true;

			pLed->CurrLedState = LED_BLINK_NORMAL;
			pLed->BlinkTimes = 2;

			if( pLed->bLedOn )
				pLed->BlinkingLedState = LED_OFF; 
			else
				pLed->BlinkingLedState = LED_ON; 
			mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL));
		}
		break;

	case LED_CTL_SITE_SURVEY:
		if( pLed->bLedBlinkInProgress == false )
		{
			pLed->bLedBlinkInProgress = true;

			if(priv->rtllib->state == RTLLIB_LINKED)
			{
				pLed->CurrLedState = LED_SCAN_BLINK;
				pLed->BlinkTimes = 4;
			}
			else
			{
				pLed->CurrLedState = LED_NO_LINK_BLINK;
				pLed->BlinkTimes = 24;
			}

			if( pLed->bLedOn )
			{
				pLed->BlinkingLedState = LED_OFF; 
				mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
			}
			else
			{
				pLed->BlinkingLedState = LED_ON; 
				mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
			}
		}
		else
		{
			if(pLed->CurrLedState != LED_NO_LINK_BLINK)
			{
				if(priv->rtllib->state == RTLLIB_LINKED)
				{
					pLed->CurrLedState = LED_SCAN_BLINK;
				}
				else
				{
					pLed->CurrLedState = LED_NO_LINK_BLINK;
				}
			}
		}
		break;

	case LED_CTL_NO_LINK:
		if( pLed->bLedBlinkInProgress == false )
		{
			pLed->bLedBlinkInProgress = true;

			pLed->CurrLedState = LED_NO_LINK_BLINK;
			pLed->BlinkTimes = 24;

			if( pLed->bLedOn )
			{
				pLed->BlinkingLedState = LED_OFF; 
				mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_CM2_BLINK_ON_INTERVAL));
			}
			else
			{
				pLed->BlinkingLedState = LED_ON; 
				mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_CM2_BLINK_OFF_INTERVAL));
			}
		}
		else
		{
			pLed->CurrLedState = LED_NO_LINK_BLINK;
		}
		break;

	case LED_CTL_LINK:
		pLed->CurrLedState = LED_ON;
		if( pLed->bLedBlinkInProgress == false )
		{
			SwLedOn(dev, pLed);
		}
		break;

	case LED_CTL_POWER_OFF:
		pLed->CurrLedState = LED_OFF;
		if(pLed->bLedBlinkInProgress)
		{
			del_timer_sync(&(pLed->BlinkTimer));
			pLed->bLedBlinkInProgress = false;
		}
		SwLedOff(dev, pLed);
		break;

	default:
		break;
	}
	
	RT_TRACE(COMP_LED, "Led %d \n", pLed->CurrLedState);
}
Esempio n. 26
0
void SwLedControlMode6(struct net_device *dev, LED_CTL_MODE LedAction)
{
	struct r8192_priv *priv = rtllib_priv(dev);
	PLED_8190 pLed0 = &(priv->SwLed0);
	PLED_8190 pLed1 = &(priv->SwLed1);
	

	switch(LedAction)
	{
	case LED_CTL_POWER_ON:
	case LED_CTL_START_TO_LINK:
	case LED_CTL_NO_LINK:
	case LED_CTL_LINK:
	case LED_CTL_SITE_SURVEY:
		pLed1->CurrLedState = LED_OFF;
		SwLedOff(dev, pLed1);
		
		if( pLed0->bLedSlowBlinkInProgress == false )
		{
			pLed0->bLedSlowBlinkInProgress = true;
			pLed0->CurrLedState = LED_BLINK_SLOWLY;
			if( pLed0->bLedOn )
				pLed0->BlinkingLedState = LED_OFF; 
			else
				pLed0->BlinkingLedState = LED_ON; 
			mod_timer(&(pLed0->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL_PORNET));
		}
		break;

	case LED_CTL_TX:
	case LED_CTL_RX:
		pLed1->CurrLedState = LED_OFF;
		SwLedOff(dev, pLed1);
		if( pLed0->bLedBlinkInProgress == false )
		{
			del_timer_sync(&(pLed0->BlinkTimer));
			pLed0->bLedSlowBlinkInProgress = false;
			pLed0->bLedBlinkInProgress = true;
			pLed0->CurrLedState = LED_BLINK_NORMAL;
			pLed0->BlinkTimes = 2;
			if( pLed0->bLedOn )
				pLed0->BlinkingLedState = LED_OFF; 
			else
				pLed0->BlinkingLedState = LED_ON; 
			mod_timer(&(pLed0->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL_PORNET));
		}		
		break;

	case LED_CTL_POWER_OFF:
		pLed1->CurrLedState = LED_OFF;
		SwLedOff(dev, pLed1);
		
		pLed0->CurrLedState = LED_OFF;
		if( pLed0->bLedSlowBlinkInProgress == true )
		{
			del_timer_sync(&(pLed0->BlinkTimer));
			pLed0->bLedSlowBlinkInProgress = false;
		}
		if(pLed0->bLedBlinkInProgress == true)
		{
			del_timer_sync(&(pLed0->BlinkTimer));
			pLed0->bLedBlinkInProgress = false;
		}
		SwLedOff(dev, pLed0);
		break;

	default:
		break;
		
		}
}
static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	struct ieee80211_conf *conf = &hw->conf;

	mutex_lock(&rtlpriv->locks.conf_mutex);
	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {	/*BIT(2)*/
		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
			 ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
	}

	/*For IPS */
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
		if (hw->conf.flags & IEEE80211_CONF_IDLE)
			rtl_ips_nic_off(hw);
		else
			rtl_ips_nic_on(hw);
	} else {
		/*
		 *although rfoff may not cause by ips, but we will
		 *check the reason in set_rf_power_state function
		 */
		if (unlikely(ppsc->rfpwr_state == ERFOFF))
			rtl_ips_nic_on(hw);
	}

	/*For LPS */
	if (changed & IEEE80211_CONF_CHANGE_PS) {
		cancel_delayed_work(&rtlpriv->works.ps_work);
		cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
		if (conf->flags & IEEE80211_CONF_PS) {
			rtlpriv->psc.sw_ps_enabled = true;
			/* sleep here is must, or we may recv the beacon and
			 * cause mac80211 into wrong ps state, this will cause
			 * power save nullfunc send fail, and further cause
			 * pkt loss, So sleep must quickly but not immediatly
			 * because that will cause nullfunc send by mac80211
			 * fail, and cause pkt loss, we have tested that 5mA
			 * is worked very well */
			if (!rtlpriv->psc.multi_buffered)
				queue_delayed_work(rtlpriv->works.rtl_wq,
						&rtlpriv->works.ps_work,
						MSECS(5));
		} else {
			rtl_swlps_rf_awake(hw);
			rtlpriv->psc.sw_ps_enabled = false;
		}
	}

	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
			 ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
			  hw->conf.long_frame_max_tx_count));
		mac->retry_long = hw->conf.long_frame_max_tx_count;
		mac->retry_short = hw->conf.long_frame_max_tx_count;
		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
					      (u8 *) (&hw->conf.
						      long_frame_max_tx_count));
	}

	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
		struct ieee80211_channel *channel = hw->conf.channel;
		u8 wide_chan = (u8) channel->hw_value;

		/*
		 *because we should back channel to
		 *current_network.chan in in scanning,
		 *So if set_chan == current_network.chan
		 *we should set it.
		 *because mac80211 tell us wrong bw40
		 *info for cisco1253 bw20, so we modify
		 *it here based on UPPER & LOWER
		 */
		switch (hw->conf.channel_type) {
		case NL80211_CHAN_HT20:
		case NL80211_CHAN_NO_HT:
			/* SC */
			mac->cur_40_prime_sc =
				PRIME_CHNL_OFFSET_DONT_CARE;
			rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
			mac->bw_40 = false;
			break;
		case NL80211_CHAN_HT40MINUS:
			/* SC */
			mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
			rtlphy->current_chan_bw =
				HT_CHANNEL_WIDTH_20_40;
			mac->bw_40 = true;

			/*wide channel */
			wide_chan -= 2;

			break;
		case NL80211_CHAN_HT40PLUS:
			/* SC */
			mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
			rtlphy->current_chan_bw =
				HT_CHANNEL_WIDTH_20_40;
			mac->bw_40 = true;

			/*wide channel */
			wide_chan += 2;

			break;
		default:
			mac->bw_40 = false;
			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
					("switch case not processed\n"));
			break;
		}

		if (wide_chan <= 0)
			wide_chan = 1;

		/* In scanning, before we go offchannel we may send a ps=1 null
		 * to AP, and then we may send a ps = 0 null to AP quickly, but
		 * first null may have caused AP to put lots of packet to hw tx
		 * buffer. These packets must be tx'd before we go off channel
		 * so we must delay more time to let AP flush these packets
		 * before going offchannel, or dis-association or delete BA will
		 * happen by AP
		 */
		if (rtlpriv->mac80211.offchan_deley) {
			rtlpriv->mac80211.offchan_deley = false;
			mdelay(50);
		}
		rtlphy->current_channel = wide_chan;

		rtlpriv->cfg->ops->switch_channel(hw);
		rtlpriv->cfg->ops->set_channel_access(hw);
		rtlpriv->cfg->ops->set_bw_mode(hw,
					       hw->conf.channel_type);
	}

	mutex_unlock(&rtlpriv->locks.conf_mutex);

	return 0;
}
Esempio n. 28
0
void ipcTest1(void)
{
  /* Actually send one more byte (end-of-string) */
#define FIVE_BYTE_MSG_LEN  6
#define SIX_BYTE_MSG_LEN   7
#define EIGHT_BYTE_MSG_LEN 9

  char fiveBytes[FIVE_BYTE_MSG_LEN] = "abcde";
  char sixBytes[SIX_BYTE_MSG_LEN] = "abcdef";
  char eightBytes[EIGHT_BYTE_MSG_LEN] = "abcdefgh";

  fiveBytes[FIVE_BYTE_MSG_LEN-1] = '\0';
  sixBytes[SIX_BYTE_MSG_LEN-1] = '\0';
  eightBytes[EIGHT_BYTE_MSG_LEN-1] = '\0';

  /****************************************************************
   *                TESTS OF THE BASIC IPC INTERFACE
   ****************************************************************/

  /* Connect to the central server */
  printf("\nIPC_connect(%s)\n", TASK_NAME);
  IPC_connect(TASK_NAME);

  /* Default is to exit on error; Override default, because some of the
     tests in this file explicitly induce errors. */
  printf("\nIPC_setVerbosity(IPC_Print_Errors)\n");
  IPC_setVerbosity(IPC_Print_Errors);

  /* Test out the timers */
  realStart = x_ipc_timeInMsecs();
  printf("\nIPC_addTimer(1000, TRIGGER_FOREVER, timerHandler, \"timer1\")\n");
  IPC_addTimer(1000, TRIGGER_FOREVER, (TIMER_HANDLER_TYPE)timerHandler,
	       (void *)"timer1");

  /* Define a fixed length message (no format string) */
  printf("\nIPC_defineMsg(%s, %d, NULL)\n", MSG1, FIVE_BYTE_MSG_LEN);
  IPC_defineMsg(MSG1, FIVE_BYTE_MSG_LEN, NULL);
  /* Define a variable length message (no format string) */
  printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, NULL)\n", MSG2);
  IPC_defineMsg(MSG2, IPC_VARIABLE_LENGTH, NULL);

  printf("\nIPC_isMsgDefined(%s) => %s\n", 
	 MSG1, IPC_isMsgDefined(MSG1) ? "TRUE" : "FALSE");
  printf("\nIPC_isMsgDefined(%s) => %s\n", 
	 MSG3, IPC_isMsgDefined(MSG3) ? "TRUE" : "FALSE");

  /* Subscribe to the first message, with client data */
  printf("\nIPC_subscribe(%s, msg1Handler, %s)\n", MSG1, "client1a");
  IPC_subscribe(MSG1, msg1Handler, (void *)"client1a");
  /* Subscribe to the second message, with client data */
  printf("\nIPC_subscribe(%s, msg1Handler, %s)\n", MSG2, "client2a");
  IPC_subscribe(MSG2, msg1Handler, (void *)"client2a");

  /* Publish the fixed length message and listen for it (in this simple 
     example program, both publisher and subscriber are in the same process */
  printf("\nIPC_publish(%s, IPC_FIXED_LENGTH, %s)\n", MSG1, fiveBytes);
  if (IPC_publish(MSG1, IPC_FIXED_LENGTH, fiveBytes) == IPC_OK) 
    /* MSECS is a simple macro that converts from seconds to msecs */
    IPC_listenClear(MSECS(1));

  /* Publish the fixed length message, giving the length explicitly */
  /* Send one extra byte -- for end-of-string */
  printf("\nIPC_publish(%s, %d, %s)\n", MSG1, FIVE_BYTE_MSG_LEN, fiveBytes);
  if (IPC_publish(MSG1, FIVE_BYTE_MSG_LEN, fiveBytes) == IPC_OK)
    IPC_listenClear(MSECS(1));

  /* Produces an error, since the length passed is not the defined length */
  printf("\nIPC_publish(%s, %d, %s)\n", MSG1, 10, fiveBytes);
  if (IPC_publish(MSG1, 10, fiveBytes) == IPC_Error) printf("ERROR\n");

  /* Publish the variable length message, sending (and receiving) 5 bytes */
  /* Send one extra byte -- for end-of-string */
  printf("\nIPC_publish(%s, %d, %s)\n", MSG2, FIVE_BYTE_MSG_LEN, fiveBytes);
  if (IPC_publish(MSG2, FIVE_BYTE_MSG_LEN, fiveBytes) == IPC_OK)
    IPC_listenClear(MSECS(1));

  /* Publish the same variable length message, this time sending 8 bytes */
  /* Send one extra byte -- for end-of-string */
  printf("\nIPC_publish(%s, %d, %s)\n", MSG2, EIGHT_BYTE_MSG_LEN, eightBytes);
  if (IPC_publish(MSG2, EIGHT_BYTE_MSG_LEN, eightBytes) == IPC_OK)
    IPC_listenClear(MSECS(1));

  /* Produces an error: Cannot pass IPC_VARIABLE_LENGTH as an argument */
  printf("\nIPC_publish(%s, IPC_VARIABLE_LENGTH, %s)\n", MSG2, eightBytes);
  if (IPC_publish(MSG2, IPC_VARIABLE_LENGTH, eightBytes) == IPC_Error)
    printf("ERROR\n");

  /* Produces an error: "msg2" is a variable length message */
  printf("\nIPC_publish(%s, IPC_FIXED_LENGTH, %s)\n", MSG2, eightBytes);
  if (IPC_publish(MSG2, IPC_FIXED_LENGTH, eightBytes) == IPC_Error)
    printf("ERROR\n");

  /* Get notified when handlers subscribe/unsubscribe to "msg2" */
  printf("\n%d handlers currently subscribed to " MSG2, IPC_numHandlers(MSG2));
  printf("\nIPC_subscribeHandlerChange("MSG2", handlerChangeHandler, NULL)\n");
  IPC_subscribeHandlerChange(MSG2, handlerChangeHandler, NULL);

  /* Subscribe a second message handler for "msg2" */
  printf("\nIPC_subscribe(%s, msg2Handler, %s)\n", MSG2, "client2b");
  IPC_subscribe(MSG2, msg2Handler, (void *)"client2b");
  /* If doing direct broadcasts, need to listen to get the direct info update */
  IPC_listen(250);

  /* Publish the message -- receive two messages (one for msg1Handler, 
     one for msg2Handler). */
  /* Send one extra byte -- for end-of-string */
  printf("\nIPC_publish(%s, %d, %s)\n", MSG2, EIGHT_BYTE_MSG_LEN, eightBytes);
  if (IPC_publish(MSG2, EIGHT_BYTE_MSG_LEN, eightBytes) == IPC_OK) {
    /* Make sure all the subscribers get invoked before continuing on
       (keep listening until a second has passed without any msgs) */
    while (IPC_listen(MSECS(1)) != IPC_Timeout){};
  }
  /* Remove this subscription */
  printf("\nIPC_unsubscribe(%s, msg2Handler)\n", MSG2);
  IPC_unsubscribe(MSG2, msg2Handler);
  /* If doing direct broadcasts, need to listen to get the direct info update */
  IPC_listen(250);

  /* No longer get notified when handlers are added/removed */
  printf("\nIPC_unsubscribeHandlerChange("MSG2", handlerChangeHandler)\n");
  IPC_unsubscribeHandlerChange(MSG2, handlerChangeHandler);
  printf("  IPC_subscribe(%s, msg2Handler, %s)\n", MSG2, "client2c");
  IPC_subscribe(MSG2, msg2Handler, (void *)"client2c");
  printf("  IPC_unsubscribe(%s, msg2Handler)\n", MSG2);
  IPC_unsubscribe(MSG2, msg2Handler);

  /* Publish the message -- receive one message (for msg1Handler) */
  printf("\nIPC_publish(%s, %d, %s)\n", MSG2, EIGHT_BYTE_MSG_LEN, eightBytes);
  if (IPC_publish(MSG2, EIGHT_BYTE_MSG_LEN, eightBytes) == IPC_OK)
    IPC_listenClear(MSECS(1));

  /* Subscription of the same message handler *replaces* the old client data */
  printf("\nIPC_subscribe(%s, msg1Handler, %s)\n", MSG1, "client1b");
  IPC_subscribe(MSG1, msg1Handler, (void *)"client1b");
  /* Receive one message (for msg1Handler), but now with new client data.
     Note use of IPC_publishFixed. */
  printf("\nIPC_publishFixed(%s, %s)\n", MSG1, fiveBytes);
  if (IPC_publishFixed(MSG1, fiveBytes) == IPC_OK) IPC_listenClear(MSECS(1));

  /* Remove subscription to "msg1" */
  printf("\nIPC_unsubscribe(%s, msg1Handler)\n", MSG1);
  IPC_unsubscribe(MSG1, msg1Handler);
  /* If doing direct broadcasts, need to listen to get the direct info update */
  IPC_listen(250);

  /* Receive no messages -- IPC_listenClear times out */
  printf("\nIPC_publishFixed(%s, %s)\n", MSG1, fiveBytes);
  if (IPC_publishFixed(MSG1, fiveBytes) == IPC_OK) 
    if (IPC_listen(MSECS(1)) == IPC_Timeout) printf("Timed out\n");

  /****************************************************************
   *                TESTS OF THE QUERY/RESPONSE FUNCTIONS
   ****************************************************************/

  /* The handler of QUERY_MSG does two things: It *publishes* a message of
     type MSG2, and it *responds* to the query with a message of type MSG2.
     The published message gets handled only by the subscriber (msg1Handler),
     and the response gets handled only be replyHandler, since a response
     is a directed message. */
  /* NOTE: It is perfectly OK to subscribe to a message before it is defined! */
  printf("\nIPC_subscribe(%s, queryHandler, %s)\n", QUERY_MSG, "qtest");
  IPC_subscribe(QUERY_MSG, queryHandler, (void *)"qtest");
  printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, NULL)\n", QUERY_MSG);
  IPC_defineMsg(QUERY_MSG, IPC_VARIABLE_LENGTH, NULL);

  /* This call allows IPC to send the process 2 messages at a time, rather than
     queueing them in the central server.
     This is needed in this example program because the sender and receiver of
     the query are the same process.  If this is taken out, the only difference
     is that the message that is published in queryHandler arrives *after* the
     message responded to (even though it is sent first).  This function should
     not be needed when we switch to using point-to-point communications
     (rather than sending via the central server). */
  IPC_setCapacity(2);

  /* Send one extra byte -- for end-of-string */
  printf("\nIPC_queryNotify(%s, %d, %s, replyHandler, %s)\n", 
	 QUERY_MSG, SIX_BYTE_MSG_LEN, sixBytes, "Notification");
  IPC_queryNotify(QUERY_MSG, SIX_BYTE_MSG_LEN, sixBytes, replyHandler,
		  (void *)"Notification");
  /* Make sure all the messages spawned by this query get handled before
     continuing (keep listening until a second has passed without any msgs) */
  while (IPC_listen(MSECS(1)) != IPC_Timeout){};

  { char *replyHandle = NULL;
    /* This essentially does the same thing as IPC_queryNotify above, except
       it is blocking, and sets the replyHandle to be the data responded to.
       Don't need to listen, since that is done within queryResponse, but
       could be dangerous to wait forever (if the response never comes ...) */
    /* Send one extra byte -- for end-of-string */
    printf("\nIPC_queryResponse(%s, %d, %s, replyHandle, IPC_WAIT_FOREVER)\n", 
	   QUERY_MSG, SIX_BYTE_MSG_LEN, sixBytes);
    if (IPC_queryResponse(QUERY_MSG, SIX_BYTE_MSG_LEN, sixBytes,
			  (void **)(void *)&replyHandle,
			  IPC_WAIT_FOREVER) == IPC_OK) {
      printf("Blocking Response: %s\n", replyHandle);
      IPC_freeByteArray((void *)replyHandle);
    }

    /* This one should time out before the response arrives */
    /* Send one extra byte -- for end-of-string */
    printf("\nIPC_queryResponse(%s, %d, %s, replyHandle, %d)\n", 
	   QUERY_MSG, SIX_BYTE_MSG_LEN, sixBytes, 0);
    if (IPC_queryResponse(QUERY_MSG, SIX_BYTE_MSG_LEN, sixBytes,
			  (void **)(void *)&replyHandle, 0) == IPC_OK) {
      printf("Blocking Response: %s\n", replyHandle);
      IPC_freeByteArray((void *)replyHandle);
    } else {
      /* NOTE: Since the function call times out before handling messages,
       * (a) The *response* to the query is lost (for good)
       * (b) The message *published* in queryHandler is waiting for the next
       *     time the module listens for messages (which actually occurs
       *     in IPC_msgFormatter, below).
       */
      printf("queryResponse timed out (replyHandle: %ld)\n", (long)replyHandle);
    }
  }

  /****************************************************************
   *                TESTS OF THE MARSHALLING FUNCTIONS
   ****************************************************************/

  /* Test the marshalling/unmarshalling functions, independently of
   *  sending/receiving messages
   */
  { IPC_VARCONTENT_TYPE varcontent;
    SAMPLE_TYPE sample;
    SAMPLE_PTR  sample2Ptr;

    sample.i1 = 666; sample.str1 = "hello, world"; sample.d1 = 3.14159;

    printf("\nIPC_marshall(...)\n");
    IPC_marshall(IPC_parseFormat(SAMPLE_FORMAT), &sample, &varcontent);
    printf("Marshall of 'sample' [length: %d]\n", varcontent.length);
    
    printf("\nIPC_unmarshall(...)\n");
    IPC_unmarshall(IPC_parseFormat(SAMPLE_FORMAT), 
		   varcontent.content, (void **)(void *)&sample2Ptr);
      
    printf("Orig: <%d, %s, %f>\nCopy: <%d, %s, %f>\n",
	    sample.i1, sample.str1, sample.d1,
	    sample2Ptr->i1, sample2Ptr->str1, sample2Ptr->d1);
    IPC_freeByteArray(varcontent.content);
    IPC_freeData(IPC_parseFormat(SAMPLE_FORMAT), sample2Ptr);
  }

  { IPC_VARCONTENT_TYPE varcontent;
    MATRIX_LIST_TYPE m1, m2, m3;
    int i, j, k;
    char *string;
    
    /* Define a variable-length message whose format is simply an integer */
    printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, %s)\n", MSG3, INT_FORMAT);
    IPC_defineMsg(MSG3, IPC_VARIABLE_LENGTH, INT_FORMAT);
    /* Define a variable-length message whose format is a string */
    printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, %s)\n", 
	   MSG4, STRING_FORMAT);
    IPC_defineMsg(MSG4, IPC_VARIABLE_LENGTH, STRING_FORMAT);
    /* Define a variable-length message whose format is a complex structure */
    printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, %s)\n", 
	   MSG5, MATRIX_LIST_FORMAT);
    IPC_defineMsg(MSG5, IPC_VARIABLE_LENGTH, MATRIX_LIST_FORMAT);

    /* Subscribe to each of the above messages, all using the same handler */
    printf("\nIPC_subscribe(%s, msg3Handler, NULL)\n", MSG3);
    IPC_subscribe(MSG3, msg3Handler, NULL);
    printf("\nIPC_subscribe(%s, msg3Handler, NULL)\n", MSG4);
    IPC_subscribe(MSG4, msg3Handler, NULL);
    printf("\nIPC_subscribe(%s, msg3Handler, NULL)\n", MSG5);
    IPC_subscribe(MSG5, msg3Handler, NULL);

    /* Marshall the integer into a byte array (takes byte-order into account) */
    i = 42;
    printf("\nIPC_marshall(...)\n");
    IPC_marshall(IPC_msgFormatter(MSG3), &i, &varcontent);
    /* Publish the marshalled byte array (message handler prints the data) */
    printf("\nIPC_publishVC(%s, varcontent[%d])\n", MSG3, varcontent.length);
    IPC_publishVC(MSG3, &varcontent);
    IPC_freeByteArray(varcontent.content);
    IPC_listenClear(MSECS(1));

    /* Marshall the string into a byte array. NOTE: Need to pass a *pointer*
       to the string! */
    string = "Hello, world";
    /* It's much better (safer) to use IPC_msgFormatter, but this is included
       just to illustrate the use of IPC_parseFormat */
    printf("\nIPC_marshall(...)\n");
    IPC_marshall(IPC_parseFormat(STRING_FORMAT), &string, &varcontent);
    /* Publish the marshalled byte array (message handler prints the data) */
    printf("\nIPC_publishVC(%s, varcontent[%d])\n", MSG4, varcontent.length);
    IPC_publishVC(MSG4, &varcontent);
    IPC_freeByteArray(varcontent.content);
    IPC_listenClear(MSECS(1));

    /* Set up a sample MATRIX_LIST structure */
    for (k=0, i=0; i<2; i++) for (j=0; j<2; j++) m1.matrix[i][j] = (i+j+k);
    m1.matrixName = "TheFirst"; m1.count = k; m1.next = &m2;

    for (k++, i=0; i<2; i++) for (j=0; j<2; j++) m2.matrix[i][j] = (i+j+k);
    m2.matrixName = "TheSecond"; m2.count = k; m2.next = &m3;

    for (k++, i=0; i<2; i++) for (j=0; j<2; j++) m3.matrix[i][j] = (i+j+k);
    m3.matrixName = "TheThird"; m3.count = k; m3.next = NULL;

    /* IPC_publishData both marsalls and publishes the data structure */
    printf("\nIPC_publishData(%s, m1)\n", MSG5);
    IPC_publishData(MSG5, &m1);
    IPC_listenClear(MSECS(1));
  }

  /* Use of IPC_queryResponseData and IPC_respondData -- 
     Send out a message with a matrix_list format;  The response is a
     message with the first matrix, but each element incremented by one. */

  { MATRIX_LIST_TYPE m1;
    MATRIX_TYPE *matrixPtr;
    int i, j, k;
    
    /* Define the "query" message */
    printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, %s)\n", 
	   QUERY2_MSG, MATRIX_LIST_FORMAT);
    IPC_defineMsg(QUERY2_MSG, IPC_VARIABLE_LENGTH, MATRIX_LIST_FORMAT);
    /* Define the "response" message */
    printf("\nIPC_defineMsg(%s, IPC_VARIABLE_LENGTH, %s)\n", 
	   RESPONSE2_MSG, MATRIX_FORMAT);
    IPC_defineMsg(RESPONSE2_MSG, IPC_VARIABLE_LENGTH, MATRIX_FORMAT);

    /* Subscribe to query message with automatic unmarshalling */
    printf("\nIPC_subscribeData(%s, query2Handler, NULL)\n", QUERY2_MSG);
    IPC_subscribeData(QUERY2_MSG, query2Handler, NULL);

    /* Set up a sample MATRIX_LIST structure */
    for (k=0, i=0; i<2; i++) for (j=0; j<2; j++) m1.matrix[i][j] = (i+j+k);
    m1.matrixName = "TheFirst"; m1.count = k; m1.next = NULL;

    /* IPC_queryResponseData both marsalls and sends the data structure */
    printf("\nIPC_queryResponseData(%s, m1, matrixPtr, IPC_WAIT_FOREVER)\n", 
	   QUERY2_MSG);
    if (IPC_queryResponseData(QUERY2_MSG, (void *)&m1, 
			      (void **)(void *)&matrixPtr, 
			      IPC_WAIT_FOREVER) == IPC_OK) {
      IPC_printData(IPC_msgFormatter(RESPONSE2_MSG), stdout, matrixPtr);
    } else {
      printf("IPC_queryResponseData failed\n");
    }
  }

#if !defined(VXWORKS) && !defined(_WINSOCK_)
 /* Don't do this for vxworks, since it does not handle stdin from the 
    terminal, nor for winsock, since it does not seem to be able to use
    select on a non-socket fd */

  /* Subscribe a handler for tty input.  Now, typing at the terminal will
      echo the input.  Typing "q" will quit the program; typing "m" will
      send a message; typing "u" will unsubscribe the handler (the program
      will no longer listen to input). */
  printf("\nIPC_subscribeFD(%d, stdinHnd, %s)\n", fileno(stdin), "FD1");
  IPC_subscribeFD(fileno(stdin), stdinHnd, (void *)"FD1");
  printf("\nEntering dispatch loop (terminal input is echoed, type 'q' to quit,\n");
  printf("  'm' to send a message, 'u' to stop listening to stdin).\n");
  IPC_dispatch();
#endif

  /* If ever reaches here, shut down gracefully */
  IPC_disconnect();
}
Esempio n. 29
0
void RxPktPendingTimeout(unsigned long data)
{
	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
	struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, RxTsRecord[pRxTs->num]);
	
	PRX_REORDER_ENTRY 	pReorderEntry = NULL;

	unsigned long flags = 0;
	struct rtllib_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
	u8 index = 0;
	bool bPktInBuf = false;


	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
	RTLLIB_DEBUG(RTLLIB_DL_REORDER,"==================>%s()\n",__FUNCTION__);
	if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
	{
		while(!list_empty(&pRxTs->RxPendingPktList))
		{
			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
			if(index == 0)
				pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;

			if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || 
				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)	)
			{
				list_del_init(&pReorderEntry->List);
			
				if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
					pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;

				RTLLIB_DEBUG(RTLLIB_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
				stats_IndicateArray[index] = pReorderEntry->prxb;
				index++;
				
				list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
			}
			else
			{
				bPktInBuf = true;
				break;
			}
		}
	}

	if(index>0)
	{
		pRxTs->RxTimeoutIndicateSeq = 0xffff;
	
		if(index > REORDER_WIN_SIZE){
			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
			return;
		}
		rtllib_indicate_packets(ieee, stats_IndicateArray, index);
		 bPktInBuf = false;

	}

	if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
	{
		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
#if 0   
		if(timer_pending(&pTS->RxPktPendingTimer))
			del_timer_sync(&pTS->RxPktPendingTimer);
		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
		add_timer(&pTS->RxPktPendingTimer);
#else
		mod_timer(&pRxTs->RxPktPendingTimer,  jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
#endif

#if 0		
		if(timer_pending(&pRxTs->RxPktPendingTimer))
			del_timer_sync(&pRxTs->RxPktPendingTimer);
		pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime;
		add_timer(&pRxTs->RxPktPendingTimer);
#endif
	}
	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
}
Esempio n. 30
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));
    }

}