示例#1
0
struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
{
	uint tmp_aid;
	s32	index;
	struct list_head *phash_list;
	struct sta_info	*psta;
	struct  __queue *pfree_sta_queue;
	struct recv_reorder_ctrl *preorder_ctrl;
	int i = 0;
	u16  wRxSeqInitialValue = 0xffff;
	unsigned long flags;

	pfree_sta_queue = &pstapriv->free_sta_queue;
	spin_lock_irqsave(&(pfree_sta_queue->lock), flags);
	if (_queue_empty(pfree_sta_queue) == true)
		psta = NULL;
	else {
		psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue),
				      struct sta_info, list);
		list_delete(&(psta->list));
		tmp_aid = psta->aid;
		_init_stainfo(psta);
		memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
		index = wifi_mac_hash(hwaddr);
		if (index >= NUM_STA) {
			psta = NULL;
			goto exit;
		}
		phash_list = &(pstapriv->sta_hash[index]);
		list_insert_tail(&psta->hash_list, phash_list);
		pstapriv->asoc_sta_count++;

/* For the SMC router, the sequence number of first packet of WPS handshake
 * will be 0. In this case, this packet will be dropped by recv_decache function
 * if we use the 0x00 as the default value for tid_rxseq variable. So, we
 * initialize the tid_rxseq variable as the 0xffff.
 */
		for (i = 0; i < 16; i++)
			memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
				&wRxSeqInitialValue, 2);
		/* for A-MPDU Rx reordering buffer control */
		for (i = 0; i < 16; i++) {
			preorder_ctrl = &psta->recvreorder_ctrl[i];
			preorder_ctrl->padapter = pstapriv->padapter;
			preorder_ctrl->indicate_seq = 0xffff;
			preorder_ctrl->wend_b = 0xffff;
			preorder_ctrl->wsize_b = 64;
			_init_queue(&preorder_ctrl->pending_recvframe_queue);
			r8712_init_recv_timer(preorder_ctrl);
		}
	}
exit:
	spin_unlock_irqrestore(&(pfree_sta_queue->lock), flags);
	return psta;
}
struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
{
	uint tmp_aid;
	s32	index;
	struct list_head *phash_list;
	struct sta_info	*psta;
	struct  __queue *pfree_sta_queue;
	struct recv_reorder_ctrl *preorder_ctrl;
	int i = 0;
	u16  wRxSeqInitialValue = 0xffff;
	unsigned long flags;

	pfree_sta_queue = &pstapriv->free_sta_queue;
	spin_lock_irqsave(&(pfree_sta_queue->lock), flags);
	if (_queue_empty(pfree_sta_queue) == true)
		psta = NULL;
	else {
		psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue),
				      struct sta_info, list);
		list_delete(&(psta->list));
		tmp_aid = psta->aid;
		_init_stainfo(psta);
		memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
		index = wifi_mac_hash(hwaddr);
		if (index >= NUM_STA) {
			psta = NULL;
			goto exit;
		}
		phash_list = &(pstapriv->sta_hash[index]);
		list_insert_tail(&psta->hash_list, phash_list);
		pstapriv->asoc_sta_count++ ;

/*                                                                         
                                                                                
                                                                         
                                                   
 */
		for (i = 0; i < 16; i++)
			memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
				&wRxSeqInitialValue, 2);
		/*                                         */
		for (i = 0; i < 16 ; i++) {
			preorder_ctrl = &psta->recvreorder_ctrl[i];
			preorder_ctrl->padapter = pstapriv->padapter;
			preorder_ctrl->indicate_seq = 0xffff;
			preorder_ctrl->wend_b = 0xffff;
			preorder_ctrl->wsize_b = 64;
			_init_queue(&preorder_ctrl->pending_recvframe_queue);
			r8712_init_recv_timer(preorder_ctrl);
		}
	}
exit:
	spin_unlock_irqrestore(&(pfree_sta_queue->lock), flags);
	return psta;
}
示例#3
0
void UIAPI uiforceevflush( void )
/********************************/
/* The EV_KILL_UI event can't be flushed */
{
    bool    ev_kill;

    // enter critical section
    ev_kill = _queue_is_member( Forced_Q, EV_KILL_UI );
    _queue_empty( Forced_Q );
    if( ev_kill ) {
        _queue_add( Forced_Q, EV_KILL_UI );
    }
    // exit critical section
}
示例#4
0
struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
{
	unsigned long irqL;
	struct wlan_network *pnetwork;
	struct  __queue *free_queue = &pmlmepriv->free_bss_pool;
	struct list_head *plist = NULL;

	if (_queue_empty(free_queue) == true)
		return NULL;
	spin_lock_irqsave(&free_queue->lock, irqL);
	plist = get_next(&(free_queue->queue));
	pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
	list_delete(&pnetwork->list);
	pnetwork->last_scanned = jiffies;
	pmlmepriv->num_of_scanned++;
	spin_unlock_irqrestore(&free_queue->lock, irqL);
	return pnetwork;
}
示例#5
0
union recv_frame *alloc_recvframe (_queue *pfree_recv_queue)
{
	_irqL irqL;
	union recv_frame  *precvframe;
	_list	*plist, *phead;
	_adapter *padapter;
	struct recv_priv *precvpriv;
_func_enter_;

