Merge tag 'mac80211-next-for-davem-2020-07-31' of git://git.kernel.org/pub/scm/linux...
authorDavid S. Miller <davem@davemloft.net>
Sat, 1 Aug 2020 01:51:40 +0000 (18:51 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 1 Aug 2020 01:51:40 +0000 (18:51 -0700)
Johannes Berg says:

====================
We have a number of changes
 * code cleanups and fixups as usual
 * AQL & internal TXQ improvements from Felix
 * some mesh 802.1X support bits
 * some injection improvements from Mathy of KRACK
   fame, so we'll see what this results in ;-)
 * some more initial S1G supports bits, this time
   (some of?) the userspace APIs
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
42 files changed:
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/mac80211_hwsim.c
include/net/cfg80211.h
include/net/fq.h
include/net/fq_impl.h
include/net/ieee80211_radiotap.h
include/net/mac80211.h
include/net/regulatory.h
include/uapi/linux/nl80211.h
include/uapi/linux/wireless.h
net/mac80211/airtime.c
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/debugfs_netdev.c
net/mac80211/driver-ops.h
net/mac80211/ht.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/mesh.c
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/offchannel.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/status.c
net/mac80211/tdls.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wme.c
net/wireless/chan.c
net/wireless/core.c
net/wireless/mesh.c
net/wireless/nl80211.c
net/wireless/scan.c
net/wireless/trace.h
net/wireless/util.c

index 919d155..3c0c33a 100644 (file)
@@ -568,11 +568,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
                case NL80211_CHAN_WIDTH_40:
                        phymode = MODE_11NG_HT40;
                        break;
-               case NL80211_CHAN_WIDTH_5:
-               case NL80211_CHAN_WIDTH_10:
-               case NL80211_CHAN_WIDTH_80:
-               case NL80211_CHAN_WIDTH_80P80:
-               case NL80211_CHAN_WIDTH_160:
+               default:
                        phymode = MODE_UNKNOWN;
                        break;
                }
@@ -597,8 +593,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
                case NL80211_CHAN_WIDTH_80P80:
                        phymode = MODE_11AC_VHT80_80;
                        break;
-               case NL80211_CHAN_WIDTH_5:
-               case NL80211_CHAN_WIDTH_10:
+               default:
                        phymode = MODE_UNKNOWN;
                        break;
                }
index 07d3e03..94ae2b9 100644 (file)
@@ -2072,7 +2072,7 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
                        ret = ath11k_wmi_send_obss_color_collision_cfg_cmd(
                                ar, arvif->vdev_id, info->he_bss_color.color,
                                ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS,
-                               !info->he_bss_color.disabled);
+                               info->he_bss_color.enabled);
                        if (ret)
                                ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
                                            arvif->vdev_id,  ret);
index 1356e8c..9dd9d73 100644 (file)
@@ -4334,7 +4334,7 @@ static int __init init_mac80211_hwsim(void)
                        break;
                case HWSIM_REGTEST_STRICT_ALL:
                        param.reg_strict = true;
-                       /* fall through */
+                       fallthrough;
                case HWSIM_REGTEST_DRIVER_REG_ALL:
                        param.reg_alpha2 = hwsim_alpha2s[0];
                        break;
