/**
 * @brief initialize AP or GO bss config
 *
 * @param priv            A pointer to moal private structure
 * @param params          A pointer to beacon_parameters structure 
 * @return                0 -- success, otherwise fail
 */
static int
woal_cfg80211_beacon_config(moal_private * priv,
                            struct beacon_parameters *params)
#endif
{
    int ret = 0;
    mlan_uap_bss_param sys_config;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
    int i = 0;
#else
    const t_u8 *ssid_ie = NULL;
    struct ieee80211_mgmt *head = NULL;
    t_u16 capab_info = 0;
#endif
    t_u8 Rates_BG[13] =
        { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
        0x60, 0x6c, 0
    };
    t_u8 Rates_A[9] = { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0 };
    t_u8 chan2Offset = 0;
#ifdef WIFI_DIRECT_SUPPORT
    t_u8 Rates_WFD[9] = { 0x8c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0 };
#endif

    ENTER();

    if (params == NULL) {
        ret = -EFAULT;
        goto done;
    }

    if (priv->bss_type != MLAN_BSS_TYPE_UAP
#ifdef WIFI_DIRECT_SUPPORT
        && priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT
#endif
        ) {
        ret = -EFAULT;
        goto done;
    }

    /* Initialize the uap bss values which are uploaded from firmware */
    if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
                                                       MLAN_ACT_GET,
                                                       MOAL_IOCTL_WAIT,
                                                       &sys_config)) {
        PRINTM(MERROR, "Error getting AP confiruration\n");
        ret = -EFAULT;
        goto done;
    }

    /* Setting the default values */
    sys_config.channel = 6;
    sys_config.preamble_type = 0;

    if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
        if (params->beacon_interval)
            sys_config.beacon_period = params->beacon_interval;
#else
        if (params->interval)
            sys_config.beacon_period = params->interval;
