diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-11-04 16:18:12 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-11-04 16:18:12 -0500 |
commit | bf515fb11ab539c76d04f0e3c5216ed41f41d81f (patch) | |
tree | 6aaa226c2a40f90a649561b4a5bb0d1772b20bf1 /net/wireless | |
parent | 6bc6c49f1e2f3ab1bec05d1c08aad219ab4eb5d0 (diff) | |
parent | cf2c92d840c1424bcb3bb501147c79c9b067ad77 (diff) |
Merge tag 'mac80211-next-for-john-2014-11-04' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg <johannes@sipsolutions.net> says:
"This relatively large batch of changes is comprised of the
following:
* large mac80211-hwsim changes from Ben, Jukka and a bit myself
* OCB/WAVE/11p support from Rostislav on behalf of the Czech Technical
University in Prague and Volkswagen Group Research
* minstrel VHT work from Karl
* more CSA work from Luca
* WMM admission control support in mac80211 (myself)
* various smaller fixes, spelling corrections, and minor API additions"
Conflicts:
drivers/net/wireless/ath/wil6210/cfg80211.c
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/Makefile | 2 | ||||
-rw-r--r-- | net/wireless/chan.c | 10 | ||||
-rw-r--r-- | net/wireless/core.c | 77 | ||||
-rw-r--r-- | net/wireless/core.h | 12 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 206 | ||||
-rw-r--r-- | net/wireless/ocb.c | 88 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 55 | ||||
-rw-r--r-- | net/wireless/sme.c | 13 | ||||
-rw-r--r-- | net/wireless/trace.h | 97 | ||||
-rw-r--r-- | net/wireless/util.c | 5 |
10 files changed, 523 insertions, 42 deletions
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index a761670af31d..4c9e39f04ef8 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o | |||
10 | obj-$(CONFIG_WEXT_PRIV) += wext-priv.o | 10 | obj-$(CONFIG_WEXT_PRIV) += wext-priv.o |
11 | 11 | ||
12 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o | 12 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o |
13 | cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o | 13 | cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o |
14 | cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o | 14 | cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o |
15 | cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o | 15 | cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o |
16 | cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o | 16 | cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 72d81e2154d5..85506f1d0789 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -115,7 +115,7 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) | |||
115 | EXPORT_SYMBOL(cfg80211_chandef_valid); | 115 | EXPORT_SYMBOL(cfg80211_chandef_valid); |
116 | 116 | ||
117 | static void chandef_primary_freqs(const struct cfg80211_chan_def *c, | 117 | static void chandef_primary_freqs(const struct cfg80211_chan_def *c, |
118 | int *pri40, int *pri80) | 118 | u32 *pri40, u32 *pri80) |
119 | { | 119 | { |
120 | int tmp; | 120 | int tmp; |
121 | 121 | ||
@@ -366,6 +366,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, | |||
366 | 366 | ||
367 | break; | 367 | break; |
368 | case NL80211_IFTYPE_STATION: | 368 | case NL80211_IFTYPE_STATION: |
369 | case NL80211_IFTYPE_OCB: | ||
369 | case NL80211_IFTYPE_P2P_CLIENT: | 370 | case NL80211_IFTYPE_P2P_CLIENT: |
370 | case NL80211_IFTYPE_MONITOR: | 371 | case NL80211_IFTYPE_MONITOR: |
371 | case NL80211_IFTYPE_AP_VLAN: | 372 | case NL80211_IFTYPE_AP_VLAN: |
@@ -892,6 +893,13 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, | |||
892 | *radar_detect |= BIT(wdev->chandef.width); | 893 | *radar_detect |= BIT(wdev->chandef.width); |
893 | } | 894 | } |
894 | return; | 895 | return; |
896 | case NL80211_IFTYPE_OCB: | ||
897 | if (wdev->chandef.chan) { | ||
898 | *chan = wdev->chandef.chan; | ||
899 | *chanmode = CHAN_MODE_SHARED; | ||
900 | return; | ||
901 | } | ||
902 | break; | ||
895 | case NL80211_IFTYPE_MONITOR: | 903 | case NL80211_IFTYPE_MONITOR: |
896 | case NL80211_IFTYPE_AP_VLAN: | 904 | case NL80211_IFTYPE_AP_VLAN: |
897 | case NL80211_IFTYPE_WDS: | 905 | case NL80211_IFTYPE_WDS: |
diff --git a/net/wireless/core.c b/net/wireless/core.c index f52a4cd7017c..a4d27927aba2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -86,11 +86,11 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) | |||
86 | return &rdev->wiphy; | 86 | return &rdev->wiphy; |
87 | } | 87 | } |
88 | 88 | ||
89 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | 89 | static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev, |
90 | char *newname) | 90 | const char *newname) |
91 | { | 91 | { |
92 | struct cfg80211_registered_device *rdev2; | 92 | struct cfg80211_registered_device *rdev2; |
93 | int wiphy_idx, taken = -1, result, digits; | 93 | int wiphy_idx, taken = -1, digits; |
94 | 94 | ||
95 | ASSERT_RTNL(); | 95 | ASSERT_RTNL(); |
96 | 96 | ||
@@ -109,15 +109,28 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
109 | return -EINVAL; | 109 | return -EINVAL; |
110 | } | 110 | } |
111 | 111 | ||
112 | /* Ensure another device does not already have this name. */ | ||
113 | list_for_each_entry(rdev2, &cfg80211_rdev_list, list) | ||
114 | if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0) | ||
115 | return -EINVAL; | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | ||
121 | char *newname) | ||
122 | { | ||
123 | int result; | ||
124 | |||
125 | ASSERT_RTNL(); | ||
112 | 126 | ||
113 | /* Ignore nop renames */ | 127 | /* Ignore nop renames */ |
114 | if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) | 128 | if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0) |
115 | return 0; | 129 | return 0; |
116 | 130 | ||
117 | /* Ensure another device does not already have this name. */ | 131 | result = cfg80211_dev_check_name(rdev, newname); |
118 | list_for_each_entry(rdev2, &cfg80211_rdev_list, list) | 132 | if (result < 0) |
119 | if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) | 133 | return result; |
120 | return -EINVAL; | ||
121 | 134 | ||
122 | result = device_rename(&rdev->wiphy.dev, newname); | 135 | result = device_rename(&rdev->wiphy.dev, newname); |
123 | if (result) | 136 | if (result) |
@@ -309,7 +322,8 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work) | |||
309 | 322 | ||
310 | /* exported functions */ | 323 | /* exported functions */ |
311 | 324 | ||
312 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | 325 | struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, |
326 | const char *requested_name) | ||
313 | { | 327 | { |
314 | static atomic_t wiphy_counter = ATOMIC_INIT(0); | 328 | static atomic_t wiphy_counter = ATOMIC_INIT(0); |
315 | 329 | ||
@@ -346,7 +360,31 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
346 | rdev->wiphy_idx--; | 360 | rdev->wiphy_idx--; |
347 | 361 | ||
348 | /* give it a proper name */ | 362 | /* give it a proper name */ |
349 | dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); | 363 | if (requested_name && requested_name[0]) { |
364 | int rv; | ||
365 | |||
366 | rtnl_lock(); | ||
367 | rv = cfg80211_dev_check_name(rdev, requested_name); | ||
368 | |||
369 | if (rv < 0) { | ||
370 | rtnl_unlock(); | ||
371 | goto use_default_name; | ||
372 | } | ||
373 | |||
374 | rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name); | ||
375 | rtnl_unlock(); | ||
376 | if (rv) | ||
377 | goto use_default_name; | ||
378 | } else { | ||
379 | use_default_name: | ||
380 | /* NOTE: This is *probably* safe w/out holding rtnl because of | ||
381 | * the restrictions on phy names. Probably this call could | ||
382 | * fail if some other part of the kernel (re)named a device | ||
383 | * phyX. But, might should add some locking and check return | ||
384 | * value, and use a different name if this one exists? | ||
385 | */ | ||
386 | dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); | ||
387 | } | ||
350 | 388 | ||
351 | INIT_LIST_HEAD(&rdev->wdev_list); | 389 | INIT_LIST_HEAD(&rdev->wdev_list); |
352 | INIT_LIST_HEAD(&rdev->beacon_registrations); | 390 | INIT_LIST_HEAD(&rdev->beacon_registrations); |
@@ -406,7 +444,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
406 | 444 | ||
407 | return &rdev->wiphy; | 445 | return &rdev->wiphy; |
408 | } | 446 | } |
409 | EXPORT_SYMBOL(wiphy_new); | 447 | EXPORT_SYMBOL(wiphy_new_nm); |
410 | 448 | ||
411 | static int wiphy_verify_combinations(struct wiphy *wiphy) | 449 | static int wiphy_verify_combinations(struct wiphy *wiphy) |
412 | { | 450 | { |
@@ -831,7 +869,22 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, | |||
831 | case NL80211_IFTYPE_P2P_GO: | 869 | case NL80211_IFTYPE_P2P_GO: |
832 | __cfg80211_stop_ap(rdev, dev, true); | 870 | __cfg80211_stop_ap(rdev, dev, true); |
833 | break; | 871 | break; |
834 | default: | 872 | case NL80211_IFTYPE_OCB: |
873 | __cfg80211_leave_ocb(rdev, dev); | ||
874 | break; | ||
875 | case NL80211_IFTYPE_WDS: | ||
876 | /* must be handled by mac80211/driver, has no APIs */ | ||
877 | break; | ||
878 | case NL80211_IFTYPE_P2P_DEVICE: | ||
879 | /* cannot happen, has no netdev */ | ||
880 | break; | ||
881 | case NL80211_IFTYPE_AP_VLAN: | ||
882 | case NL80211_IFTYPE_MONITOR: | ||
883 | /* nothing to do */ | ||
884 | break; | ||
885 | case NL80211_IFTYPE_UNSPECIFIED: | ||
886 | case NUM_NL80211_IFTYPES: | ||
887 | /* invalid */ | ||
835 | break; | 888 | break; |
836 | } | 889 | } |
837 | } | 890 | } |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 7e3a3cef7df9..61ee664cf2bd 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -290,6 +290,18 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | |||
290 | struct wireless_dev *wdev, | 290 | struct wireless_dev *wdev, |
291 | struct cfg80211_chan_def *chandef); | 291 | struct cfg80211_chan_def *chandef); |
292 | 292 | ||
293 | /* OCB */ | ||
294 | int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, | ||
295 | struct net_device *dev, | ||
296 | struct ocb_setup *setup); | ||
297 | int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, | ||
298 | struct net_device *dev, | ||
299 | struct ocb_setup *setup); | ||
300 | int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, | ||
301 | struct net_device *dev); | ||
302 | int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, | ||
303 | struct net_device *dev); | ||
304 | |||
293 | /* AP */ | 305 | /* AP */ |
294 | int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, | 306 | int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, |
295 | struct net_device *dev, bool notify); | 307 | struct net_device *dev, bool notify); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cb9f5a44ffad..1a31736914e5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -884,7 +884,12 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) | |||
884 | if (!wdev->current_bss) | 884 | if (!wdev->current_bss) |
885 | return -ENOLINK; | 885 | return -ENOLINK; |
886 | break; | 886 | break; |
887 | default: | 887 | case NL80211_IFTYPE_UNSPECIFIED: |
888 | case NL80211_IFTYPE_OCB: | ||
889 | case NL80211_IFTYPE_MONITOR: | ||
890 | case NL80211_IFTYPE_P2P_DEVICE: | ||
891 | case NL80211_IFTYPE_WDS: | ||
892 | case NUM_NL80211_IFTYPES: | ||
888 | return -EINVAL; | 893 | return -EINVAL; |
889 | } | 894 | } |
890 | 895 | ||
@@ -1514,8 +1519,8 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1514 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) | 1519 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) |
1515 | CMD(channel_switch, CHANNEL_SWITCH); | 1520 | CMD(channel_switch, CHANNEL_SWITCH); |
1516 | CMD(set_qos_map, SET_QOS_MAP); | 1521 | CMD(set_qos_map, SET_QOS_MAP); |
1517 | if (rdev->wiphy.flags & | 1522 | if (rdev->wiphy.features & |
1518 | WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) | 1523 | NL80211_FEATURE_SUPPORTS_WMM_ADMISSION) |
1519 | CMD(add_tx_ts, ADD_TX_TS); | 1524 | CMD(add_tx_ts, ADD_TX_TS); |
1520 | } | 1525 | } |
1521 | /* add into the if now */ | 1526 | /* add into the if now */ |
@@ -2605,7 +2610,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2605 | !(rdev->wiphy.interface_modes & (1 << type))) | 2610 | !(rdev->wiphy.interface_modes & (1 << type))) |
2606 | return -EOPNOTSUPP; | 2611 | return -EOPNOTSUPP; |
2607 | 2612 | ||
2608 | if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) { | 2613 | if ((type == NL80211_IFTYPE_P2P_DEVICE || |
2614 | rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) && | ||
2615 | info->attrs[NL80211_ATTR_MAC]) { | ||
2609 | nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], | 2616 | nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], |
2610 | ETH_ALEN); | 2617 | ETH_ALEN); |
2611 | if (!is_valid_ether_addr(params.macaddr)) | 2618 | if (!is_valid_ether_addr(params.macaddr)) |
@@ -4398,10 +4405,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
4398 | { | 4405 | { |
4399 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4406 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4400 | struct net_device *dev = info->user_ptr[1]; | 4407 | struct net_device *dev = info->user_ptr[1]; |
4401 | u8 *mac_addr = NULL; | 4408 | struct station_del_parameters params; |
4409 | |||
4410 | memset(¶ms, 0, sizeof(params)); | ||
4402 | 4411 | ||
4403 | if (info->attrs[NL80211_ATTR_MAC]) | 4412 | if (info->attrs[NL80211_ATTR_MAC]) |
4404 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 4413 | params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]); |
4405 | 4414 | ||
4406 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 4415 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
4407 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 4416 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
@@ -4412,7 +4421,28 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
4412 | if (!rdev->ops->del_station) | 4421 | if (!rdev->ops->del_station) |
4413 | return -EOPNOTSUPP; | 4422 | return -EOPNOTSUPP; |
4414 | 4423 | ||
4415 | return rdev_del_station(rdev, dev, mac_addr); | 4424 | if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) { |
4425 | params.subtype = | ||
4426 | nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]); | ||
4427 | if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 && | ||
4428 | params.subtype != IEEE80211_STYPE_DEAUTH >> 4) | ||
4429 | return -EINVAL; | ||
4430 | } else { | ||
4431 | /* Default to Deauthentication frame */ | ||
4432 | params.subtype = IEEE80211_STYPE_DEAUTH >> 4; | ||
4433 | } | ||
4434 | |||
4435 | if (info->attrs[NL80211_ATTR_REASON_CODE]) { | ||
4436 | params.reason_code = | ||
4437 | nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); | ||
4438 | if (params.reason_code == 0) | ||
4439 | return -EINVAL; /* 0 is reserved */ | ||
4440 | } else { | ||
4441 | /* Default to reason code 2 */ | ||
4442 | params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID; | ||
4443 | } | ||
4444 | |||
4445 | return rdev_del_station(rdev, dev, ¶ms); | ||
4416 | } | 4446 | } |
4417 | 4447 | ||
4418 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, | 4448 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, |
@@ -4624,6 +4654,96 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) | |||
4624 | return rdev_del_mpath(rdev, dev, dst); | 4654 | return rdev_del_mpath(rdev, dev, dst); |
4625 | } | 4655 | } |
4626 | 4656 | ||
4657 | static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) | ||
4658 | { | ||
4659 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
4660 | int err; | ||
4661 | struct net_device *dev = info->user_ptr[1]; | ||
4662 | struct mpath_info pinfo; | ||
4663 | struct sk_buff *msg; | ||
4664 | u8 *dst = NULL; | ||
4665 | u8 mpp[ETH_ALEN]; | ||
4666 | |||
4667 | memset(&pinfo, 0, sizeof(pinfo)); | ||
4668 | |||
4669 | if (!info->attrs[NL80211_ATTR_MAC]) | ||
4670 | return -EINVAL; | ||
4671 | |||
4672 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
4673 | |||
4674 | if (!rdev->ops->get_mpp) | ||
4675 | return -EOPNOTSUPP; | ||
4676 | |||
4677 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | ||
4678 | return -EOPNOTSUPP; | ||
4679 | |||
4680 | err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); | ||
4681 | if (err) | ||
4682 | return err; | ||
4683 | |||
4684 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
4685 | if (!msg) | ||
4686 | return -ENOMEM; | ||
4687 | |||
4688 | if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, | ||
4689 | dev, dst, mpp, &pinfo) < 0) { | ||
4690 | nlmsg_free(msg); | ||
4691 | return -ENOBUFS; | ||
4692 | } | ||
4693 | |||
4694 | return genlmsg_reply(msg, info); | ||
4695 | } | ||
4696 | |||
4697 | static int nl80211_dump_mpp(struct sk_buff *skb, | ||
4698 | struct netlink_callback *cb) | ||
4699 | { | ||
4700 | struct mpath_info pinfo; | ||
4701 | struct cfg80211_registered_device *rdev; | ||
4702 | struct wireless_dev *wdev; | ||
4703 | u8 dst[ETH_ALEN]; | ||
4704 | u8 mpp[ETH_ALEN]; | ||
4705 | int path_idx = cb->args[2]; | ||
4706 | int err; | ||
4707 | |||
4708 | err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); | ||
4709 | if (err) | ||
4710 | return err; | ||
4711 | |||
4712 | if (!rdev->ops->dump_mpp) { | ||
4713 | err = -EOPNOTSUPP; | ||
4714 | goto out_err; | ||
4715 | } | ||
4716 | |||
4717 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { | ||
4718 | err = -EOPNOTSUPP; | ||
4719 | goto out_err; | ||
4720 | } | ||
4721 | |||
4722 | while (1) { | ||
4723 | err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, | ||
4724 | mpp, &pinfo); | ||
4725 | if (err == -ENOENT) | ||
4726 | break; | ||
4727 | if (err) | ||
4728 | goto out_err; | ||
4729 | |||
4730 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, | ||
4731 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | ||
4732 | wdev->netdev, dst, mpp, | ||
4733 | &pinfo) < 0) | ||
4734 | goto out; | ||
4735 | |||
4736 | path_idx++; | ||
4737 | } | ||
4738 | |||
4739 | out: | ||
4740 | cb->args[2] = path_idx; | ||
4741 | err = skb->len; | ||
4742 | out_err: | ||
4743 | nl80211_finish_wdev_dump(rdev); | ||
4744 | return err; | ||
4745 | } | ||
4746 | |||
4627 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | 4747 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) |
4628 | { | 4748 | { |
4629 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4749 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
@@ -5923,10 +6043,10 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5923 | * function is called under RTNL lock, so this should not be a problem. | 6043 | * function is called under RTNL lock, so this should not be a problem. |
5924 | */ | 6044 | */ |
5925 | static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; | 6045 | static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; |
5926 | u8 radar_detect_width = 0; | ||
5927 | int err; | 6046 | int err; |
5928 | bool need_new_beacon = false; | 6047 | bool need_new_beacon = false; |
5929 | int len, i; | 6048 | int len, i; |
6049 | u32 cs_count; | ||
5930 | 6050 | ||
5931 | if (!rdev->ops->channel_switch || | 6051 | if (!rdev->ops->channel_switch || |
5932 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | 6052 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) |
@@ -5963,7 +6083,14 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) | |||
5963 | if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES]) | 6083 | if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES]) |
5964 | return -EINVAL; | 6084 | return -EINVAL; |
5965 | 6085 | ||
5966 | params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]); | 6086 | /* Even though the attribute is u32, the specification says |
6087 | * u8, so let's make sure we don't overflow. | ||
6088 | */ | ||
6089 | cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]); | ||
6090 | if (cs_count > 255) | ||
6091 | return -EINVAL; | ||
6092 | |||
6093 | params.count = cs_count; | ||
5967 | 6094 | ||
5968 | if (!need_new_beacon) | 6095 | if (!need_new_beacon) |
5969 | goto skip_beacons; | 6096 | goto skip_beacons; |
@@ -6051,10 +6178,8 @@ skip_beacons: | |||
6051 | if (err < 0) | 6178 | if (err < 0) |
6052 | return err; | 6179 | return err; |
6053 | 6180 | ||
6054 | if (err > 0) { | 6181 | if (err > 0) |
6055 | radar_detect_width = BIT(params.chandef.width); | ||
6056 | params.radar_required = true; | 6182 | params.radar_required = true; |
6057 | } | ||
6058 | 6183 | ||
6059 | if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) | 6184 | if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) |
6060 | params.block_tx = true; | 6185 | params.block_tx = true; |
@@ -8151,6 +8276,28 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) | |||
8151 | return -EINVAL; | 8276 | return -EINVAL; |
8152 | } | 8277 | } |
8153 | 8278 | ||
8279 | static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info) | ||
8280 | { | ||
8281 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
8282 | struct net_device *dev = info->user_ptr[1]; | ||
8283 | struct ocb_setup setup = {}; | ||
8284 | int err; | ||
8285 | |||
8286 | err = nl80211_parse_chandef(rdev, info, &setup.chandef); | ||
8287 | if (err) | ||
8288 | return err; | ||
8289 | |||
8290 | return cfg80211_join_ocb(rdev, dev, &setup); | ||
8291 | } | ||
8292 | |||
8293 | static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info) | ||
8294 | { | ||
8295 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
8296 | struct net_device *dev = info->user_ptr[1]; | ||
8297 | |||
8298 | return cfg80211_leave_ocb(rdev, dev); | ||
8299 | } | ||
8300 | |||
8154 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) | 8301 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) |
8155 | { | 8302 | { |
8156 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 8303 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
@@ -9436,7 +9583,7 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) | |||
9436 | u16 admitted_time = 0; | 9583 | u16 admitted_time = 0; |
9437 | int err; | 9584 | int err; |
9438 | 9585 | ||
9439 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) | 9586 | if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)) |
9440 | return -EOPNOTSUPP; | 9587 | return -EOPNOTSUPP; |
9441 | 9588 | ||
9442 | if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || | 9589 | if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || |
@@ -9452,12 +9599,10 @@ static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) | |||
9452 | return -EINVAL; | 9599 | return -EINVAL; |
9453 | 9600 | ||
9454 | /* WMM uses TIDs 0-7 even for TSPEC */ | 9601 | /* WMM uses TIDs 0-7 even for TSPEC */ |
9455 | if (tsid < IEEE80211_FIRST_TSPEC_TSID) { | 9602 | if (tsid >= IEEE80211_FIRST_TSPEC_TSID) { |
9456 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) | ||
9457 | return -EINVAL; | ||
9458 | } else { | ||
9459 | /* TODO: handle 802.11 TSPEC/admission control | 9603 | /* TODO: handle 802.11 TSPEC/admission control |
9460 | * need more attributes for that (e.g. BA session requirement) | 9604 | * need more attributes for that (e.g. BA session requirement); |
9605 | * change the WMM adminssion test above to allow both then | ||
9461 | */ | 9606 | */ |
9462 | return -EINVAL; | 9607 | return -EINVAL; |
9463 | } | 9608 | } |
@@ -9774,6 +9919,15 @@ static const struct genl_ops nl80211_ops[] = { | |||
9774 | NL80211_FLAG_NEED_RTNL, | 9919 | NL80211_FLAG_NEED_RTNL, |
9775 | }, | 9920 | }, |
9776 | { | 9921 | { |
9922 | .cmd = NL80211_CMD_GET_MPP, | ||
9923 | .doit = nl80211_get_mpp, | ||
9924 | .dumpit = nl80211_dump_mpp, | ||
9925 | .policy = nl80211_policy, | ||
9926 | .flags = GENL_ADMIN_PERM, | ||
9927 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
9928 | NL80211_FLAG_NEED_RTNL, | ||
9929 | }, | ||
9930 | { | ||
9777 | .cmd = NL80211_CMD_SET_MPATH, | 9931 | .cmd = NL80211_CMD_SET_MPATH, |
9778 | .doit = nl80211_set_mpath, | 9932 | .doit = nl80211_set_mpath, |
9779 | .policy = nl80211_policy, | 9933 | .policy = nl80211_policy, |
@@ -10087,6 +10241,22 @@ static const struct genl_ops nl80211_ops[] = { | |||
10087 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 10241 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
10088 | NL80211_FLAG_NEED_RTNL, | 10242 | NL80211_FLAG_NEED_RTNL, |
10089 | }, | 10243 | }, |
10244 | { | ||
10245 | .cmd = NL80211_CMD_JOIN_OCB, | ||
10246 | .doit = nl80211_join_ocb, | ||
10247 | .policy = nl80211_policy, | ||
10248 | .flags = GENL_ADMIN_PERM, | ||
10249 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
10250 | NL80211_FLAG_NEED_RTNL, | ||
10251 | }, | ||
10252 | { | ||
10253 | .cmd = NL80211_CMD_LEAVE_OCB, | ||
10254 | .doit = nl80211_leave_ocb, | ||
10255 | .policy = nl80211_policy, | ||
10256 | .flags = GENL_ADMIN_PERM, | ||
10257 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
10258 | NL80211_FLAG_NEED_RTNL, | ||
10259 | }, | ||
10090 | #ifdef CONFIG_PM | 10260 | #ifdef CONFIG_PM |
10091 | { | 10261 | { |
10092 | .cmd = NL80211_CMD_GET_WOWLAN, | 10262 | .cmd = NL80211_CMD_GET_WOWLAN, |
diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c new file mode 100644 index 000000000000..c00d4a792319 --- /dev/null +++ b/net/wireless/ocb.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * OCB mode implementation | ||
3 | * | ||
4 | * Copyright: (c) 2014 Czech Technical University in Prague | ||
5 | * (c) 2014 Volkswagen Group Research | ||
6 | * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz> | ||
7 | * Funded by: Volkswagen Group Research | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/ieee80211.h> | ||
15 | #include <net/cfg80211.h> | ||
16 | #include "nl80211.h" | ||
17 | #include "core.h" | ||
18 | #include "rdev-ops.h" | ||
19 | |||
20 | int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, | ||
21 | struct net_device *dev, | ||
22 | struct ocb_setup *setup) | ||
23 | { | ||
24 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
25 | int err; | ||
26 | |||
27 | ASSERT_WDEV_LOCK(wdev); | ||
28 | |||
29 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) | ||
30 | return -EOPNOTSUPP; | ||
31 | |||
32 | if (WARN_ON(!setup->chandef.chan)) | ||
33 | return -EINVAL; | ||
34 | |||
35 | err = rdev_join_ocb(rdev, dev, setup); | ||
36 | if (!err) | ||
37 | wdev->chandef = setup->chandef; | ||
38 | |||
39 | return err; | ||
40 | } | ||
41 | |||
42 | int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, | ||
43 | struct net_device *dev, | ||
44 | struct ocb_setup *setup) | ||
45 | { | ||
46 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
47 | int err; | ||
48 | |||
49 | wdev_lock(wdev); | ||
50 | err = __cfg80211_join_ocb(rdev, dev, setup); | ||
51 | wdev_unlock(wdev); | ||
52 | |||
53 | return err; | ||
54 | } | ||
55 | |||
56 | int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, | ||
57 | struct net_device *dev) | ||
58 | { | ||
59 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
60 | int err; | ||
61 | |||
62 | ASSERT_WDEV_LOCK(wdev); | ||
63 | |||
64 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) | ||
65 | return -EOPNOTSUPP; | ||
66 | |||
67 | if (!rdev->ops->leave_ocb) | ||
68 | return -EOPNOTSUPP; | ||
69 | |||
70 | err = rdev_leave_ocb(rdev, dev); | ||
71 | if (!err) | ||
72 | memset(&wdev->chandef, 0, sizeof(wdev->chandef)); | ||
73 | |||
74 | return err; | ||
75 | } | ||
76 | |||
77 | int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, | ||
78 | struct net_device *dev) | ||
79 | { | ||
80 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
81 | int err; | ||
82 | |||
83 | wdev_lock(wdev); | ||
84 | err = __cfg80211_leave_ocb(rdev, dev); | ||
85 | wdev_unlock(wdev); | ||
86 | |||
87 | return err; | ||
88 | } | ||
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index f6d457d6a558..1b3864cd50ca 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -178,11 +178,12 @@ static inline int rdev_add_station(struct cfg80211_registered_device *rdev, | |||
178 | } | 178 | } |
179 | 179 | ||
180 | static inline int rdev_del_station(struct cfg80211_registered_device *rdev, | 180 | static inline int rdev_del_station(struct cfg80211_registered_device *rdev, |
181 | struct net_device *dev, u8 *mac) | 181 | struct net_device *dev, |
182 | struct station_del_parameters *params) | ||
182 | { | 183 | { |
183 | int ret; | 184 | int ret; |
184 | trace_rdev_del_station(&rdev->wiphy, dev, mac); | 185 | trace_rdev_del_station(&rdev->wiphy, dev, params); |
185 | ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); | 186 | ret = rdev->ops->del_station(&rdev->wiphy, dev, params); |
186 | trace_rdev_return_int(&rdev->wiphy, ret); | 187 | trace_rdev_return_int(&rdev->wiphy, ret); |
187 | return ret; | 188 | return ret; |
188 | } | 189 | } |
@@ -263,6 +264,18 @@ static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, | |||
263 | 264 | ||
264 | } | 265 | } |
265 | 266 | ||
267 | static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, | ||
268 | struct net_device *dev, u8 *dst, u8 *mpp, | ||
269 | struct mpath_info *pinfo) | ||
270 | { | ||
271 | int ret; | ||
272 | |||
273 | trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); | ||
274 | ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); | ||
275 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
266 | static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, | 279 | static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, |
267 | struct net_device *dev, int idx, u8 *dst, | 280 | struct net_device *dev, int idx, u8 *dst, |
268 | u8 *next_hop, struct mpath_info *pinfo) | 281 | u8 *next_hop, struct mpath_info *pinfo) |
@@ -271,7 +284,20 @@ static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, | |||
271 | int ret; | 284 | int ret; |
272 | trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); | 285 | trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); |
273 | ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, | 286 | ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, |
274 | pinfo); | 287 | pinfo); |
288 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | ||
289 | return ret; | ||
290 | } | ||
291 | |||
292 | static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, | ||
293 | struct net_device *dev, int idx, u8 *dst, | ||
294 | u8 *mpp, struct mpath_info *pinfo) | ||
295 | |||
296 | { | ||
297 | int ret; | ||
298 | |||
299 | trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); | ||
300 | ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); | ||
275 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); | 301 | trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); |
276 | return ret; | 302 | return ret; |
277 | } | 303 | } |
@@ -322,6 +348,27 @@ static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev, | |||
322 | return ret; | 348 | return ret; |
323 | } | 349 | } |
324 | 350 | ||
351 | static inline int rdev_join_ocb(struct cfg80211_registered_device *rdev, | ||
352 | struct net_device *dev, | ||
353 | struct ocb_setup *setup) | ||
354 | { | ||
355 | int ret; | ||
356 | trace_rdev_join_ocb(&rdev->wiphy, dev, setup); | ||
357 | ret = rdev->ops->join_ocb(&rdev->wiphy, dev, setup); | ||
358 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
359 | return ret; | ||
360 | } | ||
361 | |||
362 | static inline int rdev_leave_ocb(struct cfg80211_registered_device *rdev, | ||
363 | struct net_device *dev) | ||
364 | { | ||
365 | int ret; | ||
366 | trace_rdev_leave_ocb(&rdev->wiphy, dev); | ||
367 | ret = rdev->ops->leave_ocb(&rdev->wiphy, dev); | ||
368 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
325 | static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, | 372 | static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, |
326 | struct net_device *dev, | 373 | struct net_device *dev, |
327 | struct bss_parameters *params) | 374 | struct bss_parameters *params) |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index dc1668ff543b..0ab3711c79a0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -80,9 +80,18 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
80 | if (!request) | 80 | if (!request) |
81 | return -ENOMEM; | 81 | return -ENOMEM; |
82 | 82 | ||
83 | if (wdev->conn->params.channel) | 83 | if (wdev->conn->params.channel) { |
84 | enum ieee80211_band band = wdev->conn->params.channel->band; | ||
85 | struct ieee80211_supported_band *sband = | ||
86 | wdev->wiphy->bands[band]; | ||
87 | |||
88 | if (!sband) { | ||
89 | kfree(request); | ||
90 | return -EINVAL; | ||
91 | } | ||
84 | request->channels[0] = wdev->conn->params.channel; | 92 | request->channels[0] = wdev->conn->params.channel; |
85 | else { | 93 | request->rates[band] = (1 << sband->n_bitrates) - 1; |
94 | } else { | ||
86 | int i = 0, j; | 95 | int i = 0, j; |
87 | enum ieee80211_band band; | 96 | enum ieee80211_band band; |
88 | struct ieee80211_supported_band *bands; | 97 | struct ieee80211_supported_band *bands; |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 625a6e6d1168..277a85df910e 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -600,6 +600,11 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ibss, | |||
600 | TP_ARGS(wiphy, netdev) | 600 | TP_ARGS(wiphy, netdev) |
601 | ); | 601 | ); |
602 | 602 | ||
603 | DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ocb, | ||
604 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | ||
605 | TP_ARGS(wiphy, netdev) | ||
606 | ); | ||
607 | |||
603 | DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, | 608 | DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, |
604 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), | 609 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), |
605 | TP_ARGS(wiphy, netdev) | 610 | TP_ARGS(wiphy, netdev) |
@@ -680,9 +685,34 @@ DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt, | |||
680 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) | 685 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) |
681 | ); | 686 | ); |
682 | 687 | ||
683 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, | 688 | DECLARE_EVENT_CLASS(station_del, |
684 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), | 689 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, |
685 | TP_ARGS(wiphy, netdev, mac) | 690 | struct station_del_parameters *params), |
691 | TP_ARGS(wiphy, netdev, params), | ||
692 | TP_STRUCT__entry( | ||
693 | WIPHY_ENTRY | ||
694 | NETDEV_ENTRY | ||
695 | MAC_ENTRY(sta_mac) | ||
696 | __field(u8, subtype) | ||
697 | __field(u16, reason_code) | ||
698 | ), | ||
699 | TP_fast_assign( | ||
700 | WIPHY_ASSIGN; | ||
701 | NETDEV_ASSIGN; | ||
702 | MAC_ASSIGN(sta_mac, params->mac); | ||
703 | __entry->subtype = params->subtype; | ||
704 | __entry->reason_code = params->reason_code; | ||
705 | ), | ||
706 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT | ||
707 | ", subtype: %u, reason_code: %u", | ||
708 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), | ||
709 | __entry->subtype, __entry->reason_code) | ||
710 | ); | ||
711 | |||
712 | DEFINE_EVENT(station_del, rdev_del_station, | ||
713 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
714 | struct station_del_parameters *params), | ||
715 | TP_ARGS(wiphy, netdev, params) | ||
686 | ); | 716 | ); |
687 | 717 | ||
688 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, | 718 | DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, |
@@ -801,6 +831,51 @@ TRACE_EVENT(rdev_dump_mpath, | |||
801 | MAC_PR_ARG(next_hop)) | 831 | MAC_PR_ARG(next_hop)) |
802 | ); | 832 | ); |
803 | 833 | ||
834 | TRACE_EVENT(rdev_get_mpp, | ||
835 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
836 | u8 *dst, u8 *mpp), | ||
837 | TP_ARGS(wiphy, netdev, dst, mpp), | ||
838 | TP_STRUCT__entry( | ||
839 | WIPHY_ENTRY | ||
840 | NETDEV_ENTRY | ||
841 | MAC_ENTRY(dst) | ||
842 | MAC_ENTRY(mpp) | ||
843 | ), | ||
844 | TP_fast_assign( | ||
845 | WIPHY_ASSIGN; | ||
846 | NETDEV_ASSIGN; | ||
847 | MAC_ASSIGN(dst, dst); | ||
848 | MAC_ASSIGN(mpp, mpp); | ||
849 | ), | ||
850 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT | ||
851 | ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, | ||
852 | MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) | ||
853 | ); | ||
854 | |||
855 | TRACE_EVENT(rdev_dump_mpp, | ||
856 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, | ||
857 | u8 *dst, u8 *mpp), | ||
858 | TP_ARGS(wiphy, netdev, idx, mpp, dst), | ||
859 | TP_STRUCT__entry( | ||
860 | WIPHY_ENTRY | ||
861 | NETDEV_ENTRY | ||
862 | MAC_ENTRY(dst) | ||
863 | MAC_ENTRY(mpp) | ||
864 | __field(int, idx) | ||
865 | ), | ||
866 | TP_fast_assign( | ||
867 | WIPHY_ASSIGN; | ||
868 | NETDEV_ASSIGN; | ||
869 | MAC_ASSIGN(dst, dst); | ||
870 | MAC_ASSIGN(mpp, mpp); | ||
871 | __entry->idx = idx; | ||
872 | ), | ||
873 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " | ||
874 | MAC_PR_FMT ", mpp: " MAC_PR_FMT, | ||
875 | WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), | ||
876 | MAC_PR_ARG(mpp)) | ||
877 | ); | ||
878 | |||
804 | TRACE_EVENT(rdev_return_int_mpath_info, | 879 | TRACE_EVENT(rdev_return_int_mpath_info, |
805 | TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), | 880 | TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), |
806 | TP_ARGS(wiphy, ret, pinfo), | 881 | TP_ARGS(wiphy, ret, pinfo), |
@@ -1246,6 +1321,22 @@ TRACE_EVENT(rdev_join_ibss, | |||
1246 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) | 1321 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) |
1247 | ); | 1322 | ); |
1248 | 1323 | ||
1324 | TRACE_EVENT(rdev_join_ocb, | ||
1325 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1326 | const struct ocb_setup *setup), | ||
1327 | TP_ARGS(wiphy, netdev, setup), | ||
1328 | TP_STRUCT__entry( | ||
1329 | WIPHY_ENTRY | ||
1330 | NETDEV_ENTRY | ||
1331 | ), | ||
1332 | TP_fast_assign( | ||
1333 | WIPHY_ASSIGN; | ||
1334 | NETDEV_ASSIGN; | ||
1335 | ), | ||
1336 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, | ||
1337 | WIPHY_PR_ARG, NETDEV_PR_ARG) | ||
1338 | ); | ||
1339 | |||
1249 | TRACE_EVENT(rdev_set_wiphy_params, | 1340 | TRACE_EVENT(rdev_set_wiphy_params, |
1250 | TP_PROTO(struct wiphy *wiphy, u32 changed), | 1341 | TP_PROTO(struct wiphy *wiphy, u32 changed), |
1251 | TP_ARGS(wiphy, changed), | 1342 | TP_ARGS(wiphy, changed), |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 5e233a577d0f..d0ac795445b7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -442,7 +442,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
442 | break; | 442 | break; |
443 | case cpu_to_le16(0): | 443 | case cpu_to_le16(0): |
444 | if (iftype != NL80211_IFTYPE_ADHOC && | 444 | if (iftype != NL80211_IFTYPE_ADHOC && |
445 | iftype != NL80211_IFTYPE_STATION) | 445 | iftype != NL80211_IFTYPE_STATION && |
446 | iftype != NL80211_IFTYPE_OCB) | ||
446 | return -1; | 447 | return -1; |
447 | break; | 448 | break; |
448 | } | 449 | } |
@@ -519,6 +520,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, | |||
519 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 520 | memcpy(hdr.addr3, skb->data, ETH_ALEN); |
520 | hdrlen = 24; | 521 | hdrlen = 24; |
521 | break; | 522 | break; |
523 | case NL80211_IFTYPE_OCB: | ||
522 | case NL80211_IFTYPE_ADHOC: | 524 | case NL80211_IFTYPE_ADHOC: |
523 | /* DA SA BSSID */ | 525 | /* DA SA BSSID */ |
524 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 526 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -937,6 +939,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
937 | if (dev->ieee80211_ptr->use_4addr) | 939 | if (dev->ieee80211_ptr->use_4addr) |
938 | break; | 940 | break; |
939 | /* fall through */ | 941 | /* fall through */ |
942 | case NL80211_IFTYPE_OCB: | ||
940 | case NL80211_IFTYPE_P2P_CLIENT: | 943 | case NL80211_IFTYPE_P2P_CLIENT: |
941 | case NL80211_IFTYPE_ADHOC: | 944 | case NL80211_IFTYPE_ADHOC: |
942 | dev->priv_flags |= IFF_DONT_BRIDGE; | 945 | dev->priv_flags |= IFF_DONT_BRIDGE; |