void orinoco_add_extscan_result(struct orinoco_private *priv,
				struct agere_ext_scan_info *bss,
				size_t len)
{
	struct wiphy *wiphy = priv_to_wiphy(priv);
	struct ieee80211_channel *channel;
	struct cfg80211_bss *cbss;
	const u8 *ie;
	u64 timestamp;
	s32 signal;
	u16 capability;
	u16 beacon_interval;
	size_t ie_len;
	int chan, freq;

	ie_len = len - sizeof(*bss);
	ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len);
	chan = ie ? ie[2] : 0;
	freq = ieee80211_dsss_chan_to_freq(chan);
	channel = ieee80211_get_channel(wiphy, freq);

	timestamp = le64_to_cpu(bss->timestamp);
	capability = le16_to_cpu(bss->capabilities);
	beacon_interval = le16_to_cpu(bss->beacon_interval);
	ie = bss->data;
	signal = SIGNAL_TO_MBM(bss->level);

	cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp,
				   capability, beacon_interval, ie, ie_len,
				   signal, GFP_KERNEL);
	cfg80211_put_bss(cbss);
}
Beispiel #2
0
Datei: ie.c Projekt: 7799/linux
/* This function parses different IEs-tail IEs, beacon IEs, probe response IEs,
 * association response IEs from cfg80211_ap_settings function and sets these IE
 * to FW.
 */
int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
			 struct cfg80211_beacon_data *info)
{
	struct mwifiex_ie *gen_ie;
	struct ieee_types_header *rsn_ie, *wpa_ie = NULL;
	u16 rsn_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
	const u8 *vendor_ie;

	if (info->tail && info->tail_len) {
		gen_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
		if (!gen_ie)
			return -ENOMEM;
		gen_ie->ie_index = cpu_to_le16(rsn_idx);
		gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
							MGMT_MASK_PROBE_RESP |
							MGMT_MASK_ASSOC_RESP);

		rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN,
						  info->tail, info->tail_len);
		if (rsn_ie) {
			memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2);
			ie_len = rsn_ie->len + 2;
			gen_ie->ie_length = cpu_to_le16(ie_len);
		}

		vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
						    WLAN_OUI_TYPE_MICROSOFT_WPA,
						    info->tail,
						    info->tail_len);
		if (vendor_ie) {
			wpa_ie = (struct ieee_types_header *)vendor_ie;
			memcpy(gen_ie->ie_buffer + ie_len,
			       wpa_ie, wpa_ie->len + 2);
			ie_len += wpa_ie->len + 2;
			gen_ie->ie_length = cpu_to_le16(ie_len);
		}

		if (rsn_ie || wpa_ie) {
			if (mwifiex_update_uap_custom_ie(priv, gen_ie, &rsn_idx,
							 NULL, NULL,
							 NULL, NULL)) {
				kfree(gen_ie);
				return -1;
			}
			priv->rsn_idx = rsn_idx;
		}

		kfree(gen_ie);
	}

	return mwifiex_set_mgmt_beacon_data_ies(priv, info);
}
Beispiel #3
0
/* This function updates 11ac related parameters from IE
 * and sets them into bss_config structure.
 */
void mwifiex_set_tpc_params(struct mwifiex_private *priv,
			    struct mwifiex_uap_bss_param *bss_cfg,
			    struct cfg80211_ap_settings *params)
{
	const u8 *tpc_ie;

	tpc_ie = cfg80211_find_ie(WLAN_EID_TPC_REQUEST, params->beacon.tail,
				  params->beacon.tail_len);
	if (tpc_ie)
		bss_cfg->power_constraint = *(tpc_ie + 2);
	else
		bss_cfg->power_constraint = 0;
}
/* This function finds supported rates IE from beacon parameter and sets
 * these rates into bss_config structure.
 */
void
mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
		      struct cfg80211_ap_settings *params)
{
	struct ieee_types_header *rate_ie;
	int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
	const u8 *var_pos = params->beacon.head + var_offset;
	int len = params->beacon.head_len - var_offset;

	rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len);
	if (rate_ie)
		memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len);

	return;
}
Beispiel #5
0
/* This function updates 11n related parameters from IE and sets them into
 * bss_config structure.
 */
void
mwifiex_set_ht_params(struct mwifiex_private *priv,
		      struct mwifiex_uap_bss_param *bss_cfg,
		      struct cfg80211_ap_settings *params)
{
	const u8 *ht_ie;
	u16 cap_info;