#endif
        if (params->dtim_period)
            sys_config.dtim_period = params->dtim_period;
    }
    if (priv->channel) {
        memset(sys_config.rates, 0, sizeof(sys_config.rates));
        sys_config.channel = priv->channel;
        if (priv->channel <= MAX_BG_CHANNEL) {
            sys_config.band_cfg = BAND_CONFIG_2G;
#ifdef WIFI_DIRECT_SUPPORT
            if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
                memcpy(sys_config.rates, Rates_WFD, sizeof(Rates_WFD));
            else
#endif
                memcpy(sys_config.rates, Rates_BG, sizeof(Rates_BG));
        } else {
            sys_config.band_cfg = BAND_CONFIG_5G;
            chan2Offset = woal_get_second_channel_offset(priv->channel);
            if (chan2Offset) {
                sys_config.band_cfg |= chan2Offset;
                sys_config.ht_cap_info = 0x117e;
                sys_config.ampdu_param = 3;
            }
#ifdef WIFI_DIRECT_SUPPORT
            if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
                memcpy(sys_config.rates, Rates_WFD, sizeof(Rates_WFD));
            else
#endif
                memcpy(sys_config.rates, Rates_A, sizeof(Rates_A));
        }
    }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0) || defined(COMPAT_WIRELESS)
    if (!params->ssid || !params->ssid_len) {
        ret = -EINVAL;
        goto done;
    }
    memcpy(sys_config.ssid.ssid, params->ssid,
           MIN(MLAN_MAX_SSID_LENGTH, params->ssid_len));
    sys_config.ssid.ssid_len = MIN(MLAN_MAX_SSID_LENGTH, params->ssid_len);
    if (params->hidden_ssid)
        sys_config.bcast_ssid_ctl = 0;
    else
        sys_config.bcast_ssid_ctl = 1;
    if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
        sys_config.auth_mode = MLAN_AUTH_MODE_SHARED;
    else
        sys_config.auth_mode = MLAN_AUTH_MODE_OPEN;

    for (i = 0; i < params->crypto.n_akm_suites; i++) {
        switch (params->crypto.akm_suites[i]) {
        case WLAN_AKM_SUITE_8021X:
            sys_config.key_mgmt = KEY_MGMT_EAP;
            if ((params->crypto.wpa_versions & NL80211_WPA_VERSION_1) &&
                (params->crypto.wpa_versions & NL80211_WPA_VERSION_2))
                sys_config.protocol = PROTOCOL_WPA | PROTOCOL_WPA2;
            else if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
                sys_config.protocol = PROTOCOL_WPA2;
            else if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
                sys_config.protocol = PROTOCOL_WPA;
            break;
        case WLAN_AKM_SUITE_PSK:
            sys_config.key_mgmt = KEY_MGMT_PSK;
            if ((params->crypto.wpa_versions & NL80211_WPA_VERSION_1) &&
                (params->crypto.wpa_versions & NL80211_WPA_VERSION_2))
                sys_config.protocol = PROTOCOL_WPA | PROTOCOL_WPA2;
            else if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
                sys_config.protocol = PROTOCOL_WPA2;
            else if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
                sys_config.protocol = PROTOCOL_WPA;
            break;
        }
    }
    sys_config.wpa_cfg.pairwise_cipher_wpa = 0;
    sys_config.wpa_cfg.pairwise_cipher_wpa2 = 0;
    for (i = 0; i < params->crypto.n_ciphers_pairwise; i++) {
        switch (params->crypto.ciphers_pairwise[i]) {
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
            break;
        case WLAN_CIPHER_SUITE_TKIP:
            if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
                sys_config.wpa_cfg.pairwise_cipher_wpa |= CIPHER_TKIP;
            if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
                sys_config.wpa_cfg.pairwise_cipher_wpa2 |= CIPHER_TKIP;
            break;
        case WLAN_CIPHER_SUITE_CCMP:
            if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
                sys_config.wpa_cfg.pairwise_cipher_wpa |= CIPHER_AES_CCMP;
            if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
                sys_config.wpa_cfg.pairwise_cipher_wpa2 |= CIPHER_AES_CCMP;
            break;
        }
    }
    switch (params->crypto.cipher_group) {
    case WLAN_CIPHER_SUITE_WEP40:
    case WLAN_CIPHER_SUITE_WEP104:
        if ((priv->cipher == WLAN_CIPHER_SUITE_WEP40) ||
            (priv->cipher == WLAN_CIPHER_SUITE_WEP104)) {
            sys_config.protocol = PROTOCOL_STATIC_WEP;
            sys_config.key_mgmt = KEY_MGMT_NONE;
            sys_config.wpa_cfg.length = 0;
            sys_config.wep_cfg.key0.key_index = priv->key_index;
            sys_config.wep_cfg.key0.is_default = 1;
            sys_config.wep_cfg.key0.length = priv->key_len;
            memcpy(sys_config.wep_cfg.key0.key, priv->key_material,
                   priv->key_len);
        }
        break;
    case WLAN_CIPHER_SUITE_TKIP:
        sys_config.wpa_cfg.group_cipher = CIPHER_TKIP;
        break;
    case WLAN_CIPHER_SUITE_CCMP:
        sys_config.wpa_cfg.group_cipher = CIPHER_AES_CCMP;
        break;
    }
#else
    /* Since in Android ICS 4.0.1's wpa_supplicant, there is no way to set ssid
       when GO (AP) starts up, so get it from beacon head parameter TODO: right
       now use hard code 24 -- ieee80211 header lenth, 12 -- fixed element
       length for beacon */
#define BEACON_IE_OFFSET	36
    /* Find SSID in head SSID IE id: 0, right now use hard code */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
    ssid_ie = woal_parse_ie_tlv(params->beacon.head + BEACON_IE_OFFSET,
                                params->beacon.head_len - BEACON_IE_OFFSET, 0);
#else
    ssid_ie = woal_parse_ie_tlv(params->head + BEACON_IE_OFFSET,
                                params->head_len - BEACON_IE_OFFSET, 0);
#endif
    if (!ssid_ie) {
        PRINTM(MERROR, "No ssid IE found.\n");
        ret = -EFAULT;
        goto done;
    }
    if (*(ssid_ie + 1) > 32) {
        PRINTM(MERROR, "ssid len error: %d\n", *(ssid_ie + 1));
        ret = -EFAULT;
        goto done;
    }
    memcpy(sys_config.ssid.ssid, ssid_ie + 2, *(ssid_ie + 1));
    sys_config.ssid.ssid_len = *(ssid_ie + 1);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
    head = (struct ieee80211_mgmt *) params->beacon.head;
#else
    head = (struct ieee80211_mgmt *) params->head;
