mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-03 17:40:04 +00:00
![Johannes Berg](/assets/img/avatar_default.png)
In order to support multi-link operation with multiple links, start adding some APIs. The notable addition here is to have the link ID in a new nl80211 attribute, that will be used to differentiate the links in many nl80211 operations. So far, this patch adds the netlink NL80211_ATTR_MLO_LINK_ID attribute (as well as the NL80211_ATTR_MLO_LINKS attribute) and plugs it through the system in some places, checking the validity etc. along with other infrastructure needed for it. For now, I've decided to include only the over-the-air link ID in the API. I know we discussed that we eventually need to have to have other ways of identifying a link, but for local AP mode and auth/assoc commands as well as set_key etc. we'll use the OTA ID. Also included in this patch is some refactoring of the data structures in struct wireless_dev, splitting for the first time the data into type dependent pieces, to make reasoning about these things easier. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
89 lines
1.9 KiB
C
89 lines
1.9 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* OCB mode implementation
|
|
*
|
|
* Copyright: (c) 2014 Czech Technical University in Prague
|
|
* (c) 2014 Volkswagen Group Research
|
|
* Copyright (C) 2022 Intel Corporation
|
|
* Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
|
|
* Funded by: Volkswagen Group Research
|
|
*/
|
|
|
|
#include <linux/ieee80211.h>
|
|
#include <net/cfg80211.h>
|
|
#include "nl80211.h"
|
|
#include "core.h"
|
|
#include "rdev-ops.h"
|
|
|
|
int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev,
|
|
struct ocb_setup *setup)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
ASSERT_WDEV_LOCK(wdev);
|
|
|
|
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
|
|
return -EOPNOTSUPP;
|
|
|
|
if (!rdev->ops->join_ocb)
|
|
return -EOPNOTSUPP;
|
|
|
|
if (WARN_ON(!setup->chandef.chan))
|
|
return -EINVAL;
|
|
|
|
err = rdev_join_ocb(rdev, dev, setup);
|
|
if (!err)
|
|
wdev->u.ocb.chandef = setup->chandef;
|
|
|
|
return err;
|
|
}
|
|
|
|
int cfg80211_join_ocb(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev,
|
|
struct ocb_setup *setup)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
wdev_lock(wdev);
|
|
err = __cfg80211_join_ocb(rdev, dev, setup);
|
|
wdev_unlock(wdev);
|
|
|
|
return err;
|
|
}
|
|
|
|
int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
ASSERT_WDEV_LOCK(wdev);
|
|
|
|
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
|
|
return -EOPNOTSUPP;
|
|
|
|
if (!rdev->ops->leave_ocb)
|
|
return -EOPNOTSUPP;
|
|
|
|
err = rdev_leave_ocb(rdev, dev);
|
|
if (!err)
|
|
memset(&wdev->u.ocb.chandef, 0, sizeof(wdev->u.ocb.chandef));
|
|
|
|
return err;
|
|
}
|
|
|
|
int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
|
|
struct net_device *dev)
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
int err;
|
|
|
|
wdev_lock(wdev);
|
|
err = __cfg80211_leave_ocb(rdev, dev);
|
|
wdev_unlock(wdev);
|
|
|
|
return err;
|
|
}
|