Exemple #1
0
static int __init
init_crypto_wep_test(void)
{
	struct ieee80211com ic;
	struct ieee80211vap vap;
	int i, pass, total;

	memset(&ic, 0, sizeof(ic));
	memset(&vap, 0, sizeof(vap));
	vap.iv_ic = ⁣
	if (debug)
		vap.iv_debug = IEEE80211_MSG_CRYPTO;
	ieee80211_crypto_attach(&ic);
	ieee80211_crypto_vattach(&vap);
	pass = 0;
	total = 0;
	for (i = 0; i < ARRAY_SIZE(weptests); i++)
		if (tests & (1 << i)) {
			total++;
			pass += runtest(&vap, &weptests[i]);
		}
	printk("%u of %u 802.11i WEP test vectors passed\n", pass, total);
	ieee80211_crypto_vdetach(&vap);
	ieee80211_crypto_detach(&ic);
	return (pass == total ? 0 : -ENXIO);
}
Exemple #2
0
static int __init
init_crypto_tkip_test(void)
{
	struct ieee80211com ic;

	memset(&ic, 0, sizeof(ic));
	if (debug)
		ic.msg_enable = IEEE80211_MSG_CRYPTO;
	ieee80211_crypto_attach(&ic);

	tkip_test(&ic);

	ieee80211_crypto_detach(&ic);
	return 0;
}
static int __init
init_crypto_wep_test(void)
{
	struct {
		struct ieee80211vap vap;
		struct ieee80211com ic;
		struct net_device netdev;
	} *buf;
	struct ieee80211vap *vap;
	int i, pass, total;

	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	vap = &buf->vap;
	vap->iv_ic = &buf->ic;
	vap->iv_dev = &buf->netdev;
	vap->iv_ic->ic_dev = vap->iv_dev;
	strncpy(vap->iv_dev->name, "WEP test", sizeof(vap->iv_dev->name) - 1);

	if (debug)
		vap->iv_debug = IEEE80211_MSG_CRYPTO;

	ieee80211_crypto_attach(vap->iv_ic);
	ieee80211_crypto_vattach(vap);

	pass = 0;
	total = 0;
	for (i = 0; i < ARRAY_SIZE(weptests); i++)
		if (tests & (1 << i)) {
			total++;
			pass += runtest(vap, &weptests[i]);
		}
	printk("%u of %u 802.11i WEP test vectors passed\n", pass, total);
	ieee80211_crypto_vdetach(vap);
	ieee80211_crypto_detach(vap->iv_ic);
	kfree(buf);
	return (pass == total ? 0 : -ENXIO);
}
static int __init
init_crypto_ccmp_test(void)
{
	struct ieee80211com *ic;
	struct ieee80211vap *vap;
	int i, pass, total;

	ic = kzalloc(sizeof(*ic), GFP_KERNEL);
	if (!ic)
		return -ENOMEM;

	ieee80211_crypto_attach(ic);

	vap = kzalloc(sizeof(*vap), GFP_KERNEL);
	if (!vap) {
		kfree(ic);
		return -ENOMEM;
	}

	vap->iv_ic = ic;
	if (debug)
		vap->iv_debug = IEEE80211_MSG_CRYPTO;

	ieee80211_crypto_vattach(vap);

	pass = 0;
	total = 0;
	for (i = 0; i < ARRAY_SIZE(ccmptests); i++)
		if (tests & (1 << i)) {
			total++;
			pass += runtest(vap, &ccmptests[i]);
		}
	printk("%u of %u 802.11i AES-CCMP test vectors passed\n", pass, total);
	ieee80211_crypto_vdetach(vap);
	ieee80211_crypto_detach(ic);
	kfree(vap);
	kfree(ic);
	return (pass == total ? 0 : -ENXIO);
}
Exemple #5
0
void
ieee80211_ifattach(struct ifnet *ifp)
{
	struct ieee80211com *ic = (void *)ifp;

	memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr,
		ETHER_ADDR_LEN);
	ether_ifattach(ifp);

	ifp->if_output = ieee80211_output;