index fc7e880..d9e6b9f 100644 (file)
@@ -267,12 +267,12 @@ struct ieee80211_he_obss_pd {
  * struct cfg80211_he_bss_color - AP settings for BSS coloring
  *
  * @color: the current color.
- * @disabled: is the feature disabled.
+ * @enabled: HE BSS color is used
  * @partial: define the AID equation.
  */
 struct cfg80211_he_bss_color {
        u8 color;
-       bool disabled;
+       bool enabled;
        bool partial;
 };
 
@@ -417,13 +417,29 @@ struct ieee80211_edmg {
        enum ieee80211_edmg_bw_config bw_config;
 };
 
+/**
+ * struct ieee80211_sta_s1g_cap - STA's S1G capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11ah S1G capabilities for a STA.
+ *
+ * @s1g_supported: is STA an S1G STA
+ * @cap: S1G capabilities information
+ * @nss_mcs: Supported NSS MCS set
+ */
+struct ieee80211_sta_s1g_cap {
+       bool s1g;
+       u8 cap[10]; /* use S1G_CAPAB_ */
+       u8 nss_mcs[5];
+};
+
 /**
  * struct ieee80211_supported_band - frequency band definition
  *
  * This structure describes a frequency band a wiphy
  * is able to operate in.
  *
- * @channels: Array of channels the hardware can operate in
+ * @channels: Array of channels the hardware can operate with
  *     in this band.
  * @band: the band this structure represents
  * @n_channels: Number of channels in @channels
@@ -448,6 +464,7 @@ struct ieee80211_supported_band {
        int n_bitrates;
        struct ieee80211_sta_ht_cap ht_cap;
        struct ieee80211_sta_vht_cap vht_cap;
+       struct ieee80211_sta_s1g_cap s1g_cap;
        struct ieee80211_edmg edmg_cap;
        u16 n_iftype_data;
        const struct ieee80211_sband_iftype_data *iftype_data;
@@ -1581,6 +1598,7 @@ struct cfg80211_tid_stats {
  *     an FCS error. This counter should be incremented only when TA of the
  *     received packet with an FCS error matches the peer MAC address.
  * @airtime_link_metric: mesh airtime link metric.
+ * @connected_to_as: true if mesh STA has a path to authentication server
  */
 struct station_info {
        u64 filled;
@@ -1638,6 +1656,8 @@ struct station_info {
        u32 fcs_err_count;
 
        u32 airtime_link_metric;
+
+       u8 connected_to_as;
 };
 
 #if IS_ENABLED(CONFIG_CFG80211)
@@ -1853,6 +1873,11 @@ struct bss_parameters {
  *      connected to a mesh gate in mesh formation info.  If false, the
  *      value in mesh formation is determined by the presence of root paths
  *      in the mesh path table
+ * @dot11MeshNolearn: Try to avoid multi-hop path discovery (e.g. PREQ/PREP
+ *      for HWMP) if the destination is a direct neighbor. Note that this might
+ *      not be the optimal decision as a multi-hop route might be better. So
+ *      if using this setting you will likely also want to disable
+ *      dot11MeshForwarding and use another mesh routing protocol on top.
  */
 struct mesh_config {
        u16 dot11MeshRetryTimeout;
@@ -1873,6 +1898,7 @@ struct mesh_config {
        u16 dot11MeshHWMPnetDiameterTraversalTime;
        u8 dot11MeshHWMPRootMode;
        bool dot11MeshConnectedToMeshGate;
+       bool dot11MeshConnectedToAuthServer;
        u16 dot11MeshHWMPRannInterval;
        bool dot11MeshGateAnnouncementProtocol;
        bool dot11MeshForwarding;
@@ -1884,6 +1910,7 @@ struct mesh_config {
        enum nl80211_mesh_power_mode power_mode;
        u16 dot11MeshAwakeWindowDuration;
        u32 plink_timeout;
+       bool dot11MeshNolearn;
 };
 
 /**
@@ -5510,7 +5537,7 @@ static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
  *
  * @skb: The input A-MSDU frame without any headers.
  * @list: The output list of 802.3 frames. It must be allocated and
- *     initialized by by the caller.
+ *     initialized by the caller.
  * @addr: The device MAC address.
  * @iftype: The device interface type.
  * @extra_headroom: The hardware extra headroom for SKBs in the @list.
@@ -7882,4 +7909,10 @@ void cfg80211_update_owe_info_event(struct net_device *netdev,
                                    struct cfg80211_update_owe_info *owe_info,
                                    gfp_t gfp);
 
+/**
+ * cfg80211_bss_flush - resets all the scan entries
+ * @wiphy: the wiphy
+ */
+void cfg80211_bss_flush(struct wiphy *wiphy);
+
 #endif /* __NET_CFG80211_H */
index 2ad85e6..e39f3f8 100644 (file)
@@ -69,7 +69,6 @@ struct fq {
        struct list_head backlogs;
        spinlock_t lock;
        u32 flows_cnt;
-       siphash_key_t   perturbation;
        u32 limit;
        u32 memory_limit;
        u32 memory_usage;
index 38a9a3d..e73d74d 100644 (file)
@@ -108,7 +108,7 @@ begin:
 
 static u32 fq_flow_idx(struct fq *fq, struct sk_buff *skb)
 {
-       u32 hash = skb_get_hash_perturb(skb, &fq->perturbation);
+       u32 hash = skb_get_hash(skb);
 
        return reciprocal_scale(hash, fq->flows_cnt);
 }
@@ -308,7 +308,6 @@ static int fq_init(struct fq *fq, int flows_cnt)
        INIT_LIST_HEAD(&fq->backlogs);
        spin_lock_init(&fq->lock);
        fq->flows_cnt = max_t(u32, flows_cnt, 1);
-       get_random_bytes(&fq->perturbation, sizeof(fq->perturbation));
        fq->quantum = 300;
        fq->limit = 8192;
        fq->memory_limit = 16 << 20; /* 16 MBytes */
index 459d355..19c00d1 100644 (file)
@@ -117,6 +117,7 @@ enum ieee80211_radiotap_tx_flags {
        IEEE80211_RADIOTAP_F_TX_CTS = 0x0002,
        IEEE80211_RADIOTAP_F_TX_RTS = 0x0004,
        IEEE80211_RADIOTAP_F_TX_NOACK = 0x0008,
+       IEEE80211_RADIOTAP_F_TX_NOSEQNO = 0x0010,
 };
 
 /* for IEEE80211_RADIOTAP_MCS "have" flags */
index 11d5610..66e2bfd 100644 (file)
@@ -825,6 +825,8 @@ enum mac80211_tx_info_flags {
  * @IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP: This frame skips mesh path lookup
  * @IEEE80211_TX_CTRL_HW_80211_ENCAP: This frame uses hardware encapsulation
  *     (header conversion)
+ * @IEEE80211_TX_CTRL_NO_SEQNO: Do not overwrite the sequence number that
+ *     has already been assigned to this frame.
  *
  * These flags are used in tx_info->control.flags.
  */
@@ -836,6 +838,7 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_CTRL_FAST_XMIT             = BIT(4),
        IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP     = BIT(5),
        IEEE80211_TX_CTRL_HW_80211_ENCAP        = BIT(6),
+       IEEE80211_TX_CTRL_NO_SEQNO              = BIT(7),
 };
 
 /*
@@ -2727,7 +2730,7 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
  * for devices that support offload of data packets (e.g. ARP responses).
  *
  * Mac80211 drivers should set the @NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 flag
- * when they are able to replace in-use PTK keys according to to following
+ * when they are able to replace in-use PTK keys according to the following
  * requirements:
  * 1) They do not hand over frames decrypted with the old key to
       mac80211 once the call to set_key() with command %DISABLE_KEY has been
@@ -4357,6 +4360,31 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
  */
 void ieee80211_restart_hw(struct ieee80211_hw *hw);
 
+/**
+ * ieee80211_rx_list - receive frame and store processed skbs in a list
+ *
+ * Use this function to hand received frames to mac80211. The receive
+ * buffer in @skb must start with an IEEE 802.11 header. In case of a
+ * paged @skb is used, the driver is recommended to put the ieee80211
+ * header of the frame on the linear part of the @skb to avoid memory
+ * allocation and/or memcpy by the stack.
+ *
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other. Calls to
+ * this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be
+ * mixed for a single hardware. Must not run concurrently with
+ * ieee80211_tx_status() or ieee80211_tx_status_ni().
+ *
+ * This function must be called with BHs disabled and RCU read lock
+ *
+ * @hw: the hardware this frame came in on
+ * @sta: the station the frame was received from, or %NULL
+ * @skb: the buffer to receive, owned by mac80211 after this call
+ * @list: the destination list
+ */
+void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+                      struct sk_buff *skb, struct list_head *list);
+
 /**
  * ieee80211_rx_napi - receive frame from NAPI context
  *
@@ -4709,7 +4737,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
  *
  * Call this function for all transmitted data frames after their transmit
  * completion. This callback should only be called for data frames which
- * are are using driver's (or hardware's) offload capability of encap/decap
+ * are using driver's (or hardware's) offload capability of encap/decap
  * 802.11 frames.
  *
  * This function may not be called in IRQ context. Calls to this function
@@ -6235,6 +6263,14 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif, struct sk_buff *skb,
                              int band, struct ieee80211_sta **sta);
 
+/**
+ * Sanity-check and parse the radiotap header of injected frames
+ * @skb: packet injected by userspace
+ * @dev: the &struct device of this 802.11 device
+ */
+bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
+                                struct net_device *dev);
+
 /**
  * struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state
  *
@@ -6344,7 +6380,7 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
  *
  * Note that this must be called in an rcu_read_lock() critical section,
  * which can only be released after the SKB was handled. Some pointers in
- * skb->cb, e.g. the key pointer, are protected by by RCU and thus the
+ * skb->cb, e.g. the key pointer, are protected by RCU and thus the
  * critical section must persist not just for the duration of this call
  * but for the duration of the frame handling.
  * However, also note that while in the wake_tx_queue() method,
index 09a3099..47f06f6 100644 (file)
@@ -44,7 +44,7 @@ enum environment_cap {
  *     and potentially inform users of which devices specifically
  *     cased the conflicts.
  * @initiator: indicates who sent this request, could be any of
- *     of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
+ *     those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
  * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
  *     regulatory domain. We have a few special codes:
  *     00 - World regulatory domain
index 4e6339a..631f3a9 100644 (file)
  *
  * By setting @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK flag drivers
  * can indicate they support offloading EAPOL handshakes for WPA/WPA2
- * preshared key authentication. In %NL80211_CMD_CONNECT the preshared
- * key should be specified using %NL80211_ATTR_PMK. Drivers supporting
- * this offload may reject the %NL80211_CMD_CONNECT when no preshared
- * key material is provided, for example when that driver does not
- * support setting the temporal keys through %CMD_NEW_KEY.
+ * preshared key authentication in station mode. In %NL80211_CMD_CONNECT
+ * the preshared key should be specified using %NL80211_ATTR_PMK. Drivers
+ * supporting this offload may reject the %NL80211_CMD_CONNECT when no
+ * preshared key material is provided, for example when that driver does
+ * not support setting the temporal keys through %NL80211_CMD_NEW_KEY.
  *
  * Similarly @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X flag can be
  * set by drivers indicating offload support of the PTK/GTK EAPOL
- * handshakes during 802.1X authentication. In order to use the offload
- * the %NL80211_CMD_CONNECT should have %NL80211_ATTR_WANT_1X_4WAY_HS
- * attribute flag. Drivers supporting this offload may reject the
- * %NL80211_CMD_CONNECT when the attribute flag is not present.
+ * handshakes during 802.1X authentication in station mode. In order to
+ * use the offload the %NL80211_CMD_CONNECT should have
+ * %NL80211_ATTR_WANT_1X_4WAY_HS attribute flag. Drivers supporting this
+ * offload may reject the %NL80211_CMD_CONNECT when the attribute flag is
+ * not present.
+ *
+ * By setting @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK flag drivers
+ * can indicate they support offloading EAPOL handshakes for WPA/WPA2
+ * preshared key authentication in AP mode. In %NL80211_CMD_START_AP
+ * the preshared key should be specified using %NL80211_ATTR_PMK. Drivers
+ * supporting this offload may reject the %NL80211_CMD_START_AP when no
+ * preshared key material is provided, for example when that driver does
+ * not support setting the temporal keys through %NL80211_CMD_NEW_KEY.
  *
  * For 802.1X the PMK or PMK-R0 are set by providing %NL80211_ATTR_PMK
  * using %NL80211_CMD_SET_PMK. For offloaded FT support also
  * @NL80211_CMD_SET_STATION: Set station attributes for station identified by
  *     %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
  * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the
- *     the interface identified by %NL80211_ATTR_IFINDEX.
+ *     interface identified by %NL80211_ATTR_IFINDEX.
  * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
  *     or, if no MAC address given, all stations, on the interface identified
  *     by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and
  * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by
  *     %NL80211_ATTR_MAC.
  * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
- *     the interface identified by %NL80211_ATTR_IFINDEX.
+ *     interface identified by %NL80211_ATTR_IFINDEX.
  * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
  *     or, if no MAC address given, all mesh paths, on the interface identified
  *     by %NL80211_ATTR_IFINDEX.
  * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules.
  *
  * @NL80211_CMD_CHANNEL_SWITCH: Perform a channel switch by announcing the
- *     the new channel information (Channel Switch Announcement - CSA)
+ *     new channel information (Channel Switch Announcement - CSA)
  *     in the beacon for some time (as defined in the
  *     %NL80211_ATTR_CH_SWITCH_COUNT parameter) and then change to the
  *     new channel. Userspace provides the new channel information (using
  *     randomization may be enabled and configured by specifying the
  *     %NL80211_ATTR_MAC and %NL80211_ATTR_MAC_MASK attributes.
  *     If a timeout is requested, use the %NL80211_ATTR_TIMEOUT attribute.
- *     A u64 cookie for further %NL80211_ATTR_COOKIE use is is returned in
+ *     A u64 cookie for further %NL80211_ATTR_COOKIE use is returned in
  *     the netlink extended ack message.
  *
  *     To cancel a measurement, close the socket that requested it.
@@ -1511,7 +1520,7 @@ enum nl80211_commands {
  *     rates as defined by IEEE 802.11 7.3.2.2 but without the length
  *     restriction (at most %NL80211_MAX_SUPP_RATES).
  * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
- *     to, or the AP interface the station was originally added to to.
+ *     to, or the AP interface the station was originally added to.
  * @NL80211_ATTR_STA_INFO: information about a station, part of station info
  *     given for %NL80211_CMD_GET_STATION, nested attribute containing
  *     info as possible, see &enum nl80211_sta_info.
@@ -2084,7 +2093,7 @@ enum nl80211_commands {
  * @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels.
  *
  * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
- *      supported operating classes.
+ *      operating classes.
  *
  * @NL80211_ATTR_HANDLE_DFS: A flag indicating whether user space
  *     controls DFS operation in IBSS mode. If the flag is included in
@@ -2362,10 +2371,11 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_PMK: attribute for passing PMK key material. Used with
  *     %NL80211_CMD_SET_PMKSA for the PMKSA identified by %NL80211_ATTR_PMKID.
- *     For %NL80211_CMD_CONNECT it is used to provide PSK for offloading 4-way
- *     handshake for WPA/WPA2-PSK networks. For 802.1X authentication it is
- *     used with %NL80211_CMD_SET_PMK. For offloaded FT support this attribute
- *     specifies the PMK-R0 if NL80211_ATTR_PMKR0_NAME is included as well.
+ *     For %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP it is used to provide
+ *     PSK for offloading 4-way handshake for WPA/WPA2-PSK networks. For 802.1X
+ *     authentication it is used with %NL80211_CMD_SET_PMK. For offloaded FT
+ *     support this attribute specifies the PMK-R0 if NL80211_ATTR_PMKR0_NAME
+ *     is included as well.
  *
  * @NL80211_ATTR_SCHED_SCAN_MULTI: flag attribute which user-space shall use to
  *     indicate that it supports multiple active scheduled scan requests.
@@ -2395,7 +2405,7 @@ enum nl80211_commands {
  *      nl80211_txq_stats)
  * @NL80211_ATTR_TXQ_LIMIT: Total packet limit for the TXQ queues for this phy.
  *      The smaller of this and the memory limit is enforced.
- * @NL80211_ATTR_TXQ_MEMORY_LIMIT: Total memory memory limit (in bytes) for the
+ * @NL80211_ATTR_TXQ_MEMORY_LIMIT: Total memory limit (in bytes) for the
  *      TXQ queues for this phy. The smaller of this and the packet limit is
  *      enforced.
  * @NL80211_ATTR_TXQ_QUANTUM: TXQ scheduler quantum (bytes). Number of bytes
@@ -3370,6 +3380,8 @@ enum nl80211_sta_bss_param {
  * @NL80211_STA_INFO_AIRTIME_LINK_METRIC: airtime link metric for mesh station
  * @NL80211_STA_INFO_ASSOC_AT_BOOTTIME: Timestamp (CLOCK_BOOTTIME, nanoseconds)
  *     of STA's association
+ * @NL80211_STA_INFO_CONNECTED_TO_AS: set to true if STA has a path to a
+ *     authentication server (u8, 0 or 1)
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -3417,6 +3429,7 @@ enum nl80211_sta_info {
        NL80211_STA_INFO_AIRTIME_WEIGHT,
        NL80211_STA_INFO_AIRTIME_LINK_METRIC,
        NL80211_STA_INFO_ASSOC_AT_BOOTTIME,
+       NL80211_STA_INFO_CONNECTED_TO_AS,
 
        /* keep last */
        __NL80211_STA_INFO_AFTER_LAST,
@@ -4236,6 +4249,16 @@ enum nl80211_mesh_power_mode {
  *     field.  If left unset then the mesh formation field will only
  *     advertise such if there is an active root mesh path.
  *
+ * @NL80211_MESHCONF_NOLEARN: Try to avoid multi-hop path discovery (e.g.
+ *      PREQ/PREP for HWMP) if the destination is a direct neighbor. Note that
+ *      this might not be the optimal decision as a multi-hop route might be
+ *      better. So if using this setting you will likely also want to disable
+ *      dot11MeshForwarding and use another mesh routing protocol on top.
+ *
+ * @NL80211_MESHCONF_CONNECTED_TO_AS: If set to true then this mesh STA
+ *     will advertise that it is connected to a authentication server
+ *     in the mesh formation field.
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -4269,6 +4292,8 @@ enum nl80211_meshconf_params {
        NL80211_MESHCONF_AWAKE_WINDOW,
        NL80211_MESHCONF_PLINK_TIMEOUT,
        NL80211_MESHCONF_CONNECTED_TO_GATE,
+       NL80211_MESHCONF_NOLEARN,
+       NL80211_MESHCONF_CONNECTED_TO_AS,
 
        /* keep last */
        __NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -4437,6 +4462,11 @@ enum nl80211_key_mode {
  *     attribute must be provided as well
  * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
  * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_1: 1 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_2: 2 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_4: 4 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_8: 8 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_16: 16 MHz OFDM channel
  */
 enum nl80211_chan_width {
        NL80211_CHAN_WIDTH_20_NOHT,
@@ -4447,6 +4477,11 @@ enum nl80211_chan_width {
        NL80211_CHAN_WIDTH_160,
        NL80211_CHAN_WIDTH_5,
        NL80211_CHAN_WIDTH_10,
+       NL80211_CHAN_WIDTH_1,
+       NL80211_CHAN_WIDTH_2,
+       NL80211_CHAN_WIDTH_4,
+       NL80211_CHAN_WIDTH_8,
+       NL80211_CHAN_WIDTH_16,
 };
 
 /**
@@ -4457,11 +4492,15 @@ enum nl80211_chan_width {
  * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible
  * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide
  * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_1: control channel is 1 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_2: control channel is 2 MHz wide
  */
 enum nl80211_bss_scan_width {
        NL80211_BSS_CHAN_WIDTH_20,
        NL80211_BSS_CHAN_WIDTH_10,
        NL80211_BSS_CHAN_WIDTH_5,
+       NL80211_BSS_CHAN_WIDTH_1,
+       NL80211_BSS_CHAN_WIDTH_2,
 };
 
 /**
@@ -4740,6 +4779,7 @@ enum nl80211_txrate_gi {
  * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
  * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 69.12 GHz)
  * @NL80211_BAND_6GHZ: around 6 GHz band (5.9 - 7.2 GHz)
+ * @NL80211_BAND_S1GHZ: around 900MHz, supported by S1G PHYs
  * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace
  *     since newer kernel versions may support more bands
  */
@@ -4748,6 +4788,7 @@ enum nl80211_band {
        NL80211_BAND_5GHZ,
        NL80211_BAND_60GHZ,
        NL80211_BAND_6GHZ,
+       NL80211_BAND_S1GHZ,
 
        NUM_NL80211_BANDS,
 };
@@ -5636,7 +5677,7 @@ enum nl80211_feature_flags {
  * enum nl80211_ext_feature_index - bit index of extended features.
  * @NL80211_EXT_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates.
  * @NL80211_EXT_FEATURE_RRM: This driver supports RRM. When featured, user can
- *     can request to use RRM (see %NL80211_ATTR_USE_RRM) with
+ *     request to use RRM (see %NL80211_ATTR_USE_RRM) with
  *     %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
  *     the ASSOC_REQ_USE_RRM flag in the association request even if
  *     NL80211_FEATURE_QUIET is not advertized.
@@ -5773,6 +5814,13 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS: The driver
  *     can report tx status for control port over nl80211 tx operations.
  *
+ * @NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION: Driver supports Operating
+ *     Channel Validation (OCV) when using driver's SME for RSNA handshakes.
+ *
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK: Device wants to do 4-way
+ *     handshake with PSK in AP mode (PSK is passed as part of the start AP
+ *     command).
+ *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
  */
@@ -5828,6 +5876,8 @@ enum nl80211_ext_feature_index {
        NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT,
        NL80211_EXT_FEATURE_SCAN_FREQ_KHZ,
        NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS,
+       NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION,
+       NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK,
 
        /* add new features before the definition below */
        NUM_NL80211_EXT_FEATURES,
@@ -6045,7 +6095,7 @@ enum nl80211_dfs_state {
 };
 
 /**
- * enum enum nl80211_protocol_features - nl80211 protocol features
+ * enum nl80211_protocol_features - nl80211 protocol features
  * @NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP: nl80211 supports splitting
  *     wiphy dumps (if requested by the application with the attribute
  *     %NL80211_ATTR_SPLIT_WIPHY_DUMP. Also supported is filtering the
index 24f3371..08967b3 100644 (file)
@@ -914,7 +914,7 @@ union iwreq_data {
        struct iw_param sens;           /* signal level threshold */
        struct iw_param bitrate;        /* default bit rate */
        struct iw_param txpower;        /* default transmit power */
-       struct iw_param rts;            /* RTS threshold threshold */
+       struct iw_param rts;            /* RTS threshold */
        struct iw_param frag;           /* Fragmentation threshold */
        __u32           mode;           /* Operation mode */
        struct iw_param retry;          /* Retry limits & lifetime */
index 9fc2968..366f76c 100644 (file)
@@ -551,7 +551,7 @@ EXPORT_SYMBOL_GPL(ieee80211_calc_tx_airtime);
 u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
                                       struct ieee80211_sta *pubsta,
-                                      int len)
+                                      int len, bool ampdu)
 {
        struct ieee80211_supported_band *sband;
        struct ieee80211_chanctx_conf *conf;
@@ -572,10 +572,26 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
        if (pubsta) {
                struct sta_info *sta = container_of(pubsta, struct sta_info,
                                                    sta);
-
-               return ieee80211_calc_tx_airtime_rate(hw,
-                                                     &sta->tx_stats.last_rate,
-                                                     band, len);
+               struct ieee80211_tx_rate *rate = &sta->tx_stats.last_rate;
+               u32 airtime;
+
+               if (!(rate->flags & (IEEE80211_TX_RC_VHT_MCS |
+                                    IEEE80211_TX_RC_MCS)))
+                       ampdu = false;
+
+               /*
+                * Assume that HT/VHT transmission on any AC except VO will
+                * use aggregation. Since we don't have reliable reporting
+                * of aggregation length, assume an average of 16.
+                * This will not be very accurate, but much better than simply
+                * assuming un-aggregated tx.
+                */
+               airtime = ieee80211_calc_tx_airtime_rate(hw, rate, band,
+                                                        ampdu ? len * 16 : len);
+               if (ampdu)
+                       airtime /= 16;
+
+               return airtime;
        }
 
        if (!conf)
index 9b36054..24e9e00 100644 (file)
@@ -608,12 +608,12 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
        case WLAN_CIPHER_SUITE_BIP_CMAC_256:
                BUILD_BUG_ON(offsetof(typeof(kseq), ccmp) !=
                             offsetof(typeof(kseq), aes_cmac));
-               /* fall through */
+               fallthrough;
        case WLAN_CIPHER_SUITE_BIP_GMAC_128:
        case WLAN_CIPHER_SUITE_BIP_GMAC_256:
                BUILD_BUG_ON(offsetof(typeof(kseq), ccmp) !=
                             offsetof(typeof(kseq), aes_gmac));
-               /* fall through */
+               fallthrough;
        case WLAN_CIPHER_SUITE_GCMP:
        case WLAN_CIPHER_SUITE_GCMP_256:
                BUILD_BUG_ON(offsetof(typeof(kseq), ccmp) !=
@@ -991,9 +991,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
                      BSS_CHANGED_SSID |
                      BSS_CHANGED_P2P_PS |
                      BSS_CHANGED_TXPOWER |
-                     BSS_CHANGED_TWT |
-                     BSS_CHANGED_HE_OBSS_PD |
-                     BSS_CHANGED_HE_BSS_COLOR;
+                     BSS_CHANGED_TWT;
        int i, err;
        int prev_beacon_int;
 
@@ -1019,6 +1017,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
                sdata->vif.bss_conf.frame_time_rts_th =
                        le32_get_bits(params->he_oper->he_oper_params,
                              IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
+               changed |= BSS_CHANGED_HE_OBSS_PD;
+
+               if (params->he_bss_color.enabled)
+                       changed |= BSS_CHANGED_HE_BSS_COLOR;
        }
 
        mutex_lock(&local->mtx);
@@ -2126,6 +2128,11 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
        if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask))
                conf->dot11MeshConnectedToMeshGate =
                        nconf->dot11MeshConnectedToMeshGate;
+       if (_chg_mesh_attr(NL80211_MESHCONF_NOLEARN, mask))
+               conf->dot11MeshNolearn = nconf->dot11MeshNolearn;
+       if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_AS, mask))
+               conf->dot11MeshConnectedToAuthServer =
+                       nconf->dot11MeshConnectedToAuthServer;
        ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
        return 0;
 }
@@ -2336,7 +2343,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
                 * for now fall through to allow scanning only when
                 * beaconing hasn't been configured yet
                 */
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
                /*
                 * If the scan has been forced (and the driver supports
@@ -3583,7 +3590,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
        }
 
        local_bh_disable();
-       ieee80211_xmit(sdata, sta, skb, 0);
+       ieee80211_xmit(sdata, sta, skb);
        local_bh_enable();
 
        ret = 0;
index e6e192f..bdc0f29 100644 (file)
@@ -313,9 +313,14 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 
        lockdep_assert_held(&local->chanctx_mtx);
 
-       /* don't optimize 5MHz, 10MHz, and radar_enabled confs */
+       /* don't optimize non-20MHz based and radar_enabled confs */
        if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
            ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
            ctx->conf.radar_enabled) {
                ctx->conf.min_def = ctx->conf.def;
                return;
@@ -743,7 +748,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
                default:
                        WARN_ONCE(1, "Invalid SMPS mode %d\n",
                                  sdata->smps_mode);
-                       /* fall through */
+                       fallthrough;
                case IEEE80211_SMPS_OFF:
                        needed_static = sdata->needed_rx_chains;
                        needed_dynamic = sdata->needed_rx_chains;
index d7e9551..fe8a7a8 100644 (file)
@@ -638,6 +638,9 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
                  u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC);
 IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate,
                  u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC);
+IEEE80211_IF_FILE(dot11MeshNolearn, u.mesh.mshcfg.dot11MeshNolearn, DEC);
+IEEE80211_IF_FILE(dot11MeshConnectedToAuthServer,
+                 u.mesh.mshcfg.dot11MeshConnectedToAuthServer, DEC);
 #endif
 
 #define DEBUGFS_ADD_MODE(name, mode) \
@@ -762,6 +765,8 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
        MESHPARAMS_ADD(power_mode);
        MESHPARAMS_ADD(dot11MeshAwakeWindowDuration);
        MESHPARAMS_ADD(dot11MeshConnectedToMeshGate);
+       MESHPARAMS_ADD(dot11MeshNolearn);
+       MESHPARAMS_ADD(dot11MeshConnectedToAuthServer);
 #undef MESHPARAMS_ADD
 }
 #endif
index de69fc9..41d495d 100644 (file)
 #include "ieee80211_i.h"
 #include "trace.h"
 
-static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
-{
-       return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),
-                    "%s:  Failed check-sdata-in-driver check, flags: 0x%x\n",
-                    sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);
-}
+#define check_sdata_in_driver(sdata)   ({                                      \
+       !WARN_ONCE(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),                 \
+                  "%s: Failed check-sdata-in-driver check, flags: 0x%x\n",     \
+                  sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);  \
+})
 
 static inline struct ieee80211_sub_if_data *
 get_bss_sdata(struct ieee80211_sub_if_data *sdata)
