예제 #1
0
파일: ibss.c 프로젝트: asmalldev/linux
static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
				struct net_device *dev,
				struct cfg80211_ibss_params *params,
				struct cfg80211_cached_keys *connkeys)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	int err;

	ASSERT_WDEV_LOCK(wdev);

	if (wdev->ssid_len)
		return -EALREADY;

	if (!params->basic_rates) {
		/*
		* If no rates were explicitly configured,
		* use the mandatory rate set for 11b or
		* 11a for maximum compatibility.
		*/
		struct ieee80211_supported_band *sband =
			rdev->wiphy.bands[params->chandef.chan->band];
		int j;
		u32 flag = params->chandef.chan->band == NL80211_BAND_5GHZ ?
			IEEE80211_RATE_MANDATORY_A :
			IEEE80211_RATE_MANDATORY_B;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].flags & flag)
				params->basic_rates |= BIT(j);
		}
	}

	if (WARN_ON(connkeys && connkeys->def < 0))
		return -EINVAL;

	if (WARN_ON(wdev->connect_keys))
		kzfree(wdev->connect_keys);
	wdev->connect_keys = connkeys;

	wdev->ibss_fixed = params->channel_fixed;
	wdev->ibss_dfs_possible = params->userspace_handles_dfs;
	wdev->chandef = params->chandef;
#ifdef CONFIG_CFG80211_WEXT
	wdev->wext.ibss.chandef = params->chandef;
#endif
	err = rdev_join_ibss(rdev, dev, params);
	if (err) {
		wdev->connect_keys = NULL;
		return err;
	}

	memcpy(wdev->ssid, params->ssid, params->ssid_len);
	wdev->ssid_len = params->ssid_len;

	return 0;
}
예제 #2
0
int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
                         struct net_device *dev,
                         struct cfg80211_ibss_params *params,
                         struct cfg80211_cached_keys *connkeys)
{
    struct wireless_dev *wdev = dev->ieee80211_ptr;
    int err;

    ASSERT_WDEV_LOCK(wdev);

    if (wdev->ssid_len)
        return -EALREADY;

    if (!params->basic_rates) {
        /*
        * If no rates were explicitly configured,
        * use the mandatory rate set for 11b or
        * 11a for maximum compatibility.
        */
        struct ieee80211_supported_band *sband =
                rdev->wiphy.bands[params->chandef.chan->band];
        int j;
        u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
                   IEEE80211_RATE_MANDATORY_A :
                   IEEE80211_RATE_MANDATORY_B;

        for (j = 0; j < sband->n_bitrates; j++) {
            if (sband->bitrates[j].flags & flag)
                params->basic_rates |= BIT(j);
        }
    }

    if (WARN_ON(wdev->connect_keys))
        kfree(wdev->connect_keys);
    wdev->connect_keys = connkeys;

    wdev->ibss_fixed = params->channel_fixed;
#ifdef CONFIG_CFG80211_WEXT
    wdev->wext.ibss.chandef = params->chandef;
#endif
    wdev->sme_state = CFG80211_SME_CONNECTING;

    err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan,
                                params->channel_fixed
                                ? CHAN_MODE_SHARED
                                : CHAN_MODE_EXCLUSIVE);
    if (err) {
        wdev->connect_keys = NULL;
        return err;
    }

    err = rdev_join_ibss(rdev, dev, params);
    if (err) {
        wdev->connect_keys = NULL;
        wdev->sme_state = CFG80211_SME_IDLE;
        return err;
    }

    memcpy(wdev->ssid, params->ssid, params->ssid_len);
    wdev->ssid_len = params->ssid_len;

    return 0;
}
예제 #3
0
int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
			 struct net_device *dev,
			 struct cfg80211_ibss_params *params,
			 struct cfg80211_cached_keys *connkeys)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct ieee80211_channel *check_chan;
	u8 radar_detect_width = 0;
	int err;

	ASSERT_WDEV_LOCK(wdev);

	if (wdev->ssid_len)
		return -EALREADY;

	if (!params->basic_rates) {
		/*
		* If no rates were explicitly configured,
		* use the mandatory rate set for 11b or
		* 11a for maximum compatibility.
		*/
		struct ieee80211_supported_band *sband =
			rdev->wiphy.bands[params->chandef.chan->band];
		int j;
		u32 flag = params->chandef.chan->band == IEEE80211_BAND_5GHZ ?
			IEEE80211_RATE_MANDATORY_A :
			IEEE80211_RATE_MANDATORY_B;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].flags & flag)
				params->basic_rates |= BIT(j);
		}
	}

	if (WARN_ON(wdev->connect_keys))
		kfree(wdev->connect_keys);
	wdev->connect_keys = connkeys;

	wdev->ibss_fixed = params->channel_fixed;
	wdev->ibss_dfs_possible = params->userspace_handles_dfs;
#ifdef CONFIG_CFG80211_WEXT
	wdev->wext.ibss.chandef = params->chandef;
#endif
	check_chan = params->chandef.chan;
	if (params->userspace_handles_dfs) {
		/* use channel NULL to check for radar even if the current
		 * channel is not a radar channel - it might decide to change
		 * to DFS channel later.
		 */
		radar_detect_width = BIT(params->chandef.width);
		check_chan = NULL;
	}

	err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
					   check_chan,
					   (params->channel_fixed &&
					    !radar_detect_width)
					   ? CHAN_MODE_SHARED
					   : CHAN_MODE_EXCLUSIVE,
					   radar_detect_width);

	if (err) {
		wdev->connect_keys = NULL;
		return err;
	}

	err = rdev_join_ibss(rdev, dev, params);
	if (err) {
		wdev->connect_keys = NULL;
		return err;
	}

	memcpy(wdev->ssid, params->ssid, params->ssid_len);
	wdev->ssid_len = params->ssid_len;

	return 0;
}