	if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
		return;

	ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail,
				 params->beacon.tail_len);
	if (ht_ie) {
		memcpy(&bss_cfg->ht_cap, ht_ie,
		       sizeof(struct ieee80211_ht_cap));
		cap_info = le16_to_cpu(bss_cfg->ht_cap.cap_info);
		memset(&bss_cfg->ht_cap.mcs, 0,
		       priv->adapter->number_of_antenna);
		switch (GET_RXSTBC(cap_info)) {
		case MWIFIEX_RX_STBC1:
			/* HT_CAP 1X1 mode */
			bss_cfg->ht_cap.mcs.rx_mask[0] = 0xff;
			break;
		case MWIFIEX_RX_STBC12:	/* fall through */
		case MWIFIEX_RX_STBC123:
			/* HT_CAP 2X2 mode */
			bss_cfg->ht_cap.mcs.rx_mask[0] = 0xff;
			bss_cfg->ht_cap.mcs.rx_mask[1] = 0xff;
			break;
		default:
			dev_warn(priv->adapter->dev,
				 "Unsupported RX-STBC, default to 2x2\n");
			bss_cfg->ht_cap.mcs.rx_mask[0] = 0xff;
			bss_cfg->ht_cap.mcs.rx_mask[1] = 0xff;
			break;
		}
		priv->ap_11n_enabled = 1;
	} else {
		memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap));
		bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP);
		bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU;
	}

	return;
}
Beispiel #6
0
/* This function updates 11ac related parameters from IE
 * and sets them into bss_config structure.
 */
void mwifiex_set_vht_params(struct mwifiex_private *priv,
			    struct mwifiex_uap_bss_param *bss_cfg,
			    struct cfg80211_ap_settings *params)
{
	const u8 *vht_ie;

	vht_ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, params->beacon.tail,
				  params->beacon.tail_len);
	if (vht_ie) {
		memcpy(&bss_cfg->vht_cap, vht_ie + 2,
		       sizeof(struct ieee80211_vht_cap));
		priv->ap_11ac_enabled = 1;
	} else {
		priv->ap_11ac_enabled = 0;
	}

	return;
}
/* This function updates 11n related parameters from IE and sets them into
 * bss_config structure.
 */
void
mwifiex_set_ht_params(struct mwifiex_private *priv,
		      struct mwifiex_uap_bss_param *bss_cfg,
		      struct cfg80211_ap_settings *params)
{
	const u8 *ht_ie;

	if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
		return;

	ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail,
				 params->beacon.tail_len);
	if (ht_ie) {
		memcpy(&bss_cfg->ht_cap, ht_ie + 2,
		       sizeof(struct ieee80211_ht_cap));
		priv->ap_11n_enabled = 1;
	} else {
		memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap));
		bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP);
		bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU;
	}

	return;
}
Beispiel #8
0
static INT CFG80211DRV_UpdateApSettingFromBeacon(PRTMP_ADAPTER pAd, UINT mbss_idx, CMD_RTPRIV_IOCTL_80211_BEACON *pBeacon)
{
	PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[mbss_idx];
	struct wifi_dev *wdev = &pMbss->wdev;
	
	const UCHAR *ssid_ie = NULL, *wpa_ie = NULL, *rsn_ie = NULL;
	const UINT WFA_OUI = 0x0050F2;
	const UCHAR WMM_OUI_TYPE = 0x2;
	UCHAR *wmm_ie = NULL;
	
	const UCHAR *supp_rates_ie = NULL;
	const UCHAR *ext_supp_rates_ie = NULL, *ht_cap = NULL, *ht_info = NULL;
	
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
	const UCHAR CFG_HT_OP_EID = WLAN_EID_HT_OPERATION; 
#else
	const UCHAR CFG_HT_OP_EID = WLAN_EID_HT_INFORMATION;
#endif /* LINUX_VERSION_CODE: 3.5.0 */

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) 
	const UCHAR CFG_WPA_EID = WLAN_EID_VENDOR_SPECIFIC;
#else
	const UCHAR CFG_WPA_EID = WLAN_EID_WPA;
