1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * OCB mode implementation 4 * 5 * Copyright: (c) 2014 Czech Technical University in Prague 6 * (c) 2014 Volkswagen Group Research 7 * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz> 8 * Funded by: Volkswagen Group Research 9 */ 10 11 #include <linux/ieee80211.h> 12 #include <net/cfg80211.h> 13 #include "nl80211.h" 14 #include "core.h" 15 #include "rdev-ops.h" 16 17 int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 18 struct net_device *dev, 19 struct ocb_setup *setup) 20 { 21 struct wireless_dev *wdev = dev->ieee80211_ptr; 22 int err; 23 24 ASSERT_WDEV_LOCK(wdev); 25 26 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) 27 return -EOPNOTSUPP; 28 29 if (!rdev->ops->join_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 } 89