Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 194979
b: refs/heads/master
c: f444de0
h: refs/heads/master
i:
  194977: 94d91fd
  194975: 8f629c1
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed May 7, 2010
1 parent 3369133 commit 8066987
Show file tree
Hide file tree
Showing 17 changed files with 301 additions and 109 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ac8dd506e40ee2c7fcc61654a44c32555a0a8d6c
refs/heads/master: f444de05d20e27cdd960c13fcbcfca3099f03143
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/libertas/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ static const u32 cipher_suites[] = {


static int lbs_cfg_set_channel(struct wiphy *wiphy,
struct net_device *netdev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/orinoco/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
}

static int orinoco_set_channel(struct wiphy *wiphy,
struct net_device *netdev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/wireless/rndis_wlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,

static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);

static int rndis_set_channel(struct wiphy *wiphy,
static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);

static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
Expand Down Expand Up @@ -2290,7 +2290,7 @@ static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
return deauthenticate(usbdev);
}

static int rndis_set_channel(struct wiphy *wiphy,
static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev,
struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
Expand Down
13 changes: 13 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
* %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
* %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
* and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
* However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
* instead, the support here is for backward compatibility only.
* @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
* or rename notification. Has attributes %NL80211_ATTR_WIPHY and
* %NL80211_ATTR_WIPHY_NAME.
Expand Down Expand Up @@ -329,6 +331,15 @@
* @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This
* command is used as an event to indicate the that a trigger level was
* reached.
* @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
* and %NL80211_ATTR_WIPHY_CHANNEL_TYPE) the given interface (identifed
* by %NL80211_ATTR_IFINDEX) shall operate on.
* In case multiple channels are supported by the device, the mechanism
* with which it switches channels is implementation-defined.
* When a monitor interface is given, it can only switch channel while
* no other interfaces are operating to avoid disturbing the operation
* of any other interfaces, and other interfaces will again take
* precedence when they are used.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
Expand Down Expand Up @@ -428,6 +439,8 @@ enum nl80211_commands {
NL80211_CMD_SET_CQM,
NL80211_CMD_NOTIFY_CQM,

NL80211_CMD_SET_CHANNEL,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down
11 changes: 9 additions & 2 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,11 @@ struct cfg80211_pmksa {
*
* @set_txq_params: Set TX queue parameters
*
* @set_channel: Set channel
* @set_channel: Set channel for a given wireless interface. Some devices
* may support multi-channel operation (by channel hopping) so cfg80211
* doesn't verify much. Note, however, that the passed netdev may be
* %NULL as well if the user requested changing the channel for the
* device itself, or for a monitor interface.
*
* @scan: Request to do a scan. If returning zero, the scan request is given
* the driver, and will be valid until passed to cfg80211_scan_done().
Expand Down Expand Up @@ -1095,7 +1099,7 @@ struct cfg80211_ops {
int (*set_txq_params)(struct wiphy *wiphy,
struct ieee80211_txq_params *params);

int (*set_channel)(struct wiphy *wiphy,
int (*set_channel)(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type);

Expand Down Expand Up @@ -1461,6 +1465,8 @@ struct cfg80211_cached_keys;
* @list: (private) Used to collect the interfaces
* @netdev: (private) Used to reference back to the netdev
* @current_bss: (private) Used by the internal configuration code
* @channel: (private) Used by the internal configuration code to track
* user-set AP, monitor and WDS channels for wireless extensions
* @bssid: (private) Used by the internal configuration code
* @ssid: (private) Used by the internal configuration code
* @ssid_len: (private) Used by the internal configuration code
Expand Down Expand Up @@ -1507,6 +1513,7 @@ struct wireless_dev {
struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
struct cfg80211_internal_bss *current_bss; /* associated / joined */
struct ieee80211_channel *channel;

bool ps;
int ps_timeout;
Expand Down
3 changes: 2 additions & 1 deletion trunk/net/mac80211/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ mac80211-y := \
key.o \
util.o \
wme.o \
event.o
event.o \
chan.o

mac80211-$(CONFIG_MAC80211_LEDS) += led.o
mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
Expand Down
41 changes: 41 additions & 0 deletions trunk/net/mac80211/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,11 +1161,24 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
}

static int ieee80211_set_channel(struct wiphy *wiphy,
struct net_device *netdev,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
struct ieee80211_local *local = wiphy_priv(wiphy);

switch (ieee80211_get_channel_mode(local, NULL)) {
case CHAN_MODE_HOPPING:
return -EBUSY;
case CHAN_MODE_FIXED:
if (local->oper_channel == chan &&
local->oper_channel_type == channel_type)
return 0;
return -EBUSY;
case CHAN_MODE_UNDEFINED:
break;
}

local->oper_channel = chan;
local->oper_channel_type = channel_type;

Expand Down Expand Up @@ -1213,6 +1226,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_assoc_request *req)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

switch (ieee80211_get_channel_mode(local, sdata)) {
case CHAN_MODE_HOPPING:
return -EBUSY;
case CHAN_MODE_FIXED:
if (local->oper_channel == req->bss->channel)
break;
return -EBUSY;
case CHAN_MODE_UNDEFINED:
break;
}

return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
}

Expand All @@ -1235,8 +1262,22 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ibss_params *params)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

switch (ieee80211_get_channel_mode(local, sdata)) {
case CHAN_MODE_HOPPING:
return -EBUSY;
case CHAN_MODE_FIXED:
if (!params->channel_fixed)
return -EBUSY;
if (local->oper_channel == params->channel)
break;
return -EBUSY;
case CHAN_MODE_UNDEFINED:
break;
}

return ieee80211_ibss_join(sdata, params);
}

Expand Down
57 changes: 57 additions & 0 deletions trunk/net/mac80211/chan.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* mac80211 - channel management
*/

#include "ieee80211_i.h"

enum ieee80211_chan_mode
__ieee80211_get_channel_mode(struct ieee80211_local *local,
struct ieee80211_sub_if_data *ignore)
{
struct ieee80211_sub_if_data *sdata;

WARN_ON(!mutex_is_locked(&local->iflist_mtx));

list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata == ignore)
continue;

if (!ieee80211_sdata_running(sdata))
continue;

if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
continue;

if (sdata->vif.type == NL80211_IFTYPE_STATION &&
!sdata->u.mgd.associated)
continue;

if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
if (!sdata->u.ibss.ssid_len)
continue;
if (!sdata->u.ibss.fixed_channel)
return CHAN_MODE_HOPPING;
}

