Exemplo n.º 1
0
int
wlan_vap_delete(wlan_if_t vaphandle)
{
    struct ieee80211vap *vap = vaphandle;
    struct ieee80211com *ic = vap->iv_ic;

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD,IEEE80211_MSG_DEBUG,
                         "%s : enter. vaphandle=0x%x\n", 
             __func__, 
             vaphandle
             );

    ieee80211_vap_pause_vdetach(ic,vap);

    IEEE80211_COMM_LOCK(ic);
#ifdef MAGPIE_HIF_GMAC
    if (ic->ic_chanchange_cnt)
        ic->ic_chanchange_cnt -= ic->ic_chanchange_tbtt;
#endif    
    if (ieee80211_vap_deleted_is_clear(vap)) /* if not deleted then it is on the list */
    {
        TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
        if (TAILQ_EMPTY(&ic->ic_vaps))      /* reset to supported mode */
            ic->ic_opmode = IEEE80211_M_STA;
        ieee80211_vap_deleted_set(vap); /* mark it as deleted */
        IEEE80211_COMM_UNLOCK(ic);

        /*
         * In case iv_bss was not stopped or is in scanning.
         * TBD: BSS should have been stopped now. We can save the time for stop bss again.
         */
        wlan_mlme_stop_bss(vap,
                           WLAN_MLME_STOP_BSS_F_SEND_DEAUTH        | 
                           WLAN_MLME_STOP_BSS_F_CLEAR_ASSOC_STATE  |
                           WLAN_MLME_STOP_BSS_F_WAIT_RX_DONE       |
                           WLAN_MLME_STOP_BSS_F_NO_RESET);

        ieee80211_sta_leave(vap->iv_bss);
        ieee80211_node_vdetach(vap);
    } else {
        IEEE80211_COMM_UNLOCK(ic);
    }

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD,IEEE80211_MSG_DEBUG,
                         "%s : exit. vaphandle=0x%x\n", 
             __func__, 
             vaphandle
             );
    return 0;
}
Exemplo n.º 2
0
int ieee80211com_unregister_event_handlers(struct ieee80211com *ic,
                                     void *event_arg,
                                     wlan_dev_event_handler_table *evtable)
{
    int i;
    IEEE80211_COMM_LOCK(ic);
    for (i=0;i<IEEE80211_MAX_DEVICE_EVENT_HANDLERS; ++i) {
        if ( ic->ic_evtable[i] == evtable &&  ic->ic_event_arg[i] == event_arg) {
            ic->ic_evtable[i] = NULL;
            ic->ic_event_arg[i] = NULL;
            IEEE80211_COMM_UNLOCK(ic);
            return 0;
        }
    }
    IEEE80211_COMM_UNLOCK(ic);
    return -EEXIST;
}
Exemplo n.º 3
0
/*
 * External UMAC Interface
 */
wlan_if_t
wlan_vap_create(wlan_dev_t            devhandle,
                enum ieee80211_opmode opmode,
                int                   scan_priority_base,
                int                   flags,
                u_int8_t              *bssid,
                u_int8_t              *mataddr,
                int                     unit)
{
    struct ieee80211com *ic = devhandle;
    struct ieee80211vap *vap;

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD, IEEE80211_MSG_DEBUG,
                         "%s : enter. devhandle=0x%x, opmode=%s, flags=0x%x\n", 
             __func__, 
             devhandle,
             ieee80211_opmode2string(opmode),
             flags
             );

    vap = ic->ic_vap_create(ic, opmode, scan_priority_base, flags, bssid, mataddr,unit);
    if (vap == NULL) {
        printk("%s: failed to create a vap object\n", __func__);
        return NULL;
    }

    ieee80211_vap_pause_late_vattach(ic,vap); 
    ieee80211_resmgr_vattach(ic->ic_resmgr, vap);

    ieee80211_vap_deleted_clear(vap); /* clear the deleted */

    /* when all  done,  add vap to queue */
    IEEE80211_COMM_LOCK(ic);
    TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
    IEEE80211_COMM_UNLOCK(ic);

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD, IEEE80211_MSG_DEBUG,
             "%s : exit. devhandle=0x%x, opmode=%s, flags=0x%x.\n",
             __func__, 
             devhandle,
             ieee80211_opmode2string(opmode),
             flags
             );
#if ATH_SUPPORT_FLOWMAC_MODULE
    /* 
     * Due to platform dependency the flow control need to check the status
     * of the lmac layer before enabling the flow mac at vap layer.
     * 
     * Enabling of the flowmac happens after creating the wifi interface
     */
    vap->iv_flowmac = ic->ic_get_flowmac_enabled_State(ic);
#endif
    return vap;
}
Exemplo n.º 4
0
int ieee80211com_register_event_handlers(struct ieee80211com *ic,
                                     void *event_arg,
                                     wlan_dev_event_handler_table *evtable)
{
    int i;
    /* unregister if there exists one already */
    ieee80211com_unregister_event_handlers(ic,event_arg,evtable);
    IEEE80211_COMM_LOCK(ic);
    for (i=0;i<IEEE80211_MAX_DEVICE_EVENT_HANDLERS; ++i) {
        if ( ic->ic_evtable[i] == NULL) {
            ic->ic_evtable[i] = evtable;
            ic->ic_event_arg[i] = event_arg;
            IEEE80211_COMM_UNLOCK(ic);
            return 0;
        }
    }
    IEEE80211_COMM_UNLOCK(ic);
    return -ENOMEM;


}
Exemplo n.º 5
0
/*
 * function to handle station joining infrastructure network.
 * used for AP mode vap only.
 */  
int ieee80211_node_join(struct ieee80211_node *ni)
{
    struct ieee80211com *ic = ni->ni_ic;
    struct ieee80211vap *vap = ni->ni_vap;

    IEEE80211_NODE_STATE_LOCK(ni);
    if (ni->ni_associd == 0) {
        u_int16_t aid;

        if(vap->iv_sta_assoc >= vap->iv_max_aid - 1) {
            IEEE80211_NODE_STATE_UNLOCK(ni);
            return -1; /* soft client limit reached */
        }

        if (vap->iv_aid_bitmap == NULL || IEEE80211_IS_TDLS_NODE(ni)) {
            IEEE80211_NODE_STATE_UNLOCK(ni);
            return -1; /* vap is being deleted */
        }

        /*
         * It would be good to search the bitmap
         * more efficiently, but this will do for now.
         */
        if (!IEEE80211_IS_TDLS_NODE(ni)) {
            for (aid = 1; aid < vap->iv_max_aid; aid++) {
                if (!IEEE80211_AID_ISSET(vap, aid))
                break;
            }

            if (aid >= vap->iv_max_aid) {
            /*
             * Keep stats on this situation.
             */
            IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, "aid (%d)"
                              " greater than max aid (%d)\n", aid,
                              vap->iv_max_aid);
            IEEE80211_NODE_STATE_UNLOCK(ni);
            IEEE80211_NODE_LEAVE(ni);
            return -1;
            }

            ni->ni_associd = aid | 0xc000;
            IEEE80211_AID_SET(vap, ni->ni_associd);
        } else {
            /* To keep the other parts of code happy. Otherwise the code assumes
             * node disconnected and tries to delete it.There are no associd for
            * TDLS nodes.
            */
            ni->ni_associd = vap->iv_bss->ni_associd;
        }
        IEEE80211_VAP_LOCK(vap);
        vap->iv_sta_assoc++;
        IEEE80211_VAP_UNLOCK(vap);
        ni->ni_leaving = 0;
        IEEE80211_COMM_LOCK(ic);
        ic->ic_sta_assoc++;
        /* Update bss load element in beacon */
        ieee80211_vap_bssload_update_set(vap);
        if ((ni->ni_flags & IEEE80211_NODE_HT) &&
            (ni->ni_flags & IEEE80211_NODE_40_INTOLERANT)) {
            ieee80211_change_cw(ic);
        }
        if (IEEE80211_IS_AMPDU_ENABLED(ic)) {
            ieee80211node_clear_flag(ni, IEEE80211_NODE_NOAMPDU);
        }
        else {
            ieee80211node_set_flag(ni, IEEE80211_NODE_NOAMPDU);
        }
        if (IEEE80211_NODE_USE_HT(ni)) {
            ic->ic_ht_sta_assoc++;
            if (ni->ni_htcap & IEEE80211_HTCAP_C_GREENFIELD)
                ic->ic_ht_gf_sta_assoc++;
#if ATH_TxBF_DYNAMIC_LOF_ON_N_CHAIN_MASK
             iee80211_txbf_loforce_check(ni,1);
#endif
	    if ((ni->ni_chwidth == IEEE80211_CWM_WIDTH40 ) || (ni->ni_chwidth == IEEE80211_CWM_WIDTH80)) {
	      ic->ic_ht40_sta_assoc++;
      	    }
	  }
      

        if ((IEEE80211_IS_CHAN_ANYG(vap->iv_bsschan) ||
            IEEE80211_IS_CHAN_11NG(vap->iv_bsschan)) && !IEEE80211_IS_TDLS_NODE(ni))
            ieee80211_node_join_11g(ni);
        IEEE80211_COMM_UNLOCK(ic);
    }
