コード例 #1
0
ファイル: wext-compat.c プロジェクト: GerardGarcia/linux
static int cfg80211_wext_siwfreq(struct net_device *dev,
				 struct iw_request_info *info,
				 struct iw_freq *wextfreq, char *extra)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
	int freq, err;

	switch (wdev->iftype) {
	case NL80211_IFTYPE_STATION:
		return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
	case NL80211_IFTYPE_ADHOC:
		return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
	case NL80211_IFTYPE_MONITOR:
	case NL80211_IFTYPE_WDS:
	case NL80211_IFTYPE_MESH_POINT:
		freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
		if (freq < 0)
			return freq;
		if (freq == 0)
			return -EINVAL;
		mutex_lock(&rdev->devlist_mtx);
		wdev_lock(wdev);
		err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
		wdev_unlock(wdev);
		mutex_unlock(&rdev->devlist_mtx);
		return err;
	default:
		return -EOPNOTSUPP;
	}
}
コード例 #2
0
int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
                               struct iw_request_info *info,
                               struct iw_freq *wextfreq, char *extra)
{
    struct wireless_dev *wdev = dev->ieee80211_ptr;
    struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
    struct ieee80211_channel *chan = NULL;
    int err, freq;

    /* call only for ibss! */
    if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
        return -EINVAL;

    if (!rdev->ops->join_ibss)
        return -EOPNOTSUPP;

    freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
    if (freq < 0)
        return freq;

    if (freq) {
        chan = ieee80211_get_channel(wdev->wiphy, freq);
        if (!chan)
            return -EINVAL;
        if (chan->flags & IEEE80211_CHAN_NO_IBSS ||
                chan->flags & IEEE80211_CHAN_DISABLED)
            return -EINVAL;
    }

    if (wdev->wext.ibss.chandef.chan == chan)
        return 0;

    wdev_lock(wdev);
    err = 0;
    if (wdev->ssid_len)
        err = __cfg80211_leave_ibss(rdev, dev, true);
    wdev_unlock(wdev);

    if (err)
        return err;

    if (chan) {
        wdev->wext.ibss.chandef.chan = chan;
        wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
        wdev->wext.ibss.channel_fixed = true;
    } else {
        /* cfg80211_ibss_wext_join will pick one if needed */
        wdev->wext.ibss.channel_fixed = false;
    }

    mutex_lock(&rdev->devlist_mtx);
    wdev_lock(wdev);
    err = cfg80211_ibss_wext_join(rdev, wdev);
    wdev_unlock(wdev);
    mutex_unlock(&rdev->devlist_mtx);

    return err;
}
コード例 #3
0
static int cfg80211_wext_siwfreq(struct net_device *dev,
				 struct iw_request_info *info,
				 struct iw_freq *wextfreq, char *extra)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_chan_def chandef = {
		.width = NL80211_CHAN_WIDTH_20_NOHT,
	};
	int freq;

	switch (wdev->iftype) {
	case NL80211_IFTYPE_STATION:
		return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
	case NL80211_IFTYPE_ADHOC:
		return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
	case NL80211_IFTYPE_MONITOR:
		freq = cfg80211_wext_freq(wextfreq);
		if (freq < 0)
			return freq;
		if (freq == 0)
			return -EINVAL;
		chandef.center_freq1 = freq;
		chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
		if (!chandef.chan)
			return -EINVAL;
		return cfg80211_set_monitor_channel(rdev, &chandef);
	case NL80211_IFTYPE_MESH_POINT:
		freq = cfg80211_wext_freq(wextfreq);
		if (freq < 0)
			return freq;
		if (freq == 0)
			return -EINVAL;
		chandef.center_freq1 = freq;
		chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
		if (!chandef.chan)
			return -EINVAL;
		return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
	default:
		return -EOPNOTSUPP;
	}
}
コード例 #4
0
ファイル: wext-sme.c プロジェクト: garwynn/I727_JB_Kernel_v1
int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
			      struct iw_request_info *info,
			      struct iw_freq *wextfreq, char *extra)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
	struct ieee80211_channel *chan = NULL;
	int err, freq;

	/* call only for station! */
	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
		return -EINVAL;

	freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
	if (freq < 0)
		return freq;

	if (freq) {
		chan = ieee80211_get_channel(wdev->wiphy, freq);
		if (!chan)
			return -EINVAL;
		if (chan->flags & IEEE80211_CHAN_DISABLED)
			return -EINVAL;
	}

	cfg80211_lock_rdev(rdev);
	mutex_lock(&rdev->devlist_mtx);
	wdev_lock(wdev);

	if (wdev->sme_state != CFG80211_SME_IDLE) {
		bool event = true;

		if (wdev->wext.connect.channel == chan) {
			err = 0;
			goto out;
		}

		/* if SSID set, we'll try right again, avoid event */
		if (wdev->wext.connect.ssid_len)
			event = false;
		err = __cfg80211_disconnect(rdev, dev,
					    WLAN_REASON_DEAUTH_LEAVING, event);
		if (err)
			goto out;
	}


	wdev->wext.connect.channel = chan;

	/* SSID is not set, we just want to switch channel */
	if (chan && !wdev->wext.connect.ssid_len) {
		err = cfg80211_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
		goto out;
	}

	err = cfg80211_mgd_wext_connect(rdev, wdev);
 out:
	wdev_unlock(wdev);
	mutex_unlock(&rdev->devlist_mtx);
	cfg80211_unlock_rdev(rdev);
	return err;
}
コード例 #5
0
ファイル: wext-sme.c プロジェクト: 020gzh/linux
int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
			      struct iw_request_info *info,
			      struct iw_freq *wextfreq, char *extra)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct ieee80211_channel *chan = NULL;
	int err, freq;

	/* call only for station! */
	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
		return -EINVAL;

	freq = cfg80211_wext_freq(wextfreq);
	if (freq < 0)
		return freq;

	if (freq) {
		chan = ieee80211_get_channel(wdev->wiphy, freq);
		if (!chan)
			return -EINVAL;
		if (chan->flags & IEEE80211_CHAN_DISABLED)
			return -EINVAL;
	}

	wdev_lock(wdev);

	if (wdev->conn) {
		bool event = true;

		if (wdev->wext.connect.channel == chan) {
			err = 0;
			goto out;
		}

		/* if SSID set, we'll try right again, avoid event */
		if (wdev->wext.connect.ssid_len)
			event = false;
		err = cfg80211_disconnect(rdev, dev,
					  WLAN_REASON_DEAUTH_LEAVING, event);
		if (err)
			goto out;
	}


	wdev->wext.connect.channel = chan;

	/*
	 * SSID is not set, we just want to switch monitor channel,
	 * this is really just backward compatibility, if the SSID
	 * is set then we use the channel to select the BSS to use
	 * to connect to instead. If we were connected on another
	 * channel we disconnected above and reconnect below.
	 */
	if (chan && !wdev->wext.connect.ssid_len) {
		struct cfg80211_chan_def chandef = {
			.width = NL80211_CHAN_WIDTH_20_NOHT,
			.center_freq1 = freq,
		};

		chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
		if (chandef.chan)
			err = cfg80211_set_monitor_channel(rdev, &chandef);
		else
			err = -EINVAL;
		goto out;
	}

	err = cfg80211_mgd_wext_connect(rdev, wdev);
 out:
	wdev_unlock(wdev);
	return err;
}