예제 #1
0
/*
 * Handle a station leaving an 11g network.
 */
static void
ieee80211_node_leave_11g(struct ieee80211com *ic, struct ieee80211_node *ni)
{
	if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
#ifdef DIAGNOSTIC
		if (ic->ic_longslotsta == 0) {
			panic("bogus long slot station count %d",
			    ic->ic_longslotsta);
		}
#endif
		/* leaving STA did not support short slot time */
		if (--ic->ic_longslotsta == 0) {
			/*
			 * All associated STAs now support short slot time, so
			 * enable this feature and give the driver a chance to
			 * reconfigure the hardware. Notice that IBSS always
			 * use a long slot time.
			 */
			if ((ic->ic_caps & IEEE80211_C_SHSLOT) &&
			    ic->ic_opmode != IEEE80211_M_IBSS)
				ieee80211_set_shortslottime(ic, 1);
		}
		IEEE80211_DPRINTF(("[%s] long slot time station leaves, "
		    "count now %d\n", ether_sprintf(ni->ni_macaddr),
		    ic->ic_longslotsta));
	}

	if (!(ni->ni_flags & IEEE80211_NODE_ERP)) {
#ifdef DIAGNOSTIC
		if (ic->ic_nonerpsta == 0) {
			panic("bogus non-ERP station count %d\n",
			    ic->ic_nonerpsta);
		}
#endif
		/* leaving STA was non-ERP */
		if (--ic->ic_nonerpsta == 0) {
			/*
			 * All associated STAs are now ERP capable, disable use
			 * of protection and re-enable short preamble support.
			 */
			ic->ic_flags &= ~IEEE80211_F_USEPROT;
			if (ic->ic_caps & IEEE80211_C_SHPREAMBLE)
				ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
		}
		IEEE80211_DPRINTF(("[%s] non-ERP station leaves, "
		    "count now %d\n", ether_sprintf(ni->ni_macaddr),
		    ic->ic_nonerpsta));
	}
}
예제 #2
0
/*
 * Handle a station joining an 11g network.
 */
static void
ieee80211_node_join_11g(struct ieee80211com *ic, struct ieee80211_node *ni)
{
	if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
		/*
		 * Joining STA doesn't support short slot time.  We must
		 * disable the use of short slot time for all other associated
		 * STAs and give the driver a chance to reconfigure the
		 * hardware.
		 */
		if (++ic->ic_longslotsta == 1) {
			if (ic->ic_caps & IEEE80211_C_SHSLOT)
				ieee80211_set_shortslottime(ic, 0);
		}
		IEEE80211_DPRINTF(("[%s] station needs long slot time, "
		    "count %d\n", ether_sprintf(ni->ni_macaddr),
		    ic->ic_longslotsta));
	}

	if (!ieee80211_iserp_sta(ni)) {
		/*
		 * Joining STA is non-ERP.
		 */
		ic->ic_nonerpsta++;

		IEEE80211_DPRINTF(("[%s] station is non-ERP, %d non-ERP "
		    "stations associated\n", ether_sprintf(ni->ni_macaddr),
		    ic->ic_nonerpsta));

		/* must enable the use of protection */
		if (ic->ic_protmode != IEEE80211_PROT_NONE) {
			IEEE80211_DPRINTF(("%s: enable use of protection\n",
			    __func__));
			ic->ic_flags |= IEEE80211_F_USEPROT;
		}

		if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
			ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
	} else
		ni->ni_flags |= IEEE80211_NODE_ERP;
}
예제 #3
0
/*
 * Handle a station leaving an 11g network.
 */