index e329062..3d62a80 100644 (file)
@@ -250,7 +250,7 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
        switch (sdata->vif.bss_conf.chandef.width) {
        default:
                WARN_ON_ONCE(1);
-               /* fall through */
+               fallthrough;
        case NL80211_CHAN_WIDTH_20_NOHT:
        case NL80211_CHAN_WIDTH_20:
                bw = IEEE80211_STA_RX_BW_20;
@@ -517,7 +517,7 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
        case IEEE80211_SMPS_AUTOMATIC:
        case IEEE80211_SMPS_NUM_MODES:
                WARN_ON(1);
-               /* fall through */
+               fallthrough;
        case IEEE80211_SMPS_OFF:
                action_frame->u.action.u.ht_smps.smps_control =
                                WLAN_HT_SMPS_CONTROL_DISABLED;
index 81d26fe..53632c2 100644 (file)
@@ -791,7 +791,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        case NL80211_CHAN_WIDTH_10:
        case NL80211_CHAN_WIDTH_20_NOHT:
                sta_flags |= IEEE80211_STA_DISABLE_HT;
-               /* fall through */
+               fallthrough;
        case NL80211_CHAN_WIDTH_20:
                sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
                break;
@@ -1401,7 +1401,7 @@ ieee80211_ibss_setup_scan_channels(struct wiphy *wiphy,
                break;
        case NL80211_CHAN_WIDTH_80P80:
                cf2 = chandef->center_freq2;
-               /* fall through */
+               fallthrough;
        case NL80211_CHAN_WIDTH_80:
                width = 80;
                break;
index ec1a71a..0b1eaec 100644 (file)
@@ -164,7 +164,6 @@ typedef unsigned __bitwise ieee80211_tx_result;
 #define TX_DROP                ((__force ieee80211_tx_result) 1u)
 #define TX_QUEUED      ((__force ieee80211_tx_result) 2u)
 
-#define IEEE80211_TX_NO_SEQNO          BIT(0)
 #define IEEE80211_TX_UNICAST           BIT(1)
 #define IEEE80211_TX_PS_BUFFERED       BIT(2)
 
@@ -218,7 +217,7 @@ enum ieee80211_rx_flags {
 };
 
 struct ieee80211_rx_data {
-       struct napi_struct *napi;
+       struct list_head *list;
        struct sk_buff *skb;
        struct ieee80211_local *local;
        struct ieee80211_sub_if_data *sdata;
@@ -1967,12 +1966,11 @@ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
                               bool bss_notify, bool enable_qos);
 void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
-                   struct sta_info *sta, struct sk_buff *skb,
-                   u32 txdata_flags);
+                   struct sta_info *sta, struct sk_buff *skb);
 
 void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
                                 struct sk_buff *skb, int tid,