#endif /* LINUX_VERSION_CODE: 3.8.0 */

	ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, pBeacon->beacon_head+36, pBeacon->beacon_head_len-36);
	supp_rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pBeacon->beacon_head+36, pBeacon->beacon_head_len-36);
	/* if it doesn't find WPA_IE in tail first 30 bytes. treat it as is not found */
	wpa_ie = cfg80211_find_ie(CFG_WPA_EID, pBeacon->beacon_tail, pBeacon->beacon_tail_len); 
	rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	wmm_ie = cfg80211_find_vendor_ie(WFA_OUI, WMM_OUI_TYPE, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	ht_cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	ht_info = cfg80211_find_ie(CFG_HT_OP_EID, pBeacon->beacon_tail, pBeacon->beacon_tail_len);

	/* SSID */
	NdisZeroMemory(pMbss->Ssid, pMbss->SsidLen);
	if (ssid_ie == NULL) 
	{
		NdisMoveMemory(pMbss->Ssid, "CFG_Linux_GO", 12);
		pMbss->SsidLen = 12;
		DBGPRINT(RT_DEBUG_ERROR,("CFG: SSID Not Found In Packet\n"));
	}
	else
	{
		pMbss->SsidLen = ssid_ie[1];
		NdisCopyMemory(pMbss->Ssid, ssid_ie+2, pMbss->SsidLen);
		DBGPRINT(RT_DEBUG_TRACE,("CFG : SSID: %s, %d\n", pMbss->Ssid, pMbss->SsidLen));
	}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
	if (pBeacon->hidden_ssid > 0 && pBeacon->hidden_ssid < 3) {
		pMbss->bHideSsid = TRUE;
	}
	else
		pMbss->bHideSsid = FALSE;

	if (pBeacon->hidden_ssid == 1)
		pMbss->SsidLen = 0;
#endif /* LINUX_VERSION_CODE 3.4.0 */

	/* WMM EDCA Paramter */ 
	CFG80211_SyncPacketWmmIe(pAd, pBeacon->beacon_tail, pBeacon->beacon_tail_len);

	/* Security */
	CFG80211_ParseBeaconIE(pAd, pMbss, wdev, wpa_ie, rsn_ie);

	pMbss->CapabilityInfo =	CAP_GENERATE(1, 0, (wdev->WepStatus != Ndis802_11EncryptionDisabled), 
			 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1), pAd->CommonCfg.bUseShortSlotTime, /*SpectrumMgmt*/FALSE);
			 
	/* Disable Driver-Internal Rekey */
	pMbss->WPAREKEY.ReKeyInterval = 0;
	pMbss->WPAREKEY.ReKeyMethod = DISABLE_REKEY;	
	
	if (pBeacon->interval != 0)
	{
		DBGPRINT(RT_DEBUG_TRACE,("CFG_TIM New BI %d\n", pBeacon->interval));
		pAd->CommonCfg.BeaconPeriod = pBeacon->interval;
	}
	
	if (pBeacon->dtim_period != 0)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("CFG_TIM New DP %d\n", pBeacon->dtim_period));
		pAd->ApCfg.DtimPeriod = pBeacon->dtim_period;	
	}
		
}
Beispiel #9
0
static int wil_cfg80211_connect(struct wiphy *wiphy,
                                struct net_device *ndev,
                                struct cfg80211_connect_params *sme)
{
    struct wil6210_priv *wil = wiphy_to_wil(wiphy);
    struct cfg80211_bss *bss;
    struct wmi_connect_cmd conn;
    const u8 *ssid_eid;
    const u8 *rsn_eid;
    int ch;
    int rc = 0;

    if (test_bit(wil_status_fwconnecting, &wil->status) ||
            test_bit(wil_status_fwconnected, &wil->status))
        return -EALREADY;

    bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
                           sme->ssid, sme->ssid_len,
                           WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
    if (!bss) {
        wil_err(wil, "Unable to find BSS\n");
        return -ENOENT;
    }

    ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
    if (!ssid_eid) {
        wil_err(wil, "No SSID\n");
        rc = -ENOENT;
        goto out;
    }

    rsn_eid = sme->ie ?
              cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
              NULL;
    if (rsn_eid) {
        if (sme->ie_len > WMI_MAX_IE_LEN) {
            rc = -ERANGE;
            wil_err(wil, "IE too large (%td bytes)\n",
                    sme->ie_len);
            goto out;
        }
        /*
         * For secure assoc, send:
         * (1) WMI_DELETE_CIPHER_KEY_CMD
         * (2) WMI_SET_APPIE_CMD
         */
        rc = wmi_del_cipher_key(wil, 0, bss->bssid);
        if (rc) {
            wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n");
            goto out;
        }
        /* WMI_SET_APPIE_CMD */
        rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
        if (rc) {
            wil_err(wil, "WMI_SET_APPIE_CMD failed\n");
            goto out;
        }
    }