	_enter_critical(&pfree_recv_queue->lock, &irqL);
	
	if(_queue_empty(pfree_recv_queue) == _TRUE)
	{
		precvframe = NULL;
	}
	else
	{
		phead = get_list_head(pfree_recv_queue);

		plist = get_next(phead);

		precvframe = LIST_CONTAINOR(plist, union recv_frame, u);

		list_delete(&precvframe->u.hdr.list);
		padapter=precvframe->u.hdr.adapter;
		if(padapter !=NULL){
			precvpriv=&padapter->recvpriv;
			if(pfree_recv_queue == &precvpriv->free_recv_queue)
				precvpriv->free_recvframe_cnt--;
		}
	}
	        
	_exit_critical(&pfree_recv_queue->lock, &irqL);
	
_func_exit_;

	return precvframe;
	
}
示例#6
0
static u8 do_join(struct _adapter *padapter)
{
	struct list_head *plist, *phead;
	u8 *pibss = NULL;
	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
	struct  __queue	*queue	= &(pmlmepriv->scanned_queue);

	phead = get_list_head(queue);
	plist = get_next(phead);
	pmlmepriv->cur_network.join_res = -2;
	pmlmepriv->fw_state |= _FW_UNDER_LINKING;
	pmlmepriv->pscanned = plist;
	pmlmepriv->to_join = true;
	if (_queue_empty(queue) == true) {
		if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
			pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
		/* when set_ssid/set_bssid for do_join(), but scanning queue
		 * is empty we try to issue sitesurvey firstly
		 */
		if (pmlmepriv->sitesurveyctrl.traffic_busy == false)
			r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid);
		return true;
	} else {
		int ret;

		ret = r8712_select_and_join_from_scan(pmlmepriv);
		if (ret == _SUCCESS)
			_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
		else {
			if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
				/* submit r8712_createbss_cmd to change to an
				 * ADHOC_MASTER pmlmepriv->lock has been
				 * acquired by caller...
				 */
				struct wlan_bssid_ex *pdev_network =
					&(padapter->registrypriv.dev_network);
				pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
				pibss = padapter->registrypriv.dev_network.
					MacAddress;
				memset(&pdev_network->Ssid, 0,
					sizeof(struct ndis_802_11_ssid));
				memcpy(&pdev_network->Ssid,
					&pmlmepriv->assoc_ssid,
					sizeof(struct ndis_802_11_ssid));
				r8712_update_registrypriv_dev_network(padapter);
				r8712_generate_random_ibss(pibss);
				if (r8712_createbss_cmd(padapter) != _SUCCESS)
					return false;
				pmlmepriv->to_join = false;
			} else {
				/* can't associate ; reset under-linking */
				if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
					pmlmepriv->fw_state ^=
							     _FW_UNDER_LINKING;
				/* when set_ssid/set_bssid for do_join(), but
				 * there are no desired bss in scanning queue
				 * we try to issue sitesurvey first
				 */
				if (!pmlmepriv->sitesurveyctrl.traffic_busy)
					r8712_sitesurvey_cmd(padapter,
						       &pmlmepriv->assoc_ssid);
			}
		}
	}
	return true;
}
示例#7
0
u8 do_join(_adapter *padapter)
{
	_list *plist, *phead;
	u8* pibss = NULL;
	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
	_queue	*queue	= &(pmlmepriv->scanned_queue);
	u8 ret = _TRUE;

_func_enter_;

	phead = get_list_head(queue);
	plist = get_next(phead);

	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+do_join: phead=%p; plist=%p\n", phead, plist));

	pmlmepriv->cur_network.join_res = -2;
	pmlmepriv->fw_state |= _FW_UNDER_LINKING;

	pmlmepriv->pscanned = plist;
	pmlmepriv->to_join = _TRUE;

	if (_queue_empty(queue) == _TRUE)
	{
		if(pmlmepriv->fw_state & _FW_UNDER_LINKING)
	               pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
            		
		//when set_ssid/set_bssid for do_join(), but scanning queue is empty
		//we try to issue sitesurvey firstly

		if (pmlmepriv->sitesurveyctrl.traffic_busy == _FALSE)
		{
			// submit site_survey_cmd
			sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid);

			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("do_join(): site survey if scanned_queue is empty\n."));
		}
		
		//ret=_FALSE;

		goto exit;
	}
	else 	
	{	
             int ret;

	     if((ret=select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS)
	     {
		_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
	}
#if 0
	     else if(ret == 2)
	{
			DBG_8712("*****UNDER_LINKED WITH SAME NETWORK, RETURN*****\n");

			if(pmlmepriv->fw_state & _FW_UNDER_LINKING)
	               	pmlmepriv->fw_state ^= _FW_UNDER_LINKING;

	}
#endif
	else
	{
		if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
		{
			// submit createbss_cmd to change to a ADHOC_MASTER

			//pmlmepriv->lock has been acquired by caller...
			WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network);

			pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;

			pibss = padapter->registrypriv.dev_network.MacAddress;

			_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
			_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
	
			update_registrypriv_dev_network(padapter);

			generate_random_ibss(pibss);
					
				if(createbss_cmd(padapter)!=_SUCCESS)
				{
					RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>do_goin: createbss_cmd status FAIL*** \n "));						
					return _FALSE;
			}

			        pmlmepriv->to_join = _FALSE;

				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> select_and_join_from_scanned_queue FAIL under STA_Mode*** \n "));						

		}
		else
		{
			// can't associate ; reset under-linking			
			if(pmlmepriv->fw_state & _FW_UNDER_LINKING)
			    pmlmepriv->fw_state ^= _FW_UNDER_LINKING;

#if 0
			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
			{
				if(_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength))
				{
					// for funk to do roaming
					// funk will reconnect, but funk will not sitesurvey before reconnect
					RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("for funk to do roaming"));
					if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE)
						sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid);
				}

			}
