Beispiel #1
0
/*
 * Detach net80211 state on device detach.  Tear down
 * all vap's and reclaim all common state prior to the
 * device state going away.  Note we may call back into
 * driver; it must be prepared for this.
 */
void
ieee80211_ifdetach(struct ieee80211com *ic)
{
	struct ifnet *ifp = ic->ic_ifp;
	struct ieee80211vap *vap;

	if_detach(ifp);

	while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
		ieee80211_vap_destroy(vap);
	ieee80211_waitfor_parent(ic);

	ieee80211_sysctl_detach(ic);
	ieee80211_dfs_detach(ic);
	ieee80211_regdomain_detach(ic);
	ieee80211_scan_detach(ic);
#ifdef IEEE80211_SUPPORT_SUPERG
	ieee80211_superg_detach(ic);
#endif
	ieee80211_ht_detach(ic);
	/* NB: must be called before ieee80211_node_detach */
	ieee80211_proto_detach(ic);
	ieee80211_crypto_detach(ic);
	ieee80211_power_detach(ic);
	ieee80211_node_detach(ic);

	ifmedia_removeall(&ic->ic_media);
	taskqueue_free(ic->ic_tq);
}
Beispiel #2
0
/*
 * Detach net80211 state on device detach.  Tear down
 * all vap's and reclaim all common state prior to the
 * device state going away.  Note we may call back into
 * driver; it must be prepared for this.
 */