#endif
    capab_info = le16_to_cpu(head->u.beacon.capab_info);
    PRINTM(MIOCTL, "capab_info=0x%x\n", head->u.beacon.capab_info);
    sys_config.auth_mode = MLAN_AUTH_MODE_OPEN;
        /** For ICS, we don't support OPEN mode */
    if ((priv->cipher == WLAN_CIPHER_SUITE_WEP40) ||
        (priv->cipher == WLAN_CIPHER_SUITE_WEP104)) {
        sys_config.protocol = PROTOCOL_STATIC_WEP;
        sys_config.key_mgmt = KEY_MGMT_NONE;
        sys_config.wpa_cfg.length = 0;
        sys_config.wep_cfg.key0.key_index = priv->key_index;
        sys_config.wep_cfg.key0.is_default = 1;
        sys_config.wep_cfg.key0.length = priv->key_len;
        memcpy(sys_config.wep_cfg.key0.key, priv->key_material, priv->key_len);
    } else {
                /** Get cipher and key_mgmt from RSN/WPA IE */
        if (capab_info & WLAN_CAPABILITY_PRIVACY) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
            if (MFALSE ==
                woal_find_wpa_ies(params->beacon.tail, params->beacon.tail_len,
                                  &sys_config))
#else
            if (MFALSE ==
                woal_find_wpa_ies(params->tail, params->tail_len, &sys_config))
#endif
            {
                /* hard code setting to wpa2-psk */
                sys_config.protocol = PROTOCOL_WPA2;
                sys_config.key_mgmt = KEY_MGMT_PSK;
                sys_config.wpa_cfg.pairwise_cipher_wpa2 = CIPHER_AES_CCMP;
                sys_config.wpa_cfg.group_cipher = CIPHER_AES_CCMP;
            }
        }
    }
#endif /* COMPAT_WIRELESS */
    /* If the security mode is configured as WEP or WPA-PSK, it will disable
       11n automatically, and if configured as open(off) or wpa2-psk, it will
       automatically enable 11n */
    if ((sys_config.protocol == PROTOCOL_STATIC_WEP) ||
        (sys_config.protocol == PROTOCOL_WPA))
        woal_uap_set_11n_status(&sys_config, MLAN_ACT_DISABLE);
    else
        woal_uap_set_11n_status(&sys_config, MLAN_ACT_ENABLE);
    if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
                                                       MLAN_ACT_SET,
                                                       MOAL_IOCTL_WAIT,
                                                       &sys_config)) {
        ret = -EFAULT;
        goto done;
    }
  done:
    LEAVE();
    return ret;
}
Exemplo n.º 2
0
/**
 * @brief initialize AP or GO bss config
 *
 * @param priv            A pointer to moal private structure
 * @param params          A pointer to beacon_parameters structure
 * @return                0 -- success, otherwise fail
 */
static int
woal_cfg80211_beacon_config(moal_private *priv,
			    struct beacon_parameters *params)
#endif
{
	int ret = 0;
	mlan_uap_bss_param sys_config;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) || defined(COMPAT_WIRELESS)
	int i = 0;
#else
	t_u8 wpa_ies;
	const t_u8 *ssid_ie = NULL;
	struct ieee80211_mgmt *head = NULL;
	t_u16 capab_info = 0;
#endif
	t_u8 rates_bg[13] = {
		0x82, 0x84, 0x8b, 0x96,
		0x0c, 0x12, 0x18, 0x24,
		0x30, 0x48, 0x60, 0x6c,
		0x00
	};
	t_u8 rates_a[9] = {
		0x8c, 0x12, 0x98, 0x24,
		0xb0, 0x48, 0x60, 0x6c,
		0x00
	};
#ifdef WIFI_DIRECT_SUPPORT
	t_u8 rates_wfd[9] = {
		0x8c, 0x12, 0x18, 0x24,
		0x30, 0x48, 0x60, 0x6c,
		0x00
	};
