diff options
| author | Johannes Berg <johannes.berg@intel.com> | 2012-06-15 18:19:54 -0400 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2012-08-20 07:58:21 -0400 |
| commit | 98104fdeda63d57631c9f89e90a7b83b58fcee40 (patch) | |
| tree | 22d0f75c2f369fd02695ea8051ddc68e6f8b8390 /include | |
| parent | cc74c0c7d6d623d0d3f13ef64895937edb7b3177 (diff) | |
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>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/nl80211.h | 30 | ||||
| -rw-r--r-- | include/net/cfg80211.h | 40 |
2 files changed, 64 insertions, 6 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 2f3878806403..458416279347 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
| @@ -565,6 +565,14 @@ | |||
| 565 | * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with | 565 | * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with |
| 566 | * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. | 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 | * @NL80211_CMD_MAX: highest used command number | 576 | * @NL80211_CMD_MAX: highest used command number |
| 569 | * @__NL80211_CMD_AFTER_LAST: internal use | 577 | * @__NL80211_CMD_AFTER_LAST: internal use |
| 570 | */ | 578 | */ |
| @@ -708,6 +716,9 @@ enum nl80211_commands { | |||
| 708 | 716 | ||
| 709 | NL80211_CMD_CH_SWITCH_NOTIFY, | 717 | NL80211_CMD_CH_SWITCH_NOTIFY, |
| 710 | 718 | ||
| 719 | NL80211_CMD_START_P2P_DEVICE, | ||
| 720 | NL80211_CMD_STOP_P2P_DEVICE, | ||
| 721 | |||
| 711 | /* add new commands above here */ | 722 | /* add new commands above here */ |
| 712 | 723 | ||
| 713 | /* used to define NL80211_CMD_MAX below */ | 724 | /* used to define NL80211_CMD_MAX below */ |
| @@ -1575,6 +1586,10 @@ enum nl80211_attrs { | |||
| 1575 | * @NL80211_IFTYPE_MESH_POINT: mesh point | 1586 | * @NL80211_IFTYPE_MESH_POINT: mesh point |
| 1576 | * @NL80211_IFTYPE_P2P_CLIENT: P2P client | 1587 | * @NL80211_IFTYPE_P2P_CLIENT: P2P client |
| 1577 | * @NL80211_IFTYPE_P2P_GO: P2P group owner | 1588 | * @NL80211_IFTYPE_P2P_GO: P2P group owner |
| 1589 | * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev | ||
| 1590 | * and therefore can't be created in the normal ways, use the | ||
| 1591 | * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE | ||
| 1592 | * commands to create and destroy one | ||
| 1578 | * @NL80211_IFTYPE_MAX: highest interface type number currently defined | 1593 | * @NL80211_IFTYPE_MAX: highest interface type number currently defined |
| 1579 | * @NUM_NL80211_IFTYPES: number of defined interface types | 1594 | * @NUM_NL80211_IFTYPES: number of defined interface types |
| 1580 | * | 1595 | * |
| @@ -1593,6 +1608,7 @@ enum nl80211_iftype { | |||
| 1593 | NL80211_IFTYPE_MESH_POINT, | 1608 | NL80211_IFTYPE_MESH_POINT, |
| 1594 | NL80211_IFTYPE_P2P_CLIENT, | 1609 | NL80211_IFTYPE_P2P_CLIENT, |
| 1595 | NL80211_IFTYPE_P2P_GO, | 1610 | NL80211_IFTYPE_P2P_GO, |
| 1611 | NL80211_IFTYPE_P2P_DEVICE, | ||
| 1596 | 1612 | ||
| 1597 | /* keep last */ | 1613 | /* keep last */ |
| 1598 | NUM_NL80211_IFTYPES, | 1614 | NUM_NL80211_IFTYPES, |
| @@ -2994,12 +3010,18 @@ enum nl80211_ap_sme_features { | |||
| 2994 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested | 3010 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested |
| 2995 | * to work properly to suppport receiving regulatory hints from | 3011 | * to work properly to suppport receiving regulatory hints from |
| 2996 | * cellular base stations. | 3012 | * cellular base stations. |
| 3013 | * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active | ||
| 3014 | * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel | ||
| 3015 | * in the interface combinations, even when it's only used for scan | ||
| 3016 | * and remain-on-channel. This could be due to, for example, the | ||
| 3017 | * remain-on-channel implementation requiring a channel context. | ||
| 2997 | */ | 3018 | */ |
| 2998 | enum nl80211_feature_flags { | 3019 | enum nl80211_feature_flags { |
| 2999 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 3020 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
| 3000 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 3021 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
| 3001 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | 3022 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, |
| 3002 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, | 3023 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, |
| 3024 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, | ||
| 3003 | }; | 3025 | }; |
| 3004 | 3026 | ||
| 3005 | /** | 3027 | /** |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 493fa0c79005..4c518f1f1aca 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
| @@ -1437,7 +1437,8 @@ struct cfg80211_gtk_rekey_data { | |||
| 1437 | * @add_virtual_intf: create a new virtual interface with the given name, | 1437 | * @add_virtual_intf: create a new virtual interface with the given name, |
| 1438 | * must set the struct wireless_dev's iftype. Beware: You must create | 1438 | * must set the struct wireless_dev's iftype. Beware: You must create |
| 1439 | * the new netdev in the wiphy's network namespace! Returns the struct | 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 | * @del_virtual_intf: remove the virtual interface | 1443 | * @del_virtual_intf: remove the virtual interface |
| 1443 | * | 1444 | * |
| @@ -1616,6 +1617,9 @@ struct cfg80211_gtk_rekey_data { | |||
| 1616 | * @get_channel: Get the current operating channel for the virtual interface. | 1617 | * @get_channel: Get the current operating channel for the virtual interface. |
| 1617 | * For monitor interfaces, it should return %NULL unless there's a single | 1618 | * For monitor interfaces, it should return %NULL unless there's a single |
| 1618 | * current monitoring channel. | 1619 | * current monitoring channel. |
| 1620 | * | ||
| 1621 | * @start_p2p_device: Start the given P2P device. | ||
| 1622 | * @stop_p2p_device: Stop the given P2P device. | ||
| 1619 | */ | 1623 | */ |
| 1620 | struct cfg80211_ops { | 1624 | struct cfg80211_ops { |
| 1621 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 1625 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
| @@ -1832,6 +1836,11 @@ struct cfg80211_ops { | |||
| 1832 | (*get_channel)(struct wiphy *wiphy, | 1836 | (*get_channel)(struct wiphy *wiphy, |
| 1833 | struct wireless_dev *wdev, | 1837 | struct wireless_dev *wdev, |
| 1834 | enum nl80211_channel_type *type); | 1838 | enum nl80211_channel_type *type); |
| 1839 | |||
| 1840 | int (*start_p2p_device)(struct wiphy *wiphy, | ||
| 1841 | struct wireless_dev *wdev); | ||
| 1842 | void (*stop_p2p_device)(struct wiphy *wiphy, | ||
| 1843 | struct wireless_dev *wdev); | ||
| 1835 | }; | 1844 | }; |
| 1836 | 1845 | ||
| 1837 | /* | 1846 | /* |
| @@ -2395,6 +2404,8 @@ struct cfg80211_cached_keys; | |||
| 2395 | * @cleanup_work: work struct used for cleanup that can't be done directly | 2404 | * @cleanup_work: work struct used for cleanup that can't be done directly |
| 2396 | * @beacon_interval: beacon interval used on this device for transmitting | 2405 | * @beacon_interval: beacon interval used on this device for transmitting |
| 2397 | * beacons, 0 when not valid | 2406 | * beacons, 0 when not valid |
| 2407 | * @address: The address for this device, valid only if @netdev is %NULL | ||
| 2408 | * @p2p_started: true if this is a P2P Device that has been started | ||
| 2398 | */ | 2409 | */ |
| 2399 | struct wireless_dev { | 2410 | struct wireless_dev { |
| 2400 | struct wiphy *wiphy; | 2411 | struct wiphy *wiphy; |
| @@ -2413,7 +2424,9 @@ struct wireless_dev { | |||
| 2413 | 2424 | ||
| 2414 | struct work_struct cleanup_work; | 2425 | struct work_struct cleanup_work; |
| 2415 | 2426 | ||
| 2416 | bool use_4addr; | 2427 | bool use_4addr, p2p_started; |
| 2428 | |||
| 2429 | u8 address[ETH_ALEN] __aligned(sizeof(u16)); | ||
| 2417 | 2430 | ||
| 2418 | /* currently used for IBSS and SME - might be rearranged later */ | 2431 | /* currently used for IBSS and SME - might be rearranged later */ |
| 2419 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 2432 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
| @@ -2461,6 +2474,13 @@ struct wireless_dev { | |||
| 2461 | #endif | 2474 | #endif |
| 2462 | }; | 2475 | }; |
| 2463 | 2476 | ||
| 2477 | static inline u8 *wdev_address(struct wireless_dev *wdev) | ||
| 2478 | { | ||
| 2479 | if (wdev->netdev) | ||
| 2480 | return wdev->netdev->dev_addr; | ||
| 2481 | return wdev->address; | ||
| 2482 | } | ||
| 2483 | |||
| 2464 | /** | 2484 | /** |
| 2465 | * wdev_priv - return wiphy priv from wireless_dev | 2485 | * wdev_priv - return wiphy priv from wireless_dev |
| 2466 | * | 2486 | * |
| @@ -3528,6 +3548,22 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, | |||
| 3528 | */ | 3548 | */ |
| 3529 | u32 cfg80211_calculate_bitrate(struct rate_info *rate); | 3549 | u32 cfg80211_calculate_bitrate(struct rate_info *rate); |
| 3530 | 3550 | ||
| 3551 | /** | ||
| 3552 | * cfg80211_unregister_wdev - remove the given wdev | ||
| 3553 | * @wdev: struct wireless_dev to remove | ||
| 3554 | * | ||
| 3555 | * Call this function only for wdevs that have no netdev assigned, | ||
| 3556 | * e.g. P2P Devices. It removes the device from the list so that | ||
| 3557 | * it can no longer be used. It is necessary to call this function | ||
| 3558 | * even when cfg80211 requests the removal of the interface by | ||
| 3559 | * calling the del_virtual_intf() callback. The function must also | ||
| 3560 | * be called when the driver wishes to unregister the wdev, e.g. | ||
| 3561 | * when the device is unbound from the driver. | ||
| 3562 | * | ||
| 3563 | * Requires the RTNL to be held. | ||
| 3564 | */ | ||
| 3565 | void cfg80211_unregister_wdev(struct wireless_dev *wdev); | ||
| 3566 | |||
| 3531 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 3567 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
| 3532 | 3568 | ||
| 3533 | /* wiphy_printk helpers, similar to dev_printk */ | 3569 | /* wiphy_printk helpers, similar to dev_printk */ |