-                                enum nl80211_band band, u32 txdata_flags);
+                                enum nl80211_band band);
 
 /* sta_out needs to be checked for ERR_PTR() before using */
 int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
@@ -1982,10 +1980,10 @@ int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
 static inline void
 ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
                          struct sk_buff *skb, int tid,
-                         enum nl80211_band band, u32 txdata_flags)
+                         enum nl80211_band band)
 {
        rcu_read_lock();
-       __ieee80211_tx_skb_tid_band(sdata, skb, tid, band, txdata_flags);
+       __ieee80211_tx_skb_tid_band(sdata, skb, tid, band);
        rcu_read_unlock();
 }
 
@@ -2003,7 +2001,7 @@ static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
        }
 
        __ieee80211_tx_skb_tid_band(sdata, skb, tid,
-                                   chanctx_conf->def.chan->band, 0);
+                                   chanctx_conf->def.chan->band);
        rcu_read_unlock();
 }
 
@@ -2290,7 +2288,7 @@ extern const struct ethtool_ops ieee80211_ethtool_ops;
 u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
                                       struct ieee80211_sta *pubsta,
-                                      int len);
+                                      int len, bool ampdu);
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
 #else
index f900c84..9740ae8 100644 (file)
@@ -978,7 +978,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        case NL80211_IFTYPE_P2P_DEVICE:
                /* relies on synchronize_rcu() below */
                RCU_INIT_POINTER(local->p2p_sdata, NULL);
-               /* fall through */
+               fallthrough;
        default:
                cancel_work_sync(&sdata->work);
                /*
@@ -1048,7 +1048,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
                        break;
 
-               /* fall through */
+               fallthrough;
        default:
                if (going_down)
                        drv_remove_interface(local, sdata);
@@ -1183,17 +1183,24 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr;
-       struct ieee80211_radiotap_header *rtap = (void *)skb->data;
+       int len_rthdr;
 
        if (local->hw.queues < IEEE80211_NUM_ACS)
                return 0;
 
-       if (skb->len < 4 ||
-           skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */)
+       /* reset flags and info before parsing radiotap header */
+       memset(info, 0, sizeof(*info));
+
+       if (!ieee80211_parse_tx_radiotap(skb, dev))
                return 0; /* doesn't matter, frame will be dropped */
 
-       hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
+       len_rthdr = ieee80211_get_radiotap_len(skb->data);
+       hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
+       if (skb->len < len_rthdr + 2 ||
+           skb->len < len_rthdr + ieee80211_hdrlen(hdr->frame_control))
+               return 0; /* doesn't matter, frame will be dropped */
 
        return ieee80211_select_queue_80211(sdata, skb, hdr);
 }
@@ -1497,7 +1504,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
                type = NL80211_IFTYPE_AP;
                sdata->vif.type = type;
                sdata->vif.p2p = true;
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
                skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
                INIT_LIST_HEAD(&sdata->u.ap.vlans);
@@ -1507,7 +1514,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
                type = NL80211_IFTYPE_STATION;
                sdata->vif.type = type;
                sdata->vif.p2p = true;
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_STATION:
                sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
                ieee80211_sta_setup_sdata(sdata);
@@ -1703,7 +1710,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
                                goto out_unlock;
                        }
                }