    /* WMI_CONNECT_CMD */
    memset(&conn, 0, sizeof(conn));
    switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) {
    case WLAN_CAPABILITY_DMG_TYPE_AP:
        conn.network_type = WMI_NETTYPE_INFRA;
        break;
    case WLAN_CAPABILITY_DMG_TYPE_PBSS:
        conn.network_type = WMI_NETTYPE_P2P;
        break;
    default:
        wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n",
                bss->capability);
        goto out;
    }
    if (rsn_eid) {
        conn.dot11_auth_mode = WMI_AUTH11_SHARED;
        conn.auth_mode = WMI_AUTH_WPA2_PSK;
        conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
        conn.pairwise_crypto_len = 16;
    } else {
        conn.dot11_auth_mode = WMI_AUTH11_OPEN;
        conn.auth_mode = WMI_AUTH_NONE;
    }

    conn.ssid_len = min_t(u8, ssid_eid[1], 32);
    memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);

    ch = bss->channel->hw_value;
    if (ch == 0) {
        wil_err(wil, "BSS at unknown frequency %dMhz\n",
                bss->channel->center_freq);
        rc = -EOPNOTSUPP;
        goto out;
    }
    conn.channel = ch - 1;

    memcpy(conn.bssid, bss->bssid, ETH_ALEN);
    memcpy(conn.dst_mac, bss->bssid, ETH_ALEN);

    set_bit(wil_status_fwconnecting, &wil->status);

    rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
    if (rc == 0) {
        /* Connect can take lots of time */
        mod_timer(&wil->connect_timer,
                  jiffies + msecs_to_jiffies(2000));
    } else {
        clear_bit(wil_status_fwconnecting, &wil->status);
    }

out:
    cfg80211_put_bss(wiphy, bss);

    return rc;
}
Beispiel #10
0
static INT CFG80211DRV_UpdateApSettingFromBeacon(PRTMP_ADAPTER pAd, UINT mbss_idx, CMD_RTPRIV_IOCTL_80211_BEACON *pBeacon)
{
	BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[mbss_idx];
	struct wifi_dev *wdev = &pMbss->wdev;
	
	const UCHAR *ssid_ie = NULL, *wpa_ie = NULL, *rsn_ie = NULL;
//	const UINT WFA_OUI = 0x0050F2;
//	const UCHAR WMM_OUI_TYPE = 0x2;
//	UCHAR *wmm_ie = NULL;
	
	const UCHAR *supp_rates_ie = NULL;
	const UCHAR *ext_supp_rates_ie = NULL, *ht_cap = NULL, *ht_info = NULL;


#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
	const UCHAR CFG_HT_OP_EID = WLAN_EID_HT_OPERATION; 
#else
	const UCHAR CFG_HT_OP_EID = WLAN_EID_HT_INFORMATION;
#endif /* LINUX_VERSION_CODE: 3.5.0 */

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) 
	const UCHAR CFG_WPA_EID = WLAN_EID_VENDOR_SPECIFIC;
#else
	const UCHAR CFG_WPA_EID = WLAN_EID_WPA;
