aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRostislav Lisovy <lisovy@gmail.com>2014-11-03 04:33:18 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-11-04 07:18:17 -0500
commit6e0bd6c35b021dc73a81ebd1ef79761233c48b50 (patch)
treef3da02d8006a5ff98f3dd33a37dc1eddafd7b85c
parent5b3dc42b1b0db0264bbbe4ae44c15ab97bfd1e93 (diff)
cfg80211: 802.11p OCB mode handling
This patch adds new iface type (NL80211_IFTYPE_OCB) representing the OCB (Outside the Context of a BSS) mode. When establishing a connection to the network a cfg80211_join_ocb function is called (particular nl80211_command is added as well). A mandatory parameters during the ocb_join operation are 'center frequency' and 'channel width (5/10 MHz)'. Changes done in mac80211 are minimal possible required to avoid many warnings (warning: enumeration value 'NL80211_IFTYPE_OCB' not handled in switch) during compilation. Full functionality (where needed) is added in the following patch. Signed-off-by: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h19
-rw-r--r--include/uapi/linux/nl80211.h11
-rw-r--r--net/mac80211/cfg.c1
-rw-r--r--net/mac80211/chan.c2
-rw-r--r--net/mac80211/iface.c5
-rw-r--r--net/mac80211/util.c3
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/chan.c8
-rw-r--r--net/wireless/core.c3
-rw-r--r--net/wireless/core.h12
-rw-r--r--net/wireless/nl80211.c39
-rw-r--r--net/wireless/ocb.c88
-rw-r--r--net/wireless/rdev-ops.h21
-rw-r--r--net/wireless/trace.h21
-rw-r--r--net/wireless/util.c5
15 files changed, 238 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f67948e18600..5c3acd07acd9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1359,6 +1359,16 @@ struct mesh_setup {
1359}; 1359};
1360 1360
1361/** 1361/**
1362 * struct ocb_setup - 802.11p OCB mode setup configuration
1363 * @chandef: defines the channel to use
1364 *
1365 * These parameters are fixed when connecting to the network
1366 */
1367struct ocb_setup {
1368 struct cfg80211_chan_def chandef;
1369};
1370
1371/**
1362 * struct ieee80211_txq_params - TX queue parameters 1372 * struct ieee80211_txq_params - TX queue parameters
1363 * @ac: AC identifier 1373 * @ac: AC identifier
1364 * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled 1374 * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled
@@ -2352,6 +2362,11 @@ struct cfg80211_qos_map {
2352 * with the peer followed by immediate teardown when the addition is later 2362 * with the peer followed by immediate teardown when the addition is later
2353 * rejected) 2363 * rejected)
2354 * @del_tx_ts: remove an existing TX TS 2364 * @del_tx_ts: remove an existing TX TS
2365 *
2366 * @join_ocb: join the OCB network with the specified parameters
2367 * (invoked with the wireless_dev mutex held)
2368 * @leave_ocb: leave the current OCB network
2369 * (invoked with the wireless_dev mutex held)
2355 */ 2370 */
2356struct cfg80211_ops { 2371struct cfg80211_ops {
2357 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); 2372 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2433,6 +2448,10 @@ struct cfg80211_ops {
2433 const struct mesh_setup *setup); 2448 const struct mesh_setup *setup);
2434 int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); 2449 int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev);
2435 2450
2451 int (*join_ocb)(struct wiphy *wiphy, struct net_device *dev,
2452 struct ocb_setup *setup);
2453 int (*leave_ocb)(struct wiphy *wiphy, struct net_device *dev);
2454
2436 int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, 2455 int (*change_bss)(struct wiphy *wiphy, struct net_device *dev,
2437 struct bss_parameters *params); 2456 struct bss_parameters *params);
2438 2457
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f7daae59248e..9b3025e4377a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -746,6 +746,11 @@
746 * destination %NL80211_ATTR_MAC on the interface identified by 746 * destination %NL80211_ATTR_MAC on the interface identified by
747 * %NL80211_ATTR_IFINDEX. 747 * %NL80211_ATTR_IFINDEX.
748 * 748 *
749 * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and
750 * bandwidth of a channel must be given.
751 * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the
752 * network is determined by the network interface.
753 *
749 * @NL80211_CMD_MAX: highest used command number 754 * @NL80211_CMD_MAX: highest used command number
750 * @__NL80211_CMD_AFTER_LAST: internal use 755 * @__NL80211_CMD_AFTER_LAST: internal use
751 */ 756 */
@@ -922,6 +927,9 @@ enum nl80211_commands {
922 927
923 NL80211_CMD_GET_MPP, 928 NL80211_CMD_GET_MPP,
924 929
930 NL80211_CMD_JOIN_OCB,
931 NL80211_CMD_LEAVE_OCB,
932
925 /* add new commands above here */ 933 /* add new commands above here */
926 934
927 /* used to define NL80211_CMD_MAX below */ 935 /* used to define NL80211_CMD_MAX below */
@@ -2074,6 +2082,8 @@ enum nl80211_attrs {
2074 * and therefore can't be created in the normal ways, use the 2082 * and therefore can't be created in the normal ways, use the
2075 * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE 2083 * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE
2076 * commands to create and destroy one 2084 * commands to create and destroy one
2085 * @NL80211_IF_TYPE_OCB: Outside Context of a BSS
2086 * This mode corresponds to the MIB variable dot11OCBActivated=true
2077 * @NL80211_IFTYPE_MAX: highest interface type number currently defined 2087 * @NL80211_IFTYPE_MAX: highest interface type number currently defined
2078 * @NUM_NL80211_IFTYPES: number of defined interface types 2088 * @NUM_NL80211_IFTYPES: number of defined interface types
2079 * 2089 *
@@ -2093,6 +2103,7 @@ enum nl80211_iftype {
2093 NL80211_IFTYPE_P2P_CLIENT, 2103 NL80211_IFTYPE_P2P_CLIENT,
2094 NL80211_IFTYPE_P2P_GO, 2104 NL80211_IFTYPE_P2P_GO,
2095 NL80211_IFTYPE_P2P_DEVICE, 2105 NL80211_IFTYPE_P2P_DEVICE,
2106 NL80211_IFTYPE_OCB,
2096 2107
2097 /* keep last */ 2108 /* keep last */
2098 NUM_NL80211_IFTYPES, 2109 NUM_NL80211_IFTYPES,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b9659b8b70f8..1e2afc95ad09 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -230,6 +230,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
230 case NUM_NL80211_IFTYPES: 230 case NUM_NL80211_IFTYPES:
231 case NL80211_IFTYPE_P2P_CLIENT: 231 case NL80211_IFTYPE_P2P_CLIENT:
232 case NL80211_IFTYPE_P2P_GO: 232 case NL80211_IFTYPE_P2P_GO:
233 case NL80211_IFTYPE_OCB:
233 /* shouldn't happen */ 234 /* shouldn't happen */
234 WARN_ON_ONCE(1); 235 WARN_ON_ONCE(1);
235 break; 236 break;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index ee71bb6f64f7..ff1f877e3b63 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -270,6 +270,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
270 case NL80211_IFTYPE_ADHOC: 270 case NL80211_IFTYPE_ADHOC:
271 case NL80211_IFTYPE_WDS: 271 case NL80211_IFTYPE_WDS:
272 case NL80211_IFTYPE_MESH_POINT: 272 case NL80211_IFTYPE_MESH_POINT:
273 case NL80211_IFTYPE_OCB:
273 width = vif->bss_conf.chandef.width; 274 width = vif->bss_conf.chandef.width;
274 break; 275 break;
275 case NL80211_IFTYPE_UNSPECIFIED: 276 case NL80211_IFTYPE_UNSPECIFIED:
@@ -909,6 +910,7 @@ ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
909 case NL80211_IFTYPE_ADHOC: 910 case NL80211_IFTYPE_ADHOC:
910 case NL80211_IFTYPE_AP: 911 case NL80211_IFTYPE_AP:
911 case NL80211_IFTYPE_MESH_POINT: 912 case NL80211_IFTYPE_MESH_POINT:
913 case NL80211_IFTYPE_OCB:
912 ieee80211_queue_work(&sdata->local->hw, 914 ieee80211_queue_work(&sdata->local->hw,
913 &sdata->csa_finalize_work); 915 &sdata->csa_finalize_work);
914 break; 916 break;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 1ffcc0701244..d69e7532095f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -521,6 +521,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
521 case NL80211_IFTYPE_MONITOR: 521 case NL80211_IFTYPE_MONITOR:
522 case NL80211_IFTYPE_ADHOC: 522 case NL80211_IFTYPE_ADHOC:
523 case NL80211_IFTYPE_P2P_DEVICE: 523 case NL80211_IFTYPE_P2P_DEVICE:
524 case NL80211_IFTYPE_OCB:
524 /* no special treatment */ 525 /* no special treatment */
525 break; 526 break;
526 case NL80211_IFTYPE_UNSPECIFIED: 527 case NL80211_IFTYPE_UNSPECIFIED:
@@ -631,6 +632,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
631 case NL80211_IFTYPE_ADHOC: 632 case NL80211_IFTYPE_ADHOC:
632 case NL80211_IFTYPE_AP: 633 case NL80211_IFTYPE_AP:
633 case NL80211_IFTYPE_MESH_POINT: 634 case NL80211_IFTYPE_MESH_POINT:
635 case NL80211_IFTYPE_OCB:
634 netif_carrier_off(dev); 636 netif_carrier_off(dev);
635 break; 637 break;
636 case NL80211_IFTYPE_WDS: 638 case NL80211_IFTYPE_WDS:
@@ -1351,6 +1353,9 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1351 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; 1353 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
1352 ieee80211_sta_setup_sdata(sdata); 1354 ieee80211_sta_setup_sdata(sdata);
1353 break; 1355 break;
1356 case NL80211_IFTYPE_OCB:
1357 /* to be implemented in the future */
1358 break;
1354 case NL80211_IFTYPE_ADHOC: 1359 case NL80211_IFTYPE_ADHOC:
1355 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 1360 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
1356 ieee80211_ibss_setup_sdata(sdata); 1361 ieee80211_ibss_setup_sdata(sdata);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 666aa1306c45..d7d69c89ff34 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1841,6 +1841,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1841 ieee80211_bss_info_change_notify(sdata, changed); 1841 ieee80211_bss_info_change_notify(sdata, changed);
1842 sdata_unlock(sdata); 1842 sdata_unlock(sdata);
1843 break; 1843 break;
1844 case NL80211_IFTYPE_OCB:
1845 /* to be implemented in the future */
1846 break;
1844 case NL80211_IFTYPE_ADHOC: 1847 case NL80211_IFTYPE_ADHOC:
1845 changed |= BSS_CHANGED_IBSS; 1848 changed |= BSS_CHANGED_IBSS;
1846 /* fall through */ 1849 /* fall through */
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
10obj-$(CONFIG_WEXT_PRIV) += wext-priv.o 10obj-$(CONFIG_WEXT_PRIV) += wext-priv.o
11 11
12cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 12cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
13cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o 13cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o
14cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 14cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
15cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 15cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
16cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o 16cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 8f39e33e71bb..85506f1d0789 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -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 da4dcb65ade4..a4d27927aba2 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -869,6 +869,9 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
869 case NL80211_IFTYPE_P2P_GO: 869 case NL80211_IFTYPE_P2P_GO:
870 __cfg80211_stop_ap(rdev, dev, true); 870 __cfg80211_stop_ap(rdev, dev, true);
871 break; 871 break;
872 case NL80211_IFTYPE_OCB:
873 __cfg80211_leave_ocb(rdev, dev);
874 break;
872 case NL80211_IFTYPE_WDS: 875 case NL80211_IFTYPE_WDS:
873 /* must be handled by mac80211/driver, has no APIs */ 876 /* must be handled by mac80211/driver, has no APIs */
874 break; 877 break;
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 */
294int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
295 struct net_device *dev,
296 struct ocb_setup *setup);
297int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
298 struct net_device *dev,
299 struct ocb_setup *setup);
300int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
301 struct net_device *dev);
302int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
303 struct net_device *dev);
304
293/* AP */ 305/* AP */
294int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 306int __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 f7d918858d32..1a31736914e5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -885,6 +885,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
885 return -ENOLINK; 885 return -ENOLINK;
886 break; 886 break;
887 case NL80211_IFTYPE_UNSPECIFIED: 887 case NL80211_IFTYPE_UNSPECIFIED:
888 case NL80211_IFTYPE_OCB:
888 case NL80211_IFTYPE_MONITOR: 889 case NL80211_IFTYPE_MONITOR:
889 case NL80211_IFTYPE_P2P_DEVICE: 890 case NL80211_IFTYPE_P2P_DEVICE:
890 case NL80211_IFTYPE_WDS: 891 case NL80211_IFTYPE_WDS:
@@ -8275,6 +8276,28 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
8275 return -EINVAL; 8276 return -EINVAL;
8276} 8277}
8277 8278
8279static 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
8293static 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
8278static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) 8301static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
8279{ 8302{
8280 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8303 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -10218,6 +10241,22 @@ static const struct genl_ops nl80211_ops[] = {
10218 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 10241 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
10219 NL80211_FLAG_NEED_RTNL, 10242 NL80211_FLAG_NEED_RTNL,
10220 }, 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 },
10221#ifdef CONFIG_PM 10260#ifdef CONFIG_PM
10222 { 10261 {
10223 .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
20int __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
42int 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
56int __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
77int 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 71b1db3cc645..1b3864cd50ca 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -348,6 +348,27 @@ static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev,
348 return ret; 348 return ret;
349} 349}
350 350
351static 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
362static 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
351static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, 372static inline int rdev_change_bss(struct cfg80211_registered_device *rdev,
352 struct net_device *dev, 373 struct net_device *dev,
353 struct bss_parameters *params) 374 struct bss_parameters *params)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index cdb2c2ef1ae1..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
603DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ocb,
604 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
605 TP_ARGS(wiphy, netdev)
606);
607
603DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, 608DEFINE_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)
@@ -1316,6 +1321,22 @@ TRACE_EVENT(rdev_join_ibss,
1316 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)
1317); 1322);
1318 1323
1324TRACE_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
1319TRACE_EVENT(rdev_set_wiphy_params, 1340TRACE_EVENT(rdev_set_wiphy_params,
1320 TP_PROTO(struct wiphy *wiphy, u32 changed), 1341 TP_PROTO(struct wiphy *wiphy, u32 changed),
1321 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;