aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-10-15 16:11:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-15 16:11:56 -0400
commitc64557d666eb62eb5f296c6b93bd0a5525ed1e36 (patch)
tree1e25cc32521d06ae876de18bb8e48b3cf9d30808 /net/wireless
parent1a63c353c856c9f6d44a533afb6ad6dbbcdea683 (diff)
parent0d91f22b75347d9503b17a42b6c74d3f7750acd6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/mlme.c23
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/radiotap.c58
-rw-r--r--net/wireless/sysfs.c9
-rw-r--r--net/wireless/wext-compat.c4
6 files changed, 104 insertions, 59 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 1684ad91763c..9c21ebf9780e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
178 char *newname) 178 char *newname)
179{ 179{
180 struct cfg80211_registered_device *rdev2; 180 struct cfg80211_registered_device *rdev2;
181 int result; 181 int wiphy_idx, taken = -1, result, digits;
182 182
183 assert_cfg80211_lock(); 183 assert_cfg80211_lock();
184 184
185 /* prohibit calling the thing phy%d when %d is not its number */
186 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
187 if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
188 /* count number of places needed to print wiphy_idx */
189 digits = 1;
190 while (wiphy_idx /= 10)
191 digits++;
192 /*
193 * deny the name if it is phy<idx> where <idx> is printed
194 * without leading zeroes. taken == strlen(newname) here
195 */
196 if (taken == strlen(PHY_NAME) + digits)
197 return -EINVAL;
198 }
199
200
185 /* Ignore nop renames */ 201 /* Ignore nop renames */
186 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 202 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
187 return 0; 203 return 0;
@@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
189 /* Ensure another device does not already have this name. */ 205 /* Ensure another device does not already have this name. */
190 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 206 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
191 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 207 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
192 return -EEXIST; 208 return -EINVAL;
193 209
194 result = device_rename(&rdev->wiphy.dev, newname); 210 result = device_rename(&rdev->wiphy.dev, newname);
195 if (result) 211 if (result)
@@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work)
304struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 320struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
305{ 321{
306 static int wiphy_counter; 322 static int wiphy_counter;
307 int i; 323
308 struct cfg80211_registered_device *rdev, *rdev2; 324 struct cfg80211_registered_device *rdev;
309 int alloc_size; 325 int alloc_size;
310 char nname[IFNAMSIZ + 1];
311 bool found = false;
312 326
313 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); 327 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
314 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); 328 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -332,37 +346,17 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
332 346
333 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { 347 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
334 wiphy_counter--; 348 wiphy_counter--;
335 goto too_many_devs;
336 }
337
338 /* 64k wiphy devices is enough for anyone! */
339 for (i = 0; i < 0xFFFF; i++) {
340 found = false;
341 snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
342 nname[sizeof(nname)-1] = 0;
343 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
344 if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
345 found = true;
346 break;
347 }
348
349 if (!found)
350 break;
351 }
352
353 if (unlikely(found)) {
354too_many_devs:
355 mutex_unlock(&cfg80211_mutex); 349 mutex_unlock(&cfg80211_mutex);
356 /* ugh, too many devices already! */ 350 /* ugh, wrapped! */
357 kfree(rdev); 351 kfree(rdev);
358 return NULL; 352 return NULL;
359 } 353 }
360 354
361 /* give it a proper name */
362 dev_set_name(&rdev->wiphy.dev, "%s", nname);
363
364 mutex_unlock(&cfg80211_mutex); 355 mutex_unlock(&cfg80211_mutex);
365 356
357 /* give it a proper name */
358 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
359
366 mutex_init(&rdev->mtx); 360 mutex_init(&rdev->mtx);
367 mutex_init(&rdev->devlist_mtx); 361 mutex_init(&rdev->devlist_mtx);
368 INIT_LIST_HEAD(&rdev->netdev_list); 362 INIT_LIST_HEAD(&rdev->netdev_list);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index caf11a427507..26838d903b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
764 u16 frame_type, const u8 *match_data, 764 u16 frame_type, const u8 *match_data,
765 int match_len) 765 int match_len)
766{ 766{
767 struct wiphy *wiphy = wdev->wiphy;
768 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
767 struct cfg80211_mgmt_registration *reg, *nreg; 769 struct cfg80211_mgmt_registration *reg, *nreg;
768 int err = 0; 770 int err = 0;
769 u16 mgmt_type; 771 u16 mgmt_type;
@@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
810 nreg->frame_type = cpu_to_le16(frame_type); 812 nreg->frame_type = cpu_to_le16(frame_type);
811 list_add(&nreg->list, &wdev->mgmt_registrations); 813 list_add(&nreg->list, &wdev->mgmt_registrations);
812 814
815 if (rdev->ops->mgmt_frame_register)
816 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
817 frame_type, true);
818
813 out: 819 out:
814 spin_unlock_bh(&wdev->mgmt_registrations_lock); 820 spin_unlock_bh(&wdev->mgmt_registrations_lock);
821
815 return err; 822 return err;
816} 823}
817 824
818void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) 825void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
819{ 826{
827 struct wiphy *wiphy = wdev->wiphy;
828 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
820 struct cfg80211_mgmt_registration *reg, *tmp; 829 struct cfg80211_mgmt_registration *reg, *tmp;
821 830
822 spin_lock_bh(&wdev->mgmt_registrations_lock); 831 spin_lock_bh(&wdev->mgmt_registrations_lock);
823 832
824 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 833 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
825 if (reg->nlpid == nlpid) { 834 if (reg->nlpid != nlpid)
826 list_del(&reg->list); 835 continue;
827 kfree(reg); 836
837 if (rdev->ops->mgmt_frame_register) {
838 u16 frame_type = le16_to_cpu(reg->frame_type);
839
840 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
841 frame_type, false);
828 } 842 }
843
844 list_del(&reg->list);
845 kfree(reg);
829 } 846 }
830 847
831 spin_unlock_bh(&wdev->mgmt_registrations_lock); 848 spin_unlock_bh(&wdev->mgmt_registrations_lock);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 882dc921103b..c506241f8637 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3153 survey->noise); 3153 survey->noise);
3154 if (survey->filled & SURVEY_INFO_IN_USE) 3154 if (survey->filled & SURVEY_INFO_IN_USE)
3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); 3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
3156 if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
3157 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
3158 survey->channel_time);
3159 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
3160 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
3161 survey->channel_time_busy);
3162 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
3163 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
3164 survey->channel_time_ext_busy);
3165 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
3166 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
3167 survey->channel_time_rx);
3168 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
3169 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
3170 survey->channel_time_tx);
3156 3171
3157 nla_nest_end(msg, infoattr); 3172 nla_nest_end(msg, infoattr);
3158 3173
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
201{ 201{
202 while (1) { 202 while (1) {
203 int hit = 0; 203 int hit = 0;
204 int pad, align, size, subns, vnslen; 204 int pad, align, size, subns;
205 uint32_t oui; 205 uint32_t oui;
206 206
207 /* if no more EXT bits, that's it */ 207 /* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
261 if (pad) 261 if (pad)
262 iterator->_arg += align - pad; 262 iterator->_arg += align - pad;
263 263
264 if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
265 int vnslen;
266
267 if ((unsigned long)iterator->_arg + size -
268 (unsigned long)iterator->_rtheader >
269 (unsigned long)iterator->_max_length)
270 return -EINVAL;
271
272 oui = (*iterator->_arg << 16) |
273 (*(iterator->_arg + 1) << 8) |
274 *(iterator->_arg + 2);
275 subns = *(iterator->_arg + 3);
276
277 find_ns(iterator, oui, subns);
278
279 vnslen = get_unaligned_le16(iterator->_arg + 4);
280 iterator->_next_ns_data = iterator->_arg + size + vnslen;
281 if (!iterator->current_namespace)
282 size += vnslen;
283 }
284
264 /* 285 /*
265 * this is what we will return to user, but we need to 286 * this is what we will return to user, but we need to
266 * move on first so next call has something fresh to test 287 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
287 /* these special ones are valid in each bitmap word */ 308 /* these special ones are valid in each bitmap word */
288 switch (iterator->_arg_index % 32) { 309 switch (iterator->_arg_index % 32) {
289 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
290 iterator->_bitmap_shifter >>= 1;
291 iterator->_arg_index++;
292
293 iterator->_reset_on_ext = 1; 311 iterator->_reset_on_ext = 1;
294 312
295 vnslen = get_unaligned_le16(iterator->this_arg + 4);
296 iterator->_next_ns_data = iterator->_arg + vnslen;
297 oui = (*iterator->this_arg << 16) |
298 (*(iterator->this_arg + 1) << 8) |
299 *(iterator->this_arg + 2);
300 subns = *(iterator->this_arg + 3);
301
302 find_ns(iterator, oui, subns);
303
304 iterator->is_radiotap_ns = 0; 313 iterator->is_radiotap_ns = 0;
305 /* allow parsers to show this information */ 314 /*
315 * If parser didn't register this vendor
316 * namespace with us, allow it to show it
317 * as 'raw. Do do that, set argument index
318 * to vendor namespace.
319 */
306 iterator->this_arg_index = 320 iterator->this_arg_index =
307 IEEE80211_RADIOTAP_VENDOR_NAMESPACE; 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
308 iterator->this_arg_size += vnslen; 322 if (!iterator->current_namespace)
309 if ((unsigned long)iterator->this_arg + 323 hit = 1;
310 iterator->this_arg_size - 324 goto next_entry;
311 (unsigned long)iterator->_rtheader >
312 (unsigned long)(unsigned long)iterator->_max_length)
313 return -EINVAL;
314 hit = 1;
315 break;
316 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
317 iterator->_bitmap_shifter >>= 1;
318 iterator->_arg_index++;
319
320 iterator->_reset_on_ext = 1; 326 iterator->_reset_on_ext = 1;
321 iterator->current_namespace = &radiotap_ns; 327 iterator->current_namespace = &radiotap_ns;
322 iterator->is_radiotap_ns = 1; 328 iterator->is_radiotap_ns = 1;
323 break; 329 goto next_entry;
324 case IEEE80211_RADIOTAP_EXT: 330 case IEEE80211_RADIOTAP_EXT:
325 /* 331 /*
326 * bit 31 was set, there is more 332 * bit 31 was set, there is more
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 74a9e3cce452..4294fa22bb2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); 36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
37 37
38static ssize_t name_show(struct device *dev,
39 struct device_attribute *attr,
40 char *buf) {
41 struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
42 return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
43}
44
45
38static ssize_t addresses_show(struct device *dev, 46static ssize_t addresses_show(struct device *dev,
39 struct device_attribute *attr, 47 struct device_attribute *attr,
40 char *buf) 48 char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
57 __ATTR_RO(macaddress), 65 __ATTR_RO(macaddress),
58 __ATTR_RO(address_mask), 66 __ATTR_RO(address_mask),
59 __ATTR_RO(addresses), 67 __ATTR_RO(addresses),
68 __ATTR_RO(name),
60 {} 69 {}
61}; 70};
62 71
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6002265289c6..12222ee6ebf2 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1366 } 1366 }
1367 1367
1368 wstats.qual.updated |= IW_QUAL_NOISE_INVALID; 1368 wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1369 if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
1370 wstats.discard.misc = sinfo.rx_dropped_misc;
1371 if (sinfo.filled & STATION_INFO_TX_FAILED)
1372 wstats.discard.retries = sinfo.tx_failed;
1369 1373
1370 return &wstats; 1374 return &wstats;
1371} 1375}