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 (!rdev->ops->join_ocb) 33 return -EOPNOTSUPP; 34 35 if (WARN_ON(!setup->chandef.chan)) 36 return -EINVAL; 37 38 err = rdev_join_ocb(rdev, dev, setup); 39 if (!err) 40 wdev->chandef = setup->chandef; 41 42 return err; 43 } 44 45 int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 46 struct net_device *dev, 47 struct ocb_setup *setup) 48 { 49 struct wireless_dev *wdev = dev->ieee80211_ptr; 50 int err; 51 52 wdev_lock(wdev); 53 err = __cfg80211_join_ocb(rdev, dev, setup); 54 wdev_unlock(wdev); 55 56 return err; 57 } 58 59 int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 60 struct net_device *dev) 61 { 62 struct wireless_dev *wdev = dev->ieee80211_ptr; 63 int err; 64 65 ASSERT_WDEV_LOCK(wdev); 66 67 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) 68 return -EOPNOTSUPP; 69 70 if (!rdev->ops->leave_ocb) 71 return -EOPNOTSUPP; 72 73 err = rdev_leave_ocb(rdev, dev); 74 if (!err) 75 memset(&wdev->chandef, 0, sizeof(wdev->chandef)); 76 77 return err; 78 } 79 80 int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 81 struct net_device *dev) 82 { 83 struct wireless_dev *wdev = dev->ieee80211_ptr; 84 int err; 85 86 wdev_lock(wdev); 87 err = __cfg80211_leave_ocb(rdev, dev); 88 wdev_unlock(wdev); 89 90 return err; 91 } 92