#endif /* LINUX_VERSION_CODE: 3.8.0 */
	
	ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, pBeacon->beacon_head+36, pBeacon->beacon_head_len-36);
	supp_rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pBeacon->beacon_head+36, pBeacon->beacon_head_len-36);
	/* if it doesn't find WPA_IE in tail first 30 bytes. treat it as is not found */
	wpa_ie = cfg80211_find_ie(CFG_WPA_EID, pBeacon->beacon_tail, pBeacon->beacon_tail_len); 
	rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, pBeacon->beacon_tail, pBeacon->beacon_tail_len);//wpa2 case.
	ext_supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	ht_cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	ht_info = cfg80211_find_ie(CFG_HT_OP_EID, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	

	
	/* SSID */

	if (ssid_ie == NULL) 
	{
		NdisMoveMemory(pMbss->Ssid, "CFG_Linux_GO", 12);
		pMbss->SsidLen = 12;
		DBGPRINT(RT_DEBUG_ERROR,("CFG: SSID Not Found In Packet\n"));
	}
	else if (pBeacon->ssid_len != 0)
	{
		NdisZeroMemory(pMbss->Ssid, pMbss->SsidLen);
		pMbss->SsidLen = pBeacon->ssid_len;
		NdisCopyMemory(pMbss->Ssid, ssid_ie+2, pMbss->SsidLen);		
		DBGPRINT(RT_DEBUG_ERROR,("\nCFG : SSID: %s, %d\n", pMbss->Ssid, pMbss->SsidLen));
	}


#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
	if (pBeacon->hidden_ssid > 0 && pBeacon->hidden_ssid < 3) 
	{
		pMbss->bHideSsid = TRUE;
		if ((pBeacon->ssid_len != 0) 
			 && (pBeacon->ssid_len <= MAX_LEN_OF_SSID))
		{
			pMbss->SsidLen = pBeacon->ssid_len;
			NdisCopyMemory(pMbss->Ssid, pBeacon->ssid, pMbss->SsidLen);
			DBGPRINT(RT_DEBUG_ERROR,("80211> [Hidden] SSID: %s, %d\n", pMbss->Ssid, pMbss->SsidLen));
		}
	}
	else
		pMbss->bHideSsid = FALSE;

#endif /* LINUX_VERSION_CODE 3.4.0 */

	/* WMM EDCA Paramter */ 
	CFG80211_SyncPacketWmmIe(pAd, pBeacon->beacon_tail, pBeacon->beacon_tail_len);
	pMbss->RSNIE_Len[0] = 0;
	pMbss->RSNIE_Len[1] = 0;
	NdisZeroMemory(pMbss->RSN_IE[0], MAX_LEN_OF_RSNIE);
	NdisZeroMemory(pMbss->RSN_IE[1], MAX_LEN_OF_RSNIE);
	
	DBGPRINT(RT_DEBUG_TRACE,("80211> pBeacon->privacy = %d\n", pBeacon->privacy));
	if (pBeacon->privacy)
	{
		/* Security */
		if (pBeacon->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
		{
			/*
				Shared WEP
			*/
			wdev->WepStatus = Ndis802_11WEPEnabled;
			wdev->AuthMode = Ndis802_11AuthModeShared;
		}
		else
			CFG80211_ParseBeaconIE(pAd, pMbss, wdev, (UCHAR *)wpa_ie, (UCHAR *)rsn_ie);

		if ((wdev->WepStatus == 0) &&
			(wdev->AuthMode == 0))
		{
			/*
				WEP Auto
			*/
			wdev->WepStatus = Ndis802_11WEPEnabled;
			wdev->AuthMode = Ndis802_11AuthModeAutoSwitch;
		}
	}
	else
	{
		wdev->WepStatus = Ndis802_11EncryptionDisabled;		
		wdev->AuthMode = Ndis802_11AuthModeOpen;		
	}
	CFG80211_ParseBeaconIE(pAd, pMbss, wdev, (UCHAR *)wpa_ie, (UCHAR *)rsn_ie);
	pMbss->CapabilityInfo =	CAP_GENERATE(1, 0, (wdev->WepStatus != Ndis802_11EncryptionDisabled), 
			 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1), pAd->CommonCfg.bUseShortSlotTime, /*SpectrumMgmt*/FALSE);
			 
	/* Disable Driver-Internal Rekey */
	pMbss->WPAREKEY.ReKeyInterval = 0;
	pMbss->WPAREKEY.ReKeyMethod = DISABLE_REKEY;	
	
	if (pBeacon->interval != 0)
	{
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("CFG_TIM New BI %d\n", pBeacon->interval));
		pAd->CommonCfg.BeaconPeriod = pBeacon->interval;
	}
	
	if (pBeacon->dtim_period != 0)
	{
		MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("CFG_TIM New DP %d\n", pBeacon->dtim_period));
		pAd->ApCfg.DtimPeriod = pBeacon->dtim_period;	
	}

	return TRUE;		
}
Beispiel #11
0
/* REF: ap_connect.c ApMakeBssBeacon */
BOOLEAN CFG80211DRV_OpsBeaconSet(
        VOID                                            *pAdOrg,
        VOID                                            *pData,
	BOOLEAN                                          isAdd)
{
	CFG80211DBG(RT_DEBUG_TRACE, ("80211> CFG80211DRV_OpsBeaconSet ==> %d\n", isAdd));
        PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
        CMD_RTPRIV_IOCTL_80211_BEACON *pBeacon;
        PTXWI_STRUC    pTxWI = &pAd->BeaconTxWI;
        HTTRANSMIT_SETTING      BeaconTransmit;   /* MGMT frame PHY rate setting when operatin at Ht rate. */
        BCN_TIME_CFG_STRUC csr9;
        UCHAR  *ptr;
        UINT  i;
        UINT32 longValue;
        UINT8 TXWISize = pAd->chipCap.TXWISize;
	UINT32 rx_filter_flag;
	BOOLEAN TxPreamble, SpectrumMgmt = FALSE;
	BOOLEAN	bWmmCapable = FALSE;
	UCHAR	BBPR1 = 0, BBPR3 = 0;
	INT idx;
	ULONG offset;

	CFG80211DBG(RT_DEBUG_TRACE, ("80211> CFG80211DRV_OpsBeaconSet ==> \n"));
	pBeacon = (CMD_RTPRIV_IOCTL_80211_BEACON *)pData;

#ifdef WFD_SUPPORT
	if (pAd->StaCfg.WfdCfg.bSuppInsertWfdIe)
	{
		ULONG TmpLen, WfdIeBitmap;

		ptr = pBeacon->beacon + pBeacon->beacon_len;
		WfdIeBitmap = (0x1 << SUBID_WFD_DEVICE_INFO) | (0x1 << SUBID_WFD_ASSOCIATED_BSSID) |
			(0x1 << SUBID_WFD_COUPLED_SINK_INFO);
		WfdMakeWfdIE(pAd, WfdIeBitmap, ptr, &TmpLen);
		pBeacon->beacon_len += TmpLen;
	}
#endif /* WFD_SUPPORT */

	if (isAdd)
	{
		rx_filter_flag = APNORMAL;
		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);     /* enable RX of DMA block */
	
		pAd->ApCfg.BssidNum = 1;
		pAd->MacTab.MsduLifeTime = 20; /* default 5 seconds */
		pAd->ApCfg.MBSSID[MAIN_MBSSID].bBcnSntReq = TRUE;

#ifdef INF_AMAZON_SE
		printk("YF DEBUG: INF_AMAZON_SE\n");
		for (i = 0; i < NUM_OF_TX_RING; i++)
		{
			pAd->BulkOutDataSizeLimit[i]=24576;
		}
#endif /* INF_AMAZON_SE  */
	
		AsicDisableSync(pAd);

		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
		{
			if (pAd->CommonCfg.Channel > 14)
				pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11AN_MIXED;
			else
				pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BGN_MIXED;
		}
		else
		{
			if (pAd->CommonCfg.Channel > 14)
				pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11A;
			else
				pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BG_MIXED;
		}

		TxPreamble = (pAd->CommonCfg.TxPreamble == Rt802_11PreambleLong ? 0 : 1);	
	}

	PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID];

	const UCHAR *ssid_ie = NULL;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
	ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, pBeacon->beacon+36, pBeacon->beacon_len-36);