#if ATH_SUPPORT_WIFIPOS
    // Time stamp to send in status response
    ni->last_rx_desc_tsf = ic->ic_get_TSF32(ic);
#endif
    ni->ni_inact_reload = ni->ni_vap->iv_inact_auth;
    ni->ni_inact = ni->ni_inact_reload;
    
    /* Multicast enhancement: If the entry with the node's address exists in 
     * the snoop table, it should be removed.
     */
    if (vap->iv_ique_ops.me_clean) {
        vap->iv_ique_ops.me_clean(ni);
    }
    /*
     * HBR / headline block removal: add the node entity to the table
     * for HBR purpose
     */
    if (vap->iv_ique_ops.hbr_nodejoin) {
        vap->iv_ique_ops.hbr_nodejoin(vap, ni);
    }
    IEEE80211_NODE_STATE_UNLOCK(ni);
    IEEE80211_ADD_NODE_TARGET(ni, ni->ni_vap, 0);
	return 0;
}
Exemplo n.º 6
0
bool _ieee80211_node_leave(struct ieee80211_node *ni)
#endif
{
    struct ieee80211com *ic = ni->ni_ic;
    struct ieee80211vap *vap = ni->ni_vap;
	bool   retval = false;
#ifdef IEEE80211_DEBUG_REFCNT
    TRACENODE(ni, func, line);
#endif
    IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni,
                   "station with aid %d leaves (refcnt %u) \n",
                   IEEE80211_NODE_AID(ni), ieee80211_node_refcnt(ni));
#ifdef ATH_SWRETRY
    if (ic->ic_reset_pause_tid)
        ic->ic_reset_pause_tid(ni->ni_ic, ni);
#endif

    if (!IEEE80211_IS_TDLS_NODE(ni)) 
    KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP
            || vap->iv_opmode == IEEE80211_M_WDS ||
            vap->iv_opmode == IEEE80211_M_BTAMP  ||
            vap->iv_opmode == IEEE80211_M_IBSS,
            ("unexpected operating mode %u", vap->iv_opmode));

    /* Multicast enhancement: If the entry with the node's address exists in 
     * the snoop table, it should be removed.
     */
    if (vap->iv_ique_ops.me_clean) {
        vap->iv_ique_ops.me_clean(ni);
    }
	/*    
     * HBR / headline block removal: delete the node entity from the table
     * for HBR purpose
     */
    if (vap->iv_ique_ops.hbr_nodeleave) {
        vap->iv_ique_ops.hbr_nodeleave(vap, ni);
    }
    /*
     * If node wasn't previously associated all
     * we need to do is reclaim the reference.
     */
    /* XXX ibss mode bypasses 11g and notification */

    IEEE80211_NODE_STATE_LOCK(ni);
    if (ni->ni_associd && (0 == ni->ni_leaving)) {
        ni->ni_leaving = 1;
        IEEE80211_VAP_LOCK(vap);
        vap->iv_sta_assoc--;
        IEEE80211_VAP_UNLOCK(vap);		
        IEEE80211_COMM_LOCK(ic);
        ic->ic_sta_assoc--;
        /* Update bss load element in beacon */
        ieee80211_vap_bssload_update_set(vap);

        if (IEEE80211_NODE_USE_HT(ni)) {
            ic->ic_ht_sta_assoc--;
            if (ni->ni_htcap & IEEE80211_HTCAP_C_GREENFIELD) {
                ASSERT(ic->ic_ht_gf_sta_assoc > 0);
                ic->ic_ht_gf_sta_assoc--;
            }
#if ATH_TxBF_DYNAMIC_LOF_ON_N_CHAIN_MASK
            iee80211_txbf_loforce_check(ni,0);
#endif
            if ((ni->ni_chwidth == IEEE80211_CWM_WIDTH40) || (ni->ni_chwidth == IEEE80211_CWM_WIDTH80))
	      ic->ic_ht40_sta_assoc--;
	  }
    

        if ((IEEE80211_IS_CHAN_ANYG(vap->iv_bsschan) ||
            IEEE80211_IS_CHAN_11NG(vap->iv_bsschan))  && !IEEE80211_IS_TDLS_NODE(ni))
            ieee80211_node_leave_11g(ni);

        ieee80211_admctl_node_leave(vap, ni);

        /*
         * Cleanup station state.  In particular clear various state that 
         * might otherwise be reused if the node is reused before the
         * reference count goes to zero (and memory is reclaimed).
         *
         * If ni is not in node table, it has been reclaimed in another thread.
         */
        retval = ieee80211_sta_leave(ni);

        IEEE80211_COMM_UNLOCK(ic);
        IEEE80211_NODE_STATE_UNLOCK(ni);
        IEEE80211_DELETE_NODE_TARGET(ni, ic, vap, 0);
    } else {
        ieee80211_admctl_node_leave(vap, ni);
        retval = ieee80211_sta_leave(ni);
        IEEE80211_NODE_STATE_UNLOCK(ni);
    }

    if ((ni->ni_flags & IEEE80211_NODE_HT) && 
        (ni->ni_flags & IEEE80211_NODE_40_INTOLERANT)) {
        ieee80211_change_cw(ic);
    }

    return retval;
}
Exemplo n.º 7
0
/* End: gengzj added end */
int
wlan_vap_delete(wlan_if_t vaphandle)
{
    struct ieee80211vap *vap = vaphandle;
    struct ieee80211com *ic = vap->iv_ic;

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD,IEEE80211_MSG_DEBUG,
                         "%s : enter. vaphandle=0x%x\n",
                         __func__,
                         vaphandle
                        );

    ieee80211_vap_pause_vdetach(ic,vap);

    IEEE80211_COMM_LOCK(ic);
    /* Begin: gengzj added for wifipos 2013-11-26 */
    /*AUTELAN-Added-begin:Added by pengdecai for wifi scan locate function*/