#endif
	t_u8 chan2Offset = 0;
	t_u8 enable_11n = MTRUE;
	ENTER();

	if (params == NULL) {
		ret = -EFAULT;
		goto done;
	}

	if (priv->bss_type != MLAN_BSS_TYPE_UAP
#ifdef WIFI_DIRECT_SUPPORT
	    && priv->bss_type != MLAN_BSS_TYPE_WIFIDIRECT
#endif
		) {
		ret = -EFAULT;
		goto done;
	}

	/* Initialize the uap bss values which are uploaded from firmware */
	if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
							   MLAN_ACT_GET,
							   MOAL_IOCTL_WAIT,
							   &sys_config)) {
		PRINTM(MERROR, "Error getting AP confiruration\n");
		ret = -EFAULT;
		goto done;
	}

	/* Setting the default values */
	sys_config.channel = 6;
	sys_config.preamble_type = 0;
	sys_config.mgmt_ie_passthru_mask = priv->mgmt_subtype_mask;
	memcpy(sys_config.mac_addr, priv->current_addr, ETH_ALEN);

	if (priv->bss_type == MLAN_BSS_TYPE_UAP) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
		if (params->beacon_interval)
			sys_config.beacon_period = params->beacon_interval;
#else
		if (params->interval)
			sys_config.beacon_period = params->interval;
#endif
		if (params->dtim_period)
			sys_config.dtim_period = params->dtim_period;
	}
	if (priv->channel) {
		memset(sys_config.rates, 0, sizeof(sys_config.rates));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
		switch (params->chandef.width) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
		case NL80211_CHAN_WIDTH_5:
		case NL80211_CHAN_WIDTH_10:
#endif
		case NL80211_CHAN_WIDTH_20_NOHT:
			enable_11n = MFALSE;
			break;
		case NL80211_CHAN_WIDTH_20:
			break;
		case NL80211_CHAN_WIDTH_40:
		case NL80211_CHAN_WIDTH_80:
		case NL80211_CHAN_WIDTH_80P80:
		case NL80211_CHAN_WIDTH_160:
			if (params->chandef.center_freq1 <
			    params->chandef.chan->center_freq)
				chan2Offset = SECOND_CHANNEL_BELOW;
			else
				chan2Offset = SECOND_CHANNEL_ABOVE;
			break;
		default:
			PRINTM(MWARN, "Unknown channel width: %d\n",
			       params->chandef.width);
			break;
		}
#else
		switch (params->channel_type) {
		case NL80211_CHAN_NO_HT:
			enable_11n = MFALSE;
			break;
		case NL80211_CHAN_HT20:
			break;
		case NL80211_CHAN_HT40PLUS:
			chan2Offset = SECOND_CHANNEL_ABOVE;
			break;
		case NL80211_CHAN_HT40MINUS:
			chan2Offset = SECOND_CHANNEL_BELOW;
			break;
		default:
			PRINTM(MWARN, "Unknown channel type: %d\n",
			       params->channel_type);
			break;
		}
#endif
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */
		sys_config.channel = priv->channel;
		if (priv->channel <= MAX_BG_CHANNEL) {
			sys_config.band_cfg = BAND_CONFIG_2G;
#ifdef WIFI_DIRECT_SUPPORT
			if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
				memcpy(sys_config.rates, rates_wfd,
				       sizeof(rates_wfd));
			else
#endif
				memcpy(sys_config.rates, rates_bg,
				       sizeof(rates_bg));
		} else {
			sys_config.band_cfg = BAND_CONFIG_5G;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
			chan2Offset =
				woal_get_second_channel_offset(priv->channel);
#else
#ifdef WIFI_DIRECT_SUPPORT
			/* Force enable 40MHZ on WFD interface */
			if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
				chan2Offset =
					woal_get_second_channel_offset(priv->
								       channel);
#endif
#endif

#ifdef WIFI_DIRECT_SUPPORT
			if (priv->bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
				memcpy(sys_config.rates, rates_wfd,
				       sizeof(rates_wfd));
			else
#endif
				memcpy(sys_config.rates, rates_a,
				       sizeof(rates_a));
		}
		/* Disable GreenField by default */
		sys_config.ht_cap_info = 0x10c;
		if (enable_11n)
			sys_config.ht_cap_info |= 0x20;
		if (chan2Offset) {
			sys_config.band_cfg |= chan2Offset;
			sys_config.ht_cap_info |= 0x1042;
			sys_config.ampdu_param = 3;
		}
		PRINTM(MCMND,
		       "11n=%d, ht_cap=0x%x, channel=%d, band_cfg=0x%x\n",
		       enable_11n, sys_config.ht_cap_info, priv->channel,
		       sys_config.band_cfg);
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) || defined(COMPAT_WIRELESS)
	if (!params->ssid || !params->ssid_len) {
		ret = -EINVAL;
		goto done;
	}
	memcpy(sys_config.ssid.ssid, params->ssid,
	       MIN(MLAN_MAX_SSID_LENGTH, params->ssid_len));
	sys_config.ssid.ssid_len = MIN(MLAN_MAX_SSID_LENGTH, params->ssid_len);
	if (params->hidden_ssid)
		sys_config.bcast_ssid_ctl = 0;
	else
		sys_config.bcast_ssid_ctl = 1;
	if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
		sys_config.auth_mode = MLAN_AUTH_MODE_SHARED;
	else
		sys_config.auth_mode = MLAN_AUTH_MODE_OPEN;
	if (params->crypto.n_akm_suites) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
		woal_find_wpa_ies(params->beacon.tail,
				  (int)params->beacon.tail_len, &sys_config);
