示例#1
0
u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
	       bool active, u16 reason)
{
	u8 beacon_updated = false;
	struct sta_priv *pstapriv = &padapter->stapriv;

	if (!psta)
		return beacon_updated;

	/* tear down Rx AMPDU */
	send_delba(padapter, 0, psta->hwaddr);/*  recipient */

	/* tear down TX AMPDU */
	send_delba(padapter, 1, psta->hwaddr);/*  originator */
	psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
	psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */

	if (active)
		issue_deauth(padapter, psta->hwaddr, reason);

	/* clear cam entry / key */
	rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true);

	spin_lock_bh(&psta->lock);
	psta->state &= ~_FW_LINKED;
	spin_unlock_bh(&psta->lock);

	rtw_indicate_sta_disassoc_event(padapter, psta);

	report_del_sta_event(padapter, psta->hwaddr, reason);

	beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);

	spin_lock_bh(&pstapriv->sta_hash_lock);
	rtw_free_stainfo(padapter, psta);
	spin_unlock_bh(&pstapriv->sta_hash_lock);

	return beacon_updated;
}
// using pstapriv->sta_hash_lock to protect
u32	rtw_free_stainfo(_adapter *padapter , struct sta_info *psta)
{
    int i;
    _irqL irqL0;
    _queue *pfree_sta_queue;
    struct recv_reorder_ctrl *preorder_ctrl;
    struct	sta_xmit_priv	*pstaxmitpriv;
    struct	xmit_priv	*pxmitpriv= &padapter->xmitpriv;
    struct	sta_priv *pstapriv = &padapter->stapriv;


    _func_enter_;

    if (psta == NULL)
        goto exit;

    pfree_sta_queue = &pstapriv->free_sta_queue;


    pstaxmitpriv = &psta->sta_xmitpriv;

    //rtw_list_delete(&psta->sleep_list);

    //rtw_list_delete(&psta->wakeup_list);

    rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
    psta->sleepq_len = 0;

    _enter_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0);

    rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);

    rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));

    _exit_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0);


    _enter_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0);

    rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);

    rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));

    _exit_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0);


    _enter_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0);

    rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);

    rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));

    _exit_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0);

    _enter_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0);

    rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->be_q.sta_pending);

    rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));

    _exit_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0);


    rtw_list_delete(&psta->hash_list);
    RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("\n free number_%d stainfo  with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x  \n",pstapriv->asoc_sta_count , psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]));
    pstapriv->asoc_sta_count --;


    // re-init sta_info; 20061114
    _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
    _rtw_init_sta_recv_priv(&psta->sta_recvpriv);

    _cancel_timer_ex(&psta->addba_retry_timer);

#ifdef CONFIG_TDLS
    _cancel_timer_ex(&psta->TPK_timer);
    _cancel_timer_ex(&psta->option_timer);
    _cancel_timer_ex(&psta->base_ch_timer);
    _cancel_timer_ex(&psta->off_ch_timer);
#endif

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

        _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
    }


#ifdef CONFIG_AP_MODE

    rtw_list_delete(&psta->asoc_list);
    rtw_list_delete(&psta->auth_list);
    psta->expire_to = 0;

    psta->sleepq_ac_len = 0;
    psta->qos_info = 0;

    psta->max_sp_len = 0;
    psta->uapsd_bk = 0;
    psta->uapsd_be = 0;
    psta->uapsd_vi = 0;
    psta->uapsd_vo = 0;

    psta->has_legacy_ac = 0;

#ifdef CONFIG_NATIVEAP_MLME

    pstapriv->sta_dz_bitmap &=~BIT(psta->aid);
    pstapriv->tim_bitmap &=~BIT(psta->aid);

    rtw_indicate_sta_disassoc_event(padapter, psta);

    if (pstapriv->sta_aid[psta->aid - 1] == psta)
    {
        pstapriv->sta_aid[psta->aid - 1] = NULL;
        psta->aid = 0;
    }

#endif

#endif

    _enter_critical_bh(&(pfree_sta_queue->lock), &irqL0);
    rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
    _exit_critical_bh(&(pfree_sta_queue->lock), &irqL0);

exit:

    _func_exit_;

    return _SUCCESS;

}