static void
ieee80211_node_leave_11g(struct ieee80211_node *ni)
{
    struct ieee80211com *ic = ni->ni_ic;
    struct ieee80211vap *vap = ni->ni_vap;
   
    KASSERT((IEEE80211_IS_CHAN_ANYG(vap->iv_bsschan)
             || IEEE80211_IS_CHAN_11NG(vap->iv_bsschan)),
            ("not in 11g, bss %u:0x%x, curmode %u", vap->iv_bsschan->ic_freq,
             vap->iv_bsschan->ic_flags, ic->ic_curmode));

    KASSERT((ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP ||
             ni->ni_vap->iv_opmode == IEEE80211_M_BTAMP), (" node leave in invalid opmode "));

    /*
     * If a long slot station do the slot time bookkeeping.
     */
    if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {
        if (ic->ic_longslotsta) {
           ic->ic_longslotsta--; 
           IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
                       "long slot time station leaves, count now %d",
                       ic->ic_longslotsta);
        } else {
#ifdef NOT_YET
           KASSERT(ic->ic_longslotsta > 0,
                ("bogus long slot station count %d", ic->ic_longslotsta));
#endif
           IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
                "bogus long slot station count %d", ic->ic_longslotsta);
        }

        if (ic->ic_longslotsta == 0) {
            /*
             * Re-enable use of short slot time if supported
             * and not operating in IBSS mode (per spec).
             */
            if (ic->ic_caps & IEEE80211_C_SHSLOT) {
                IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
                                  "%s: re-enable use of short slot time\n",
                                  __func__);
                ieee80211_set_shortslottime(ic, 1);
            }
        }
    }
    
    /*
     * If a non-ERP station do the protection-related bookkeeping.
     */
    if ((ni->ni_flags & IEEE80211_NODE_ERP) == 0) {
        KASSERT(ic->ic_nonerpsta > 0, ("bogus non-ERP station count %d", ic->ic_nonerpsta));
        ic->ic_nonerpsta--;
        IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
                       "non-ERP station leaves, count now %d", ic->ic_nonerpsta);
        if (ic->ic_nonerpsta == 0) {
	    struct ieee80211vap *tmpvap;
            ieee80211_update_erp_info(vap); 
            /* XXX verify mode? */
            if (ic->ic_caps & IEEE80211_C_SHPREAMBLE) {
                IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
                                  "%s: re-enable use of short preamble\n",
                                  __func__);
                ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
                ic->ic_flags &= ~IEEE80211_F_USEBARKER;
            }
 	    TAILQ_FOREACH(tmpvap, &(ic)->ic_vaps, iv_next)
		ieee80211_vap_erpupdate_set(tmpvap);
        }
    }
}
예제 #4
0
/*
 * Handle a station joining an 11g network.
 */
static void
ieee80211_node_join_11g(struct ieee80211_node *ni)
{
    struct ieee80211com *ic = ni->ni_ic;
    struct ieee80211vap *vap = ni->ni_vap;

    KASSERT((IEEE80211_IS_CHAN_ANYG(vap->iv_bsschan) ||
             IEEE80211_IS_CHAN_11NG(vap->iv_bsschan)),
            ("not in 11g, bss %u:0x%x, curmode %u", vap->iv_bsschan->ic_freq,
             vap->iv_bsschan->ic_flags, ic->ic_curmode));

    KASSERT((ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP ||
             ni->ni_vap->iv_opmode == IEEE80211_M_BTAMP), (" node join in invalid opmode "));
    /*
     * Station isn't capable of short slot time.  Bump
     * the count of long slot time stations and disable
     * use of short slot time.  Note that the actual switch
     * over to long slot time use may not occur until the
     * next beacon transmission (per sec. 7.3.1.4 of 11g).
     */
    if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) == 0) {
        ic->ic_longslotsta++;
        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni,
                       "station needs long slot time, count %d",
                       ic->ic_longslotsta);
        /* XXX vap's w/ conflicting needs won't work */
        if (!IEEE80211_IS_CHAN_108G(vap->iv_bsschan)) {
            /*
             * Don't force slot time when switched to turbo
             * mode as non-ERP stations won't be present; this
             * need only be done when on the normal G channel.
             */
            ieee80211_set_shortslottime(ic, 0);
        }
    }
    /*
     * If the new station is not an ERP station
     * then bump the counter and enable protection
     * if configured.
     */
    if (!ieee80211_iserp_rateset(ic, &ni->ni_rates)) {
        ic->ic_nonerpsta++;
        IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni,
                       "station is !ERP, %d non-ERP stations associated",
                       ic->ic_nonerpsta);
            /*
             * If protection is configured, enable it.
             */
            if (ic->ic_protmode != IEEE80211_PROT_NONE) {
                IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_ASSOC,
                                  "%s: enable use of protection\n", __func__);
                ic->ic_flags |= IEEE80211_F_USEPROT;
                ic->ic_update_protmode(ic);
            }
            /*
             * If station does not support short preamble
             * then we must enable use of Barker preamble.
             */
            if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) == 0) {
                IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ASSOC, ni,
                               "%s", "station needs long preamble");
                ic->ic_flags |= IEEE80211_F_USEBARKER;
                ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
            }

            /* Update ERP element if this is first non ERP station */
            if (ic->ic_nonerpsta == 1) {
	          struct ieee80211vap *tmpvap;
	          TAILQ_FOREACH(tmpvap, &(ic)->ic_vaps, iv_next)
		    ieee80211_vap_erpupdate_set(tmpvap);
	      }
    } else
        ni->ni_flags |= IEEE80211_NODE_ERP;
}
예제 #5
0
void ieee80211_mlme_join_infra_continue(struct ieee80211vap *vap, int32_t status)
{
    struct ieee80211com           *ic = vap->iv_ic;
    struct ieee80211_node         *ni;
    struct ieee80211_mlme_priv    *mlme_priv = vap->iv_mlme_priv;
    u_int32_t                     join_timeout_ms;

    if (mlme_priv->im_request_type != MLME_REQ_JOIN_INFRA) {
        IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s : im_request_type != JOIN_INFRA\n", 
            __func__);
        return;
    }
    
    if (status != EOK) {
        mlme_priv->im_request_type = MLME_REQ_NONE;
        IEEE80211_DELIVER_EVENT_MLME_JOIN_COMPLETE_INFRA(vap, IEEE80211_STATUS_UNSPECIFIED);
        return;
     }
    
    /* iv_bss is valid only after ieee80211_sta_join */ 
    ni = vap->iv_bss;

    IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s ni=%02X:%02X:%02X:%02X:%02X:%02X\n", 
        __func__,
        ni->ni_macaddr[0], ni->ni_macaddr[1], ni->ni_macaddr[2],
        ni->ni_macaddr[3], ni->ni_macaddr[4], ni->ni_macaddr[5]);
    
    /* Update erp info */
    if (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)
        ic->ic_flags |= IEEE80211_F_USEPROT;
    else
        ic->ic_flags &= ~IEEE80211_F_USEPROT;
    ic->ic_update_protmode(ic);

    if(ni->ni_erp & IEEE80211_ERP_LONG_PREAMBLE)
        ic->ic_flags |= IEEE80211_F_USEBARKER;
    else
        ic->ic_flags &= (~IEEE80211_F_USEBARKER);

    /* Update slot time info */
    ieee80211_set_shortslottime(ic,
                                IEEE80211_IS_CHAN_A(vap->iv_bsschan) ||
                                IEEE80211_IS_CHAN_11NA(vap->iv_bsschan) ||
                                (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));

    /* Put underlying H/W to JOIN state */
    ieee80211_vap_join(vap);