-               /* fall through */
+               fallthrough;
        default:
                /* assign a new address if possible -- try n_addresses first */
                for (i = 0; i < local->hw.wiphy->n_addresses; i++) {
index 8f403c1..9c28880 100644 (file)
@@ -225,7 +225,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
                 */
                if (sdata->hw_80211_encap)
                        return -EINVAL;
-               /* Fall through */
+               fallthrough;
 
        case WLAN_CIPHER_SUITE_AES_CMAC:
        case WLAN_CIPHER_SUITE_BIP_CMAC_256:
index 5f1ca25..d0db6af 100644 (file)
@@ -260,6 +260,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
        bool is_connected_to_gate = ifmsh->num_gates > 0 ||
                ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol ||
                ifmsh->mshcfg.dot11MeshConnectedToMeshGate;
+       bool is_connected_to_as = ifmsh->mshcfg.dot11MeshConnectedToAuthServer;
 
        if (skb_tailroom(skb) < 2 + meshconf_len)
                return -ENOMEM;
@@ -284,7 +285,9 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
        /* Mesh Formation Info - number of neighbors */
        neighbors = atomic_read(&ifmsh->estab_plinks);
        neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS);
-       *pos++ = (neighbors << 1) | is_connected_to_gate;
+       *pos++ = (is_connected_to_as << 7) |
+                (neighbors << 1) |
+                is_connected_to_gate;
        /* Mesh capability */
        *pos = 0x00;
        *pos |= ifmsh->mshcfg.dot11MeshForwarding ?
@@ -1094,10 +1097,10 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
        switch (sdata->vif.bss_conf.chandef.width) {
        case NL80211_CHAN_WIDTH_20_NOHT:
                sta_flags |= IEEE80211_STA_DISABLE_HT;
-               /* fall through */
+               fallthrough;
        case NL80211_CHAN_WIDTH_20:
                sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
-               /* fall through */
+               fallthrough;
        case NL80211_CHAN_WIDTH_40:
                sta_flags |= IEEE80211_STA_DISABLE_VHT;
                break;
index 02cde0f..bec23d2 100644 (file)
@@ -1172,6 +1172,40 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
        return -ENOENT;
 }
 
+/**
+ * mesh_nexthop_lookup_nolearn - try to set next hop without path discovery
+ * @skb: 802.11 frame to be sent
+ * @sdata: network subif the frame will be sent through
+ *
+ * Check if the meshDA (addr3) of a unicast frame is a direct neighbor.
+ * And if so, set the RA (addr1) to it to transmit to this node directly,
+ * avoiding PREQ/PREP path discovery.
+ *
+ * Returns: 0 if the next hop was found and -ENOENT otherwise.
+ */
+static int mesh_nexthop_lookup_nolearn(struct ieee80211_sub_if_data *sdata,
+                                      struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct sta_info *sta;
+
+       if (is_multicast_ether_addr(hdr->addr1))
+               return -ENOENT;
+
+       rcu_read_lock();
+       sta = sta_info_get(sdata, hdr->addr3);
+
+       if (!sta || sta->mesh->plink_state != NL80211_PLINK_ESTAB) {
+               rcu_read_unlock();
+               return -ENOENT;
+       }
+       rcu_read_unlock();
+
+       memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
+       memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
+       return 0;
+}
+
 /**
  * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
  * this function is considered "using" the associated mpath, so preempt a path
@@ -1185,11 +1219,16 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
 int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
                        struct sk_buff *skb)
 {
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
        struct mesh_path *mpath;
        struct sta_info *next_hop;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        u8 *target_addr = hdr->addr3;
 
+       if (ifmsh->mshcfg.dot11MeshNolearn &&
+           !mesh_nexthop_lookup_nolearn(sdata, skb))
+               return 0;
+
        mpath = mesh_path_lookup(sdata, target_addr);
        if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
                return -ENOENT;
@@ -1266,7 +1305,7 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
                break;
        case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
                flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
-               /* fall through */
+               fallthrough;
        case IEEE80211_PROACTIVE_PREQ_NO_PREP:
                interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
                target_flags |= IEEE80211_PREQ_TO_FLAG |
index 798e4b6..15f2fc6 100644 (file)
@@ -699,7 +699,7 @@ void mesh_plink_timer(struct timer_list *t)
                        break;
                }
                reason = WLAN_REASON_MESH_MAX_RETRIES;
-               /* fall through */
+               fallthrough;
        case NL80211_PLINK_CNF_RCVD:
                /* confirm timer */
                if (!reason)
index b2a9d47..839d036 100644 (file)
@@ -533,7 +533,7 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
        case IEEE80211_SMPS_AUTOMATIC:
        case IEEE80211_SMPS_NUM_MODES:
                WARN_ON(1);
-               /* fall through */
+               fallthrough;
        case IEEE80211_SMPS_OFF:
                cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
                        IEEE80211_HT_CAP_SM_PS_SHIFT;
@@ -1529,7 +1529,7 @@ ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata,
        switch (channel->band) {
        default:
                WARN_ON_ONCE(1);
-               /* fall through */
+               fallthrough;
        case NL80211_BAND_2GHZ:
        case NL80211_BAND_60GHZ:
                chan_increment = 1;
@@ -3460,10 +3460,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                bss_conf->he_bss_color.partial =
                        le32_get_bits(elems->he_operation->he_oper_params,
                                      IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR);
-               bss_conf->he_bss_color.disabled =
-                       le32_get_bits(elems->he_operation->he_oper_params,
-                                     IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
-               changed |= BSS_CHANGED_HE_BSS_COLOR;
+               bss_conf->he_bss_color.enabled =
+                       !le32_get_bits(elems->he_operation->he_oper_params,
+                                      IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
+
+               if (bss_conf->he_bss_color.enabled)
+                       changed |= BSS_CHANGED_HE_BSS_COLOR;
 
                bss_conf->htc_trig_based_pkt_ext =
                        le32_get_bits(elems->he_operation->he_oper_params,
index db3b8bf..f470d1a 100644 (file)
@@ -264,7 +264,7 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
        if (roc->mgmt_tx_cookie) {
                if (!WARN_ON(!roc->frame)) {
                        ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7,
-                                                 roc->chan->band, 0);
+                                                 roc->chan->band);
                        roc->frame = NULL;
                }
        } else {
@@ -808,13 +808,13 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                if (!sdata->vif.bss_conf.ibss_joined)
                        need_offchan = true;
 #ifdef CONFIG_MAC80211_MESH
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_MESH_POINT:
                if (ieee80211_vif_is_mesh(&sdata->vif) &&
                    !sdata->u.mesh.mesh_id_len)
                        need_offchan = true;
 #endif
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
        case NL80211_IFTYPE_P2P_GO:
index 5c5af4b..836cde5 100644 (file)
@@ -2578,8 +2578,8 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
                memset(skb->cb, 0, sizeof(skb->cb));
 
                /* deliver to local stack */
-               if (rx->napi)
-                       napi_gro_receive(rx->napi, skb);
+               if (rx->list)
+                       list_add_tail(&skb->list, rx->list);
                else
                        netif_receive_skb(skb);
        }
@@ -3591,7 +3591,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
                }
 
                __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7,
-                                           status->band, 0);
+                                           status->band);
        }
        dev_kfree_skb(rx->skb);
        return RX_QUEUED;
@@ -3736,7 +3736,7 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
                I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop);
                if (rx->sta)
                        rx->sta->rx_stats.dropped++;
-               /* fall through */
+               fallthrough;
        case RX_CONTINUE: {
                struct ieee80211_rate *rate = NULL;
                struct ieee80211_supported_band *sband;
@@ -3869,7 +3869,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
                /* This is OK -- must be QoS data frame */
                .security_idx = tid,
                .seqno_idx = tid,
-               .napi = NULL, /* must be NULL to not have races */
        };
        struct tid_ampdu_rx *tid_agg_rx;
 
@@ -4479,8 +4478,8 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
        /* deliver to local stack */
        skb->protocol = eth_type_trans(skb, fast_rx->dev);
        memset(skb->cb, 0, sizeof(skb->cb));
-       if (rx->napi)
-               napi_gro_receive(rx->napi, skb);
+       if (rx->list)
+               list_add_tail(&skb->list, rx->list);
        else
                netif_receive_skb(skb);
 
@@ -4547,7 +4546,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                                         struct ieee80211_sta *pubsta,
                                         struct sk_buff *skb,
-                                        struct napi_struct *napi)
+                                        struct list_head *list)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata;
@@ -4562,7 +4561,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
        memset(&rx, 0, sizeof(rx));
        rx.skb = skb;
        rx.local = local;
-       rx.napi = napi;
+       rx.list = list;
 
        if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
                I802_DEBUG_INC(local->dot11ReceivedFragmentCount);
@@ -4670,8 +4669,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
  * This is the receive path handler. It is called by a low level driver when an
  * 802.11 MPDU is received from the hardware.
  */
-void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
-                      struct sk_buff *skb, struct napi_struct *napi)
+void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+                      struct sk_buff *skb, struct list_head *list)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rate *rate = NULL;
@@ -4752,7 +4751,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
                        break;
                default:
                        WARN_ON_ONCE(1);
-                       /* fall through */
+                       fallthrough;
                case RX_ENC_LEGACY:
                        if (WARN_ON(status->rate_idx >= sband->n_bitrates))
                                goto drop;
@@ -4762,13 +4761,6 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
 
        status->rx_flags = 0;
 
-       /*
-        * key references and virtual interfaces are protected using RCU
-        * and this requires that we are in a read-side RCU section during
-        * receive processing
-        */
-       rcu_read_lock();
-
        /*
         * Frames with failed FCS/PLCP checksum are not returned,
         * all other frames are returned without radiotap header
@@ -4776,23 +4768,47 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
         * Also, frames with less than 16 bytes are dropped.
         */
        skb = ieee80211_rx_monitor(local, skb, rate);
-       if (!skb) {
-               rcu_read_unlock();
+       if (!skb)
                return;
-       }
 
        ieee80211_tpt_led_trig_rx(local,
                        ((struct ieee80211_hdr *)skb->data)->frame_control,
                        skb->len);
 
-       __ieee80211_rx_handle_packet(hw, pubsta, skb, napi);
-
-       rcu_read_unlock();
+       __ieee80211_rx_handle_packet(hw, pubsta, skb, list);
 
        return;
  drop:
        kfree_skb(skb);
 }
+EXPORT_SYMBOL(ieee80211_rx_list);
+
+void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
+                      struct sk_buff *skb, struct napi_struct *napi)
+{
+       struct sk_buff *tmp;
+       LIST_HEAD(list);
+
+
+       /*
+        * key references and virtual interfaces are protected using RCU
+        * and this requires that we are in a read-side RCU section during
+        * receive processing
+        */
+       rcu_read_lock();
+       ieee80211_rx_list(hw, pubsta, skb, &list);
+       rcu_read_unlock();
+
+       if (!napi) {
+               netif_receive_skb_list(&list);
+               return;
+       }
+
+       list_for_each_entry_safe(skb, tmp, &list, list) {
+               skb_list_del_init(skb);
+               napi_gro_receive(napi, skb);
+       }
+}
 EXPORT_SYMBOL(ieee80211_rx_napi);
 
 /* This is a version of the rx handler that can be called from hard irq
index ad90bbe..5ac2785 100644 (file)
@@ -591,7 +591,6 @@ static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata,
                                          struct ieee80211_channel *channel)
 {
        struct sk_buff *skb;
-       u32 txdata_flags = 0;
 
        skb = ieee80211_build_probe_req(sdata, src, dst, ratemask, channel,
                                        ssid, ssid_len,
@@ -600,15 +599,15 @@ static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata,
        if (skb) {
                if (flags & IEEE80211_PROBE_FLAG_RANDOM_SN) {
                        struct ieee80211_hdr *hdr = (void *)skb->data;
+                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
                        u16 sn = get_random_u32();
 
-                       txdata_flags |= IEEE80211_TX_NO_SEQNO;
+                       info->control.flags |= IEEE80211_TX_CTRL_NO_SEQNO;
                        hdr->seq_ctrl =
                                cpu_to_le16(IEEE80211_SN_TO_SEQ(sn));
                }
                IEEE80211_SKB_CB(skb)->flags |= tx_flags;
-               ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band,
-                                         txdata_flags);
+               ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band);
        }
 }
 
@@ -913,6 +912,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
        case NL80211_BSS_CHAN_WIDTH_10:
                local->scan_chandef.width = NL80211_CHAN_WIDTH_10;
                break;
+       default:
        case NL80211_BSS_CHAN_WIDTH_20:
                /* If scanning on oper channel, use whatever channel-type
                 * is currently in use.
index cd8487b..bf9abfa 100644 (file)
@@ -1455,7 +1455,7 @@ static void ieee80211_send_null_response(struct sta_info *sta, int tid,
        }
 
        info->band = chanctx_conf->def.chan->band;
-       ieee80211_xmit(sdata, sta, skb, 0);
+       ieee80211_xmit(sdata, sta, skb);
        rcu_read_unlock();
 }
 
@@ -2426,7 +2426,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
                                 BIT_ULL(NL80211_STA_INFO_LOCAL_PM) |
                                 BIT_ULL(NL80211_STA_INFO_PEER_PM) |
                                 BIT_ULL(NL80211_STA_INFO_NONPEER_PM) |
-                                BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE);
+                                BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE) |
+                                BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_AS);
 
                sinfo->llid = sta->mesh->llid;
                sinfo->plid = sta->mesh->plid;
@@ -2439,6 +2440,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
                sinfo->peer_pm = sta->mesh->peer_pm;
                sinfo->nonpeer_pm = sta->mesh->nonpeer_pm;
                sinfo->connected_to_gate = sta->mesh->connected_to_gate;
+               sinfo->connected_to_as = sta->mesh->connected_to_as;
 #endif
        }
 
index 4972804..9d398c9 100644 (file)
@@ -385,6 +385,7 @@ DECLARE_EWMA(mesh_tx_rate_avg, 8, 16)
  * @processed_beacon: set to true after peer rates and capabilities are
  *     processed
  * @connected_to_gate: true if mesh STA has a path to a mesh gate
+ * @connected_to_as: true if mesh STA has a path to a authentication server
  * @fail_avg: moving percentage of failed MSDUs
  * @tx_rate_avg: moving average of tx bitrate
  */
@@ -404,6 +405,7 @@ struct mesh_sta {
 
        bool processed_beacon;
        bool connected_to_gate;
+       bool connected_to_as;
 
        enum nl80211_plink_state plink_state;
        u32 plink_timeout;
index cbc40b3..adb1d30 100644 (file)
@@ -799,7 +799,6 @@ static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
                                  struct ieee80211_tx_info *info,
                                  int *retry_count)
 {
-       int rates_idx = -1;
        int count = -1;
        int i;
 
@@ -821,13 +820,12 @@ static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
 
                count += info->status.rates[i].count;
        }
-       rates_idx = i - 1;
 
        if (count < 0)
                count = 0;
 
        *retry_count = count;
-       return rates_idx;
+       return i - 1;
 }
 
 void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
index 4b0cff4..e01e4da 100644 (file)
@@ -239,7 +239,7 @@ static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac)
        switch (ac) {
        default:
                WARN_ON_ONCE(1);
-               /* fall through */
+               fallthrough;
        case 0:
                return IEEE80211_AC_BE;
        case 1:
@@ -952,7 +952,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
                        set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
                        sta->sta.tdls_initiator = false;
                }
-               /* fall-through */
+               fallthrough;
        case WLAN_TDLS_SETUP_CONFIRM:
        case WLAN_TDLS_DISCOVERY_REQUEST:
                initiator = true;
@@ -967,7 +967,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
                        clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
                        sta->sta.tdls_initiator = true;
                }
-               /* fall-through */
+               fallthrough;
        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
                initiator = false;
                break;
@@ -1222,7 +1222,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
                 * by the AP.
                 */
                drv_mgd_protect_tdls_discover(sdata->local, sdata);
-               /* fall-through */
+               fallthrough;
        case WLAN_TDLS_SETUP_CONFIRM:
        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
                /* no special handling */
index 1a2941e..ec35a92 100644 (file)
@@ -166,6 +166,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                        if (r->flags & IEEE80211_RATE_MANDATORY_A)
                                mrate = r->bitrate;
                        break;
+               case NL80211_BAND_S1GHZ:
                case NL80211_BAND_60GHZ:
                        /* TODO, for now fall through */
                case NUM_NL80211_BANDS:
@@ -824,6 +825,9 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
        if (ieee80211_is_qos_nullfunc(hdr->frame_control))
                return TX_CONTINUE;
 
+       if (info->control.flags & IEEE80211_TX_CTRL_NO_SEQNO)
+               return TX_CONTINUE;
+
        /*
         * Anything but QoS data that has a sequence number field
         * (is long enough) gets a sequence number from the global
@@ -832,8 +836,6 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
         */
        if (!ieee80211_is_data_qos(hdr->frame_control) ||
            is_multicast_ether_addr(hdr->addr1)) {
-               if (tx->flags & IEEE80211_TX_NO_SEQNO)
-                       return TX_CONTINUE;
                /* driver should assign sequence number */
                info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
                /* for pure STA mode without beacons, we can do it */
@@ -1739,7 +1741,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
        case NL80211_IFTYPE_AP_VLAN:
                sdata = container_of(sdata->bss,
                                     struct ieee80211_sub_if_data, u.ap);
-               /* fall through */
+               fallthrough;
        default:
                vif = &sdata->vif;
                break;
@@ -1890,7 +1892,7 @@ EXPORT_SYMBOL(ieee80211_tx_prepare_skb);
  */
 static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
                         struct sta_info *sta, struct sk_buff *skb,
-                        bool txpending, u32 txdata_flags)
+                        bool txpending)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_data tx;
@@ -1908,8 +1910,6 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
        led_len = skb->len;
        res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb);
 
-       tx.flags |= txdata_flags;
-
        if (unlikely(res_prepare == TX_DROP)) {
                ieee80211_free_txskb(&local->hw, skb);
                return true;
@@ -1977,8 +1977,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
 }
 
 void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
-                   struct sta_info *sta, struct sk_buff *skb,
-                   u32 txdata_flags)
+                   struct sta_info *sta, struct sk_buff *skb)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -2013,12 +2012,13 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
        }
 
        ieee80211_set_qos_hdr(sdata, skb);
-       ieee80211_tx(sdata, sta, skb, false, txdata_flags);
+       ieee80211_tx(sdata, sta, skb, false);
 }
 
-static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
-                                       struct sk_buff *skb)
+bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
+                                struct net_device *dev)
 {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_radiotap_iterator iterator;
        struct ieee80211_radiotap_header *rthdr =
                (struct ieee80211_radiotap_header *) skb->data;
@@ -2037,6 +2037,18 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
        u8 vht_mcs = 0, vht_nss = 0;
        int i;
 
+       /* check for not even having the fixed radiotap header part */
+       if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
+               return false; /* too short to be possibly valid */
+
+       /* is it a header version we can trust to find length from? */
+       if (unlikely(rthdr->it_version))
+               return false; /* only version 0 is supported */
+
+       /* does the skb contain enough to deliver on the alleged length? */
+       if (unlikely(skb->len < ieee80211_get_radiotap_len(skb->data)))
+               return false; /* skb too short for claimed rt header extent */
+
        info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
                       IEEE80211_TX_CTL_DONTFRAG;
 
@@ -2084,6 +2096,8 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
                        txflags = get_unaligned_le16(iterator.this_arg);
                        if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
                                info->flags |= IEEE80211_TX_CTL_NO_ACK;
+                       if (txflags & IEEE80211_RADIOTAP_F_TX_NOSEQNO)
+                               info->control.flags |= IEEE80211_TX_CTRL_NO_SEQNO;
                        break;
 
                case IEEE80211_RADIOTAP_RATE:
@@ -2188,13 +2202,6 @@ static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
                                                     local->hw.max_rate_tries);
        }
 
-       /*
-        * remove the radiotap header
-        * iterator->_max_length was sanity-checked against
-        * skb->len by iterator init
-        */
-       skb_pull(skb, iterator._max_length);
-
        return true;
 }
 
@@ -2203,8 +2210,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_chanctx_conf *chanctx_conf;
-       struct ieee80211_radiotap_header *prthdr =
-               (struct ieee80211_radiotap_header *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr;
        struct ieee80211_sub_if_data *tmp_sdata, *sdata;
@@ -2212,21 +2217,17 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
        u16 len_rthdr;
        int hdrlen;
 
-       /* check for not even having the fixed radiotap header part */
-       if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
-               goto fail; /* too short to be possibly valid */
+       memset(info, 0, sizeof(*info));
+       info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
+                     IEEE80211_TX_CTL_INJECTED;
 
-       /* is it a header version we can trust to find length from? */
-       if (unlikely(prthdr->it_version))
-               goto fail; /* only version 0 is supported */
+       /* Sanity-check and process the injection radiotap header */
+       if (!ieee80211_parse_tx_radiotap(skb, dev))
+               goto fail;
 
-       /* then there must be a radiotap header with a length we can use */
+       /* we now know there is a radiotap header with a length we can use */
        len_rthdr = ieee80211_get_radiotap_len(skb->data);
 
-       /* does the skb contain enough to deliver on the alleged length? */
-       if (unlikely(skb->len < len_rthdr))
-               goto fail; /* skb too short for claimed rt header extent */
-
        /*
         * fix up the pointers accounting for the radiotap
         * header still being in there.  We are being given
@@ -2272,11 +2273,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
                skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
        }
 
-       memset(info, 0, sizeof(*info));
-
-       info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
-                     IEEE80211_TX_CTL_INJECTED;
-
        rcu_read_lock();
 
        /*
@@ -2342,11 +2338,10 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
 
        info->band = chandef->chan->band;
 
-       /* process and remove the injection radiotap header */
-       if (!ieee80211_parse_tx_radiotap(local, skb))
-               goto fail_rcu;
+       /* remove the injection radiotap header */
+       skb_pull(skb, len_rthdr);
 
-       ieee80211_xmit(sdata, NULL, skb, 0);
+       ieee80211_xmit(sdata, NULL, skb);
        rcu_read_unlock();
 
        return NETDEV_TX_OK;
@@ -2382,7 +2377,7 @@ int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
                } else if (sdata->wdev.use_4addr) {
                        return -ENOLINK;
                }
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_OCB:
        case NL80211_IFTYPE_ADHOC:
@@ -2552,7 +2547,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
                band = chanctx_conf->def.chan->band;
                if (sdata->wdev.use_4addr)
                        break;
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
                if (sdata->vif.type == NL80211_IFTYPE_AP)
                        chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
@@ -2999,7 +2994,7 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
                        build.hdr_len = 30;
                        break;
                }
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
                fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
                /* DA BSSID SA */
@@ -3618,7 +3613,7 @@ begin:
        tx.skb = skb;
        tx.sdata = vif_to_sdata(info->control.vif);
 