#else
		woal_find_wpa_ies(params->tail, params->tail_len, &sys_config);
#endif
	}
	for (i = 0; i < params->crypto.n_akm_suites; i++) {
		switch (params->crypto.akm_suites[i]) {
		case WLAN_AKM_SUITE_8021X:
			sys_config.key_mgmt |= KEY_MGMT_EAP;
			if ((params->crypto.
			     wpa_versions & NL80211_WPA_VERSION_1) &&
			    (params->crypto.
			     wpa_versions & NL80211_WPA_VERSION_2))
				sys_config.protocol =
					PROTOCOL_WPA | PROTOCOL_WPA2;
			else if (params->crypto.
				 wpa_versions & NL80211_WPA_VERSION_2)
				sys_config.protocol = PROTOCOL_WPA2;
			else if (params->crypto.
				 wpa_versions & NL80211_WPA_VERSION_1)
				sys_config.protocol = PROTOCOL_WPA;
			break;
		case WLAN_AKM_SUITE_PSK:
			sys_config.key_mgmt |= KEY_MGMT_PSK;
			if ((params->crypto.
			     wpa_versions & NL80211_WPA_VERSION_1) &&
			    (params->crypto.
			     wpa_versions & NL80211_WPA_VERSION_2))
				sys_config.protocol =
					PROTOCOL_WPA | PROTOCOL_WPA2;
			else if (params->crypto.
				 wpa_versions & NL80211_WPA_VERSION_2)
				sys_config.protocol = PROTOCOL_WPA2;
			else if (params->crypto.
				 wpa_versions & NL80211_WPA_VERSION_1)
				sys_config.protocol = PROTOCOL_WPA;
			break;
		}
	}
	sys_config.wpa_cfg.pairwise_cipher_wpa = 0;
	sys_config.wpa_cfg.pairwise_cipher_wpa2 = 0;
	for (i = 0; i < params->crypto.n_ciphers_pairwise; i++) {
		switch (params->crypto.ciphers_pairwise[i]) {
		case WLAN_CIPHER_SUITE_WEP40:
		case WLAN_CIPHER_SUITE_WEP104:
			break;
		case WLAN_CIPHER_SUITE_TKIP:
			if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
				sys_config.wpa_cfg.pairwise_cipher_wpa |=
					CIPHER_TKIP;
			if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
				sys_config.wpa_cfg.pairwise_cipher_wpa2 |=
					CIPHER_TKIP;
			break;
		case WLAN_CIPHER_SUITE_CCMP:
			if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
				sys_config.wpa_cfg.pairwise_cipher_wpa |=
					CIPHER_AES_CCMP;
			if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
				sys_config.wpa_cfg.pairwise_cipher_wpa2 |=
					CIPHER_AES_CCMP;
			break;
		}
	}
	switch (params->crypto.cipher_group) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
		if ((priv->cipher == WLAN_CIPHER_SUITE_WEP40) ||
		    (priv->cipher == WLAN_CIPHER_SUITE_WEP104)) {
			sys_config.protocol = PROTOCOL_STATIC_WEP;
			sys_config.key_mgmt = KEY_MGMT_NONE;
			sys_config.wpa_cfg.length = 0;
			memcpy(&sys_config.wep_cfg.key0, &priv->uap_wep_key[0],
			       sizeof(wep_key));
			memcpy(&sys_config.wep_cfg.key1, &priv->uap_wep_key[1],
			       sizeof(wep_key));
			memcpy(&sys_config.wep_cfg.key2, &priv->uap_wep_key[2],
			       sizeof(wep_key));
			memcpy(&sys_config.wep_cfg.key3, &priv->uap_wep_key[3],
			       sizeof(wep_key));
		}
		break;
	case WLAN_CIPHER_SUITE_TKIP:
		sys_config.wpa_cfg.group_cipher = CIPHER_TKIP;
		break;
	case WLAN_CIPHER_SUITE_CCMP:
		sys_config.wpa_cfg.group_cipher = CIPHER_AES_CCMP;
		break;
	}
