summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2020-08-01 04:51:40 +0300
committerDavid S. Miller <davem@davemloft.net>2020-08-01 04:51:40 +0300
commit6f3de75cdf60c1b859bc8c1904d25889c00d7bbe (patch)
treea0915726f401ed1ba81f62b4a65f8737b403332d
parent829eb208e80d6db95c0201cb8fa00c2f9ad87faf (diff)
parentc8ad010665c0b85c6a35466b2159e907b8dd85d1 (diff)
downloadlinux-6f3de75cdf60c1b859bc8c1904d25889c00d7bbe.tar.xz
Merge tag 'mac80211-next-for-davem-2020-07-31' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
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>
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c2
-rw-r--r--include/net/cfg80211.h41
-rw-r--r--include/net/fq.h1
-rw-r--r--include/net/fq_impl.h3
-rw-r--r--include/net/ieee80211_radiotap.h1
-rw-r--r--include/net/mac80211.h42
-rw-r--r--include/net/regulatory.h2
-rw-r--r--include/uapi/linux/nl80211.h94
-rw-r--r--include/uapi/linux/wireless.h2
-rw-r--r--net/mac80211/airtime.c26
-rw-r--r--net/mac80211/cfg.c21
-rw-r--r--net/mac80211/chan.c9
-rw-r--r--net/mac80211/debugfs_netdev.c5
-rw-r--r--net/mac80211/driver-ops.h11
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c4
-rw-r--r--net/mac80211/ieee80211_i.h16
-rw-r--r--net/mac80211/iface.c25
-rw-r--r--net/mac80211/key.c2
-rw-r--r--net/mac80211/mesh.c9
-rw-r--r--net/mac80211/mesh_hwmp.c41
-rw-r--r--net/mac80211/mesh_plink.c2
-rw-r--r--net/mac80211/mlme.c14
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/rx.c66
-rw-r--r--net/mac80211/scan.c8
-rw-r--r--net/mac80211/sta_info.c6
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/status.c4
-rw-r--r--net/mac80211/tdls.c8
-rw-r--r--net/mac80211/tx.c99
-rw-r--r--net/mac80211/util.c20
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/wireless/chan.c35
-rw-r--r--net/wireless/core.c5
-rw-r--r--net/wireless/mesh.c1
-rw-r--r--net/wireless/nl80211.c74
-rw-r--r--net/wireless/scan.c10
-rw-r--r--net/wireless/trace.h4
-rw-r--r--net/wireless/util.c8
42 files changed, 511 insertions, 235 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 919d15584d4a..3c0c33a9f30c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -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;
}
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 07d3e031c75a..94ae2b9ea663 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -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);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 1356e8cbe617..9dd9d73f4484 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -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;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fc7e8807838d..d9e6b9fbd95b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -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;
};
@@ -418,12 +418,28 @@ struct ieee80211_edmg {
};
/**
+ * 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 */
diff --git a/include/net/fq.h b/include/net/fq.h
index 2ad85e683041..e39f3f8d5f8a 100644
--- a/include/net/fq.h
+++ b/include/net/fq.h
@@ -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;
diff --git a/include/net/fq_impl.h b/include/net/fq_impl.h
index 38a9a3d1222b..e73d74d2fabf 100644
--- a/include/net/fq_impl.h
+++ b/include/net/fq_impl.h
@@ -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 */
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 459d355f6506..19c00d100096 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -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 */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 11d5610d2ad5..66e2bfd165e8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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
@@ -4358,6 +4361,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
*
* Use this function to hand received frames to mac80211. The receive
@@ -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
@@ -6236,6 +6264,14 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
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
*
* @next_tsf: TSF timestamp of the next absent state change
@@ -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,
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index 09a3099886e5..47f06f6f5a67 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -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
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 4e6339ab1fce..631f3a997b3c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -183,18 +183,27 @@
*
* 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
@@ -363,7 +372,7 @@
* @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
@@ -383,7 +392,7 @@
* @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.
@@ -934,7 +943,7 @@
* @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
@@ -1113,7 +1122,7 @@
* 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
diff --git a/include/uapi/linux/wireless.h b/include/uapi/linux/wireless.h
index 24f3371ad826..08967b3f19c8 100644
--- a/include/uapi/linux/wireless.h
+++ b/include/uapi/linux/wireless.h
@@ -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 */
diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
index 9fc2968856c0..366f76c9003d 100644
--- a/net/mac80211/airtime.c
+++ b/net/mac80211/airtime.c
@@ -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)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9b360544ad6f..24e9e00decb8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -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;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index e6e192f53e4e..bdc0f29dc6cd 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -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;
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index d7e955127d5c..fe8a7a87e513 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -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
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index de69fc9c4f07..41d495d73d3a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -12,12 +12,11 @@
#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)
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index e32906202575..3d62a80b5790 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -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;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 81d26fef41e9..53632c2f5217 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -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;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ec1a71ac65f2..0b1eaec6649f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -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
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f900c84fb40f..9740ae8fa697 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -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++) {
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 8f403c1bb908..9c2888004878 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -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:
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 5f1ca25b6c97..d0db6af16427 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -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;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 02cde0fd08fe..bec23d2eee7a 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1173,6 +1173,40 @@ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
}
/**
+ * 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
* refresh if this mpath expires soon.
@@ -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 |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 798e4b6b383f..15f2fc658f70 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -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)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b2a9d47cf86d..839d0367446c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -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,
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index db3b8bf75656..f470d1a7ce9b 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -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:
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5c5af4b5fc08..836cde516a18 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -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;
@@ -4763,36 +4762,53 @@ 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
* if it was previously present.
* 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
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ad90bbe57457..5ac2785cdc7b 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -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.
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index cd8487bc6fc2..bf9abfa25bc3 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -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
}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 49728047dfad..9d398c9daa4c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -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;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index cbc40b358ba2..adb1d30ce06e 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -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,
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 4b0cff4a07bd..e01e4daeb8cd 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -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 */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1a2941e5244f..ec35a92df8ed 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -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();
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 21c94094a699..b768ebd7117f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -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);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 72920d82928c..2fb99325135a 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -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;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index cddf92c5d09e..90f0f82cd9ca 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -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;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index c623d9bf5096..1971d7e6eb55 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -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;
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index eac5aa1419fc..e4e363138279 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -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 = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0e07fb8585fb..a096682ec0ad 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -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;
}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 74ea4cfb39fb..e67a74488bbe 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -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,
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index b23cab016521..6e218a0acd4e 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -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; \
@@ -109,6 +110,7 @@
conf->dot11MeshHWMProotInterval; \
__entry->dot11MeshHWMPconfirmationInterval = \
conf->dot11MeshHWMPconfirmationInterval; \
+ __entry->dot11MeshNolearn = conf->dot11MeshNolearn; \
} while (0)
#define CHAN_ENTRY __field(enum nl80211_band, band) \
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4d3b76f94f55..26a977343c3b 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -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);