if (sdata->vif.type == NL80211_IFTYPE_AP &&
!sdata->u.ap.beacon)
continue;

return CHAN_MODE_FIXED;
}

return CHAN_MODE_UNDEFINED;
}

enum ieee80211_chan_mode
ieee80211_get_channel_mode(struct ieee80211_local *local,
struct ieee80211_sub_if_data *ignore)
{
enum ieee80211_chan_mode mode;

mutex_lock(&local->iflist_mtx);
mode = __ieee80211_get_channel_mode(local, ignore);
mutex_unlock(&local->iflist_mtx);

return mode;
}
11 changes: 11 additions & 0 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,17 @@ int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
int ieee80211_wk_cancel_remain_on_channel(
struct ieee80211_sub_if_data *sdata, u64 cookie);

/* channel management */
enum ieee80211_chan_mode {
CHAN_MODE_UNDEFINED,
CHAN_MODE_HOPPING,
CHAN_MODE_FIXED,
};

enum ieee80211_chan_mode
ieee80211_get_channel_mode(struct ieee80211_local *local,
struct ieee80211_sub_if_data *ignore);

#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
#else
Expand Down
56 changes: 17 additions & 39 deletions trunk/net/wireless/chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,6 @@
#include <net/cfg80211.h>
#include "core.h"

struct ieee80211_channel *
rdev_fixed_channel(struct cfg80211_registered_device *rdev,
struct wireless_dev *for_wdev)
{
struct wireless_dev *wdev;
struct ieee80211_channel *result = NULL;

WARN_ON(!mutex_is_locked(&rdev->devlist_mtx));

list_for_each_entry(wdev, &rdev->netdev_list, list) {
if (wdev == for_wdev)
continue;

/*
* Lock manually to tell lockdep about allowed
* nesting here if for_wdev->mtx is held already.
* This is ok as it's all under the rdev devlist
* mutex and as such can only be done once at any
* given time.
*/
mutex_lock_nested(&wdev->mtx, SINGLE_DEPTH_NESTING);
if (wdev->current_bss)
result = wdev->current_bss->pub.channel;
wdev_unlock(wdev);

if (result)
break;
}

return result;
}

struct ieee80211_channel *
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
int freq, enum nl80211_channel_type channel_type)
Expand Down Expand Up @@ -75,15 +43,22 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
return chan;
}

int rdev_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *for_wdev,
int freq, enum nl80211_channel_type channel_type)
int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int freq,
enum nl80211_channel_type channel_type)
{
struct ieee80211_channel *chan;
int result;

if (rdev_fixed_channel(rdev, for_wdev))
return -EBUSY;
if (wdev->iftype == NL80211_IFTYPE_MONITOR)
wdev = NULL;

if (wdev) {
ASSERT_WDEV_LOCK(wdev);

if (!netif_running(wdev->netdev))
return -ENETDOWN;
}

if (!rdev->ops->set_channel)
return -EOPNOTSUPP;
Expand All @@ -92,11 +67,14 @@ int rdev_set_freq(struct cfg80211_registered_device *rdev,
if (!chan)
return -EINVAL;

result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type);
result = rdev->ops->set_channel(&rdev->wiphy,
wdev ? wdev->netdev : NULL,
chan, channel_type);
if (result)
return result;

rdev->channel = chan;
if (wdev)
wdev->channel = chan;

return 0;
}
12 changes: 3 additions & 9 deletions trunk/net/wireless/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ struct cfg80211_registered_device {
struct work_struct conn_work;
struct work_struct event_work;

/* current channel */
struct ieee80211_channel *channel;

/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
Expand Down Expand Up @@ -387,15 +384,12 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
u32 *flags, struct vif_params *params);
void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);

struct ieee80211_channel *
rdev_fixed_channel(struct cfg80211_registered_device *rdev,
struct wireless_dev *for_wdev);
struct ieee80211_channel *
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
int freq, enum nl80211_channel_type channel_type);
int rdev_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *for_wdev,
int freq, enum nl80211_channel_type channel_type);
int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int freq,
enum nl80211_channel_type channel_type);

u16 cfg80211_calculate_bitrate(struct rate_info *rate);

Expand Down
5 changes: 0 additions & 5 deletions trunk/net/wireless/ibss.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,10 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
struct cfg80211_cached_keys *connkeys)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct ieee80211_channel *chan;
int err;

ASSERT_WDEV_LOCK(wdev);

chan = rdev_fixed_channel(rdev, wdev);
if (chan && chan != params->channel)
return -EBUSY;

if (wdev->ssid_len)
return -EALREADY;

Expand Down
Loading

0 comments on commit 8066987

Please sign in to comment.