#else
	/* Since in Android ICS 4.0.1's wpa_supplicant, there is no way to set
	   ssid when GO (AP) starts up, so get it from beacon head parameter
	   TODO: right now use hard code 24 -- ieee80211 header lenth, 12 --
	   fixed element length for beacon */
#define BEACON_IE_OFFSET	36
	/* Find SSID in head SSID IE id: 0, right now use hard code */
	ssid_ie = woal_parse_ie_tlv(params->head + BEACON_IE_OFFSET,
				    params->head_len - BEACON_IE_OFFSET, 0);

	if (!ssid_ie) {
		PRINTM(MERROR, "No ssid IE found.\n");
		ret = -EFAULT;
		goto done;
	}
	if (*(ssid_ie + 1) > 32) {
		PRINTM(MERROR, "ssid len error: %d\n", *(ssid_ie + 1));
		ret = -EFAULT;
		goto done;
	}
	memcpy(sys_config.ssid.ssid, ssid_ie + 2, *(ssid_ie + 1));
	sys_config.ssid.ssid_len = *(ssid_ie + 1);
	head = (struct ieee80211_mgmt *)params->head;

	capab_info = le16_to_cpu(head->u.beacon.capab_info);
	PRINTM(MIOCTL, "capab_info=0x%x\n", head->u.beacon.capab_info);
	sys_config.auth_mode = MLAN_AUTH_MODE_OPEN;
	/** For ICS, we don't support OPEN mode */
	if ((priv->cipher == WLAN_CIPHER_SUITE_WEP40) ||
	    (priv->cipher == WLAN_CIPHER_SUITE_WEP104)) {
		sys_config.protocol = PROTOCOL_STATIC_WEP;
		sys_config.key_mgmt = KEY_MGMT_NONE;
		sys_config.wpa_cfg.length = 0;
		memcpy(&sys_config.wep_cfg.key0, &priv->uap_wep_key[0],
		       sizeof(wep_key));
		memcpy(&sys_config.wep_cfg.key1, &priv->uap_wep_key[1],
		       sizeof(wep_key));
		memcpy(&sys_config.wep_cfg.key2, &priv->uap_wep_key[2],
		       sizeof(wep_key));
		memcpy(&sys_config.wep_cfg.key3, &priv->uap_wep_key[3],
		       sizeof(wep_key));
	} else {
		/** Get cipher and key_mgmt from RSN/WPA IE */
		if (capab_info & WLAN_CAPABILITY_PRIVACY) {
			wpa_ies =
				woal_find_wpa_ies(params->tail,
						  params->tail_len,
						  &sys_config);
			if (wpa_ies == MFALSE) {
				/* hard code setting to wpa2-psk */
				sys_config.protocol = PROTOCOL_WPA2;
				sys_config.key_mgmt = KEY_MGMT_PSK;
				sys_config.wpa_cfg.pairwise_cipher_wpa2 =
					CIPHER_AES_CCMP;
				sys_config.wpa_cfg.group_cipher =
					CIPHER_AES_CCMP;
			}
		}
	}
#endif /* COMPAT_WIRELESS */
	/* If the security mode is configured as WEP or WPA-PSK, it will
	   disable 11n automatically, and if configured as open(off) or
	   wpa2-psk, it will automatically enable 11n */
	if ((sys_config.protocol == PROTOCOL_STATIC_WEP) ||
	    (sys_config.protocol == PROTOCOL_WPA))
		enable_11n = MFALSE;
	if (!enable_11n) {
		woal_uap_set_11n_status(&sys_config, MLAN_ACT_DISABLE);
	} else {
		woal_uap_set_11n_status(&sys_config, MLAN_ACT_ENABLE);
		woal_set_get_tx_bf_cap(priv, MLAN_ACT_GET,
				       &sys_config.tx_bf_cap);
	}
	if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
							   MLAN_ACT_SET,
							   MOAL_IOCTL_WAIT,
							   &sys_config)) {
		ret = -EFAULT;
		goto done;
	}
done:
	LEAVE();
	return ret;
}