diff options
author | Rostislav Lisovy <lisovy@gmail.com> | 2014-11-03 04:33:18 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-11-04 07:18:17 -0500 |
commit | 6e0bd6c35b021dc73a81ebd1ef79761233c48b50 (patch) | |
tree | f3da02d8006a5ff98f3dd33a37dc1eddafd7b85c | |
parent | 5b3dc42b1b0db0264bbbe4ae44c15ab97bfd1e93 (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.h | 19 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 11 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 1 | ||||
-rw-r--r-- | net/mac80211/chan.c | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 5 | ||||
-rw-r--r-- | net/mac80211/util.c | 3 | ||||
-rw-r--r-- | net/wireless/Makefile | 2 | ||||
-rw-r--r-- | net/wireless/chan.c | 8 | ||||
-rw-r--r-- | net/wireless/core.c | 3 | ||||
-rw-r--r-- | net/wireless/core.h | 12 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 39 | ||||
-rw-r--r-- | net/wireless/ocb.c | 88 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 21 | ||||
-rw-r--r-- | net/wireless/trace.h | 21 | ||||
-rw-r--r-- | net/wireless/util.c | 5 |
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 | */ | ||
1367 | struct 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 | */ |
2356 | struct cfg80211_ops { | 2371 | struct 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 | |||
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 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 */ | ||
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 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 | ||
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 | |||
8278 | 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) |
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 | |||
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 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 | ||
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 | |||
351 | static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, | 372 | static 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 | ||
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) |
@@ -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 | ||
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 | |||
1319 | TRACE_EVENT(rdev_set_wiphy_params, | 1340 | TRACE_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; |