#endif

			//when set_ssid/set_bssid for do_join(), but there are no desired bss in scanning queue
			//we try to issue sitesurvey firstly
				if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE)
				{
				//printk("do_join() when no desired bss in scanning queue\n");
				sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid);
		}


			}

		}

	}

exit:

_func_exit_;

	return ret;
}
示例#8
0
//struct	sta_info *alloc_stainfo(_queue *pfree_sta_queue, unsigned char *hwaddr)
struct	sta_info *alloc_stainfo(struct	sta_priv *pstapriv, u8 *hwaddr) 
{	
	_irqL irqL, irqL2;
	uint tmp_aid;
	s32	index;
	_list	*phash_list;
	struct sta_info	*psta;
	_queue *pfree_sta_queue;
	struct recv_reorder_ctrl *preorder_ctrl;
	int i = 0;
	u16  wRxSeqInitialValue = 0xffff;
	
_func_enter_;	

	pfree_sta_queue = &pstapriv->free_sta_queue;
	
	_enter_critical_bh(&(pfree_sta_queue->lock), &irqL);

	if (_queue_empty(pfree_sta_queue) == _TRUE)
	{
		psta = NULL;
	}
	else
	{
		psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list);
		
		list_delete(&(psta->list));
		
		tmp_aid = psta->aid;	
	
		_init_stainfo(psta);

		_memcpy(psta->hwaddr, hwaddr, ETH_ALEN);

		index = wifi_mac_hash(hwaddr);

		RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("alloc_stainfo: index  = %x", index));

		if(index >= NUM_STA){
			RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("ERROR=> alloc_stainfo: index >= NUM_STA"));
			psta= NULL;	
			goto exit;
		}
		phash_list = &(pstapriv->sta_hash[index]);

		_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);

		list_insert_tail(&psta->hash_list, phash_list);

		pstapriv->asoc_sta_count ++ ;

		_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);

// Commented by Albert 2009/08/13
// For the SMC router, the sequence number of first packet of WPS handshake will be 0.
// In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable.
// So, we initialize the tid_rxseq variable as the 0xffff.

		for( i = 0; i < 16; i++ )
		{
                     _memcpy( &psta->sta_recvpriv.rxcache.tid_rxseq[ i ], &wRxSeqInitialValue, 2 );
		}

		RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("alloc number_%d stainfo  with hwaddr = %x %x %x %x %x %x  \n", 
		pstapriv->asoc_sta_count , hwaddr[0], hwaddr[1], hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]));

		init_addba_retry_timer(pstapriv->padapter, psta);

		//for A-MPDU Rx reordering buffer control
		for(i=0; i < 16 ; i++)
		{
			preorder_ctrl = &psta->recvreorder_ctrl[i];

			preorder_ctrl->padapter = pstapriv->padapter;
		
			preorder_ctrl->enable = _FALSE;
		
			preorder_ctrl->indicate_seq = 0xffff;
			preorder_ctrl->wend_b= 0xffff;       
			//preorder_ctrl->wsize_b = (NR_RECVBUFF-2);
			preorder_ctrl->wsize_b = 64;//64;

			_init_queue(&preorder_ctrl->pending_recvframe_queue);

			init_recv_timer(preorder_ctrl);
		}

	}
	