void
ieee80211_ifdetach(struct ieee80211com *ic)
{
	struct ifnet *ifp = ic->ic_ifp;
	struct ieee80211vap *vap;

	/*
	 * This detaches the main interface, but not the vaps.
	 * Each VAP may be in a separate VIMAGE.
	 */
	CURVNET_SET(ifp->if_vnet);
	if_detach(ifp);
	CURVNET_RESTORE();

	/*
	 * The VAP is responsible for setting and clearing
	 * the VIMAGE context.
	 */
	while ((vap = TAILQ_FIRST(&ic->ic_vaps)) != NULL)
		ieee80211_vap_destroy(vap);
	ieee80211_waitfor_parent(ic);

	ieee80211_sysctl_detach(ic);
	ieee80211_dfs_detach(ic);
	ieee80211_regdomain_detach(ic);
	ieee80211_scan_detach(ic);
#ifdef IEEE80211_SUPPORT_SUPERG
	ieee80211_superg_detach(ic);
#endif
	ieee80211_ht_detach(ic);
	/* NB: must be called before ieee80211_node_detach */
	ieee80211_proto_detach(ic);
	ieee80211_crypto_detach(ic);
	ieee80211_power_detach(ic);
	ieee80211_node_detach(ic);

	/* XXX VNET needed? */
	ifmedia_removeall(&ic->ic_media);

	taskqueue_free(ic->ic_tq);
	IEEE80211_TX_LOCK_DESTROY(ic);
	IEEE80211_LOCK_DESTROY(ic);
}
Beispiel #3
0
int
ieee80211_ifattach(struct ieee80211com *ic, IEEE80211_REG_PARAMETERS *ieee80211_reg_parm)
{
    u_int8_t bcast[IEEE80211_ADDR_LEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
    int error = 0;

    ic->ic_reg_parm = *ieee80211_reg_parm;
    /* set up broadcast address */
    IEEE80211_ADDR_COPY(ic->ic_broadcast, bcast);

    /* initialize channel list */
    ieee80211_update_channellist(ic, 0);

    /* initialize rate set */
    ieee80211_init_rateset(ic);

    /* validate ic->ic_curmode */
    if (!IEEE80211_SUPPORT_PHY_MODE(ic, ic->ic_curmode))
        ic->ic_curmode = IEEE80211_MODE_AUTO;

    /* setup initial channel settings */
    ic->ic_curchan = ieee80211_get_channel(ic, 0); /* arbitrarily pick the first channel */

    /* Enable marking of dfs by default */
    ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;

    if (ic->ic_reg_parm.htEnableWepTkip) {
        ieee80211_ic_wep_tkip_htrate_set(ic);
    } else {
        ieee80211_ic_wep_tkip_htrate_clear(ic);
    }

    if (ic->ic_reg_parm.htVendorIeEnable)
        IEEE80211_ENABLE_HTVIE(ic);

    /* whether to ignore 11d beacon */
    if (ic->ic_reg_parm.ignore11dBeacon)
        IEEE80211_ENABLE_IGNORE_11D_BEACON(ic);

    if (ic->ic_reg_parm.disallowAutoCCchange) {
        ieee80211_ic_disallowAutoCCchange_set(ic);
    }
    else {
        ieee80211_ic_disallowAutoCCchange_clear(ic);
    }

    (void) ieee80211_setmode(ic, ic->ic_curmode, ic->ic_opmode);

    ic->ic_intval = IEEE80211_BINTVAL_DEFAULT; /* beacon interval */
    ic->ic_set_beacon_interval(ic);

    ic->ic_lintval = 1;         /* listen interval */
    ic->ic_lintval_assoc = IEEE80211_LINTVAL_MAX; /* listen interval to use in association */
    ic->ic_bmisstimeout = IEEE80211_BMISS_LIMIT * ic->ic_intval;
    TAILQ_INIT(&ic->ic_vaps);

    ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;

    /* Intialize WDS Auto Detect mode */
    ic->ic_flags_ext |= IEEE80211_FEXT_WDS_AUTODETECT;

	/*
	** Enable the 11d country code IE by default
	*/

	ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;

    /* setup CWM configuration */
    ic->ic_cwm_set_mode(ic, ic->ic_reg_parm.cwmMode);
    ic->ic_cwm_set_extoffset(ic, ic->ic_reg_parm.cwmExtOffset);
    ic->ic_cwm_set_extprotmode(ic, ic->ic_reg_parm.cwmExtProtMode);
    ic->ic_cwm_set_extprotspacing(ic, ic->ic_reg_parm.cwmExtProtSpacing);

#if tbd
    /* XXX - TODO - move these into ath layer */
#else
    ic->ic_cwm_set_enable(ic, ic->ic_reg_parm.cwmEnable);
    ic->ic_cwm_set_extbusythreshold(ic, ic->ic_reg_parm.cwmExtBusyThreshold);
#endif

    ic->ic_enable2GHzHt40Cap = ic->ic_reg_parm.enable2GHzHt40Cap;

#ifdef ATH_COALESCING
    ic->ic_tx_coalescing     = ic->ic_reg_parm.txCoalescingEnable;
#endif
    ic->ic_ignoreDynamicHalt = ic->ic_reg_parm.ignoreDynamicHalt;

    /* default to auto ADDBA mode */
    ic->ic_addba_mode = ADDBA_MODE_AUTO;

    if (ic->ic_reg_parm.ht20AdhocEnable) {
        /*
         * Support HT rates in Ad hoc connections.
         */
        if (IEEE80211_SUPPORT_PHY_MODE(ic, IEEE80211_MODE_11NA_HT20) ||
            IEEE80211_SUPPORT_PHY_MODE(ic, IEEE80211_MODE_11NG_HT20)) {
            ieee80211_ic_ht20Adhoc_set(ic);

            if (ic->ic_reg_parm.htAdhocAggrEnable) {
                ieee80211_ic_htAdhocAggr_set(ic);
            }
        }
    }

    if (ic->ic_reg_parm.ht40AdhocEnable) {
        /*
         * Support HT rates in Ad hoc connections.
         */
        if (IEEE80211_SUPPORT_PHY_MODE(ic, IEEE80211_MODE_11NA_HT40PLUS) ||
            IEEE80211_SUPPORT_PHY_MODE(ic, IEEE80211_MODE_11NA_HT40MINUS) ||
            IEEE80211_SUPPORT_PHY_MODE(ic, IEEE80211_MODE_11NG_HT40PLUS) ||
            IEEE80211_SUPPORT_PHY_MODE(ic, IEEE80211_MODE_11NG_HT40MINUS)) {
            ieee80211_ic_ht40Adhoc_set(ic);

            if (ic->ic_reg_parm.htAdhocAggrEnable) {
                ieee80211_ic_htAdhocAggr_set(ic);
            }
        }
    }

    OS_INIT_TIMER(ic->ic_osdev, &(ic->ic_inact_timer), ieee80211_inact_timeout, (void *) (ic));
#if UMAC_SUPPORT_WNM
    OS_INIT_TIMER(ic->ic_osdev, &(ic->ic_bssload_timer), ieee80211_bssload_timeout, (void *) (ic));
#endif

    if (ic->ic_reg_parm.disable2040Coexist) {
        ic->ic_flags |= IEEE80211_F_COEXT_DISABLE;
    } else {
        ic->ic_flags &= ~IEEE80211_F_COEXT_DISABLE;
    }

    /* setup other modules */

    /* The TSF Timer module is required when P2P or Off-channel support are required */
    ic->ic_tsf_timer = ieee80211_tsf_timer_attach(ic);
#if UMAC_SUPPORT_TDLS_CHAN_SWITCH
     /* TDLS off-channel support requires TSF timer */
    if (ic->ic_tsf_timer) {
        ieee80211_ic_off_channel_support_set(ic);
    }
    else {
        ieee80211_ic_off_channel_support_clear(ic);
    }
#else
    ieee80211_ic_off_channel_support_clear(ic);
#endif

    ieee80211_p2p_attach(ic);
    ieee80211_crypto_attach(ic);
    ieee80211_node_attach(ic);
    ieee80211_proto_attach(ic);
    ieee80211_power_attach(ic);
    ieee80211_mlme_attach(ic);
#if ATH_SUPPORT_DFS
    ieee80211_dfs_attach(ic);
#endif /* ATH_SUPPORT_DFS */

    if (IEEE80211_ENAB_AOW(ic))
        ieee80211_aow_attach(ic);

    error = ieee80211_scan_table_attach(ic, &(ic->ic_scan_table), ic->ic_osdev);
    if (error) {
        ieee80211_node_detach(ic);
        return error;
    }

    /*
     * By default overwrite probe response with beacon IE in scan entry.
     */
    ieee80211_ic_override_proberesp_ie_set(ic);
    error = ieee80211_scan_attach(&(ic->ic_scanner),
                          ic,
                          ic->ic_osdev,
                          ieee80211_is_connected,
                          ieee80211_is_txq_empty,
                          ieee80211_is_sw_txq_empty);
    if (error) {
        /* detach and free already allocated memory for scan */
        ieee80211_scan_table_detach(&(ic->ic_scan_table));
        ieee80211_node_detach(ic);
        return error;
    }

    ic->ic_resmgr = ieee80211_resmgr_create(ic, IEEE80211_RESMGR_MODE_SINGLE_CHANNEL);

    error = ieee80211_acs_attach(&(ic->ic_acs),
                          ic,
                          ic->ic_osdev);
    if (error) {
        /* detach and free already allocated memory for scan */
        ieee80211_scan_table_detach(&(ic->ic_scan_table));
        ieee80211_scan_detach(&(ic->ic_scanner));
        ieee80211_node_detach(ic);
        return error;
    }

    ic->ic_notify_tx_bcn_mgr = ieee80211_notify_tx_bcn_attach(ic);
    ieee80211_rptplacement_attach(ic);
    IEEE80211_TDLS_ATTACH(ic);
#if UMAC_SUPPORT_VI_DBG
    ieee80211_vi_dbg_attach(ic);
#endif
    ieee80211_quiet_attach(ic);
	ieee80211_admctl_attach(ic);

    /*
     * Perform steps that require multiple objects to be initialized.
     * For example, cross references between objects such as ResMgr and Scanner.
     */
    ieee80211_scan_attach_complete(ic->ic_scanner);
    ieee80211_resmgr_create_complete(ic->ic_resmgr);
    ieee80211_smartantenna_attach(ic);

    ieee80211_prdperfstats_attach(ic);

    ic->ic_get_ext_chan_info = ieee80211_get_extchan_info;

    /* initialization complete */
    ic->ic_initialized = 1;

    return 0;
}
Beispiel #4
0
void
ieee80211_ifdetach(struct ieee80211com *ic)
{
    if (!ic->ic_initialized) {
        return;
    }

    /*
     * Preparation for detaching objects.
     * For example, remove and cross references between objects such as those
     * between ResMgr and Scanner.
     */
    ieee80211_scan_detach_prepare(ic->ic_scanner);
    ieee80211_resmgr_delete_prepare(ic->ic_resmgr);

    OS_FREE_TIMER(&ic->ic_inact_timer);
#if UMAC_SUPPORT_WNM
    OS_FREE_TIMER(&ic->ic_bssload_timer);
#endif

    /* all the vaps should have been deleted now */
    ASSERT(TAILQ_FIRST(&ic->ic_vaps) == NULL);

    ieee80211_scan_table_detach(&(ic->ic_scan_table));
    ieee80211_node_detach(ic);
    ieee80211_quiet_detach(ic);
	ieee80211_admctl_detach(ic);

    if (IEEE80211_ENAB_AOW(ic))
        ieee80211_aow_detach(ic);

#if ATH_SUPPORT_DFS
    ieee80211_dfs_detach(ic);
#endif /* ATH_SUPPORT_DFS */
    ieee80211_proto_detach(ic);
    ieee80211_crypto_detach(ic);
    ieee80211_power_detach(ic);
    ieee80211_mlme_detach(ic);
    ieee80211_notify_tx_bcn_detach(ic->ic_notify_tx_bcn_mgr);
    ieee80211_resmgr_delete(ic->ic_resmgr);
    ieee80211_scan_detach(&(ic->ic_scanner));
    ieee80211_p2p_detach(ic);
    ieee80211_acs_detach(&(ic->ic_acs));
    ieee80211_rptplacement_detach(ic);
    IEEE80211_TDLS_DETACH(ic);
#if UMAC_SUPPORT_VI_DBG
    ieee80211_vi_dbg_detach(ic);
#endif
    ieee80211_smartantenna_detach(ic);

    ieee80211_prdperfstats_detach(ic);
    spin_lock_destroy(&ic->ic_lock);
    /* Detach TSF timer at the end to avoid assertion */
    if (ic->ic_tsf_timer) {
        ieee80211_tsf_timer_detach(ic->ic_tsf_timer);
        ic->ic_tsf_timer = NULL;
    }

    spin_lock_destroy(&ic->ic_lock);
    IEEE80211_STATE_LOCK_DESTROY(ic);
}