#if 0
    if((NULL != vap->iv_scan_locate) && \
            (NULL != vap->iv_scan_locate->sl_sock))
    {
        //	printk("driver:fun %s  vap->iv_scan_locate->sl_sock= %p\n",__func__, vap->iv_scan_locate->sl_sock);
        vap->iv_locate = 0;
        if(NULL != vap->iv_scan_locate->sl_sock) {
            OS_SOCKET_RELEASE(vap->iv_scan_locate->sl_sock);
        }
        //free scan locate struct
        OS_FREE(vap->iv_scan_locate);
        vap->iv_scan_locate = NULL;
    }
#endif
    /*AUTELAN-Added-end:Added by pengdecai for wifi scan locate function*/
    /* End: gengzj added end */

#ifdef MAGPIE_HIF_GMAC
    if (ic->ic_chanchange_cnt)
        ic->ic_chanchange_cnt -= ic->ic_chanchange_tbtt;
#endif
    if (ieee80211_vap_deleted_is_clear(vap)) /* if not deleted then it is on the list */
    {
        TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next);
        if (TAILQ_EMPTY(&ic->ic_vaps))      /* reset to supported mode */
            ic->ic_opmode = IEEE80211_M_STA;
        ieee80211_vap_deleted_set(vap); /* mark it as deleted */
        IEEE80211_COMM_UNLOCK(ic);

        /*
         * In case iv_bss was not stopped or is in scanning.
         * TBD: BSS should have been stopped now. We can save the time for stop bss again.
         */
        wlan_mlme_stop_bss(vap,
                           WLAN_MLME_STOP_BSS_F_SEND_DEAUTH        |
                           WLAN_MLME_STOP_BSS_F_CLEAR_ASSOC_STATE  |
                           WLAN_MLME_STOP_BSS_F_WAIT_RX_DONE       |
                           WLAN_MLME_STOP_BSS_F_NO_RESET);

        /*zhaoyang1 transplant from 717*/
        /*suzhaoyu add for customer online-traffic limit*/
        OS_FREE_TIMER(&vap->online_traffic_timer);
        /*suzhaoyu addend*/
        /*zhaoyang1 transplant end*/
        ieee80211_sta_leave(vap->iv_bss);
        ieee80211_node_vdetach(vap);
    } else {
        IEEE80211_COMM_UNLOCK(ic);
    }

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD,IEEE80211_MSG_DEBUG,
                         "%s : exit. vaphandle=0x%x\n",
                         __func__,
                         vaphandle
                        );
    return 0;
}
Exemplo n.º 8
0
/*
 * External UMAC Interface
 */
