/* any station allocated can be searched by hash list */ struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) { unsigned long irqL; struct list_head *plist, *phead; struct sta_info *psta = NULL; u32 index; if (hwaddr == NULL) return NULL; index = wifi_mac_hash(hwaddr); spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); phead = &(pstapriv->sta_hash[index]); plist = phead->next; while (!end_of_queue_search(phead, plist)) { psta = container_of(plist, struct sta_info, hash_list); if ((!memcmp(psta->hwaddr, hwaddr, ETH_ALEN))) { /* if found the matched address */ break; } psta = NULL; plist = plist->next; } spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); return psta; }
void free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue) { union recv_frame *precvframe; _list *plist, *phead; _func_enter_; _spinlock(&pframequeue->lock); phead = get_list_head(pframequeue); plist = get_next(phead); while(end_of_queue_search(phead, plist) == _FALSE) { precvframe = LIST_CONTAINOR(plist, union recv_frame, u); plist = get_next(plist); //list_delete(&precvframe->u.hdr.list); // will do this in free_recvframe() free_recvframe(precvframe, pfree_recv_queue); } _spinunlock(&pframequeue->lock); _func_exit_; }
void r8712_free_all_stainfo(struct _adapter *padapter) { unsigned long irqL; struct list_head *plist, *phead; s32 index; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *pbcmc_stainfo = r8712_get_bcmc_stainfo(padapter); if (pstapriv->asoc_sta_count == 1) return; spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); for (index = 0; index < NUM_STA; index++) { phead = &(pstapriv->sta_hash[index]); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == false) { psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); plist = get_next(plist); if (pbcmc_stainfo != psta) r8712_free_stainfo(padapter , psta); } } spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); }
void free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue) { union recv_frame *precvframe; _list *plist, *phead; _func_enter_; { unsigned long flags; spin_lock_irqsave(&pframequeue->lock, flags); phead = get_list_head(pframequeue); plist = get_next(phead); while(end_of_queue_search(phead, plist) == _FALSE) { precvframe = LIST_CONTAINOR(plist, union recv_frame, u); plist = get_next(plist); //list_delete(&precvframe->u.hdr.list); // will do this in free_recvframe() free_recvframe(precvframe, pfree_recv_queue); } spin_unlock_irqrestore(&pframequeue->lock, flags); } _func_exit_; }
struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) { unsigned long irqL; struct list_head *plist, *phead; struct sta_info *psta = NULL; u32 index; if (hwaddr == NULL) return NULL; index = wifi_mac_hash(hwaddr); spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); phead = &(pstapriv->sta_hash[index]); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == false) { psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); if ((!memcmp(psta->hwaddr, hwaddr, ETH_ALEN))) { /* */ break; } psta = NULL; plist = get_next(plist); } spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); return psta; }
// this function is used to free the memory of lock || sema for all stainfos void mfree_all_stainfo(struct sta_priv *pstapriv ) { _irqL irqL; _list *plist, *phead; struct sta_info *psta = NULL; _func_enter_; _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); phead = get_list_head(&pstapriv->free_sta_queue); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == _FALSE) { psta = LIST_CONTAINOR(plist, struct sta_info ,list); plist = get_next(plist); mfree_stainfo(psta); } _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); _func_exit_; }
/* any station allocated can be searched by hash list */ struct sta_info *get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) { _irqL irqL; _list *plist, *phead; struct sta_info *psta = NULL; u32 index; u8 *addr; u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; _func_enter_; if(hwaddr==NULL) return NULL; if(IS_MCAST(hwaddr)) { addr = bc_addr; } else { addr = hwaddr; } index = wifi_mac_hash(addr); _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); phead = &(pstapriv->sta_hash[index]); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == _FALSE) { psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); if ((_memcmp(psta->hwaddr, addr, ETH_ALEN))== _TRUE) { // if found the matched address break; } psta=NULL; plist = get_next(plist); } _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); _func_exit_; return psta; }
/* this function is used to free the memory of lock || sema for all stainfos */ static void mfree_all_stainfo(struct sta_priv *pstapriv) { unsigned long irqL; struct list_head *plist, *phead; spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); phead = &pstapriv->free_sta_queue.queue; plist = phead->next; while (!end_of_queue_search(phead, plist)) plist = plist->next; spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); }
static void mfree_all_stainfo(struct sta_priv *pstapriv) { unsigned long irqL; struct list_head *plist, *phead; struct sta_info *psta = NULL; spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL); phead = get_list_head(&pstapriv->free_sta_queue); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == false) { psta = LIST_CONTAINOR(plist, struct sta_info, list); plist = get_next(plist); } spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL); }
void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue) { unsigned long irqL; struct list_head *plist, *phead; struct xmit_frame *pxmitframe; spin_lock_irqsave(&(pframequeue->lock), irqL); phead = &pframequeue->queue; plist = phead->next; while (!end_of_queue_search(phead, plist)) { pxmitframe = container_of(plist, struct xmit_frame, list); plist = plist->next; r8712_free_xmitframe(pxmitpriv, pxmitframe); } spin_unlock_irqrestore(&(pframequeue->lock), irqL); }
static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, struct __queue *pframe_queue) { struct list_head *xmitframe_plist, *xmitframe_phead; struct xmit_frame *pxmitframe = NULL; xmitframe_phead = get_list_head(pframe_queue); xmitframe_plist = get_next(xmitframe_phead); if ((end_of_queue_search(xmitframe_phead, xmitframe_plist)) == false) { pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); list_delete(&pxmitframe->list); ptxservq->qcnt--; phwxmit->txcmdcnt++; }
static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, struct __queue *pframe_queue) { struct list_head *xmitframe_plist, *xmitframe_phead; struct xmit_frame *pxmitframe = NULL; xmitframe_phead = &pframe_queue->queue; xmitframe_plist = xmitframe_phead->next; if (!end_of_queue_search(xmitframe_phead, xmitframe_plist)) { pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list); list_del_init(&pxmitframe->list); ptxservq->qcnt--; phwxmit->txcmdcnt++; }
static void _free_network_queue(struct _adapter *padapter) { unsigned long irqL; struct list_head *phead, *plist; struct wlan_network *pnetwork; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct __queue *scanned_queue = &pmlmepriv->scanned_queue; spin_lock_irqsave(&scanned_queue->lock, irqL); phead = get_list_head(scanned_queue); plist = get_next(phead); while (end_of_queue_search(phead, plist) == false) { pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); plist = get_next(plist); _free_network(pmlmepriv, pnetwork); } spin_unlock_irqrestore(&scanned_queue->lock, irqL); }
// free all stainfo which in sta_hash[all] void free_all_stainfo(_adapter *padapter) { _irqL irqL; _list *plist, *phead; s32 index; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info* pbcmc_stainfo =get_bcmc_stainfo( padapter); _func_enter_; if(pstapriv->asoc_sta_count==1) goto exit; _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); for(index=0; index< NUM_STA; index++) { phead = &(pstapriv->sta_hash[index]); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == _FALSE) { psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list); plist = get_next(plist); if(pbcmc_stainfo!=psta) free_stainfo(padapter , psta); } } _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); exit: _func_exit_; }
struct wlan_network *r8712_get_oldest_wlan_network( struct __queue *scanned_queue) { struct list_head *plist, *phead; struct wlan_network *pwlan = NULL; struct wlan_network *oldest = NULL; phead = get_list_head(scanned_queue); plist = get_next(phead); while (1) { if (end_of_queue_search(phead, plist) == true) break; pwlan = LIST_CONTAINOR(plist, struct wlan_network, list); if (pwlan->fixed != true) { if (oldest == NULL || time_after((unsigned long)oldest->last_scanned, (unsigned long)pwlan->last_scanned)) oldest = pwlan; } plist = get_next(plist); } return oldest; }
int proc_get_all_sta_info(char *page, char **start, off_t offset, int count, int *eof, void *data) { _irqL irqL; struct sta_info *psta; struct net_device *dev = data; _adapter *padapter = (_adapter *)netdev_priv(dev); struct sta_priv *pstapriv = &padapter->stapriv; int i, j; _list *plist, *phead; struct recv_reorder_ctrl *preorder_ctrl; int len = 0; len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); for(i=0; i< NUM_STA; i++) { phead = &(pstapriv->sta_hash[i]); plist = get_next(phead); while ((end_of_queue_search(phead, plist)) == _FALSE) { psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); plist = get_next(plist); //if(extra_arg == psta->aid) { len += snprintf(page + len, count - len, "sta's macaddr:" MACSTR "\n", MAC2STR(psta->hwaddr)); len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self); len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate); len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid); len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi); len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable); len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap); len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len); for(j=0;j<16;j++) { preorder_ctrl = &psta->recvreorder_ctrl[j]; if(preorder_ctrl->enable) { len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq); } } } } } _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); *eof = 1; return len; }
int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv) { struct list_head *phead; unsigned char *dst_ssid, *src_ssid; struct _adapter *adapter; struct __queue *queue = NULL; struct wlan_network *pnetwork = NULL; struct wlan_network *pnetwork_max_rssi = NULL; adapter = (struct _adapter *)pmlmepriv->nic_hdl; queue = &pmlmepriv->scanned_queue; phead = get_list_head(queue); pmlmepriv->pscanned = get_next(phead); while (1) { if (end_of_queue_search(phead, pmlmepriv->pscanned) == true) { if ((pmlmepriv->assoc_by_rssi == true) && (pnetwork_max_rssi != NULL)) { pnetwork = pnetwork_max_rssi; goto ask_for_joinbss; } return _FAIL; } pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list); if (pnetwork == NULL) return _FAIL; pmlmepriv->pscanned = get_next(pmlmepriv->pscanned); if (pmlmepriv->assoc_by_bssid == true) { dst_ssid = pnetwork->network.MacAddress; src_ssid = pmlmepriv->assoc_bssid; if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { if (is_same_network(&pmlmepriv-> cur_network.network, &pnetwork->network)) { _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); /*r8712_indicate_connect again*/ r8712_indicate_connect(adapter); return 2; } r8712_disassoc_cmd(adapter); r8712_ind_disconnect(adapter); r8712_free_assoc_resources(adapter); } goto ask_for_joinbss; } } else if (pmlmepriv->assoc_ssid.SsidLength == 0) goto ask_for_joinbss; dst_ssid = pnetwork->network.Ssid.Ssid; src_ssid = pmlmepriv->assoc_ssid.Ssid; if ((pnetwork->network.Ssid.SsidLength == pmlmepriv->assoc_ssid.SsidLength) && (!memcmp(dst_ssid, src_ssid, pmlmepriv->assoc_ssid.SsidLength))) { if (pmlmepriv->assoc_by_rssi == true) { /* if the ssid is the same, select the bss * which has the max rssi*/ if (pnetwork_max_rssi) { if (pnetwork->network.Rssi > pnetwork_max_rssi->network.Rssi) pnetwork_max_rssi = pnetwork; } else pnetwork_max_rssi = pnetwork; } else if (is_desired_network(adapter, pnetwork)) { if (check_fwstate(pmlmepriv, _FW_LINKED)) { r8712_disassoc_cmd(adapter); r8712_free_assoc_resources(adapter); } goto ask_for_joinbss; } } } return _FAIL; ask_for_joinbss: return r8712_joinbss_cmd(adapter, pnetwork); }
/* 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; } }