#if NBPFILTER > 0
	bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11,
	    sizeof(struct ieee80211_frame_addr4));
#endif
	ieee80211_crypto_attach(ifp);

	ieee80211_channel_init(ifp);

	/* IEEE 802.11 defines a MTU >= 2290 */
	ifp->if_capabilities |= IFCAP_VLAN_MTU;

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

	if (ic->ic_lintval == 0)
		ic->ic_lintval = 100;		/* default sleep */
	ic->ic_bmisstimeout = 7*ic->ic_lintval;	/* default 7 beacons */
	ic->ic_dtim_period = 1;	/* all TIMs are DTIMs */

	LIST_INSERT_HEAD(&ieee80211com_head, ic, ic_list);
	ieee80211_node_attach(ifp);
	ieee80211_proto_attach(ifp);

	if_addgroup(ifp, "wlan");
	ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY;
}
Exemple #6
0
static int __init
init_crypto_ccmp_test(void)
{
#define	N(a)	(sizeof(a)/sizeof(a[0]))
	struct ieee80211com ic;
	int i, pass, total;

	memset(&ic, 0, sizeof(ic));
	if (debug)
		ic.msg_enable = IEEE80211_MSG_CRYPTO;
	ieee80211_crypto_attach(&ic);

	pass = 0;
	total = 0;
	for (i = 0; i < N(ccmptests); i++)
		if (tests & (1<<i)) {
			total++;
			pass += runtest(&ic, &ccmptests[i]);
		}
	printk("%u of %u 802.11i AES-CCMP test vectors passed\n", pass, total);
	ieee80211_crypto_detach(&ic);
	return (pass == total ? 0 : -1);
#undef N
}
Exemple #7
0
/*
 * Attach/setup the common net80211 state.  Called by
 * the driver on attach to prior to creating any vap's.
 */
void
ieee80211_ifattach(struct ieee80211com *ic,
	const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
	struct ifnet *ifp = ic->ic_ifp;
	struct sockaddr_dl *sdl;
	struct ifaddr *ifa;

	KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));

	TAILQ_INIT(&ic->ic_vaps);

	/* Create a taskqueue for all state changes */
	ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
	    taskqueue_thread_enqueue, &ic->ic_tq);
	taskqueue_start_threads(&ic->ic_tq, 1, TDPRI_KERN_DAEMON, -1,
	    "%s taskq", ifp->if_xname);
	/*
	 * Fill in 802.11 available channel set, mark all
	 * available channels as active, and pick a default
	 * channel if not already specified.
	 */
	ieee80211_media_init(ic);

	ic->ic_update_mcast = null_update_mcast;
	ic->ic_update_promisc = null_update_promisc;

	ic->ic_hash_key = karc4random();
	ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
	ic->ic_lintval = ic->ic_bintval;
	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;

	ieee80211_crypto_attach(ic);
	ieee80211_node_attach(ic);
	ieee80211_power_attach(ic);
	ieee80211_proto_attach(ic);
#ifdef IEEE80211_SUPPORT_SUPERG
	ieee80211_superg_attach(ic);
#endif
	ieee80211_ht_attach(ic);
	ieee80211_scan_attach(ic);
	ieee80211_regdomain_attach(ic);
	ieee80211_dfs_attach(ic);

	ieee80211_sysctl_attach(ic);

	ifp->if_addrlen = IEEE80211_ADDR_LEN;
	ifp->if_hdrlen = 0;
	if_attach(ifp, NULL);
	ifp->if_mtu = IEEE80211_MTU_MAX;
	ifp->if_broadcastaddr = ieee80211broadcastaddr;
	ifp->if_output = null_output;
	ifp->if_input = null_input;	/* just in case */
	ifp->if_resolvemulti = NULL;	/* NB: callers check */

	ifa = ifaddr_byindex(ifp->if_index);
	KASSERT(ifa != NULL, ("%s: no lladdr!", __func__));
	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
	sdl->sdl_type = IFT_ETHER;		/* XXX IFT_IEEE80211? */
	sdl->sdl_alen = IEEE80211_ADDR_LEN;
	IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