wlan_if_t
wlan_vap_create(wlan_dev_t            devhandle,
                enum ieee80211_opmode opmode,
                int                   scan_priority_base,
                int                   flags,
                u_int8_t              *bssid)
{
#if ATH_SUPPORT_FLOWMAC_MODULE
#define FLOWMAC_FLOWCONTROL_VAP 1
#define FLOWMAC_FLOWCONTROL_ETH 2
#endif
    struct ieee80211com *ic = devhandle;
    struct ieee80211vap *vap;

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD, IEEE80211_MSG_DEBUG,
                         "%s : enter. devhandle=0x%x, opmode=%s, flags=0x%x\n",
                         __func__,
                         devhandle,
                         ieee80211_opmode2string(opmode),
                         flags
                        );

    vap = ic->ic_vap_create(ic, opmode, scan_priority_base, flags, bssid);
    if (vap == NULL) {
        printk("%s: failed to create a vap object\n", __func__);
        return NULL;
    }

    ieee80211_vap_pause_late_vattach(ic,vap);
    ieee80211_resmgr_vattach(ic->ic_resmgr, vap);

    ieee80211_vap_deleted_clear(vap); /* clear the deleted */

    /* when all  done,  add vap to queue */
    IEEE80211_COMM_LOCK(ic);
    TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next);
    IEEE80211_COMM_UNLOCK(ic);

    IEEE80211_DPRINTF_IC(ic, IEEE80211_VERBOSE_LOUD, IEEE80211_MSG_DEBUG,
                         "%s : exit. devhandle=0x%x, opmode=%s, flags=0x%x.\n",
                         __func__,
                         devhandle,
                         ieee80211_opmode2string(opmode),
                         flags
                        );
    /* Begin: gengzj added for wifipos 2013-11-26 */
    /*AUTELAN-Added-begin:Added by pengdecai for wifi scan locate function*/
    vap->iv_locate = 0;
    vap->iv_sl_debug = 0;
    vap->iv_sl_asinfo = 0;
    vap->iv_sl_pckcnt = 0;
    /*AUTELAN-Added-end:Added by pengdecai for wifi scan locate function*/
    /* End: gengzj added end */
    /* TODO FIXME
    *  To check the ath layer flow control status in softc and the create
    *  enable or disable the flow control status in vap
    */
#if ATH_SUPPORT_FLOWMAC_MODULE
    vap->iv_flowmac = FLOWMAC_FLOWCONTROL_VAP | FLOWMAC_FLOWCONTROL_ETH;
#endif
    ieee80211_vap_cache_attach(vap); //added by duanmingzhe for 80211 cache

    /* Begin: Added by wangjia, for traffic limit. 2012-10-25. */
    ieee80211_tl_vap_init(vap);
    /* End: Added by wangjia, for traffic limit. 2012-10-25. */

    /*zhaoyang1 transplant from 717*/
    /*Begin:Added by duanmingzhe for user isolation*/
    vap->iv_switch = 0;
    /*End:Added by duanmingzhe for user isolation*/
    /*Begin:Add by duanmingzhe for develop the policy of mac binding*/
    vap->vap_dhcp_enable = 0;
    vap->vap_ip_auto_learning = 0;
    vap->vap_pppoe_enable = 0;
    /*End:Add by duanmingzhe for develop the policy of mac binding*/
    /*zhaoyang add for noisefloor switch when channel 0*/
    vap->noisefloor_enable = 1;
    /*zhaoyang add end*/
    /*zhaoyang modify for add rd_trap switch*/
#if ATH_SUPPORT_WAPI
    vap->rd_trap = 0;
#endif
    /*zhaoyang modify end*/
    /*suzhaoyu add for customer online-traffic limit*/
    vap->lowest_traffic_limit_switch = 0;
    vap->lowest_traffic_limit_threshold = 0;
    vap->lowest_traffic_limit_timelength =5;
    OS_INIT_TIMER(ic->ic_osdev, &(vap->online_traffic_timer), ieee80211_online_traffic_check, (void *) (vap));
    /*suzhaoyu addend*/
    /*zhaoyang1 transplant end*/
    /*<begin : transplant by caizhibang  from apv5*/
    /*yanggs add for thinap wds*/
    vap->vap_wds = 0;
    /*yanggs add end*/
    /*end : transplant by caizhibang from apv5 >*/
    /*zhaoyang modify for default disable UAPSD*/
    IEEE80211_VAP_UAPSD_DISABLE(vap);
    /*zhaoyang modify end*/
    return vap;
}