cfg80211: add P2P Device abstraction
In order to support using a different MAC address for the P2P Device address we must first have a P2P Device abstraction that can be assigned a MAC address. This abstraction will also be useful to support offloading P2P operations to the device, e.g. periodic listen for discoverability. Currently, the driver is responsible for assigning a MAC address to the P2P Device, but this could be changed by allowing a MAC address to be given to the NEW_INTERFACE command. As it has no associated netdev, a P2P Device can only be identified by its wdev identifier but the previous patches allowed using the wdev identifier in various APIs, e.g. remain-on-channel. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -230,9 +230,24 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
|
||||
rtnl_lock();
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
|
||||
list_for_each_entry(wdev, &rdev->wdev_list, list)
|
||||
if (wdev->netdev)
|
||||
list_for_each_entry(wdev, &rdev->wdev_list, list) {
|
||||
if (wdev->netdev) {
|
||||
dev_close(wdev->netdev);
|
||||
continue;
|
||||
}
|
||||
/* otherwise, check iftype */
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
if (!wdev->p2p_started)
|
||||
break;
|
||||
rdev->ops->stop_p2p_device(&rdev->wiphy, wdev);
|
||||
wdev->p2p_started = false;
|
||||
rdev->opencount--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&rdev->devlist_mtx);
|
||||
rtnl_unlock();
|
||||
@@ -407,6 +422,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
|
||||
if (WARN_ON(wiphy->software_iftypes & types))
|
||||
return -EINVAL;
|
||||
|
||||
/* Only a single P2P_DEVICE can be allowed */
|
||||
if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
||||
c->limits[j].max > 1))
|
||||
return -EINVAL;
|
||||
|
||||
cnt += c->limits[j].max;
|
||||
/*
|
||||
* Don't advertise an unsupported type
|
||||
@@ -734,6 +754,35 @@ static void wdev_cleanup_work(struct work_struct *work)
|
||||
dev_put(wdev->netdev);
|
||||
}
|
||||
|
||||
void cfg80211_unregister_wdev(struct wireless_dev *wdev)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (WARN_ON(wdev->netdev))
|
||||
return;
|
||||
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
list_del_rcu(&wdev->list);
|
||||
rdev->devlist_generation++;
|
||||
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
if (!wdev->p2p_started)
|
||||
break;
|
||||
rdev->ops->stop_p2p_device(&rdev->wiphy, wdev);
|
||||
wdev->p2p_started = false;
|
||||
rdev->opencount--;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&rdev->devlist_mtx);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_unregister_wdev);
|
||||
|
||||
static struct device_type wiphy_type = {
|
||||
.name = "wlan",
|
||||
};
|
||||
|
Reference in New Issue
Block a user