#endif
	NdisZeroMemory(pMbss->Ssid, pMbss->SsidLen);
	if (ssid_ie == NULL) 
	{
		printk("YF Debug: SSID Not Found In Packet\n");
		NdisMoveMemory(pMbss->Ssid, "P2P_Linux_AP", 12);
		pMbss->SsidLen = 12;
	}
	else
	{
		pMbss->SsidLen = ssid_ie[1];
		NdisCopyMemory(pMbss->Ssid, ssid_ie+2, pMbss->SsidLen);
		printk("YF Debug: SSID: %s, %d\n", pMbss->Ssid, pMbss->SsidLen);
	}
	
	if (isAdd)
	{
		//if (pMbss->bWmmCapable)
		//{
        		bWmmCapable = FALSE;
			pMbss->bWmmCapable = FALSE;
		//}

		pMbss->MSSIDDev = pAd->net_dev;
		COPY_MAC_ADDR(pMbss->Bssid, pAd->CurrentAddress);
		printk("AP BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->CurrentAddress));
		
		/* GO always use WPA2PSK / AES */
		pMbss->AuthMode = Ndis802_11AuthModeWPA2PSK;
 		pMbss->WepStatus = Ndis802_11Encryption3Enabled;
		pMbss->WscSecurityMode = WPA2PSKAES;
		pMbss->GroupKeyWepStatus = pMbss->WepStatus;
		pMbss->CapabilityInfo =
			CAP_GENERATE(1, 0, (pMbss->WepStatus != Ndis802_11EncryptionDisabled), TxPreamble, pAd->CommonCfg.bUseShortSlotTime, SpectrumMgmt);

		RTMPMakeRSNIE(pAd, Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled, MAIN_MBSSID);

#ifdef DOT11_N_SUPPORT
		RTMPSetPhyMode(pAd,  pAd->CommonCfg.PhyMode);
		SetCommonHT(pAd);

		if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->Antenna.field.TxPath == 2))
		{
			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
			BBPR1 &= (~0x18);
			BBPR1 |= 0x10;
			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
		}
		else
