Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+265 -20
+26 -4
include/linux/nl80211.h
··· 565 565 * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with 566 566 * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. 567 567 * 568 + * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by 569 + * its %NL80211_ATTR_WDEV identifier. It must have been created with 570 + * %NL80211_CMD_NEW_INTERFACE previously. After it has been started, the 571 + * P2P Device can be used for P2P operations, e.g. remain-on-channel and 572 + * public action frame TX. 573 + * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by 574 + * its %NL80211_ATTR_WDEV identifier. 575 + * 568 576 * @NL80211_CMD_MAX: highest used command number 569 577 * @__NL80211_CMD_AFTER_LAST: internal use 570 578 */ ··· 715 707 NL80211_CMD_SET_NOACK_MAP, 716 708 717 709 NL80211_CMD_CH_SWITCH_NOTIFY, 710 + 711 + NL80211_CMD_START_P2P_DEVICE, 712 + NL80211_CMD_STOP_P2P_DEVICE, 718 713 719 714 /* add new commands above here */ 720 715 ··· 1586 1575 * @NL80211_IFTYPE_MESH_POINT: mesh point 1587 1576 * @NL80211_IFTYPE_P2P_CLIENT: P2P client 1588 1577 * @NL80211_IFTYPE_P2P_GO: P2P group owner 1578 + * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev 1579 + * and therefore can't be created in the normal ways, use the 1580 + * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE 1581 + * commands to create and destroy one 1589 1582 * @NL80211_IFTYPE_MAX: highest interface type number currently defined 1590 1583 * @NUM_NL80211_IFTYPES: number of defined interface types 1591 1584 * ··· 1608 1593 NL80211_IFTYPE_MESH_POINT, 1609 1594 NL80211_IFTYPE_P2P_CLIENT, 1610 1595 NL80211_IFTYPE_P2P_GO, 1596 + NL80211_IFTYPE_P2P_DEVICE, 1611 1597 1612 1598 /* keep last */ 1613 1599 NUM_NL80211_IFTYPES, ··· 3010 2994 * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested 3011 2995 * to work properly to suppport receiving regulatory hints from 3012 2996 * cellular base stations. 2997 + * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active 2998 + * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel 2999 + * in the interface combinations, even when it's only used for scan 3000 + * and remain-on-channel. This could be due to, for example, the 3001 + * remain-on-channel implementation requiring a channel context. 3013 3002 */ 3014 3003 enum nl80211_feature_flags { 3015 - NL80211_FEATURE_SK_TX_STATUS = 1 << 0, 3016 - NL80211_FEATURE_HT_IBSS = 1 << 1, 3017 - NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, 3018 - NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, 3004 + NL80211_FEATURE_SK_TX_STATUS = 1 << 0, 3005 + NL80211_FEATURE_HT_IBSS = 1 << 1, 3006 + NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, 3007 + NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, 3008 + NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, 3019 3009 }; 3020 3010 3021 3011 /**
+38 -2
include/net/cfg80211.h
··· 1437 1437 * @add_virtual_intf: create a new virtual interface with the given name, 1438 1438 * must set the struct wireless_dev's iftype. Beware: You must create 1439 1439 * the new netdev in the wiphy's network namespace! Returns the struct 1440 - * wireless_dev, or an ERR_PTR. 1440 + * wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must 1441 + * also set the address member in the wdev. 1441 1442 * 1442 1443 * @del_virtual_intf: remove the virtual interface 1443 1444 * ··· 1617 1616 * @get_channel: Get the current operating channel for the virtual interface. 1618 1617 * For monitor interfaces, it should return %NULL unless there's a single 1619 1618 * current monitoring channel. 1619 + * 1620 + * @start_p2p_device: Start the given P2P device. 1621 + * @stop_p2p_device: Stop the given P2P device. 1620 1622 */ 1621 1623 struct cfg80211_ops { 1622 1624 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ··· 1836 1832 (*get_channel)(struct wiphy *wiphy, 1837 1833 struct wireless_dev *wdev, 1838 1834 enum nl80211_channel_type *type); 1835 + 1836 + int (*start_p2p_device)(struct wiphy *wiphy, 1837 + struct wireless_dev *wdev); 1838 + void (*stop_p2p_device)(struct wiphy *wiphy, 1839 + struct wireless_dev *wdev); 1839 1840 }; 1840 1841 1841 1842 /* ··· 2404 2395 * @cleanup_work: work struct used for cleanup that can't be done directly 2405 2396 * @beacon_interval: beacon interval used on this device for transmitting 2406 2397 * beacons, 0 when not valid 2398 + * @address: The address for this device, valid only if @netdev is %NULL 2399 + * @p2p_started: true if this is a P2P Device that has been started 2407 2400 */ 2408 2401 struct wireless_dev { 2409 2402 struct wiphy *wiphy; ··· 2424 2413 2425 2414 struct work_struct cleanup_work; 2426 2415 2427 - bool use_4addr; 2416 + bool use_4addr, p2p_started; 2417 + 2418 + u8 address[ETH_ALEN] __aligned(sizeof(u16)); 2428 2419 2429 2420 /* currently used for IBSS and SME - might be rearranged later */ 2430 2421 u8 ssid[IEEE80211_MAX_SSID_LEN]; ··· 2473 2460 } wext; 2474 2461 #endif 2475 2462 }; 2463 + 2464 + static inline u8 *wdev_address(struct wireless_dev *wdev) 2465 + { 2466 + if (wdev->netdev) 2467 + return wdev->netdev->dev_addr; 2468 + return wdev->address; 2469 + } 2476 2470 2477 2471 /** 2478 2472 * wdev_priv - return wiphy priv from wireless_dev ··· 3547 3527 * return 0 if MCS index >= 32 3548 3528 */ 3549 3529 u32 cfg80211_calculate_bitrate(struct rate_info *rate); 3530 + 3531 + /** 3532 + * cfg80211_unregister_wdev - remove the given wdev 3533 + * @wdev: struct wireless_dev to remove 3534 + * 3535 + * Call this function only for wdevs that have no netdev assigned, 3536 + * e.g. P2P Devices. It removes the device from the list so that 3537 + * it can no longer be used. It is necessary to call this function 3538 + * even when cfg80211 requests the removal of the interface by 3539 + * calling the del_virtual_intf() callback. The function must also 3540 + * be called when the driver wishes to unregister the wdev, e.g. 3541 + * when the device is unbound from the driver. 3542 + * 3543 + * Requires the RTNL to be held. 3544 + */ 3545 + void cfg80211_unregister_wdev(struct wireless_dev *wdev); 3550 3546 3551 3547 /* Logging, debugging and troubleshooting/diagnostic helpers. */ 3552 3548
+3
net/mac80211/iface.c
··· 449 449 case NUM_NL80211_IFTYPES: 450 450 case NL80211_IFTYPE_P2P_CLIENT: 451 451 case NL80211_IFTYPE_P2P_GO: 452 + case NL80211_IFTYPE_P2P_DEVICE: 452 453 /* cannot happen */ 453 454 WARN_ON(1); 454 455 break; ··· 1147 1146 case NL80211_IFTYPE_WDS: 1148 1147 case NL80211_IFTYPE_AP_VLAN: 1149 1148 break; 1149 + case NL80211_IFTYPE_P2P_DEVICE: 1150 + /* not yet supported */ 1150 1151 case NL80211_IFTYPE_UNSPECIFIED: 1151 1152 case NUM_NL80211_IFTYPES: 1152 1153 BUG();
+2
net/mac80211/util.c
··· 1390 1390 case NL80211_IFTYPE_MONITOR: 1391 1391 /* ignore virtual */ 1392 1392 break; 1393 + case NL80211_IFTYPE_P2P_DEVICE: 1394 + /* not yet supported */ 1393 1395 case NL80211_IFTYPE_UNSPECIFIED: 1394 1396 case NUM_NL80211_IFTYPES: 1395 1397 case NL80211_IFTYPE_P2P_CLIENT:
+6 -1
net/wireless/chan.c
··· 105 105 106 106 ASSERT_WDEV_LOCK(wdev); 107 107 108 - if (!netif_running(wdev->netdev)) 108 + if (wdev->netdev && !netif_running(wdev->netdev)) 109 109 return; 110 110 111 111 switch (wdev->iftype) { ··· 142 142 case NL80211_IFTYPE_AP_VLAN: 143 143 case NL80211_IFTYPE_WDS: 144 144 /* these interface types don't really have a channel */ 145 + return; 146 + case NL80211_IFTYPE_P2P_DEVICE: 147 + if (wdev->wiphy->features & 148 + NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL) 149 + *chanmode = CHAN_MODE_EXCLUSIVE; 145 150 return; 146 151 case NL80211_IFTYPE_UNSPECIFIED: 147 152 case NUM_NL80211_IFTYPES:
+51 -2
net/wireless/core.c
··· 230 230 rtnl_lock(); 231 231 mutex_lock(&rdev->devlist_mtx); 232 232 233 - list_for_each_entry(wdev, &rdev->wdev_list, list) 234 - if (wdev->netdev) 233 + list_for_each_entry(wdev, &rdev->wdev_list, list) { 234 + if (wdev->netdev) { 235 235 dev_close(wdev->netdev); 236 + continue; 237 + } 238 + /* otherwise, check iftype */ 239 + switch (wdev->iftype) { 240 + case NL80211_IFTYPE_P2P_DEVICE: 241 + if (!wdev->p2p_started) 242 + break; 243 + rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); 244 + wdev->p2p_started = false; 245 + rdev->opencount--; 246 + break; 247 + default: 248 + break; 249 + } 250 + } 236 251 237 252 mutex_unlock(&rdev->devlist_mtx); 238 253 rtnl_unlock(); ··· 420 405 421 406 /* Shouldn't list software iftypes in combinations! */ 422 407 if (WARN_ON(wiphy->software_iftypes & types)) 408 + return -EINVAL; 409 + 410 + /* Only a single P2P_DEVICE can be allowed */ 411 + if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && 412 + c->limits[j].max > 1)) 423 413 return -EINVAL; 424 414 425 415 cnt += c->limits[j].max; ··· 753 733 754 734 dev_put(wdev->netdev); 755 735 } 736 + 737 + void cfg80211_unregister_wdev(struct wireless_dev *wdev) 738 + { 739 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 740 + 741 + ASSERT_RTNL(); 742 + 743 + if (WARN_ON(wdev->netdev)) 744 + return; 745 + 746 + mutex_lock(&rdev->devlist_mtx); 747 + list_del_rcu(&wdev->list); 748 + rdev->devlist_generation++; 749 + 750 + switch (wdev->iftype) { 751 + case NL80211_IFTYPE_P2P_DEVICE: 752 + if (!wdev->p2p_started) 753 + break; 754 + rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); 755 + wdev->p2p_started = false; 756 + rdev->opencount--; 757 + break; 758 + default: 759 + WARN_ON_ONCE(1); 760 + break; 761 + } 762 + mutex_unlock(&rdev->devlist_mtx); 763 + } 764 + EXPORT_SYMBOL(cfg80211_unregister_wdev); 756 765 757 766 static struct device_type wiphy_type = { 758 767 .name = "wlan",
+7 -3
net/wireless/mlme.c
··· 736 736 const u8 *buf, size_t len, bool no_cck, 737 737 bool dont_wait_for_ack, u64 *cookie) 738 738 { 739 - struct net_device *dev = wdev->netdev; 740 739 const struct ieee80211_mgmt *mgmt; 741 740 u16 stype; 742 741 ··· 795 796 case NL80211_IFTYPE_AP: 796 797 case NL80211_IFTYPE_P2P_GO: 797 798 case NL80211_IFTYPE_AP_VLAN: 798 - if (!ether_addr_equal(mgmt->bssid, dev->dev_addr)) 799 + if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev))) 799 800 err = -EINVAL; 800 801 break; 801 802 case NL80211_IFTYPE_MESH_POINT: ··· 808 809 * cfg80211 doesn't track the stations 809 810 */ 810 811 break; 812 + case NL80211_IFTYPE_P2P_DEVICE: 813 + /* 814 + * fall through, P2P device only supports 815 + * public action frames 816 + */ 811 817 default: 812 818 err = -EOPNOTSUPP; 813 819 break; ··· 823 819 return err; 824 820 } 825 821 826 - if (!ether_addr_equal(mgmt->sa, dev->dev_addr)) 822 + if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) 827 823 return -EINVAL; 828 824 829 825 /* Transmit the Action frame as requested by user space */
+116 -6
net/wireless/nl80211.c
··· 1100 1100 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) 1101 1101 goto nla_put_failure; 1102 1102 } 1103 + CMD(start_p2p_device, START_P2P_DEVICE); 1103 1104 1104 1105 #ifdef CONFIG_NL80211_TESTMODE 1105 1106 CMD(testmode_cmd, TESTMODE); ··· 1749 1748 1750 1749 if (dev && 1751 1750 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || 1752 - nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) || 1753 - nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dev->dev_addr))) 1751 + nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name))) 1754 1752 goto nla_put_failure; 1755 1753 1756 1754 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 1757 1755 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || 1758 1756 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || 1757 + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) || 1759 1758 nla_put_u32(msg, NL80211_ATTR_GENERATION, 1760 1759 rdev->devlist_generation ^ 1761 1760 (cfg80211_rdev_list_generation << 2))) ··· 2022 2021 return PTR_ERR(wdev); 2023 2022 } 2024 2023 2025 - if (type == NL80211_IFTYPE_MESH_POINT && 2026 - info->attrs[NL80211_ATTR_MESH_ID]) { 2024 + switch (type) { 2025 + case NL80211_IFTYPE_MESH_POINT: 2026 + if (!info->attrs[NL80211_ATTR_MESH_ID]) 2027 + break; 2027 2028 wdev_lock(wdev); 2028 2029 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != 2029 2030 IEEE80211_MAX_MESH_ID_LEN); ··· 2034 2031 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), 2035 2032 wdev->mesh_id_up_len); 2036 2033 wdev_unlock(wdev); 2034 + break; 2035 + case NL80211_IFTYPE_P2P_DEVICE: 2036 + /* 2037 + * P2P Device doesn't have a netdev, so doesn't go 2038 + * through the netdev notifier and must be added here 2039 + */ 2040 + mutex_init(&wdev->mtx); 2041 + INIT_LIST_HEAD(&wdev->event_list); 2042 + spin_lock_init(&wdev->event_lock); 2043 + INIT_LIST_HEAD(&wdev->mgmt_registrations); 2044 + spin_lock_init(&wdev->mgmt_registrations_lock); 2045 + 2046 + mutex_lock(&rdev->devlist_mtx); 2047 + wdev->identifier = ++rdev->wdev_id; 2048 + list_add_rcu(&wdev->list, &rdev->wdev_list); 2049 + rdev->devlist_generation++; 2050 + mutex_unlock(&rdev->devlist_mtx); 2051 + break; 2052 + default: 2053 + break; 2037 2054 } 2038 2055 2039 2056 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, ··· 6076 6053 case NL80211_IFTYPE_AP_VLAN: 6077 6054 case NL80211_IFTYPE_MESH_POINT: 6078 6055 case NL80211_IFTYPE_P2P_GO: 6056 + case NL80211_IFTYPE_P2P_DEVICE: 6079 6057 break; 6080 6058 default: 6081 6059 return -EOPNOTSUPP; ··· 6123 6099 case NL80211_IFTYPE_AP_VLAN: 6124 6100 case NL80211_IFTYPE_MESH_POINT: 6125 6101 case NL80211_IFTYPE_P2P_GO: 6102 + case NL80211_IFTYPE_P2P_DEVICE: 6126 6103 break; 6127 6104 default: 6128 6105 return -EOPNOTSUPP; ··· 6220 6195 case NL80211_IFTYPE_AP: 6221 6196 case NL80211_IFTYPE_AP_VLAN: 6222 6197 case NL80211_IFTYPE_P2P_GO: 6198 + case NL80211_IFTYPE_P2P_DEVICE: 6223 6199 break; 6224 6200 default: 6225 6201 return -EOPNOTSUPP; ··· 6836 6810 return 0; 6837 6811 } 6838 6812 6813 + static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) 6814 + { 6815 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6816 + struct wireless_dev *wdev = info->user_ptr[1]; 6817 + int err; 6818 + 6819 + if (!rdev->ops->start_p2p_device) 6820 + return -EOPNOTSUPP; 6821 + 6822 + if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) 6823 + return -EOPNOTSUPP; 6824 + 6825 + if (wdev->p2p_started) 6826 + return 0; 6827 + 6828 + mutex_lock(&rdev->devlist_mtx); 6829 + err = cfg80211_can_add_interface(rdev, wdev->iftype); 6830 + mutex_unlock(&rdev->devlist_mtx); 6831 + if (err) 6832 + return err; 6833 + 6834 + err = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); 6835 + if (err) 6836 + return err; 6837 + 6838 + wdev->p2p_started = true; 6839 + mutex_lock(&rdev->devlist_mtx); 6840 + rdev->opencount++; 6841 + mutex_unlock(&rdev->devlist_mtx); 6842 + 6843 + return 0; 6844 + } 6845 + 6846 + static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) 6847 + { 6848 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6849 + struct wireless_dev *wdev = info->user_ptr[1]; 6850 + 6851 + if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) 6852 + return -EOPNOTSUPP; 6853 + 6854 + if (!rdev->ops->stop_p2p_device) 6855 + return -EOPNOTSUPP; 6856 + 6857 + if (!wdev->p2p_started) 6858 + return 0; 6859 + 6860 + rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); 6861 + wdev->p2p_started = false; 6862 + 6863 + mutex_lock(&rdev->devlist_mtx); 6864 + rdev->opencount--; 6865 + mutex_unlock(&rdev->devlist_mtx); 6866 + 6867 + if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { 6868 + rdev->scan_req->aborted = true; 6869 + ___cfg80211_scan_done(rdev, true); 6870 + } 6871 + 6872 + return 0; 6873 + } 6874 + 6839 6875 #define NL80211_FLAG_NEED_WIPHY 0x01 6840 6876 #define NL80211_FLAG_NEED_NETDEV 0x02 6841 6877 #define NL80211_FLAG_NEED_RTNL 0x04 ··· 6905 6817 #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ 6906 6818 NL80211_FLAG_CHECK_NETDEV_UP) 6907 6819 #define NL80211_FLAG_NEED_WDEV 0x10 6908 - /* If a netdev is associated, it must be UP */ 6820 + /* If a netdev is associated, it must be UP, P2P must be started */ 6909 6821 #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ 6910 6822 NL80211_FLAG_CHECK_NETDEV_UP) 6911 6823 ··· 6966 6878 } 6967 6879 6968 6880 dev_hold(dev); 6881 + } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { 6882 + if (!wdev->p2p_started) { 6883 + mutex_unlock(&cfg80211_mutex); 6884 + if (rtnl) 6885 + rtnl_unlock(); 6886 + return -ENETDOWN; 6887 + } 6969 6888 } 6970 6889 6971 6890 cfg80211_lock_rdev(rdev); ··· 7534 7439 .internal_flags = NL80211_FLAG_NEED_NETDEV | 7535 7440 NL80211_FLAG_NEED_RTNL, 7536 7441 }, 7537 - 7442 + { 7443 + .cmd = NL80211_CMD_START_P2P_DEVICE, 7444 + .doit = nl80211_start_p2p_device, 7445 + .policy = nl80211_policy, 7446 + .flags = GENL_ADMIN_PERM, 7447 + .internal_flags = NL80211_FLAG_NEED_WDEV | 7448 + NL80211_FLAG_NEED_RTNL, 7449 + }, 7450 + { 7451 + .cmd = NL80211_CMD_STOP_P2P_DEVICE, 7452 + .doit = nl80211_stop_p2p_device, 7453 + .policy = nl80211_policy, 7454 + .flags = GENL_ADMIN_PERM, 7455 + .internal_flags = NL80211_FLAG_NEED_WDEV_UP | 7456 + NL80211_FLAG_NEED_RTNL, 7457 + }, 7538 7458 }; 7539 7459 7540 7460 static struct genl_multicast_group nl80211_mlme_mcgrp = {
+16 -2
net/wireless/util.c
··· 800 800 if (otype == NL80211_IFTYPE_AP_VLAN) 801 801 return -EOPNOTSUPP; 802 802 803 + /* cannot change into P2P device type */ 804 + if (ntype == NL80211_IFTYPE_P2P_DEVICE) 805 + return -EOPNOTSUPP; 806 + 803 807 if (!rdev->ops->change_virtual_intf || 804 808 !(rdev->wiphy.interface_modes & (1 << ntype))) 805 809 return -EOPNOTSUPP; ··· 880 876 case NL80211_IFTYPE_UNSPECIFIED: 881 877 case NUM_NL80211_IFTYPES: 882 878 /* not happening */ 879 + break; 880 + case NL80211_IFTYPE_P2P_DEVICE: 881 + WARN_ON(1); 883 882 break; 884 883 } 885 884 } ··· 1048 1041 list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { 1049 1042 if (wdev_iter == wdev) 1050 1043 continue; 1051 - if (!netif_running(wdev_iter->netdev)) 1052 - continue; 1044 + if (wdev_iter->netdev) { 1045 + if (!netif_running(wdev_iter->netdev)) 1046 + continue; 1047 + } else if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) { 1048 + if (!wdev_iter->p2p_started) 1049 + continue; 1050 + } else { 1051 + WARN_ON(1); 1052 + } 1053 1053 1054 1054 if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) 1055 1055 continue;