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; }
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 }
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; }
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; }
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; }
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; }
//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; }
/* 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; } }
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 ); }