#endif /* DOT11_N_SUPPORT */
		{
			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
			BBPR1 &= (~0x18);
			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
		}
	
		/* Receiver Antenna selection, write to BBP R3(bit4:3) */
		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
		BBPR3 &= (~0x18);
		if(pAd->Antenna.field.RxPath == 3)
		{
			BBPR3 |= (0x10);
		}
		else if(pAd->Antenna.field.RxPath == 2)
		{
			BBPR3 |= (0x8);
		}
		else if(pAd->Antenna.field.RxPath == 1)
		{
			BBPR3 |= (0x0);
		}
		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);

		if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
		{
			if ((pAd->CommonCfg.PhyMode > PHY_11G) || bWmmCapable)
			{
				/* EDCA parameters used for AP's own transmission */
				pAd->CommonCfg.APEdcaParm.bValid = TRUE;
				pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
				pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
				pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
				pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;

				pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
				pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
				pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
				pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;

				pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
				pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
				pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
				pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;

				pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
				pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
				pAd->CommonCfg.APEdcaParm.Txop[2]  = 94;	/*96; */
				pAd->CommonCfg.APEdcaParm.Txop[3]  = 47;	/*48; */
				AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);

				/* EDCA parameters to be annouced in outgoing BEACON, used by WMM STA */
				pAd->ApCfg.BssEdcaParm.bValid = TRUE;
				pAd->ApCfg.BssEdcaParm.Aifsn[0] = 3;
				pAd->ApCfg.BssEdcaParm.Aifsn[1] = 7;
				pAd->ApCfg.BssEdcaParm.Aifsn[2] = 2;
				pAd->ApCfg.BssEdcaParm.Aifsn[3] = 2;

				pAd->ApCfg.BssEdcaParm.Cwmin[0] = 4;
				pAd->ApCfg.BssEdcaParm.Cwmin[1] = 4;
				pAd->ApCfg.BssEdcaParm.Cwmin[2] = 3;
				pAd->ApCfg.BssEdcaParm.Cwmin[3] = 2;

				pAd->ApCfg.BssEdcaParm.Cwmax[0] = 10;
				pAd->ApCfg.BssEdcaParm.Cwmax[1] = 10;
				pAd->ApCfg.BssEdcaParm.Cwmax[2] = 4;
				pAd->ApCfg.BssEdcaParm.Cwmax[3] = 3;
	
				pAd->ApCfg.BssEdcaParm.Txop[0]  = 0;
				pAd->ApCfg.BssEdcaParm.Txop[1]  = 0;
				pAd->ApCfg.BssEdcaParm.Txop[2]  = 94;	/*96; */
				pAd->ApCfg.BssEdcaParm.Txop[3]  = 47;	/*48; */
			}
			else
			{
				AsicSetEdcaParm(pAd, NULL);
			}
		}

#ifdef DOT11_N_SUPPORT
		if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
		{
			/* Patch UI */
			pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = BW_20;
		}

		/* init */
		if (pAd->CommonCfg.bRdg)
		{	
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
			AsicEnableRDG(pAd);
		}
		else	
		{
			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RDG_ACTIVE);
			AsicDisableRDG(pAd);
		}	
