diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2010-01-20 06:02:33 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-22 16:11:16 -0500 |
commit | ef15aac6073b27fd4f70007784d2d52ed394bf43 (patch) | |
tree | 80eeb99e74263e255d4e8af582550a6363ad7884 /net | |
parent | b3fbdcf49f940d0703c356441e0daf045e64e076 (diff) |
cfg80211: export multiple MAC addresses in sysfs
If a device has multiple MAC addresses, userspace will
need to know about that. Similarly, if it allows the
MAC addresses to vary by a bitmask.
If a driver exports multiple addresses, it is assumed
that it will be able to deal with that many different
addresses, which need not necessarily match the ones
programmed into the device; if a mask is set then the
device should deal addresses within that mask based
on an arbitrary "base address".
To test it all and show how it is used, add support
to hwsim even though it can't actually deal with
addresses different from the default.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/core.c | 12 | ||||
-rw-r--r-- | net/wireless/sysfs.c | 20 |
2 files changed, 32 insertions, 0 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index d07f57c906db..71b6b3a9cf1f 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -413,6 +413,18 @@ int wiphy_register(struct wiphy *wiphy) | |||
413 | int i; | 413 | int i; |
414 | u16 ifmodes = wiphy->interface_modes; | 414 | u16 ifmodes = wiphy->interface_modes; |
415 | 415 | ||
416 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) | ||
417 | return -EINVAL; | ||
418 | |||
419 | if (WARN_ON(wiphy->addresses && | ||
420 | !is_zero_ether_addr(wiphy->perm_addr) && | ||
421 | memcmp(wiphy->perm_addr, wiphy->addresses[0].addr, | ||
422 | ETH_ALEN))) | ||
423 | return -EINVAL; | ||
424 | |||
425 | if (wiphy->addresses) | ||
426 | memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN); | ||
427 | |||
416 | /* sanity check ifmodes */ | 428 | /* sanity check ifmodes */ |
417 | WARN_ON(!ifmodes); | 429 | WARN_ON(!ifmodes); |
418 | ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; | 430 | ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index efe3c5c92b2d..9f2cef3e0ca0 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -33,10 +33,30 @@ static ssize_t name ## _show(struct device *dev, \ | |||
33 | 33 | ||
34 | SHOW_FMT(index, "%d", wiphy_idx); | 34 | SHOW_FMT(index, "%d", wiphy_idx); |
35 | SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); | 35 | SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); |
36 | SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); | ||
37 | |||
38 | static ssize_t addresses_show(struct device *dev, | ||
39 | struct device_attribute *attr, | ||
40 | char *buf) | ||
41 | { | ||
42 | struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; | ||
43 | char *start = buf; | ||
44 | int i; | ||
45 | |||
46 | if (!wiphy->addresses) | ||
47 | return sprintf(buf, "%pM\n", wiphy->perm_addr); | ||
48 | |||
49 | for (i = 0; i < wiphy->n_addresses; i++) | ||
50 | buf += sprintf(buf, "%pM\n", &wiphy->addresses[i].addr); | ||
51 | |||
52 | return buf - start; | ||
53 | } | ||
36 | 54 | ||
37 | static struct device_attribute ieee80211_dev_attrs[] = { | 55 | static struct device_attribute ieee80211_dev_attrs[] = { |
38 | __ATTR_RO(index), | 56 | __ATTR_RO(index), |
39 | __ATTR_RO(macaddress), | 57 | __ATTR_RO(macaddress), |
58 | __ATTR_RO(address_mask), | ||
59 | __ATTR_RO(addresses), | ||
40 | {} | 60 | {} |
41 | }; | 61 | }; |
42 | 62 | ||