exit:

	_exit_critical_bh(&(pfree_sta_queue->lock), &irqL);
	
_func_exit_;	

	return psta;


}
示例#9
0
/*
Caller must hold pmlmepriv->lock first.
*/
static void update_scanned_network(struct _adapter *adapter,
			    struct ndis_wlan_bssid_ex *target)
{
	struct list_head *plist, *phead;

	u32 bssid_ex_sz;
	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
	struct  __queue *queue = &pmlmepriv->scanned_queue;
	struct wlan_network *pnetwork = NULL;
	struct wlan_network *oldest = NULL;

	phead = get_list_head(queue);
	plist = get_next(phead);

	while (1) {
		if (end_of_queue_search(phead, plist) == true)
			break;

		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
		if (is_same_network(&pnetwork->network, target))
			break;
		if ((oldest == ((struct wlan_network *)0)) ||
		    time_after((unsigned long)oldest->last_scanned,
				(unsigned long)pnetwork->last_scanned))
			oldest = pnetwork;

		plist = get_next(plist);
	}


	/* If we didn't find a match, then get a new network slot to initialize
	 * with this beacon's information */
	if (end_of_queue_search(phead, plist) == true) {
		if (_queue_empty(&pmlmepriv->free_bss_pool) == true) {
			/* If there are no more slots, expire the oldest */
			pnetwork = oldest;
			target->Rssi = (pnetwork->network.Rssi +
					target->Rssi) / 2;
			memcpy(&pnetwork->network, target,
				r8712_get_ndis_wlan_bssid_ex_sz(target));
			pnetwork->last_scanned = jiffies;
		} else {
			/* Otherwise just pull from the free list */
			/* update scan_time */
			pnetwork = alloc_network(pmlmepriv);
			if (pnetwork == NULL)
				return;
			bssid_ex_sz = r8712_get_ndis_wlan_bssid_ex_sz(target);
			target->Length = bssid_ex_sz;
			memcpy(&pnetwork->network, target, bssid_ex_sz);
			list_insert_tail(&pnetwork->list, &queue->queue);
		}
	} else {
		/* we have an entry and we are going to update it. But
		 * this entry may be already expired. In this case we
		 * do the same as we found a new net and call the new_net
		 * handler
		 */
		update_network(&pnetwork->network, target, adapter);
		pnetwork->last_scanned = jiffies;
	}
}
示例#10
0
static void _clock_isr( int vector, int code ) {
	(void)(vector);
	(void)(code);

	pcb_t *pcb;

	// spin the pinwheel

	++_pinwheel;
	if( _pinwheel == (CLOCK_FREQUENCY / 10) ) {
		_pinwheel = 0;
		++_pindex;
		c_putchar_at( 79, 0, "|/-\\"[ _pindex & 3 ] );
	}

	// increment the system time

	++_system_time;

	/*
	** wake up any sleeper whose time has come
	**
	** we give awakened processes preference over the
	** current process (when it is scheduled again)
	*/

	while( !_queue_empty(_sleeping) &&
	       (uint32_t) _queue_kpeek(_sleeping) <= _system_time ) {

		// time to wake up!  remove it from the queue
		pcb = (pcb_t *) _queue_remove( _sleeping );
		if( pcb == NULL ) {
#ifdef DEBUG
			_kpanic( "_clock_isr", "NULL from sleep queue remove" );
#else
			c_puts( "*** _clock_isr: NULL from sleep queue\n" );
			break;
#endif
		}

		// and schedule it for dispatch
		_schedule( pcb );
	}

	// check the current process to see if it needs to be scheduled

	// sanity check!

	_current->quantum -= 1;
	if( _current->quantum < 1 ) {
		_schedule( _current );
		_dispatch();
	}

#ifdef DUMP_QUEUES
	// Approximately every 10 seconds, dump the queues, and
	// print the contents of the SIO buffers.

	if( (_system_time % SECONDS_TO_TICKS(10)) == 0 ) {
		c_printf( "Queue contents @%08x\n", _system_time );
		_queue_dump( "ready[0]", _ready[0] );
		_queue_dump( "ready[1]", _ready[1] );
		_queue_dump( "ready[2]", _ready[2] );
		_queue_dump( "ready[3]", _ready[3] );
		_queue_dump( "sleep", _sleeping );
		_sio_dump();
	}
#endif

	// tell the PIC we're done

	__outb( PIC_MASTER_CMD_PORT, PIC_EOI );

}