^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * OCB mode implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright: (c) 2014 Czech Technical University in Prague
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (c) 2014 Volkswagen Group Research
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Funded by: Volkswagen Group Research
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/ieee80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "nl80211.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "rdev-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct ocb_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (!rdev->ops->join_ocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (WARN_ON(!setup->chandef.chan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) err = rdev_join_ocb(rdev, dev, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) wdev->chandef = setup->chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct ocb_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) err = __cfg80211_join_ocb(rdev, dev, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!rdev->ops->leave_ocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) err = rdev_leave_ocb(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) memset(&wdev->chandef, 0, sizeof(wdev->chandef));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) err = __cfg80211_leave_ocb(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }