mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next
This commit is contained in:
commit
133189a46c
@ -567,6 +567,26 @@ struct ieee80211s_hdr {
|
||||
#define MESH_FLAGS_AE 0x3
|
||||
#define MESH_FLAGS_PS_DEEP 0x4
|
||||
|
||||
/**
|
||||
* enum ieee80211_preq_flags - mesh PREQ element flags
|
||||
*
|
||||
* @IEEE80211_PREQ_PROACTIVE_PREP_FLAG: proactive PREP subfield
|
||||
*/
|
||||
enum ieee80211_preq_flags {
|
||||
IEEE80211_PREQ_PROACTIVE_PREP_FLAG = 1<<2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ieee80211_preq_target_flags - mesh PREQ element per target flags
|
||||
*
|
||||
* @IEEE80211_PREQ_TO_FLAG: target only subfield
|
||||
* @IEEE80211_PREQ_USN_FLAG: unknown target HWMP sequence number subfield
|
||||
*/
|
||||
enum ieee80211_preq_target_flags {
|
||||
IEEE80211_PREQ_TO_FLAG = 1<<0,
|
||||
IEEE80211_PREQ_USN_FLAG = 1<<2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_quiet_ie
|
||||
*
|
||||
@ -1443,7 +1463,7 @@ enum ieee80211_tdls_actioncode {
|
||||
*
|
||||
* @IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET: the default synchronization method
|
||||
* @IEEE80211_SYNC_METHOD_VENDOR: a vendor specific synchronization method
|
||||
* that will be specified in a vendor specific information element
|
||||
* that will be specified in a vendor specific information element
|
||||
*/
|
||||
enum {
|
||||
IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET = 1,
|
||||
@ -1455,7 +1475,7 @@ enum {
|
||||
*
|
||||
* @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
|
||||
* @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
|
||||
* be specified in a vendor specific information element
|
||||
* be specified in a vendor specific information element
|
||||
*/
|
||||
enum {
|
||||
IEEE80211_PATH_PROTOCOL_HWMP = 1,
|
||||
@ -1467,13 +1487,35 @@ enum {
|
||||
*
|
||||
* @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
|
||||
* @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
|
||||
* specified in a vendor specific information element
|
||||
* specified in a vendor specific information element
|
||||
*/
|
||||
enum {
|
||||
IEEE80211_PATH_METRIC_AIRTIME = 1,
|
||||
IEEE80211_PATH_METRIC_VENDOR = 255,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ieee80211_root_mode_identifier - root mesh STA mode identifier
|
||||
*
|
||||
* These attribute are used by dot11MeshHWMPRootMode to set root mesh STA mode
|
||||
*
|
||||
* @IEEE80211_ROOTMODE_NO_ROOT: the mesh STA is not a root mesh STA (default)
|
||||
* @IEEE80211_ROOTMODE_ROOT: the mesh STA is a root mesh STA if greater than
|
||||
* this value
|
||||
* @IEEE80211_PROACTIVE_PREQ_NO_PREP: the mesh STA is a root mesh STA supports
|
||||
* the proactive PREQ with proactive PREP subfield set to 0
|
||||
* @IEEE80211_PROACTIVE_PREQ_WITH_PREP: the mesh STA is a root mesh STA
|
||||
* supports the proactive PREQ with proactive PREP subfield set to 1
|
||||
* @IEEE80211_PROACTIVE_RANN: the mesh STA is a root mesh STA supports
|
||||
* the proactive RANN
|
||||
*/
|
||||
enum ieee80211_root_mode_identifier {
|
||||
IEEE80211_ROOTMODE_NO_ROOT = 0,
|
||||
IEEE80211_ROOTMODE_ROOT = 1,
|
||||
IEEE80211_PROACTIVE_PREQ_NO_PREP = 2,
|
||||
IEEE80211_PROACTIVE_PREQ_WITH_PREP = 3,
|
||||
IEEE80211_PROACTIVE_RANN = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
* IEEE 802.11-2007 7.3.2.9 Country information element
|
||||
@ -1589,6 +1631,8 @@ enum ieee80211_sa_query_action {
|
||||
|
||||
#define WLAN_OUI_WFA 0x506f9a
|
||||
#define WLAN_OUI_TYPE_WFA_P2P 9
|
||||
#define WLAN_OUI_MICROSOFT 0x0050f2
|
||||
#define WLAN_OUI_TYPE_MICROSOFT_WPA 1
|
||||
|
||||
/*
|
||||
* WMM/802.11e Tspec Element
|
||||
|
@ -277,6 +277,12 @@
|
||||
* @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
|
||||
* NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
|
||||
*
|
||||
* @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC
|
||||
* (for the BSSID) and %NL80211_ATTR_PMKID.
|
||||
* @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
|
||||
* (for the BSSID) and %NL80211_ATTR_PMKID.
|
||||
* @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
|
||||
*
|
||||
* @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
|
||||
* has been changed and provides details of the request information
|
||||
* that caused the change such as who initiated the regulatory request
|
||||
@ -456,6 +462,10 @@
|
||||
* the frame.
|
||||
* @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for
|
||||
* backward compatibility.
|
||||
*
|
||||
* @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE
|
||||
* @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE
|
||||
*
|
||||
* @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command
|
||||
* is used to configure connection quality monitoring notification trigger
|
||||
* levels.
|
||||
@ -771,6 +781,13 @@ enum nl80211_commands {
|
||||
* section 7.3.2.25.1, e.g. 0x000FAC04)
|
||||
* @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
|
||||
* CCMP keys, each six bytes in little endian
|
||||
* @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key
|
||||
* @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the
|
||||
* default management key
|
||||
* @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or
|
||||
* other commands, indicates which pairwise cipher suites are used
|
||||
* @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or
|
||||
* other commands, indicates which group cipher suite is used
|
||||
*
|
||||
* @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU
|
||||
* @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing
|
||||
@ -1006,6 +1023,8 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
|
||||
* acknowledged by the recipient.
|
||||
*
|
||||
* @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values.
|
||||
*
|
||||
* @NL80211_ATTR_CQM: connection quality monitor configuration in a
|
||||
* nested attribute with %NL80211_ATTR_CQM_* sub-attributes.
|
||||
*
|
||||
@ -1063,7 +1082,7 @@ enum nl80211_commands {
|
||||
* flag isn't set, the frame will be rejected. This is also used as an
|
||||
* nl80211 capability flag.
|
||||
*
|
||||
* @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16)
|
||||
* @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16)
|
||||
*
|
||||
* @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags
|
||||
* attributes, specifying what a key should be set as default as.
|
||||
@ -1087,10 +1106,10 @@ enum nl80211_commands {
|
||||
* indicate which WoW triggers should be enabled. This is also
|
||||
* used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN
|
||||
* triggers.
|
||||
|
||||
*
|
||||
* @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan
|
||||
* cycles, in msecs.
|
||||
|
||||
*
|
||||
* @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more
|
||||
* sets of attributes to match during scheduled scans. Only BSSs
|
||||
* that match any of the sets will be reported. These are
|
||||
@ -1117,7 +1136,7 @@ enum nl80211_commands {
|
||||
* are managed in software: interfaces of these types aren't subject to
|
||||
* any restrictions in their number or combinations.
|
||||
*
|
||||
* @%NL80211_ATTR_REKEY_DATA: nested attribute containing the information
|
||||
* @NL80211_ATTR_REKEY_DATA: nested attribute containing the information
|
||||
* necessary for GTK rekeying in the device, see &enum nl80211_rekey_data.
|
||||
*
|
||||
* @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan,
|
||||
@ -1184,7 +1203,6 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from
|
||||
* &enum nl80211_feature_flags and is advertised in wiphy information.
|
||||
* @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe
|
||||
*
|
||||
* requests while operating in AP-mode.
|
||||
* This attribute holds a bitmap of the supported protocols for
|
||||
* offloading (see &enum nl80211_probe_resp_offload_support_attr).
|
||||
@ -1963,7 +1981,7 @@ enum nl80211_reg_rule_attr {
|
||||
enum nl80211_sched_scan_match_attr {
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID,
|
||||
|
||||
NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
|
||||
@ -1971,6 +1989,9 @@ enum nl80211_sched_scan_match_attr {
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/* only for backward compatibility */
|
||||
#define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID
|
||||
|
||||
/**
|
||||
* enum nl80211_reg_rule_flags - regulatory rule flags
|
||||
*
|
||||
@ -2090,77 +2111,90 @@ enum nl80211_mntr_flags {
|
||||
* @__NL80211_MESHCONF_INVALID: internal use
|
||||
*
|
||||
* @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in
|
||||
* millisecond units, used by the Peer Link Open message
|
||||
* millisecond units, used by the Peer Link Open message
|
||||
*
|
||||
* @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in
|
||||
* millisecond units, used by the peer link management to close a peer link
|
||||
* millisecond units, used by the peer link management to close a peer link
|
||||
*
|
||||
* @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in
|
||||
* millisecond units
|
||||
* millisecond units
|
||||
*
|
||||
* @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed
|
||||
* on this mesh interface
|
||||
* on this mesh interface
|
||||
*
|
||||
* @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link
|
||||
* open retries that can be sent to establish a new peer link instance in a
|
||||
* mesh
|
||||
* open retries that can be sent to establish a new peer link instance in a
|
||||
* mesh
|
||||
*
|
||||
* @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
|
||||
* point.
|
||||
* point.
|
||||
*
|
||||
* @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
|
||||
* open peer links when we detect compatible mesh peers.
|
||||
* open peer links when we detect compatible mesh peers.
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
|
||||
* containing a PREQ that an MP can send to a particular destination (path
|
||||
* target)
|
||||
* containing a PREQ that an MP can send to a particular destination (path
|
||||
* target)
|
||||
*
|
||||
* @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths
|
||||
* (in milliseconds)
|
||||
* (in milliseconds)
|
||||
*
|
||||
* @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait
|
||||
* until giving up on a path discovery (in milliseconds)
|
||||
* until giving up on a path discovery (in milliseconds)
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh
|
||||
* points receiving a PREQ shall consider the forwarding information from the
|
||||
* root to be valid. (TU = time unit)
|
||||
* points receiving a PREQ shall consider the forwarding information from
|
||||
* the root to be valid. (TU = time unit)
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in
|
||||
* TUs) during which an MP can send only one action frame containing a PREQ
|
||||
* reference element
|
||||
* TUs) during which an MP can send only one action frame containing a PREQ
|
||||
* reference element
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
|
||||
* that it takes for an HWMP information element to propagate across the mesh
|
||||
* that it takes for an HWMP information element to propagate across the
|
||||
* mesh
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not
|
||||
*
|
||||
* @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
|
||||
* source mesh point for path selection elements.
|
||||
* source mesh point for path selection elements.
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between
|
||||
* root announcements are transmitted.
|
||||
* root announcements are transmitted.
|
||||
*
|
||||
* @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has
|
||||
* access to a broader network beyond the MBSS. This is done via Root
|
||||
* Announcement frames.
|
||||
* access to a broader network beyond the MBSS. This is done via Root
|
||||
* Announcement frames.
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in
|
||||
* TUs) during which a mesh STA can send only one Action frame containing a
|
||||
* PERR element.
|
||||
* TUs) during which a mesh STA can send only one Action frame containing a
|
||||
* PERR element.
|
||||
*
|
||||
* @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
|
||||
* or forwarding entity (default is TRUE - forwarding entity)
|
||||
* or forwarding entity (default is TRUE - forwarding entity)
|
||||
*
|
||||
* @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
|
||||
* threshold for average signal strength of candidate station to establish
|
||||
* a peer link.
|
||||
* threshold for average signal strength of candidate station to establish
|
||||
* a peer link.
|
||||
*
|
||||
* @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors
|
||||
* to synchronize to for 11s default synchronization method
|
||||
* (see 11C.12.2.2)
|
||||
*
|
||||
* @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode.
|
||||
*
|
||||
* @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
|
||||
*
|
||||
* @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors
|
||||
* to synchronize to for 11s default synchronization method (see 11C.12.2.2)
|
||||
* @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for
|
||||
* which mesh STAs receiving a proactive PREQ shall consider the forwarding
|
||||
* information to the root mesh STA to be valid.
|
||||
*
|
||||
* @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode.
|
||||
* @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between
|
||||
* proactive PREQs are transmitted.
|
||||
*
|
||||
* @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time
|
||||
* (in TUs) during which a mesh STA can send only one Action frame
|
||||
* containing a PREQ element for root path confirmation.
|
||||
*
|
||||
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
@ -2188,6 +2222,9 @@ enum nl80211_meshconf_params {
|
||||
NL80211_MESHCONF_RSSI_THRESHOLD,
|
||||
NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
|
||||
NL80211_MESHCONF_HT_OPMODE,
|
||||
NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
|
||||
NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
|
||||
NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_MESHCONF_ATTR_AFTER_LAST,
|
||||
@ -2203,34 +2240,36 @@ enum nl80211_meshconf_params {
|
||||
* @__NL80211_MESH_SETUP_INVALID: Internal use
|
||||
*
|
||||
* @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a
|
||||
* vendor specific path selection algorithm or disable it to use the default
|
||||
* HWMP.
|
||||
* vendor specific path selection algorithm or disable it to use the
|
||||
* default HWMP.
|
||||
*
|
||||
* @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a
|
||||
* vendor specific path metric or disable it to use the default Airtime
|
||||
* metric.
|
||||
* vendor specific path metric or disable it to use the default Airtime
|
||||
* metric.
|
||||
*
|
||||
* @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a
|
||||
* robust security network ie, or a vendor specific information element that
|
||||
* vendors will use to identify the path selection methods and metrics in use.
|
||||
* robust security network ie, or a vendor specific information element
|
||||
* that vendors will use to identify the path selection methods and
|
||||
* metrics in use.
|
||||
*
|
||||
* @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
|
||||
* daemon will be authenticating mesh candidates.
|
||||
* daemon will be authenticating mesh candidates.
|
||||
*
|
||||
* @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication
|
||||
* daemon will be securing peer link frames. AMPE is a secured version of Mesh
|
||||
* Peering Management (MPM) and is implemented with the assistance of a
|
||||
* userspace daemon. When this flag is set, the kernel will send peer
|
||||
* management frames to a userspace daemon that will implement AMPE
|
||||
* functionality (security capabilities selection, key confirmation, and key
|
||||
* management). When the flag is unset (default), the kernel can autonomously
|
||||
* complete (unsecured) mesh peering without the need of a userspace daemon.
|
||||
*
|
||||
* @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
|
||||
* daemon will be securing peer link frames. AMPE is a secured version of
|
||||
* Mesh Peering Management (MPM) and is implemented with the assistance of
|
||||
* a userspace daemon. When this flag is set, the kernel will send peer
|
||||
* management frames to a userspace daemon that will implement AMPE
|
||||
* functionality (security capabilities selection, key confirmation, and
|
||||
* key management). When the flag is unset (default), the kernel can
|
||||
* autonomously complete (unsecured) mesh peering without the need of a
|
||||
* userspace daemon.
|
||||
*
|
||||
* @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a
|
||||
* vendor specific synchronization method or disable it to use the default
|
||||
* neighbor offset synchronization
|
||||
* vendor specific synchronization method or disable it to use the default
|
||||
* neighbor offset synchronization
|
||||
*
|
||||
* @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
|
||||
*
|
||||
* @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
|
||||
*/
|
||||
@ -2500,6 +2539,11 @@ enum nl80211_band {
|
||||
NL80211_BAND_5GHZ,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_ps_state - powersave state
|
||||
* @NL80211_PS_DISABLED: powersave is disabled
|
||||
* @NL80211_PS_ENABLED: powersave is enabled
|
||||
*/
|
||||
enum nl80211_ps_state {
|
||||
NL80211_PS_DISABLED,
|
||||
NL80211_PS_ENABLED,
|
||||
|
@ -627,10 +627,10 @@ struct sta_bss_parameters {
|
||||
* @llid: mesh local link id
|
||||
* @plid: mesh peer link id
|
||||
* @plink_state: mesh peer link state
|
||||
* @signal: the signal strength, type depends on the wiphy's signal_type
|
||||
NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
|
||||
* @signal_avg: avg signal strength, type depends on the wiphy's signal_type
|
||||
NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
|
||||
* @signal: The signal strength, type depends on the wiphy's signal_type.
|
||||
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
|
||||
* @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
|
||||
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
|
||||
* @txrate: current unicast bitrate from this station
|
||||
* @rxrate: current unicast bitrate to this station
|
||||
* @rx_packets: packets received from this station
|
||||
@ -790,43 +790,95 @@ struct bss_parameters {
|
||||
int ht_opmode;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* struct mesh_config - 802.11s mesh configuration
|
||||
*
|
||||
* These parameters can be changed while the mesh is active.
|
||||
*
|
||||
* @dot11MeshRetryTimeout: the initial retry timeout in millisecond units used
|
||||
* by the Mesh Peering Open message
|
||||
* @dot11MeshConfirmTimeout: the initial retry timeout in millisecond units
|
||||
* used by the Mesh Peering Open message
|
||||
* @dot11MeshHoldingTimeout: the confirm timeout in millisecond units used by
|
||||
* the mesh peering management to close a mesh peering
|
||||
* @dot11MeshMaxPeerLinks: the maximum number of peer links allowed on this
|
||||
* mesh interface
|
||||
* @dot11MeshMaxRetries: the maximum number of peer link open retries that can
|
||||
* be sent to establish a new peer link instance in a mesh
|
||||
* @dot11MeshTTL: the value of TTL field set at a source mesh STA
|
||||
* @element_ttl: the value of TTL field set at a mesh STA for path selection
|
||||
* elements
|
||||
* @auto_open_plinks: whether we should automatically open peer links when we
|
||||
* detect compatible mesh peers
|
||||
* @dot11MeshNbrOffsetMaxNeighbor: the maximum number of neighbors to
|
||||
* synchronize to for 11s default synchronization method
|
||||
* @dot11MeshHWMPmaxPREQretries: the number of action frames containing a PREQ
|
||||
* that an originator mesh STA can send to a particular path target
|
||||
* @path_refresh_time: how frequently to refresh mesh paths in milliseconds
|
||||
* @min_discovery_timeout: the minimum length of time to wait until giving up on
|
||||
* a path discovery in milliseconds
|
||||
* @dot11MeshHWMPactivePathTimeout: the time (in TUs) for which mesh STAs
|
||||
* receiving a PREQ shall consider the forwarding information from the
|
||||
* root to be valid. (TU = time unit)
|
||||
* @dot11MeshHWMPpreqMinInterval: the minimum interval of time (in TUs) during
|
||||
* which a mesh STA can send only one action frame containing a PREQ
|
||||
* element
|
||||
* @dot11MeshHWMPperrMinInterval: the minimum interval of time (in TUs) during
|
||||
* which a mesh STA can send only one Action frame containing a PERR
|
||||
* element
|
||||
* @dot11MeshHWMPnetDiameterTraversalTime: the interval of time (in TUs) that
|
||||
* it takes for an HWMP information element to propagate across the mesh
|
||||
* @dot11MeshHWMPRootMode: the configuration of a mesh STA as root mesh STA
|
||||
* @dot11MeshHWMPRannInterval: the interval of time (in TUs) between root
|
||||
* announcements are transmitted
|
||||
* @dot11MeshGateAnnouncementProtocol: whether to advertise that this mesh
|
||||
* station has access to a broader network beyond the MBSS. (This is
|
||||
* missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol set to true
|
||||
* only means that the station will announce others it's a mesh gate, but
|
||||
* not necessarily using the gate announcement protocol. Still keeping the
|
||||
* same nomenclature to be in sync with the spec)
|
||||
* @dot11MeshForwarding: whether the Mesh STA is forwarding or non-forwarding
|
||||
* entity (default is TRUE - forwarding entity)
|
||||
* @rssi_threshold: the threshold for average signal strength of candidate
|
||||
* station to establish a peer link
|
||||
* @ht_opmode: mesh HT protection mode
|
||||
*
|
||||
* @dot11MeshHWMPactivePathToRootTimeout: The time (in TUs) for which mesh STAs
|
||||
* receiving a proactive PREQ shall consider the forwarding information to
|
||||
* the root mesh STA to be valid.
|
||||
*
|
||||
* @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive
|
||||
* PREQs are transmitted.
|
||||
* @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs)
|
||||
* during which a mesh STA can send only one Action frame containing
|
||||
* a PREQ element for root path confirmation.
|
||||
*/
|
||||
struct mesh_config {
|
||||
/* Timeouts in ms */
|
||||
/* Mesh plink management parameters */
|
||||
u16 dot11MeshRetryTimeout;
|
||||
u16 dot11MeshConfirmTimeout;
|
||||
u16 dot11MeshHoldingTimeout;
|
||||
u16 dot11MeshMaxPeerLinks;
|
||||
u8 dot11MeshMaxRetries;
|
||||
u8 dot11MeshTTL;
|
||||
/* ttl used in path selection information elements */
|
||||
u8 element_ttl;
|
||||
u8 dot11MeshMaxRetries;
|
||||
u8 dot11MeshTTL;
|
||||
u8 element_ttl;
|
||||
bool auto_open_plinks;
|
||||
/* neighbor offset synchronization */
|
||||
u32 dot11MeshNbrOffsetMaxNeighbor;
|
||||
/* HWMP parameters */
|
||||
u8 dot11MeshHWMPmaxPREQretries;
|
||||
u8 dot11MeshHWMPmaxPREQretries;
|
||||
u32 path_refresh_time;
|
||||
u16 min_discovery_timeout;
|
||||
u32 dot11MeshHWMPactivePathTimeout;
|
||||
u16 dot11MeshHWMPpreqMinInterval;
|
||||
u16 dot11MeshHWMPperrMinInterval;
|
||||
u16 dot11MeshHWMPnetDiameterTraversalTime;
|
||||
u8 dot11MeshHWMPRootMode;
|
||||
u8 dot11MeshHWMPRootMode;
|
||||
u16 dot11MeshHWMPRannInterval;
|
||||
/* This is missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol
|
||||
* set to true only means that the station will announce others it's a
|
||||
* mesh gate, but not necessarily using the gate announcement protocol.
|
||||
* Still keeping the same nomenclature to be in sync with the spec. */
|
||||
bool dot11MeshGateAnnouncementProtocol;
|
||||
bool dot11MeshGateAnnouncementProtocol;
|
||||
bool dot11MeshForwarding;
|
||||
s32 rssi_threshold;
|
||||
u16 ht_opmode;
|
||||
u32 dot11MeshHWMPactivePathToRootTimeout;
|
||||
u16 dot11MeshHWMProotInterval;
|
||||
u16 dot11MeshHWMPconfirmationInterval;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -689,7 +689,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
|
||||
case CHAN_MODE_HOPPING:
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_FIXED:
|
||||
if (local->oper_channel != chan)
|
||||
if (local->oper_channel != chan ||
|
||||
(!sdata && local->_oper_channel_type != channel_type))
|
||||
return -EBUSY;
|
||||
if (!sdata && local->_oper_channel_type == channel_type)
|
||||
return 0;
|
||||
@ -1529,7 +1530,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
|
||||
conf->dot11MeshTTL = nconf->dot11MeshTTL;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
|
||||
conf->dot11MeshTTL = nconf->element_ttl;
|
||||
conf->element_ttl = nconf->element_ttl;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
|
||||
conf->auto_open_plinks = nconf->auto_open_plinks;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
|
||||
@ -1564,17 +1565,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
||||
* announcements, so require this ifmsh to also be a root node
|
||||
* */
|
||||
if (nconf->dot11MeshGateAnnouncementProtocol &&
|
||||
!conf->dot11MeshHWMPRootMode) {
|
||||
conf->dot11MeshHWMPRootMode = 1;
|
||||
!(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) {
|
||||
conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
|
||||
ieee80211_mesh_root_setup(ifmsh);
|
||||
}
|
||||
conf->dot11MeshGateAnnouncementProtocol =
|
||||
nconf->dot11MeshGateAnnouncementProtocol;
|
||||
}
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) {
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
|
||||
conf->dot11MeshHWMPRannInterval =
|
||||
nconf->dot11MeshHWMPRannInterval;
|
||||
}
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
|
||||
conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
|
||||
@ -1590,6 +1590,15 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
||||
sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
|
||||
}
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
|
||||
conf->dot11MeshHWMPactivePathToRootTimeout =
|
||||
nconf->dot11MeshHWMPactivePathToRootTimeout;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
|
||||
conf->dot11MeshHWMProotInterval =
|
||||
nconf->dot11MeshHWMProotInterval;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
|
||||
conf->dot11MeshHWMPconfirmationInterval =
|
||||
nconf->dot11MeshHWMPconfirmationInterval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2309,6 +2318,21 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
|
||||
struct ieee80211_roc_work *dep, *tmp2;
|
||||
|
||||
list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
|
||||
if (!mgmt_tx && (unsigned long)dep != cookie)
|
||||
continue;
|
||||
else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
|
||||
continue;
|
||||
/* found dependent item -- just remove it */
|
||||
list_del(&dep->list);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_roc_notify_destroy(dep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mgmt_tx && (unsigned long)roc != cookie)
|
||||
continue;
|
||||
else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
|
||||
@ -2323,6 +2347,13 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* We found the item to cancel, so do that. Note that it
|
||||
* may have dependents, which we also cancel (and send
|
||||
* the expired signal for.) Not doing so would be quite
|
||||
* tricky here, but we may need to fix it later.
|
||||
*/
|
||||
|
||||
if (local->ops->remain_on_channel) {
|
||||
if (found->started) {
|
||||
ret = drv_cancel_remain_on_channel(local);
|
||||
@ -2334,8 +2365,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
||||
|
||||
list_del(&found->list);
|
||||
|
||||
ieee80211_run_deferred_scan(local);
|
||||
ieee80211_start_next_roc(local);
|
||||
if (found->started)
|
||||
ieee80211_start_next_roc(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_roc_notify_destroy(found);
|
||||
@ -2489,16 +2520,30 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
|
||||
u16 frame_type, bool reg)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
|
||||
return;
|
||||
switch (frame_type) {
|
||||
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
|
||||
if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
||||
if (reg)
|
||||
local->probe_req_reg++;
|
||||
else
|
||||
local->probe_req_reg--;
|
||||
if (reg)
|
||||
ifibss->auth_frame_registrations++;
|
||||
else
|
||||
ifibss->auth_frame_registrations--;
|
||||
}
|
||||
break;
|
||||
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
|
||||
if (reg)
|
||||
local->probe_req_reg++;
|
||||
else
|
||||
local->probe_req_reg--;
|
||||
|
||||
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
|
||||
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
|
||||
|
@ -468,48 +468,54 @@ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
|
||||
IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_congestion,
|
||||
u.mesh.mshstats.dropped_frames_congestion, DEC);
|
||||
u.mesh.mshstats.dropped_frames_congestion, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_no_route,
|
||||
u.mesh.mshstats.dropped_frames_no_route, DEC);
|
||||
u.mesh.mshstats.dropped_frames_no_route, DEC);
|
||||
IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
|
||||
|
||||
/* Mesh parameters */
|
||||
IEEE80211_IF_FILE(dot11MeshMaxRetries,
|
||||
u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
|
||||
u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshRetryTimeout,
|
||||
u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
|
||||
u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
|
||||
u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
|
||||
IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
|
||||
IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
|
||||
u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
|
||||
u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
|
||||
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
|
||||
u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
|
||||
u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
|
||||
IEEE80211_IF_FILE(path_refresh_time,
|
||||
u.mesh.mshcfg.path_refresh_time, DEC);
|
||||
u.mesh.mshcfg.path_refresh_time, DEC);
|
||||
IEEE80211_IF_FILE(min_discovery_timeout,
|
||||
u.mesh.mshcfg.min_discovery_timeout, DEC);
|
||||
u.mesh.mshcfg.min_discovery_timeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
|
||||
u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
|
||||
u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
|
||||
u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
|
||||
IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
|
||||
IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
|
||||
u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC);
|
||||
#endif
|
||||
|
||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||
@ -611,6 +617,9 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
||||
MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
|
||||
MESHPARAMS_ADD(rssi_threshold);
|
||||
MESHPARAMS_ADD(ht_opmode);
|
||||
MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
|
||||
MESHPARAMS_ADD(dot11MeshHWMProotInterval);
|
||||
MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
|
||||
#undef MESHPARAMS_ADD
|
||||
}
|
||||
#endif
|
||||
|
@ -279,7 +279,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
|
||||
/* If it fails, maybe we raced another insertion? */
|
||||
if (sta_info_insert_rcu(sta))
|
||||
return sta_info_get(sdata, addr);
|
||||
if (auth) {
|
||||
if (auth && !sdata->u.ibss.auth_frame_registrations) {
|
||||
ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
|
||||
sdata->vif.addr, sdata->u.ibss.bssid, addr);
|
||||
ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
|
||||
|
@ -55,11 +55,14 @@ struct ieee80211_local;
|
||||
#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
|
||||
#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
|
||||
|
||||
/*
|
||||
* Some APs experience problems when working with U-APSD. Decrease the
|
||||
* probability of that happening by using legacy mode for all ACs but VO.
|
||||
* The AP that caused us trouble was a Cisco 4410N. It ignores our
|
||||
* setting, and always treats non-VO ACs as legacy.
|
||||
*/
|
||||
#define IEEE80211_DEFAULT_UAPSD_QUEUES \
|
||||
(IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
|
||||
|
||||
#define IEEE80211_DEFAULT_MAX_SP_LEN \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
|
||||
@ -508,6 +511,7 @@ struct ieee80211_if_ibss {
|
||||
bool privacy;
|
||||
|
||||
bool control_port;
|
||||
unsigned int auth_frame_registrations;
|
||||
|
||||
u8 bssid[ETH_ALEN] __aligned(2);
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
@ -677,6 +681,9 @@ struct ieee80211_sub_if_data {
|
||||
/* TID bitmap for NoAck policy */
|
||||
u16 noack_map;
|
||||
|
||||
/* bit field of ACM bits (BIT(802.1D tag)) */
|
||||
u8 wmm_acm;
|
||||
|
||||
struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
|
||||
struct ieee80211_key __rcu *default_unicast_key;
|
||||
struct ieee80211_key __rcu *default_multicast_key;
|
||||
@ -881,6 +888,9 @@ struct ieee80211_local {
|
||||
/* device is started */
|
||||
bool started;
|
||||
|
||||
/* device is during a HW reconfig */
|
||||
bool in_reconfig;
|
||||
|
||||
/* wowlan is enabled -- don't reconfig on resume */
|
||||
bool wowlan;
|
||||
|
||||
@ -1019,7 +1029,6 @@ struct ieee80211_local {
|
||||
int total_ps_buffered; /* total number of all buffered unicast and
|
||||
* multicast packets for power saving stations
|
||||
*/
|
||||
unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
|
||||
|
||||
bool pspolling;
|
||||
bool offchannel_ps_enabled;
|
||||
|
@ -808,7 +808,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
|
||||
|
||||
hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
|
||||
|
||||
return ieee80211_select_queue_80211(local, skb, hdr);
|
||||
return ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
}
|
||||
|
||||
static const struct net_device_ops ieee80211_monitorif_ops = {
|
||||
|
@ -345,6 +345,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
|
||||
ieee80211_stop_queues_by_reason(hw,
|
||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||
|
||||
/*
|
||||
* Stop all Rx during the reconfig. We don't want state changes
|
||||
* or driver callbacks while this is in progress.
|
||||
*/
|
||||
local->in_reconfig = true;
|
||||
barrier();
|
||||
|
||||
schedule_work(&local->restart_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_restart_hw);
|
||||
@ -455,7 +462,9 @@ static const struct ieee80211_txrx_stypes
|
||||
ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
||||
[NL80211_IFTYPE_ADHOC] = {
|
||||
.tx = 0xffff,
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4),
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
BIT(IEEE80211_STYPE_AUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_DEAUTH >> 4),
|
||||
},
|
||||
[NL80211_IFTYPE_STATION] = {
|
||||
.tx = 0xffff,
|
||||
|
@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data)
|
||||
|
||||
void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
|
||||
{
|
||||
if (ifmsh->mshcfg.dot11MeshHWMPRootMode)
|
||||
if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)
|
||||
set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
|
||||
else {
|
||||
clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
|
||||
@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
|
||||
static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u32 interval;
|
||||
|
||||
mesh_path_tx_root_frame(sdata);
|
||||
|
||||
if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN)
|
||||
interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
|
||||
else
|
||||
interval = ifmsh->mshcfg.dot11MeshHWMProotInterval;
|
||||
|
||||
mod_timer(&ifmsh->mesh_path_root_timer,
|
||||
round_jiffies(TU_TO_EXP_TIME(
|
||||
ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
|
||||
round_jiffies(TU_TO_EXP_TIME(interval)));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -104,6 +104,7 @@ enum mesh_deferred_task_flags {
|
||||
* an mpath to a hash bucket on a path table.
|
||||
* @rann_snd_addr: the RANN sender address
|
||||
* @rann_metric: the aggregated path metric towards the root node
|
||||
* @last_preq_to_root: Timestamp of last PREQ sent to root
|
||||
* @is_root: the destination station of this path is a root node
|
||||
* @is_gate: the destination station of this path is a mesh gate
|
||||
*
|
||||
@ -131,6 +132,7 @@ struct mesh_path {
|
||||
spinlock_t state_lock;
|
||||
u8 rann_snd_addr[ETH_ALEN];
|
||||
u32 rann_metric;
|
||||
unsigned long last_preq_to_root;
|
||||
bool is_root;
|
||||
bool is_gate;
|
||||
};
|
||||
@ -245,7 +247,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
|
||||
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211s_init(void);
|
||||
void ieee80211s_update_metric(struct ieee80211_local *local,
|
||||
struct sta_info *stainfo, struct sk_buff *skb);
|
||||
struct sta_info *sta, struct sk_buff *skb);
|
||||
void ieee80211s_stop(void);
|
||||
void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
|
||||
|
@ -98,6 +98,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
|
||||
#define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
|
||||
#define disc_timeout_jiff(s) \
|
||||
msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
|
||||
#define root_path_confirmation_jiffies(s) \
|
||||
msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval)
|
||||
|
||||
enum mpath_frame_type {
|
||||
MPATH_PREQ = 0,
|
||||
@ -303,7 +305,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
|
||||
}
|
||||
|
||||
void ieee80211s_update_metric(struct ieee80211_local *local,
|
||||
struct sta_info *stainfo, struct sk_buff *skb)
|
||||
struct sta_info *sta, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
@ -315,15 +317,14 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
|
||||
failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
|
||||
|
||||
/* moving average, scaled to 100 */
|
||||
stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed);
|
||||
if (stainfo->fail_avg > 95)
|
||||
mesh_plink_broken(stainfo);
|
||||
sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed);
|
||||
if (sta->fail_avg > 95)
|
||||
mesh_plink_broken(sta);
|
||||
}
|
||||
|
||||
static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct rate_info rinfo;
|
||||
/* This should be adjusted for each device */
|
||||
int device_constant = 1 << ARITH_SHIFT;
|
||||
@ -333,8 +334,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||
u32 tx_time, estimated_retx;
|
||||
u64 result;
|
||||
|
||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||
|
||||
if (sta->fail_avg >= 100)
|
||||
return MAX_METRIC;
|
||||
|
||||
@ -519,10 +518,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
struct mesh_path *mpath = NULL;
|
||||
u8 *target_addr, *orig_addr;
|
||||
const u8 *da;
|
||||
u8 target_flags, ttl;
|
||||
u32 orig_sn, target_sn, lifetime;
|
||||
u8 target_flags, ttl, flags;
|
||||
u32 orig_sn, target_sn, lifetime, orig_metric;
|
||||
bool reply = false;
|
||||
bool forward = true;
|
||||
bool root_is_gate;
|
||||
|
||||
/* Update target SN, if present */
|
||||
target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
|
||||
@ -530,6 +530,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
target_sn = PREQ_IE_TARGET_SN(preq_elem);
|
||||
orig_sn = PREQ_IE_ORIG_SN(preq_elem);
|
||||
target_flags = PREQ_IE_TARGET_F(preq_elem);
|
||||
orig_metric = metric;
|
||||
/* Proactive PREQ gate announcements */
|
||||
flags = PREQ_IE_FLAGS(preq_elem);
|
||||
root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
|
||||
|
||||
mhwmp_dbg("received PREQ from %pM", orig_addr);
|
||||
|
||||
@ -544,6 +548,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
target_sn = ++ifmsh->sn;
|
||||
ifmsh->last_sn_update = jiffies;
|
||||
}
|
||||
} else if (is_broadcast_ether_addr(target_addr) &&
|
||||
(target_flags & IEEE80211_PREQ_TO_FLAG)) {
|
||||
rcu_read_lock();
|
||||
mpath = mesh_path_lookup(orig_addr, sdata);
|
||||
if (mpath) {
|
||||
if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
|
||||
reply = true;
|
||||
target_addr = sdata->vif.addr;
|
||||
target_sn = ++ifmsh->sn;
|
||||
metric = 0;
|
||||
ifmsh->last_sn_update = jiffies;
|
||||
}
|
||||
if (root_is_gate)
|
||||
mesh_path_add_gate(mpath);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
rcu_read_lock();
|
||||
mpath = mesh_path_lookup(target_addr, sdata);
|
||||
@ -576,13 +596,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
|
||||
cpu_to_le32(lifetime), cpu_to_le32(metric),
|
||||
0, sdata);
|
||||
} else
|
||||
} else {
|
||||
ifmsh->mshstats.dropped_frames_ttl++;
|
||||
}
|
||||
}
|
||||
|
||||
if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
u32 preq_id;
|
||||
u8 hopcount, flags;
|
||||
u8 hopcount;
|
||||
|
||||
ttl = PREQ_IE_TTL(preq_elem);
|
||||
lifetime = PREQ_IE_LIFETIME(preq_elem);
|
||||
@ -592,11 +613,17 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
|
||||
--ttl;
|
||||
flags = PREQ_IE_FLAGS(preq_elem);
|
||||
preq_id = PREQ_IE_PREQ_ID(preq_elem);
|
||||
hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
|
||||
da = (mpath && mpath->is_root) ?
|
||||
mpath->rann_snd_addr : broadcast_addr;
|
||||
|
||||
if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
|
||||
target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
|
||||
target_sn = PREQ_IE_TARGET_SN(preq_elem);
|
||||
metric = orig_metric;
|
||||
}
|
||||
|
||||
mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
|
||||
cpu_to_le32(orig_sn), target_flags, target_addr,
|
||||
cpu_to_le32(target_sn), da,
|
||||
@ -744,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
bool root_is_gate;
|
||||
|
||||
ttl = rann->rann_ttl;
|
||||
if (ttl <= 1) {
|
||||
ifmsh->mshstats.dropped_frames_ttl++;
|
||||
return;
|
||||
}
|
||||
ttl--;
|
||||
flags = rann->rann_flags;
|
||||
root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
|
||||
orig_addr = rann->rann_addr;
|
||||
@ -785,34 +807,49 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(SN_LT(mpath->sn, orig_sn)) &&
|
||||
!(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
|
||||
time_after(jiffies, mpath->exp_time - 1*HZ)) &&
|
||||
!(mpath->flags & MESH_PATH_FIXED)) {
|
||||
(time_after(jiffies, mpath->last_preq_to_root +
|
||||
root_path_confirmation_jiffies(sdata)) ||
|
||||
time_before(jiffies, mpath->last_preq_to_root))) &&
|
||||
!(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) {
|
||||
mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
|
||||
orig_addr);
|
||||
mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
|
||||
mpath->last_preq_to_root = jiffies;
|
||||
}
|
||||
|
||||
if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
|
||||
metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
mpath->sn = orig_sn;
|
||||
mpath->rann_metric = metric + metric_txsta;
|
||||
mpath->is_root = true;
|
||||
/* Recording RANNs sender address to send individually
|
||||
* addressed PREQs destined for root mesh STA */
|
||||
memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
|
||||
|
||||
if (root_is_gate)
|
||||
mesh_path_add_gate(mpath);
|
||||
|
||||
if (ttl <= 1) {
|
||||
ifmsh->mshstats.dropped_frames_ttl++;
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
ttl--;
|
||||
|
||||
if (ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
|
||||
cpu_to_le32(orig_sn),
|
||||
0, NULL, 0, broadcast_addr,
|
||||
hopcount, ttl, cpu_to_le32(interval),
|
||||
cpu_to_le32(metric + metric_txsta),
|
||||
0, sdata);
|
||||
mpath->sn = orig_sn;
|
||||
mpath->rann_metric = metric + metric_txsta;
|
||||
/* Recording RANNs sender address to send individually
|
||||
* addressed PREQs destined for root mesh STA */
|
||||
memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
|
||||
}
|
||||
|
||||
mpath->is_root = true;
|
||||
|
||||
if (root_is_gate)
|
||||
mesh_path_add_gate(mpath);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@ -1157,13 +1194,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
|
||||
u8 flags;
|
||||
u8 flags, target_flags = 0;
|
||||
|
||||
flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
|
||||
? RANN_FLAG_IS_GATE : 0;
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
|
||||
|
||||
switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
|
||||
case IEEE80211_PROACTIVE_RANN:
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
|
||||
cpu_to_le32(++ifmsh->sn),
|
||||
0, NULL, 0, broadcast_addr,
|
||||
0, sdata->u.mesh.mshcfg.element_ttl,
|
||||
0, ifmsh->mshcfg.element_ttl,
|
||||
cpu_to_le32(interval), 0, 0, sdata);
|
||||
break;
|
||||
case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
|
||||
flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
|
||||
case IEEE80211_PROACTIVE_PREQ_NO_PREP:
|
||||
interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
|
||||
target_flags |= IEEE80211_PREQ_TO_FLAG |
|
||||
IEEE80211_PREQ_USN_FLAG;
|
||||
mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
|
||||
cpu_to_le32(++ifmsh->sn), target_flags,
|
||||
(u8 *) broadcast_addr, 0, broadcast_addr,
|
||||
0, ifmsh->mshcfg.element_ttl,
|
||||
cpu_to_le32(interval),
|
||||
0, cpu_to_le32(ifmsh->preq_id++), sdata);
|
||||
break;
|
||||
default:
|
||||
mhwmp_dbg("Proactive mechanism not supported");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1141,7 +1141,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
local->wmm_acm = 0;
|
||||
sdata->wmm_acm = 0;
|
||||
for (; left >= 4; left -= 4, pos += 4) {
|
||||
int aci = (pos[0] >> 5) & 0x03;
|
||||
int acm = (pos[0] >> 4) & 0x01;
|
||||
@ -1152,21 +1152,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
||||
case 1: /* AC_BK */
|
||||
queue = 3;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
|
||||
sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
|
||||
uapsd = true;
|
||||
break;
|
||||
case 2: /* AC_VI */
|
||||
queue = 1;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
|
||||
sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
|
||||
uapsd = true;
|
||||
break;
|
||||
case 3: /* AC_VO */
|
||||
queue = 0;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
|
||||
sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
|
||||
uapsd = true;
|
||||
break;
|
||||
@ -1174,7 +1174,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
||||
default:
|
||||
queue = 2;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
|
||||
sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
|
||||
uapsd = true;
|
||||
break;
|
||||
@ -1275,7 +1275,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
bss_info_changed |= BSS_CHANGED_BEACON_INT;
|
||||
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
|
||||
cbss->capability, bss->has_erp_value, bss->erp_value);
|
||||
bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value);
|
||||
|
||||
sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
|
||||
IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
|
||||
@ -3012,7 +3012,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_bss *bss = (void *)cbss->priv;
|
||||
struct sta_info *sta;
|
||||
struct sta_info *sta = NULL;
|
||||
bool have_sta = false;
|
||||
int err;
|
||||
int ht_cfreq;
|
||||
@ -3102,7 +3102,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
||||
local->oper_channel = cbss->channel;
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
|
||||
if (!have_sta) {
|
||||
if (sta) {
|
||||
u32 rates = 0, basic_rates = 0;
|
||||
bool have_higher_than_11mbit;
|
||||
int min_rate = INT_MAX, min_rate_index = -1;
|
||||
|
@ -25,8 +25,7 @@
|
||||
* because we *may* be doing work on-operating channel, and want our
|
||||
* hardware unconditionally awake, but still let the AP send us normal frames.
|
||||
*/
|
||||
static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
|
||||
bool tell_ap)
|
||||
static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
@ -47,8 +46,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
||||
}
|
||||
|
||||
if (tell_ap && (!local->offchannel_ps_enabled ||
|
||||
!(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)))
|
||||
if (!local->offchannel_ps_enabled ||
|
||||
!(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
|
||||
/*
|
||||
* If power save was enabled, no need to send a nullfunc
|
||||
* frame because AP knows that we are sleeping. But if the
|
||||
@ -133,7 +132,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
|
||||
if (offchannel_ps_enable &&
|
||||
(sdata->vif.type == NL80211_IFTYPE_STATION) &&
|
||||
sdata->u.mgd.associated)
|
||||
ieee80211_offchannel_ps_enable(sdata, true);
|
||||
ieee80211_offchannel_ps_enable(sdata);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
@ -263,6 +262,9 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
|
||||
roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
|
||||
list);
|
||||
|
||||
if (WARN_ON_ONCE(roc->started))
|
||||
return;
|
||||
|
||||
if (local->ops->remain_on_channel) {
|
||||
int ret, duration = roc->duration;
|
||||
|
||||
@ -378,8 +380,8 @@ void ieee80211_sw_roc_work(struct work_struct *work)
|
||||
|
||||
ieee80211_recalc_idle(local);
|
||||
|
||||
ieee80211_start_next_roc(local);
|
||||
ieee80211_run_deferred_scan(local);
|
||||
if (roc->started)
|
||||
ieee80211_start_next_roc(local);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
@ -410,9 +412,6 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
|
||||
/* if there's another roc, start it now */
|
||||
ieee80211_start_next_roc(local);
|
||||
|
||||
/* or scan maybe */
|
||||
ieee80211_run_deferred_scan(local);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&local->mtx);
|
||||
}
|
||||
@ -455,7 +454,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
|
||||
}
|
||||
|
||||
ieee80211_start_next_roc(local);
|
||||
ieee80211_run_deferred_scan(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
|
||||
|
@ -78,6 +78,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
if (err < 0) {
|
||||
local->quiescing = false;
|
||||
local->wowlan = false;
|
||||
if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
|
||||
mutex_lock(&local->sta_mtx);
|
||||
list_for_each_entry(sta,
|
||||
&local->sta_list, list) {
|
||||
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
}
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
}
|
||||
ieee80211_wake_queues_by_reason(hw,
|
||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||
return err;
|
||||
} else if (err > 0) {
|
||||
WARN_ON(err != 1);
|
||||
|
@ -1935,7 +1935,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
||||
ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
||||
return RX_CONTINUE;
|
||||
|
||||
q = ieee80211_select_queue_80211(local, skb, hdr);
|
||||
q = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
if (ieee80211_queue_stopped(&local->hw, q)) {
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
||||
return RX_DROP_MONITOR;
|
||||
@ -3027,6 +3027,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
if (unlikely(local->quiescing || local->suspended))
|
||||
goto drop;
|
||||
|
||||
/* We might be during a HW reconfig, prevent Rx for the same reason */
|
||||
if (unlikely(local->in_reconfig))
|
||||
goto drop;
|
||||
|
||||
/*
|
||||
* The same happens when we're not even started,
|
||||
* but that's worth a warning.
|
||||
|
@ -1411,6 +1411,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
if (ieee80211_sdata_running(sdata))
|
||||
ieee80211_enable_keys(sdata);
|
||||
|
||||
local->in_reconfig = false;
|
||||
barrier();
|
||||
|
||||
wake_up:
|
||||
/*
|
||||
* Clear the WLAN_STA_BLOCK_BA flag so new aggregation
|
||||
|
@ -52,11 +52,11 @@ static int wme_downgrade_ac(struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
static u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
|
||||
static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
/* in case we are a client verify acm is not set for this ac */
|
||||
while (unlikely(local->wmm_acm & BIT(skb->priority))) {
|
||||
while (unlikely(sdata->wmm_acm & BIT(skb->priority))) {
|
||||
if (wme_downgrade_ac(skb)) {
|
||||
/*
|
||||
* This should not really happen. The AP has marked all
|
||||
@ -73,10 +73,11 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
|
||||
}
|
||||
|
||||
/* Indicate which queue to use for this fully formed 802.11 frame */
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb,
|
||||
struct ieee80211_hdr *hdr)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u8 *p;
|
||||
|
||||
if (local->hw.queues < IEEE80211_NUM_ACS)
|
||||
@ -94,7 +95,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
|
||||
p = ieee80211_get_qos_ctl(hdr);
|
||||
skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
|
||||
return ieee80211_downgrade_queue(local, skb);
|
||||
return ieee80211_downgrade_queue(sdata, skb);
|
||||
}
|
||||
|
||||
/* Indicate which queue to use. */
|
||||
@ -156,7 +157,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
|
||||
* data frame has */
|
||||
skb->priority = cfg80211_classify8021d(skb);
|
||||
|
||||
return ieee80211_downgrade_queue(local, skb);
|
||||
return ieee80211_downgrade_queue(sdata, skb);
|
||||
}
|
||||
|
||||
void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
extern const int ieee802_1d_to_ac[8];
|
||||
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb,
|
||||
struct ieee80211_hdr *hdr);
|
||||
u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
|
||||
|
@ -96,69 +96,6 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
|
||||
return &rdev->wiphy;
|
||||
}
|
||||
|
||||
/* requires cfg80211_mutex to be held! */
|
||||
struct cfg80211_registered_device *
|
||||
__cfg80211_rdev_from_info(struct genl_info *info)
|
||||
{
|
||||
int ifindex;
|
||||
struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
|
||||
struct net_device *dev;
|
||||
int err = -EINVAL;
|
||||
|
||||
assert_cfg80211_lock();
|
||||
|
||||
if (info->attrs[NL80211_ATTR_WIPHY]) {
|
||||
bywiphyidx = cfg80211_rdev_by_wiphy_idx(
|
||||
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
|
||||
err = -ENODEV;
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_IFINDEX]) {
|
||||
ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
|
||||
dev = dev_get_by_index(genl_info_net(info), ifindex);
|
||||
if (dev) {
|
||||
if (dev->ieee80211_ptr)
|
||||
byifidx =
|
||||
wiphy_to_dev(dev->ieee80211_ptr->wiphy);
|
||||
dev_put(dev);
|
||||
}
|
||||
err = -ENODEV;
|
||||
}
|
||||
|
||||
if (bywiphyidx && byifidx) {
|
||||
if (bywiphyidx != byifidx)
|
||||
return ERR_PTR(-EINVAL);
|
||||
else
|
||||
return bywiphyidx; /* == byifidx */
|
||||
}
|
||||
if (bywiphyidx)
|
||||
return bywiphyidx;
|
||||
|
||||
if (byifidx)
|
||||
return byifidx;
|
||||
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
struct cfg80211_registered_device *
|
||||
cfg80211_get_dev_from_info(struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
|
||||
mutex_lock(&cfg80211_mutex);
|
||||
rdev = __cfg80211_rdev_from_info(info);
|
||||
|
||||
/* if it is not an error we grab the lock on
|
||||
* it to assure it won't be going away while
|
||||
* we operate on it */
|
||||
if (!IS_ERR(rdev))
|
||||
mutex_lock(&rdev->mtx);
|
||||
|
||||
mutex_unlock(&cfg80211_mutex);
|
||||
|
||||
return rdev;
|
||||
}
|
||||
|
||||
struct cfg80211_registered_device *
|
||||
cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
|
||||
{
|
||||
|
@ -159,32 +159,6 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
|
||||
struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
|
||||
int get_wiphy_idx(struct wiphy *wiphy);
|
||||
|
||||
struct cfg80211_registered_device *
|
||||
__cfg80211_rdev_from_info(struct genl_info *info);
|
||||
|
||||
/*
|
||||
* This function returns a pointer to the driver
|
||||
* that the genl_info item that is passed refers to.
|
||||
* If successful, it returns non-NULL and also locks
|
||||
* the driver's mutex!
|
||||
*
|
||||
* This means that you need to call cfg80211_unlock_rdev()
|
||||
* before being allowed to acquire &cfg80211_mutex!
|
||||
*
|
||||
* This is necessary because we need to lock the global
|
||||
* mutex to get an item off the list safely, and then
|
||||
* we lock the rdev mutex so it doesn't go away under us.
|
||||
*
|
||||
* We don't want to keep cfg80211_mutex locked
|
||||
* for all the time in order to allow requests on
|
||||
* other interfaces to go through at the same time.
|
||||
*
|
||||
* The result of this can be a PTR_ERR and hence must
|
||||
* be checked with IS_ERR() for errors.
|
||||
*/
|
||||
extern struct cfg80211_registered_device *
|
||||
cfg80211_get_dev_from_info(struct genl_info *info);
|
||||
|
||||
/* requires cfg80211_rdev_mutex to be held! */
|
||||
struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
|
||||
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
#define MESH_PATH_TIMEOUT 5000
|
||||
#define MESH_RANN_INTERVAL 5000
|
||||
#define MESH_PATH_TO_ROOT_TIMEOUT 6000
|
||||
#define MESH_ROOT_INTERVAL 5000
|
||||
#define MESH_ROOT_CONFIRMATION_INTERVAL 2000
|
||||
|
||||
/*
|
||||
* Minimum interval between two consecutive PREQs originated by the same
|
||||
@ -62,6 +65,9 @@ const struct mesh_config default_mesh_config = {
|
||||
.dot11MeshForwarding = true,
|
||||
.rssi_threshold = MESH_RSSI_THRESHOLD,
|
||||
.ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
|
||||
.dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT,
|
||||
.dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL,
|
||||
.dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
|
||||
};
|
||||
|
||||
const struct mesh_setup default_mesh_setup = {
|
||||
|
@ -70,6 +70,94 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cfg80211_registered_device *
|
||||
__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = NULL, *tmp;
|
||||
struct net_device *netdev;
|
||||
|
||||
assert_cfg80211_lock();
|
||||
|
||||
if (!attrs[NL80211_ATTR_WIPHY] &&
|
||||
!attrs[NL80211_ATTR_IFINDEX])
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (attrs[NL80211_ATTR_WIPHY])
|
||||
rdev = cfg80211_rdev_by_wiphy_idx(
|
||||
nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
|
||||
|
||||
if (attrs[NL80211_ATTR_IFINDEX]) {
|
||||
int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
|
||||
netdev = dev_get_by_index(netns, ifindex);
|
||||
if (netdev) {
|
||||
if (netdev->ieee80211_ptr)
|
||||
tmp = wiphy_to_dev(
|
||||
netdev->ieee80211_ptr->wiphy);
|
||||
else
|
||||
tmp = NULL;
|
||||
|
||||
dev_put(netdev);
|
||||
|
||||
/* not wireless device -- return error */
|
||||
if (!tmp)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* mismatch -- return error */
|
||||
if (rdev && tmp != rdev)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
rdev = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rdev)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (netns != wiphy_net(&rdev->wiphy))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return rdev;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns a pointer to the driver
|
||||
* that the genl_info item that is passed refers to.
|
||||
* If successful, it returns non-NULL and also locks
|
||||
* the driver's mutex!
|
||||
*
|
||||
* This means that you need to call cfg80211_unlock_rdev()
|
||||
* before being allowed to acquire &cfg80211_mutex!
|
||||
*
|
||||
* This is necessary because we need to lock the global
|
||||
* mutex to get an item off the list safely, and then
|
||||
* we lock the rdev mutex so it doesn't go away under us.
|
||||
*
|
||||
* We don't want to keep cfg80211_mutex locked
|
||||
* for all the time in order to allow requests on
|
||||
* other interfaces to go through at the same time.
|
||||
*
|
||||
* The result of this can be a PTR_ERR and hence must
|
||||
* be checked with IS_ERR() for errors.
|
||||
*/
|
||||
static struct cfg80211_registered_device *
|
||||
cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
|
||||
mutex_lock(&cfg80211_mutex);
|
||||
rdev = __cfg80211_rdev_from_attrs(netns, info->attrs);
|
||||
|
||||
/* if it is not an error we grab the lock on
|
||||
* it to assure it won't be going away while
|
||||
* we operate on it */
|
||||
if (!IS_ERR(rdev))
|
||||
mutex_lock(&rdev->mtx);
|
||||
|
||||
mutex_unlock(&cfg80211_mutex);
|
||||
|
||||
return rdev;
|
||||
}
|
||||
|
||||
/* policy for the attributes */
|
||||
static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
||||
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
||||
@ -115,7 +203,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
|
||||
[NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
|
||||
[NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_MAX_MESH_ID_LEN },
|
||||
.len = IEEE80211_MAX_MESH_ID_LEN },
|
||||
[NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
|
||||
|
||||
[NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
|
||||
@ -250,7 +338,7 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
|
||||
|
||||
static const struct nla_policy
|
||||
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
|
||||
[NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY,
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_MAX_SSID_LEN },
|
||||
};
|
||||
|
||||
@ -1334,7 +1422,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
if (!netdev) {
|
||||
rdev = __cfg80211_rdev_from_info(info);
|
||||
rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
|
||||
info->attrs);
|
||||
if (IS_ERR(rdev)) {
|
||||
mutex_unlock(&cfg80211_mutex);
|
||||
return PTR_ERR(rdev);
|
||||
@ -2246,6 +2335,33 @@ static int nl80211_parse_beacon(struct genl_info *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_ap_settings *params)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
bool ret = false;
|
||||
|
||||
mutex_lock(&rdev->devlist_mtx);
|
||||
|
||||
list_for_each_entry(wdev, &rdev->netdev_list, list) {
|
||||
if (wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
continue;
|
||||
|
||||
if (!wdev->preset_chan)
|
||||
continue;
|
||||
|
||||
params->channel = wdev->preset_chan;
|
||||
params->channel_type = wdev->preset_chantype;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&rdev->devlist_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
@ -2348,7 +2464,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
} else if (wdev->preset_chan) {
|
||||
params.channel = wdev->preset_chan;
|
||||
params.channel_type = wdev->preset_chantype;
|
||||
} else
|
||||
} else if (!nl80211_get_ap_channel(rdev, ¶ms))
|
||||
return -EINVAL;
|
||||
|
||||
if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
|
||||
@ -2356,8 +2472,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
|
||||
err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
wdev->preset_chan = params.channel;
|
||||
wdev->preset_chantype = params.channel_type;
|
||||
wdev->beacon_interval = params.beacon_interval;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3469,7 +3588,13 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
|
||||
nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
|
||||
cur_params.rssi_threshold) ||
|
||||
nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
|
||||
cur_params.ht_opmode))
|
||||
cur_params.ht_opmode) ||
|
||||
nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
|
||||
cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
|
||||
nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
|
||||
cur_params.dot11MeshHWMProotInterval) ||
|
||||
nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
|
||||
cur_params.dot11MeshHWMPconfirmationInterval))
|
||||
goto nla_put_failure;
|
||||
nla_nest_end(msg, pinfoattr);
|
||||
genlmsg_end(msg, hdr);
|
||||
@ -3492,7 +3617,6 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
|
||||
[NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
|
||||
[NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
|
||||
[NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
|
||||
|
||||
[NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
|
||||
[NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
|
||||
[NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
|
||||
@ -3504,8 +3628,11 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
|
||||
[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
|
||||
[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
|
||||
[NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
|
||||
[NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
|
||||
[NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16},
|
||||
[NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
|
||||
[NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
|
||||
[NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
|
||||
[NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
|
||||
[NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
@ -3515,7 +3642,7 @@ static const struct nla_policy
|
||||
[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
|
||||
[NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
|
||||
[NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_MAX_DATA_LEN },
|
||||
.len = IEEE80211_MAX_DATA_LEN },
|
||||
[NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
@ -3548,63 +3675,82 @@ do {\
|
||||
|
||||
/* Fill in the params struct */
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
|
||||
mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
|
||||
mask, NL80211_MESHCONF_RETRY_TIMEOUT,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
|
||||
mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
|
||||
mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
|
||||
mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
|
||||
mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
|
||||
mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
|
||||
mask, NL80211_MESHCONF_MAX_PEER_LINKS,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
|
||||
mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
|
||||
mask, NL80211_MESHCONF_MAX_RETRIES,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
|
||||
mask, NL80211_MESHCONF_TTL, nla_get_u8);
|
||||
mask, NL80211_MESHCONF_TTL, nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
|
||||
mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
|
||||
mask, NL80211_MESHCONF_ELEMENT_TTL,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
|
||||
mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
|
||||
mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
|
||||
nla_get_u32);
|
||||
mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask,
|
||||
NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
|
||||
nla_get_u32);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
|
||||
mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
|
||||
nla_get_u8);
|
||||
mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
|
||||
mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
|
||||
mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
|
||||
nla_get_u32);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
|
||||
mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
|
||||
mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
|
||||
nla_get_u32);
|
||||
mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask,
|
||||
NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
|
||||
nla_get_u32);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
|
||||
mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
|
||||
nla_get_u16);
|
||||
mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
|
||||
mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
|
||||
nla_get_u16);
|
||||
mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
|
||||
dot11MeshHWMPnetDiameterTraversalTime,
|
||||
mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
|
||||
nla_get_u16);
|
||||
dot11MeshHWMPnetDiameterTraversalTime, mask,
|
||||
NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
|
||||
NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
|
||||
NL80211_MESHCONF_HWMP_RANN_INTERVAL,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
|
||||
dot11MeshHWMPRootMode, mask,
|
||||
NL80211_MESHCONF_HWMP_ROOTMODE,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
|
||||
dot11MeshHWMPRannInterval, mask,
|
||||
NL80211_MESHCONF_HWMP_RANN_INTERVAL,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
|
||||
dot11MeshGateAnnouncementProtocol, mask,
|
||||
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
|
||||
nla_get_u8);
|
||||
dot11MeshGateAnnouncementProtocol, mask,
|
||||
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
|
||||
mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
|
||||
mask, NL80211_MESHCONF_FORWARDING,
|
||||
nla_get_u8);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
|
||||
mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
|
||||
mask, NL80211_MESHCONF_RSSI_THRESHOLD,
|
||||
nla_get_u32);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
|
||||
mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16);
|
||||
mask, NL80211_MESHCONF_HT_OPMODE,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
|
||||
mask,
|
||||
NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
|
||||
nla_get_u32);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
|
||||
mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
|
||||
nla_get_u16);
|
||||
FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
|
||||
dot11MeshHWMPconfirmationInterval, mask,
|
||||
NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
|
||||
nla_get_u16);
|
||||
if (mask_out)
|
||||
*mask_out = mask;
|
||||
|
||||
@ -4246,7 +4392,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||
nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
|
||||
nla_data(attr), nla_len(attr),
|
||||
nl80211_match_policy);
|
||||
ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID];
|
||||
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
|
||||
if (ssid) {
|
||||
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
|
||||
err = -EINVAL;
|
||||
@ -5114,21 +5260,18 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
|
||||
nl80211_policy);
|
||||
if (err)
|
||||
return err;
|
||||
if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
|
||||
phy_idx = nla_get_u32(
|
||||
nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
|
||||
} else {
|
||||
struct net_device *netdev;
|
||||
|
||||
err = get_rdev_dev_by_ifindex(sock_net(skb->sk),
|
||||
nl80211_fam.attrbuf,
|
||||
&rdev, &netdev);
|
||||
if (err)
|
||||
return err;
|
||||
dev_put(netdev);
|
||||
phy_idx = rdev->wiphy_idx;
|
||||
cfg80211_unlock_rdev(rdev);
|
||||
mutex_lock(&cfg80211_mutex);
|
||||
rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
|
||||
nl80211_fam.attrbuf);
|
||||
if (IS_ERR(rdev)) {
|
||||
mutex_unlock(&cfg80211_mutex);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
phy_idx = rdev->wiphy_idx;
|
||||
rdev = NULL;
|
||||
mutex_unlock(&cfg80211_mutex);
|
||||
|
||||
if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
|
||||
cb->args[1] =
|
||||
(long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
|
||||
@ -6511,7 +6654,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
|
||||
rtnl_lock();
|
||||
|
||||
if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
|
||||
rdev = cfg80211_get_dev_from_info(info);
|
||||
rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
|
||||
if (IS_ERR(rdev)) {
|
||||
if (rtnl)
|
||||
rtnl_unlock();
|
||||
|
Loading…
Reference in New Issue
Block a user