#ifdef ATH_SUPPORT_TxBF
    ieee80211_init_txbf(ic, ni);
#endif
    /* Send a direct probe to increase the odds of receiving a probe response */
    ieee80211_send_probereq(ni, ic->ic_myaddr, ni->ni_bssid,
                            ni->ni_bssid, ni->ni_essid, ni->ni_esslen,
                            vap->iv_opt_ie.ie, vap->iv_opt_ie.length);

    /* Set the timeout timer for Join Failure case. */
    join_timeout_ms = IEEE80211_TU_TO_MS(mlme_priv->im_timeout * ni->ni_intval);
    IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Setting Join Timeout timer for %d ms\n", __func__, join_timeout_ms);
    OS_SET_TIMER(&mlme_priv->im_timeout_timer, join_timeout_ms);

    /* Set the appropriate filtering function and wait for Join Beacon */
    MLME_WAIT_FOR_BSS_JOIN(mlme_priv);
}
예제 #6
0
/*zhaoyang1 transplant end*/
int
wlan_set_param(wlan_if_t vaphandle, ieee80211_param param, u_int32_t val)
{
    struct ieee80211vap *vap = vaphandle;
    struct ieee80211com *ic = vap->iv_ic;
	struct ieee80211_node_table *nt = &ic->ic_sta;
    int retv = 0;

    switch (param) {
    case IEEE80211_AUTO_ASSOC:
       if (val)
            IEEE80211_VAP_AUTOASSOC_ENABLE(vap);
        else
            IEEE80211_VAP_AUTOASSOC_DISABLE(vap);
        break;

    case IEEE80211_SAFE_MODE:
        if (val)
            IEEE80211_VAP_SAFEMODE_ENABLE(vap);
        else
            IEEE80211_VAP_SAFEMODE_DISABLE(vap);
        break;

    case IEEE80211_SEND_80211:
        if (val)
            IEEE80211_VAP_SEND_80211_ENABLE(vap);
        else
            IEEE80211_VAP_SEND_80211_DISABLE(vap);
        break;

    case IEEE80211_RECEIVE_80211:
        if (val)
            IEEE80211_VAP_DELIVER_80211_ENABLE(vap);
        else
            IEEE80211_VAP_DELIVER_80211_DISABLE(vap);
        break;

    case IEEE80211_FEATURE_DROP_UNENC:
        if (val)
            IEEE80211_VAP_DROP_UNENC_ENABLE(vap);
        else
            IEEE80211_VAP_DROP_UNENC_DISABLE(vap);
        break;

#ifdef ATH_COALESCING
    case IEEE80211_FEATURE_TX_COALESCING:
        ic->ic_tx_coalescing = val;
        break;
#endif
    case IEEE80211_SHORT_PREAMBLE:
        if (val)
           IEEE80211_ENABLE_CAP_SHPREAMBLE(ic);
        else
           IEEE80211_DISABLE_CAP_SHPREAMBLE(ic);
         retv = EOK;
        break;    
    
    case IEEE80211_SHORT_SLOT:
        if (val)
            ieee80211_set_shortslottime(ic, 1);
        else
            ieee80211_set_shortslottime(ic, 0);
        break;

    case IEEE80211_RTS_THRESHOLD:
        /* XXX This may force us to flush any packets for which we are 
           might have already calculated the RTS */
        if (val > IEEE80211_RTS_MAX)
            vap->iv_rtsthreshold = IEEE80211_RTS_MAX;
        else
            vap->iv_rtsthreshold = (u_int16_t)val;
        break;

    case IEEE80211_FRAG_THRESHOLD:
        /* XXX We probably should flush our tx path when changing fragthresh */
        if (val > 2346)
            vap->iv_fragthreshold = 2346;
        else if (val < 256)
            vap->iv_fragthreshold = 256;
        else
            vap->iv_fragthreshold = (u_int16_t)val;
        break;

    case IEEE80211_BEACON_INTVAL:
        ic->ic_intval = (u_int16_t)val;
        LIMIT_BEACON_PERIOD(ic->ic_intval);
        break;

#if ATH_SUPPORT_AP_WDS_COMBO
    case IEEE80211_NO_BEACON:
        vap->iv_no_beacon = (u_int8_t) val;
        ic->ic_set_config(vap);
        break;
#endif
    case IEEE80211_LISTEN_INTVAL:
        ic->ic_lintval = 1;
        vap->iv_bss->ni_lintval = ic->ic_lintval;
        break;

    case IEEE80211_ATIM_WINDOW:
        LIMIT_BEACON_PERIOD(val);
        vap->iv_atim_window = (u_int8_t)val;
        break;

    case IEEE80211_DTIM_INTVAL:
        LIMIT_DTIM_PERIOD(val);
        vap->iv_dtim_period = (u_int8_t)val;
        break;

    case IEEE80211_BMISS_COUNT_RESET:
        vap->iv_bmiss_count_for_reset = (u_int8_t)val;
        break;

    case IEEE80211_BMISS_COUNT_MAX:
        vap->iv_bmiss_count_max = (u_int8_t)val;
        break;

    case IEEE80211_TXPOWER:
        break;

    case IEEE80211_MULTI_DOMAIN:
        if(!ic->ic_country.isMultidomain)
            return -EINVAL;
        
        if (val)
            ic->ic_multiDomainEnabled = 1;
        else
            ic->ic_multiDomainEnabled = 0;
        break;

    case IEEE80211_MSG_FLAGS:
        /*
         * ic_debug will be overwritten every time the VAP debug level is changed.
         */
        ic->ic_debug = val;
        vap->iv_debug = ic->ic_debug;
        break;

    case IEEE80211_FEATURE_WMM:
        if (!(ic->ic_caps & IEEE80211_C_WME))
            return -EINVAL;
        
        if (val)
            ieee80211_vap_wme_set(vap);
        else
            ieee80211_vap_wme_clear(vap);
        break;

    case IEEE80211_FEATURE_PRIVACY:
        if (val)
            IEEE80211_VAP_PRIVACY_ENABLE(vap);
        else
            IEEE80211_VAP_PRIVACY_DISABLE(vap);
        break;

    case IEEE80211_FEATURE_WMM_PWRSAVE:
        /*
         * NB: AP WMM power save is a compilation option,
         * and can not be turned on/off at run time.
         */
        if (vap->iv_opmode != IEEE80211_M_STA)
            return -EINVAL;

        if (val)
            ieee80211_set_wmm_power_save(vap, 1);
        else
            ieee80211_set_wmm_power_save(vap, 0);
        break;

    case IEEE80211_FEATURE_UAPSD:
        if (vap->iv_opmode == IEEE80211_M_STA) {
            ieee80211_set_uapsd_flags(vap, (u_int8_t)(val & WME_CAPINFO_UAPSD_ALL));
            return ieee80211_pwrsave_uapsd_set_max_sp_length(vap, ((val & WME_CAPINFO_UAPSD_MAXSP_MASK)) >> WME_CAPINFO_UAPSD_MAXSP_SHIFT );
        }
        else {
            if (IEEE80211_IS_UAPSD_ENABLED(ic)) {