diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2008-09-13 22:12:57 +0200 |
---|---|---|
committer | Luis R. Rodriguez <lrodriguez@atheros.com> | 2008-09-15 09:44:47 -0700 |
commit | 56f9673db912e7509b9b1331f0f692578b542f6b (patch) | |
tree | bc3d615bd9bf6cf901be0c64c84fb901a5f17e7f | |
parent | ff88abe209b342f1704f24eff1fd4d0b1a9663e3 (diff) | |
download | compat-wireless-2.6-old-56f9673db912e7509b9b1331f0f692578b542f6b.tar.gz |
Backport: cfg80211: keep track of supported interface modes
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
-rw-r--r-- | drivers/net/wireless/adm8211.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 5 | ||||
-rw-r--r-- | include/linux/nl80211.h | 6 | ||||
-rw-r--r-- | include/net/wireless.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 7 | ||||
-rw-r--r-- | net/wireless/core.c | 9 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 22 |
10 files changed, 61 insertions, 3 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 9d1770b..4a0b050 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -1963,6 +1963,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); dev->channel_change_time = 1000; dev->max_signal = 100; /* FIXME: find better value */ diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index da80d88..6087257 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -448,6 +448,9 @@ static int __init init_mac80211_hwsim(void) hw->channel_change_time = 1; hw->queues = 1; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP); memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 0ab83a8..e4db844 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -991,6 +991,9 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SIGNAL_UNSPEC; + + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + dev->channel_change_time = 1000; /* TODO: find actual value */ dev->max_signal = 127; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 56dbc23..5857189 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1048,6 +1048,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); + rt2x00dev->hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + /* * Let the driver probe the device to detect the capabilities. */ diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 175d247..be81d09 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -938,6 +938,11 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | IEEE80211_HW_SIGNAL_DB; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_MESH_POINT) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + hw->max_signal = 100; hw->queues = 1; hw->extra_tx_headroom = sizeof(struct zd_ctrlset); diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 2be7c63..2bd5f1a 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -192,6 +192,10 @@ enum nl80211_commands { * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of * &enum nl80211_mntr_flags. * + * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all + * supported interface types, each a flag attribute with the number + * of the interface mode. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -235,6 +239,8 @@ enum nl80211_attrs { NL80211_ATTR_MPATH_NEXT_HOP, NL80211_ATTR_MPATH_INFO, + NL80211_ATTR_SUPPORTED_IFTYPES, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/wireless.h b/include/net/wireless.h index 9324f8d..1dc8ec3 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h @@ -185,6 +185,9 @@ struct wiphy { /* permanent MAC address */ u8 perm_addr[ETH_ALEN]; + /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ + u16 interface_modes; + /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't * know whether it points to a wiphy your driver has registered diff --git a/net/mac80211/main.c b/net/mac80211/main.c index fe3b128..261718a 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1660,6 +1660,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) } } + /* if low-level driver supports AP, we also support VLAN */ + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) + local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); + + /* mac80211 always supports monitor */ + local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); + result = wiphy_register(local->hw.wiphy); if (result < 0) return result; diff --git a/net/wireless/core.c b/net/wireless/core.c index 617673d..0ba5a4f 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1,7 +1,7 @@ /* * This is the linux wireless configuration interface. * - * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> + * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net> */ #include <linux/if.h> @@ -259,6 +259,13 @@ int wiphy_register(struct wiphy *wiphy) struct ieee80211_supported_band *sband; bool have_band = false; int i; + u16 ifmodes = wiphy->interface_modes; + + /* sanity check ifmodes */ + WARN_ON(!ifmodes); + ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; + if (WARN_ON(ifmodes != wiphy->interface_modes)) + wiphy->interface_modes = ifmodes; /* sanity check supported bands/channels */ for (band = 0; band < IEEE80211_NUM_BANDS; band++) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cfe4130..772f8aa 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -106,10 +106,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct nlattr *nl_bands, *nl_band; struct nlattr *nl_freqs, *nl_freq; struct nlattr *nl_rates, *nl_rate; + struct nlattr *nl_modes; enum ieee80211_band band; struct ieee80211_channel *chan; struct ieee80211_rate *rate; int i; + u16 ifmodes = dev->wiphy.interface_modes; hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); if (!hdr) @@ -118,6 +120,20 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); + nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); + if (!nl_modes) + goto nla_put_failure; + + i = 0; + while (ifmodes) { + if (ifmodes & 1) + NLA_PUT_FLAG(msg, i); + ifmodes >>= 1; + i++; + } + + nla_nest_end(msg, nl_modes); + nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); if (!nl_bands) goto nla_put_failure; @@ -398,7 +414,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) ifindex = dev->ifindex; dev_put(dev); - if (!drv->ops->change_virtual_intf) { + if (!drv->ops->change_virtual_intf || + !(drv->wiphy.interface_modes & (1 << type))) { err = -EOPNOTSUPP; goto unlock; } @@ -445,7 +462,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(drv)) return PTR_ERR(drv); - if (!drv->ops->add_virtual_intf) { + if (!drv->ops->add_virtual_intf || + !(drv->wiphy.interface_modes & (1 << type))) { err = -EOPNOTSUPP; goto unlock; } |