-       if (txq->sta) {
+       if (txq->sta && !(info->flags & IEEE80211_TX_CTL_INJECTED)) {
                tx.sta = container_of(txq->sta, struct sta_info, sta);
                /*
                 * Drop unicast frames to unauthorised stations unless they are
@@ -3710,7 +3705,7 @@ begin:
        case NL80211_IFTYPE_AP_VLAN:
                tx.sdata = container_of(tx.sdata->bss,
                                        struct ieee80211_sub_if_data, u.ap);
-               /* fall through */
+               fallthrough;
        default:
                vif = &tx.sdata->vif;
                break;
@@ -3721,10 +3716,11 @@ encap_out:
 
        if (vif &&
            wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
+               bool ampdu = txq->ac != IEEE80211_AC_VO;
                u32 airtime;
 
                airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
-                                                            skb->len);
+                                                            skb->len, ampdu);
                if (airtime) {
                        airtime = ieee80211_info_set_tx_time_est(info, airtime);
                        ieee80211_sta_update_pending_airtime(local, tx.sta,
@@ -3950,6 +3946,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
        if (local->ops->wake_tx_queue) {
                u16 queue = __ieee80211_select_queue(sdata, sta, skb);
                skb_set_queue_mapping(skb, queue);
+               skb_get_hash(skb);
        }
 
        if (sta) {
@@ -4008,7 +4005,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 
                ieee80211_tx_stats(dev, skb->len);
 
-               ieee80211_xmit(sdata, sta, skb, 0);
+               ieee80211_xmit(sdata, sta, skb);
        }
        goto out;
  out_free:
@@ -4049,7 +4046,7 @@ static bool ieee80211_multicast_to_unicast(struct sk_buff *skb,
                        return false;
                if (sdata->wdev.use_4addr)
                        return false;
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
                /* check runtime toggle for this bss */
                if (!sdata->bss->multicast_to_unicast)
@@ -4374,7 +4371,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
                        return true;
                }
                info->band = chanctx_conf->def.chan->band;
-               result = ieee80211_tx(sdata, NULL, skb, true, 0);
+               result = ieee80211_tx(sdata, NULL, skb, true);
        } else if (info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP) {
                if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
                        dev_kfree_skb(skb);
@@ -5333,7 +5330,7 @@ EXPORT_SYMBOL(ieee80211_unreserve_tid);
 
 void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
                                 struct sk_buff *skb, int tid,
-                                enum nl80211_band band, u32 txdata_flags)
+                                enum nl80211_band band)
 {
        int ac = ieee80211_ac_from_tid(tid);
 
@@ -5350,7 +5347,7 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
         */
        local_bh_disable();
        IEEE80211_SKB_CB(skb)->band = band;
-       ieee80211_xmit(sdata, NULL, skb, txdata_flags);
+       ieee80211_xmit(sdata, NULL, skb);
        local_bh_enable();
 }
 
index 21c9409..b768ebd 100644 (file)
@@ -2347,10 +2347,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                case NL80211_IFTYPE_ADHOC:
                        if (sdata->vif.bss_conf.ibss_joined)
                                WARN_ON(drv_join_ibss(local, sdata));
-                       /* fall through */
+                       fallthrough;
                default:
                        ieee80211_reconfig_stations(sdata);
-                       /* fall through */
+                       fallthrough;
                case NL80211_IFTYPE_AP: /* AP stations are handled later */
                        for (i = 0; i < IEEE80211_NUM_ACS; i++)
                                drv_conf_tx(local, sdata, i,
@@ -2399,7 +2399,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                        break;
                case NL80211_IFTYPE_ADHOC:
                        changed |= BSS_CHANGED_IBSS;
-                       /* fall through */
+                       fallthrough;
                case NL80211_IFTYPE_AP:
                        changed |= BSS_CHANGED_SSID | BSS_CHANGED_P2P_PS;
 
@@ -2414,8 +2414,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                if (rcu_access_pointer(sdata->u.ap.beacon))
                                        drv_start_ap(local, sdata);
                        }
-
-                       /* fall through */
+                       fallthrough;
                case NL80211_IFTYPE_MESH_POINT:
                        if (sdata->vif.bss_conf.enable_beacon) {
                                changed |= BSS_CHANGED_BEACON |
@@ -2885,7 +2884,7 @@ void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
        case IEEE80211_SMPS_AUTOMATIC:
        case IEEE80211_SMPS_NUM_MODES:
                WARN_ON(1);
-               /* fall through */
+               fallthrough;
        case IEEE80211_SMPS_OFF:
                cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED,
                                       IEEE80211_HE_6GHZ_CAP_SM_PS);
@@ -3196,7 +3195,7 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, u32 vht_cap_info,
                break;
        case 0x01:
                support_80_80 = false;
-               /* fall through */
+               fallthrough;
        case 0x02:
        case 0x03:
                ccf1 = ccfs2;
@@ -3566,7 +3565,7 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
                break;
        default:
                WARN_ON(1);
-               /* fall through */
+               fallthrough;
        case RX_ENC_LEGACY: {
                struct ieee80211_supported_band *sband;
                int shift = 0;
@@ -3730,6 +3729,11 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
                c->width = NL80211_CHAN_WIDTH_20_NOHT;
                ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
                break;
+       case NL80211_CHAN_WIDTH_1:
+       case NL80211_CHAN_WIDTH_2:
+       case NL80211_CHAN_WIDTH_4:
+       case NL80211_CHAN_WIDTH_8:
+       case NL80211_CHAN_WIDTH_16:
        case NL80211_CHAN_WIDTH_5:
        case NL80211_CHAN_WIDTH_10:
                WARN_ON_ONCE(1);
index 72920d8..2fb9932 100644 (file)
@@ -198,7 +198,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
                sta = rcu_dereference(sdata->u.vlan.sta);
                if (sta)
                        break;
-               /* fall through */
+               fallthrough;
        case NL80211_IFTYPE_AP:
                ra = skb->data;
                break;
index cddf92c..90f0f82 100644 (file)
@@ -153,6 +153,11 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
        control_freq = chandef->chan->center_freq;
 
        switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_1:
+       case NL80211_CHAN_WIDTH_2:
+       case NL80211_CHAN_WIDTH_4:
+       case NL80211_CHAN_WIDTH_8:
+       case NL80211_CHAN_WIDTH_16:
        case NL80211_CHAN_WIDTH_5:
        case NL80211_CHAN_WIDTH_10:
        case NL80211_CHAN_WIDTH_20:
@@ -263,6 +268,21 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
        int width;
 
        switch (c->width) {
+       case NL80211_CHAN_WIDTH_1:
+               width = 1;
+               break;
+       case NL80211_CHAN_WIDTH_2:
+               width = 2;
+               break;
+       case NL80211_CHAN_WIDTH_4:
+               width = 4;
+               break;
+       case NL80211_CHAN_WIDTH_8:
+               width = 8;
+               break;
+       case NL80211_CHAN_WIDTH_16:
+               width = 16;
+               break;
        case NL80211_CHAN_WIDTH_5:
                width = 5;
                break;
@@ -911,6 +931,21 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
        control_freq = chandef->chan->center_freq;
 
        switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_1:
+               width = 1;
+               break;
+       case NL80211_CHAN_WIDTH_2:
+               width = 2;
+               break;
+       case NL80211_CHAN_WIDTH_4:
+               width = 4;
+               break;
+       case NL80211_CHAN_WIDTH_8:
+               width = 8;
+               break;
+       case NL80211_CHAN_WIDTH_16:
+               width = 16;
+               break;
        case NL80211_CHAN_WIDTH_5:
                width = 5;
                break;
index c623d9b..1971d7e 100644 (file)
@@ -803,10 +803,11 @@ int wiphy_register(struct wiphy *wiphy)
                if (WARN_ON(!sband->n_channels))
                        return -EINVAL;
                /*
-                * on 60GHz band, there are no legacy rates, so
+                * on 60GHz or sub-1Ghz band, there are no legacy rates, so
                 * n_bitrates is 0
                 */
-               if (WARN_ON(band != NL80211_BAND_60GHZ &&
+               if (WARN_ON((band != NL80211_BAND_60GHZ &&
+                            band != NL80211_BAND_S1GHZ) &&
                            !sband->n_bitrates))
                        return -EINVAL;
 
index eac5aa1..e4e3631 100644 (file)
@@ -78,6 +78,7 @@ const struct mesh_config default_mesh_config = {
        .power_mode = NL80211_MESH_POWER_ACTIVE,
        .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
        .plink_timeout = MESH_DEFAULT_PLINK_TIMEOUT,
+       .dot11MeshNolearn = false,
 };
 
 const struct mesh_setup default_mesh_setup = {
index 0e07fb8..a096682 100644 (file)
@@ -4713,8 +4713,8 @@ static int nl80211_parse_he_bss_color(struct nlattr *attrs,
 
        he_bss_color->color =
                nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
-       he_bss_color->disabled =
-               nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
+       he_bss_color->enabled =
+               !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
        he_bss_color->partial =
                nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
 
@@ -5395,6 +5395,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
        PUT_SINFO(PEER_PM, peer_pm, u32);
        PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
        PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
+       PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8);
 
        if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
                bss_param = nla_nest_start_noflag(msg,
@@ -6885,7 +6886,11 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
            nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
                        cur_params.plink_timeout) ||
            nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
-                      cur_params.dot11MeshConnectedToMeshGate))
+                      cur_params.dot11MeshConnectedToMeshGate) ||
+           nla_put_u8(msg, NL80211_MESHCONF_NOLEARN,
+                      cur_params.dot11MeshNolearn) ||
+           nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_AS,
+                      cur_params.dot11MeshConnectedToAuthServer))
                goto nla_put_failure;
        nla_nest_end(msg, pinfoattr);
        genlmsg_end(msg, hdr);
@@ -6943,6 +6948,8 @@ nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
        [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
        [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
        [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
+       [NL80211_MESHCONF_NOLEARN] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
+       [NL80211_MESHCONF_CONNECTED_TO_AS] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
 };
 
 static const struct nla_policy
@@ -7055,6 +7062,9 @@ do {                                                                      \
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
                                  NL80211_MESHCONF_CONNECTED_TO_GATE,
                                  nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToAuthServer, mask,
+                                 NL80211_MESHCONF_CONNECTED_TO_AS,
+                                 nla_get_u8);
        /*
         * Check HT operation mode based on
         * IEEE 802.11-2016 9.4.2.57 HT Operation element.
@@ -7094,6 +7104,8 @@ do {                                                                      \
                                  NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
                                  NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNolearn, mask,
+                                 NL80211_MESHCONF_NOLEARN, nla_get_u8);
        if (mask_out)
                *mask_out = mask;
 
@@ -7774,10 +7786,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->scan)
                return -EOPNOTSUPP;
 
-       if (rdev->scan_req || rdev->scan_msg) {
-               err = -EBUSY;
-               goto unlock;
-       }
+       if (rdev->scan_req || rdev->scan_msg)
+               return -EBUSY;
 
        if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
                if (!wiphy_ext_feature_isset(wiphy,
@@ -7790,10 +7800,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
        if (scan_freqs) {
                n_channels = validate_scan_freqs(scan_freqs);
-               if (!n_channels) {
-                       err = -EINVAL;
-                       goto unlock;
-               }
+               if (!n_channels)
+                       return -EINVAL;
        } else {
                n_channels = ieee80211_get_num_supported_channels(wiphy);
        }
@@ -7802,29 +7810,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
                        n_ssids++;
 
-       if (n_ssids > wiphy->max_scan_ssids) {
-               err = -EINVAL;
-               goto unlock;
-       }
+       if (n_ssids > wiphy->max_scan_ssids)
+               return -EINVAL;
 
        if (info->attrs[NL80211_ATTR_IE])
                ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        else
                ie_len = 0;
 
-       if (ie_len > wiphy->max_scan_ie_len) {
-               err = -EINVAL;
-               goto unlock;
-       }
+       if (ie_len > wiphy->max_scan_ie_len)
+               return -EINVAL;
 
        request = kzalloc(sizeof(*request)
                        + sizeof(*request->ssids) * n_ssids
                        + sizeof(*request->channels) * n_channels
                        + ie_len, GFP_KERNEL);
-       if (!request) {
-               err = -ENOMEM;
-               goto unlock;
-       }
+       if (!request)
+               return -ENOMEM;
 
        if (n_ssids)
                request->ssids = (void *)&request->channels[n_channels];
@@ -8003,17 +8005,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        rdev->scan_req = request;
        err = rdev_scan(rdev, request);
 
-       if (!err) {
-               nl80211_send_scan_start(rdev, wdev);
-               if (wdev->netdev)
-                       dev_hold(wdev->netdev);
-       } else {
+       if (err)
+               goto out_free;
+
+       nl80211_send_scan_start(rdev, wdev);
+       if (wdev->netdev)
+               dev_hold(wdev->netdev);
+
+       return 0;
+
  out_free:
-               rdev->scan_req = NULL;
-               kfree(request);
-       }
+       rdev->scan_req = NULL;
+       kfree(request);
 
- unlock:
        return err;
 }
 
@@ -9438,7 +9442,9 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
                if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
                        return -EINVAL;
                if (!wiphy_ext_feature_isset(&rdev->wiphy,
-                                            NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
+                                            NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
+                   !wiphy_ext_feature_isset(&rdev->wiphy,
+                                            NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
                        return -EINVAL;
                settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
        }
@@ -13479,7 +13485,7 @@ static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
                if (err == -ENOBUFS || err == -ENOENT) {
                        genlmsg_cancel(skb, hdr);
                        break;
-               } else if (err) {
+               } else if (err <= 0) {
                        genlmsg_cancel(skb, hdr);
                        goto out;
                }
index 74ea4cf..e67a744 100644 (file)
@@ -712,6 +712,16 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
        __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
 }
 
+void cfg80211_bss_flush(struct wiphy *wiphy)
+{
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+
+       spin_lock_bh(&rdev->bss_lock);
+       __cfg80211_bss_expire(rdev, jiffies);
+       spin_unlock_bh(&rdev->bss_lock);
+}
+EXPORT_SYMBOL(cfg80211_bss_flush);
+
 const struct element *
 cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
                         const u8 *match, unsigned int match_len,
index b23cab0..6e218a0 100644 (file)
@@ -68,7 +68,8 @@
                       __field(u16, ht_opmode)                             \
                       __field(u32, dot11MeshHWMPactivePathToRootTimeout)  \
                       __field(u16, dot11MeshHWMProotInterval)             \
-                      __field(u16, dot11MeshHWMPconfirmationInterval)
+                      __field(u16, dot11MeshHWMPconfirmationInterval)     \
+                      __field(bool, dot11MeshNolearn)
 #define MESH_CFG_ASSIGN                                                              \
        do {                                                                  \
                __entry->dot11MeshRetryTimeout = conf->dot11MeshRetryTimeout; \
                                conf->dot11MeshHWMProotInterval;              \
                __entry->dot11MeshHWMPconfirmationInterval =                  \
                                conf->dot11MeshHWMPconfirmationInterval;      \
+               __entry->dot11MeshNolearn = conf->dot11MeshNolearn;           \
        } while (0)
 
 #define CHAN_ENTRY __field(enum nl80211_band, band) \
index 4d3b76f..26a9773 100644 (file)
@@ -102,6 +102,8 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
                if (chan < 7)
                        return MHZ_TO_KHZ(56160 + chan * 2160);
                break;
+       case NL80211_BAND_S1GHZ:
+               return 902000 + chan * 500;
        default:
                ;
        }
@@ -210,6 +212,12 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband)
                WARN_ON(!sband->ht_cap.ht_supported);
                WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e);
                break;
+       case NL80211_BAND_S1GHZ:
+               /* Figure 9-589bd: 3 means unsupported, so != 3 means at least
+                * mandatory is ok.
+                */
+               WARN_ON((sband->s1g_cap.nss_mcs[0] & 0x3) == 0x3);
+               break;
        case NUM_NL80211_BANDS:
        default:
                WARN_ON(1);