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; }
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; }