//	IFAFREE(ifa);
}
Exemple #8
0
void
ieee80211_ifattach(struct ieee80211com *ic)
{
	struct ifnet *ifp = ic->ic_ifp;
	struct ieee80211_channel *c;
	int i;

#ifdef __NetBSD__
	ieee80211_init();
#endif /* __NetBSD__ */

	ether_ifattach(ifp, ic->ic_myaddr);
	bpf_attach2(ifp, DLT_IEEE802_11,
	    sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);

	ieee80211_crypto_attach(ic);

	/*
	 * Fill in 802.11 available channel set, mark
	 * all available channels as active, and pick
	 * a default channel if not already specified.
	 */
	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
	ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
		c = &ic->ic_channels[i];
		if (c->ic_flags) {
			/*
			 * Verify driver passed us valid data.
			 */
			if (i != ieee80211_chan2ieee(ic, c)) {
				if_printf(ifp, "bad channel ignored; "
					"freq %u flags %x number %u\n",
					c->ic_freq, c->ic_flags, i);
				c->ic_flags = 0;	/* NB: remove */
				continue;
			}
			setbit(ic->ic_chan_avail, i);
			/*
			 * Identify mode capabilities.
			 */
			if (IEEE80211_IS_CHAN_A(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11A;
			if (IEEE80211_IS_CHAN_B(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11B;
			if (IEEE80211_IS_CHAN_PUREG(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
			if (IEEE80211_IS_CHAN_FHSS(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_FH;
			if (IEEE80211_IS_CHAN_T(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_A;
			if (IEEE80211_IS_CHAN_108G(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_G;
			if (ic->ic_curchan == NULL) {
				/* arbitrarily pick the first channel */
				ic->ic_curchan = &ic->ic_channels[i];
			}
		}
	}
	/* validate ic->ic_curmode */
	if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
		ic->ic_curmode = IEEE80211_MODE_AUTO;
	ic->ic_des_chan = IEEE80211_CHAN_ANYC;	/* any channel is ok */
#if 0
	/*
	 * Enable WME by default if we're capable.
	 */
	if (ic->ic_caps & IEEE80211_C_WME)
		ic->ic_flags |= IEEE80211_F_WME;
#endif
	(void) ieee80211_setmode(ic, ic->ic_curmode);

	if (ic->ic_bintval == 0)
		ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
	ic->ic_bmisstimeout = 7*ic->ic_bintval;	/* default 7 beacons */
	ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT;
	IEEE80211_BEACON_LOCK_INIT(ic, "beacon");

	if (ic->ic_lintval == 0)
		ic->ic_lintval = ic->ic_bintval;
	ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;

	LIST_INSERT_HEAD(&ieee80211com_head, ic, ic_list);
	ieee80211_node_attach(ic);
	ieee80211_proto_attach(ic);

	ieee80211_add_vap(ic);

	ieee80211_sysctl_attach(ic);		/* NB: requires ic_vap */

	/*
	 * Install a default reset method for the ioctl support.
	 * The driver is expected to fill this in before calling us.
	 */
	if (ic->ic_reset == NULL)
		ic->ic_reset = ieee80211_default_reset;
}
Exemple #9
0
void
ieee80211_ifattach(struct ifnet *ifp)
{
	struct ieee80211com *ic = (void *)ifp;
	struct ieee80211_channel *c;
	int i;

	memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr,
		ETHER_ADDR_LEN);
	ether_ifattach(ifp);

	ifp->if_output = ieee80211_output;

#if NBPFILTER > 0
	bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11,
	    sizeof(struct ieee80211_frame_addr4));
#endif
	ieee80211_crypto_attach(ifp);

	/*
	 * Fill in 802.11 available channel set, mark
	 * all available channels as active, and pick
	 * a default channel if not already specified.
	 */
	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
	ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
		c = &ic->ic_channels[i];
		if (c->ic_flags) {
			/*
			 * Verify driver passed us valid data.
			 */
			if (i != ieee80211_chan2ieee(ic, c)) {
				printf("%s: bad channel ignored; "
					"freq %u flags %x number %u\n",
					ifp->if_xname, c->ic_freq, c->ic_flags,
					i);
				c->ic_flags = 0;	/* NB: remove */
				continue;
			}
			setbit(ic->ic_chan_avail, i);
			/*
			 * Identify mode capabilities.
			 */
			if (IEEE80211_IS_CHAN_A(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11A;
			if (IEEE80211_IS_CHAN_B(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11B;
			if (IEEE80211_IS_CHAN_PUREG(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
			if (IEEE80211_IS_CHAN_T(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO;
		}
	}
	/* validate ic->ic_curmode */
	if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
		ic->ic_curmode = IEEE80211_MODE_AUTO;
	ic->ic_des_chan = IEEE80211_CHAN_ANYC;	/* any channel is ok */
	ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;

	/* IEEE 802.11 defines a MTU >= 2290 */
	ifp->if_capabilities |= IFCAP_VLAN_MTU;

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

	if (ic->ic_lintval == 0)
		ic->ic_lintval = 100;		/* default sleep */
	ic->ic_bmisstimeout = 7*ic->ic_lintval;	/* default 7 beacons */
	ic->ic_dtim_period = 1;	/* all TIMs are DTIMs */

	LIST_INSERT_HEAD(&ieee80211com_head, ic, ic_list);
	ieee80211_node_attach(ifp);
	ieee80211_proto_attach(ifp);

	if_addgroup(ifp, "wlan");
	ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY;
}
Exemple #10
0
void
ieee80211_ifattach(struct ifnet *ifp)
{
	struct ieee80211com *ic = (void *)ifp;
	struct ieee80211_channel *c;
	int i;

	ether_ifattach(ifp, ic->ic_myaddr);
#if NBPFILTER > 0
	bpfattach2(ifp, DLT_IEEE802_11,
	    sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);
#endif
	ieee80211_crypto_attach(ifp);

	/*
	 * Fill in 802.11 available channel set, mark
	 * all available channels as active, and pick
	 * a default channel if not already specified.
	 */
	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
	ic->ic_modecaps |= 1<<IEEE80211_MODE_AUTO;
	for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
		c = &ic->ic_channels[i];
		if (c->ic_flags) {
			/*
			 * Verify driver passed us valid data.
			 */
			if (i != ieee80211_chan2ieee(ic, c)) {
				if_printf(ifp, "bad channel ignored; "
					"freq %u flags %x number %u\n",
					c->ic_freq, c->ic_flags, i);
				c->ic_flags = 0;	/* NB: remove */
				continue;
			}
			setbit(ic->ic_chan_avail, i);
			/*
			 * Identify mode capabilities.
			 */
			if (IEEE80211_IS_CHAN_A(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11A;
			if (IEEE80211_IS_CHAN_B(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11B;
			if (IEEE80211_IS_CHAN_PUREG(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
			if (IEEE80211_IS_CHAN_FHSS(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_FH;
			if (IEEE80211_IS_CHAN_T(c))
				ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO;
		}
	}
	/* validate ic->ic_curmode */
	if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
		ic->ic_curmode = IEEE80211_MODE_AUTO;

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

	ic->ic_des_chan = IEEE80211_CHAN_ANYC;	/* any channel is ok */
	if (ic->ic_lintval == 0)
		ic->ic_lintval = 100;		/* default sleep */
	ic->ic_bmisstimeout = 7*ic->ic_lintval;	/* default 7 beacons */

	ieee80211_node_attach(ifp);
	ieee80211_proto_attach(ifp);
}
Exemple #11
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;
}