#endif /* DOT11_N_SUPPORT */

		//AsicSetBssid(pAd, pAd->CurrentAddress); 
		AsicSetMcastWC(pAd);
		
		/* In AP mode,  First WCID Table in ASIC will never be used. To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
		/* p.s ASIC use all 0xff as termination of WCID table search. */
		RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
		RTMP_IO_WRITE32(pAd, MAC_WCID_BASE+4, 0x0);

		/* reset WCID table */
		for (idx=2; idx<255; idx++)
		{
			offset = MAC_WCID_BASE + (idx * HW_WCID_ENTRY_SIZE);	
			RTMP_IO_WRITE32(pAd, offset, 0x0);
			RTMP_IO_WRITE32(pAd, offset+4, 0x0);
		}

		pAd->MacTab.Content[0].Addr[0] = 0x01;
		pAd->MacTab.Content[0].HTPhyMode.field.MODE = MODE_OFDM;
		pAd->MacTab.Content[0].HTPhyMode.field.MCS = 3;

		AsicBBPAdjust(pAd);
		//MlmeSetTxPreamble(pAd, (USHORT)pAd->CommonCfg.TxPreamble);	
	
		{
			ULONG	Addr4;
			UINT32	regValue;
			PUCHAR pP2PBssid = &pAd->CurrentAddress[0];
		
			Addr4 = (ULONG)(pP2PBssid[0])	    | 
				(ULONG)(pP2PBssid[1] << 8)  | 
				(ULONG)(pP2PBssid[2] << 16) |
				(ULONG)(pP2PBssid[3] << 24);
			RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
	
			Addr4 = 0;

			Addr4 = (ULONG)(pP2PBssid[4]) | (ULONG)(pP2PBssid[5] << 8);
			RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
	
			RTMP_IO_READ32(pAd, MAC_BSSID_DW1, &regValue);
			regValue &= 0x0000FFFF;

			regValue |= (1 << 16);

			if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
				regValue |= (1 << 21);
			RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, regValue);		
		}
	

#ifdef RTMP_MAC_USB
		printk("YF DEBUG: RTUSBBssBeaconInit\n");
        	RTUSBBssBeaconInit(pAd);
#endif /* RTMP_MAC_USB */
	}

	UCHAR apcliIdx, apidx = MAIN_MBSSID;

	//pAd->ApCfg.MBSSID[MAIN_MBSSID].PhyMode = PHY_11BGN_MIXED;


	printk("YF DEBUG: Beacon Len %d\n", pBeacon->beacon_len);
	printk("YF DEBUG: Beacon Interval %d\n", pBeacon->interval);
        BeaconTransmit.word = 0;

        RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID,
                pBeacon->beacon_len, PID_MGMT, 0, 0,IFS_HTTXOP, FALSE, &BeaconTransmit);

        ptr = (PUCHAR)&pAd->BeaconTxWI;
#ifdef RT_BIG_ENDIAN
        RTMPWIEndianChange(ptr, TYPE_TXWI);
#endif

        for (i=0; i<TXWISize; i+=4)  /* 16-byte TXWI field */
        {
                longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
                RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[0] + i, longValue);
                ptr += 4;
        }

        /* update BEACON frame content. start right after the 16-byte TXWI field. */
        ptr = pBeacon->beacon;
#ifdef RT_BIG_ENDIAN
        RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
#endif

        for (i= 0; i< pBeacon->beacon_len; i+=4)
        {
                longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
                RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[0] + TXWISize + i, longValue);
                ptr += 4;
        }

	if (isAdd)
	{
		/* Enable Bss Sync*/
		RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
        	csr9.field.BeaconInterval = (pBeacon->interval) << 4; /* ASIC register in units of 1/16 TU*/
        	csr9.field.bTsfTicking = 1;
        	csr9.field.TsfSyncMode = 3;
	        csr9.field.bTBTTEnable = 1;
        	csr9.field.bBeaconGen = 1;
	        RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);

		pAd->P2pCfg.bSentProbeRSP = TRUE;

#ifdef RTMP_MAC_USB
		/*
		 * Support multiple BulkIn IRP,
	 	 * the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
		 */
	
		UCHAR num_idx;

		for(num_idx=0; num_idx < pAd->CommonCfg.NumOfBulkInIRP; num_idx++)
		{
			RTUSBBulkReceive(pAd);
			printk("RTUSBBulkReceive!\n" );
		}
	
#endif /* RTMP_MAC_USB */
	}

#ifdef WFD_SUPPORT
	pAd->StaCfg.WfdCfg.bSuppGoOn = TRUE;
#endif /* WFD_SUPPORT */
		
	return TRUE;

}