Browse Source

mt76: update to the latest version

1.04.5
X-osadmin 2 weeks ago
parent
commit
2f45156804
  1. 8
      include/prereq-build.mk
  2. 297
      package/kernel/mac80211/subsys/010-sync-nl80211_h.patch
  3. 12
      package/kernel/mac80211/subsys/110-mac80211_keep_keys_on_stop_ap.patch
  4. 43
      package/kernel/mac80211/subsys/120-cfg80211_allow_perm_addr_change.patch
  5. 67
      package/kernel/mac80211/subsys/150-disable_addr_notifier.patch
  6. 11
      package/kernel/mac80211/subsys/210-ap_scan.patch
  7. 279
      package/kernel/mac80211/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch
  8. 271
      package/kernel/mac80211/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch
  9. 74
      package/kernel/mac80211/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch
  10. 38
      package/kernel/mac80211/subsys/304-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch
  11. 95
      package/kernel/mac80211/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch
  12. 144
      package/kernel/mac80211/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch
  13. 317
      package/kernel/mac80211/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch
  14. 570
      package/kernel/mac80211/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch
  15. 116
      package/kernel/mac80211/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch
  16. 123
      package/kernel/mac80211/subsys/320-mac80211_hwsim-add-6GHz-channels.patch
  17. 74
      package/kernel/mac80211/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch
  18. 166
      package/kernel/mac80211/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch
  19. 762
      package/kernel/mac80211/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch
  20. 1328
      package/kernel/mac80211/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch
  21. 96
      package/kernel/mac80211/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch
  22. 67
      package/kernel/mac80211/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch
  23. 31
      package/kernel/mac80211/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch
  24. 124
      package/kernel/mac80211/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch
  25. 20
      package/kernel/mac80211/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch
  26. 34
      package/kernel/mac80211/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch
  27. 412
      package/kernel/mac80211/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch
  28. 54
      package/kernel/mac80211/subsys/347-mac80211-minstrel_ht-update-total-packets-counter-in.patch
  29. 102
      package/kernel/mac80211/subsys/348-mac80211-minstrel_ht-reduce-the-need-to-sample-slowe.patch
  30. 767
      package/kernel/mac80211/subsys/349-mac80211-minstrel_ht-significantly-redesign-the-rate.patch
  31. 58
      package/kernel/mac80211/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch
  32. 279
      package/kernel/mac80211/subsys/351-mac80211-minstrel_ht-remove-sample-rate-switching-co.patch
  33. 23
      package/kernel/mac80211/subsys/352-mac80211-minstrel_ht-fix-regression-in-the-max_prob_.patch
  34. 21
      package/kernel/mac80211/subsys/353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch
  35. 30
      package/kernel/mac80211/subsys/354-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch
  36. 151
      package/kernel/mac80211/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch
  37. 60
      package/kernel/mac80211/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch
  38. 21
      package/kernel/mac80211/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch
  39. 134
      package/kernel/mac80211/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch
  40. 126
      package/kernel/mac80211/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch
  41. 114
      package/kernel/mac80211/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch
  42. 126
      package/kernel/mac80211/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch
  43. 23
      package/kernel/mac80211/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch
  44. 112
      package/kernel/mac80211/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch
  45. 111
      package/kernel/mac80211/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch
  46. 39
      package/kernel/mac80211/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch
  47. 1277
      package/kernel/mac80211/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch
  48. 398
      package/kernel/mac80211/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch
  49. 51
      package/kernel/mac80211/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch
  50. 26
      package/kernel/mac80211/subsys/386-mac80211-check-per-vif-offload_flags-in-Tx-path.patch
  51. 485
      package/kernel/mac80211/subsys/387-nl80211-add-support-for-BSS-coloring.patch
  52. 524
      package/kernel/mac80211/subsys/388-mac80211-add-support-for-BSS-color-change.patch
  53. 112
      package/kernel/mac80211/subsys/389-ieee80211-add-TWT-element-definitions.patch
  54. 580
      package/kernel/mac80211/subsys/390-mac80211-introduce-individual-TWT-support-in-AP-mode.patch
  55. 29
      package/kernel/mac80211/subsys/400-allow-ibss-mixed.patch
  56. 160
      package/kernel/mac80211/subsys/500-mac80211_configure_antenna_gain.patch
  57. 59
      package/kernel/mac80211/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch
  58. 6
      package/kernel/mt76/Makefile
  59. 4
      target/linux/x86/base-files/etc/board.d/01_leds
  60. 3
      target/linux/x86/base-files/etc/board.d/02_network
  61. 10
      target/linux/x86/base-files/lib/upgrade/platform.sh
  62. 20
      target/linux/x86/modules.mk
  63. 32
      target/linux/x86/patches-5.10/101-v5.15-mfd-lpc_ich-Enable-GPIO-driver-for-DH89xxCC.patch
  64. 300
      target/linux/x86/patches-5.10/102-v5.15-platform-x86-add-meraki-mx100-platform-driver.patch

8
include/prereq-build.mk

@ -162,7 +162,7 @@ $(eval $(call SetupHostCommand,python,Please install Python >= 3.6, \
python3.8 -V 2>&1 | grep 'Python 3', \
python3.7 -V 2>&1 | grep 'Python 3', \
python3.6 -V 2>&1 | grep 'Python 3', \
python3 -V 2>&1 | grep -E 'Python 3\.[6-9]\.?'))
python3 -V 2>&1 | grep -E 'Python 3\.([6-9]|10)\.?'))
$(eval $(call SetupHostCommand,python3,Please install Python >= 3.6, \
python3.10 -V 2>&1 | grep 'Python 3', \
@ -170,7 +170,7 @@ $(eval $(call SetupHostCommand,python3,Please install Python >= 3.6, \
python3.8 -V 2>&1 | grep 'Python 3', \
python3.7 -V 2>&1 | grep 'Python 3', \
python3.6 -V 2>&1 | grep 'Python 3', \
python3 -V 2>&1 | grep -E 'Python 3\.[6-9]\.?'))
python3 -V 2>&1 | grep -E 'Python 3\.([6-9]|10)\.?'))
$(eval $(call TestHostCommand,python3-distutils, \
Please install the Python3 distutils module, \
@ -186,7 +186,9 @@ $(eval $(call SetupHostCommand,rsync,Please install 'rsync', \
rsync --version </dev/null))
$(eval $(call SetupHostCommand,which,Please install 'which', \
which which | grep which))
/usr/bin/which which, \
/bin/which which, \
which which))
$(STAGING_DIR_HOST)/bin/mkhash: $(SCRIPT_DIR)/mkhash.c
mkdir -p $(dir [email protected])

297
package/kernel/mac80211/subsys/010-sync-nl80211_h.patch

@ -0,0 +1,297 @@
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -655,6 +655,9 @@
* When a security association was established on an 802.1X network using
* fast transition, this event should be followed by an
* %NL80211_CMD_PORT_AUTHORIZED event.
+ * Following a %NL80211_CMD_ROAM event userspace can issue
+ * %NL80211_CMD_GET_SCAN in order to obtain the scan information for the
+ * new BSS the card/driver roamed to.
* @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
* userspace that a connection was dropped by the AP or due to other
* reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
@@ -757,7 +760,8 @@
* of any other interfaces, and other interfaces will again take
* precedence when they are used.
*
- * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
+ * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface
+ * (no longer supported).
*
* @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform
* multicast to unicast conversion. When enabled, all multicast packets
@@ -1177,6 +1181,10 @@
* includes the contents of the frame. %NL80211_ATTR_ACK flag is included
* if the recipient acknowledged the frame.
*
+ * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is
+ * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
+ * specify the wiphy index to be applied to.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1407,6 +1415,8 @@ enum nl80211_commands {
NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
+ NL80211_CMD_SET_SAR_SPECS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1750,8 +1760,9 @@ enum nl80211_commands {
* specify just a single bitrate, which is to be used for the beacon.
* The driver must also specify support for this with the extended
* features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
- * NL80211_EXT_FEATURE_BEACON_RATE_HT and
- * NL80211_EXT_FEATURE_BEACON_RATE_VHT.
+ * NL80211_EXT_FEATURE_BEACON_RATE_HT,
+ * NL80211_EXT_FEATURE_BEACON_RATE_VHT and
+ * NL80211_EXT_FEATURE_BEACON_RATE_HE.
*
* @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
* at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
@@ -1955,8 +1966,15 @@ enum nl80211_commands {
* @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
* probe-response frame. The DA field in the 802.11 header is zero-ed out,
* to be filled by the FW.
- * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
- * this feature. Currently, only supported in mac80211 drivers.
+ * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
+ * this feature during association. This is a flag attribute.
+ * Currently only supported in mac80211 drivers.
+ * @NL80211_ATTR_DISABLE_VHT: Force VHT capable interfaces to disable
+ * this feature during association. This is a flag attribute.
+ * Currently only supported in mac80211 drivers.
+ * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable
+ * this feature during association. This is a flag attribute.
+ * Currently only supported in mac80211 drivers.
* @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
* ATTR_HT_CAPABILITY to which attention should be paid.
* Currently, only mac80211 NICs support this feature.
@@ -2077,7 +2095,8 @@ enum nl80211_commands {
* until the channel switch event.
* @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
* must be blocked on the current channel (before the channel switch
- * operation).
+ * operation). Also included in the channel switch started event if quiet
+ * was requested by the AP.
* @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
* for the time while performing a channel switch.
* @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel
@@ -2527,6 +2546,20 @@ enum nl80211_commands {
* override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
* NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
*
+ * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE
+ * derivation in WPA3-Personal networks which are using SAE authentication.
+ * This is a u8 attribute that encapsulates one of the values from
+ * &enum nl80211_sae_pwe_mechanism.
+ *
+ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
+ * used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields
+ * of %nl80211_sar_attrs which specifies the sar type and related
+ * sar specs. Sar specs contains array of %nl80211_sar_specs_attrs.
+ *
+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and
+ * disassoc events to indicate that an immediate reconnect to the AP
+ * is desired.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3016,6 +3049,14 @@ enum nl80211_attrs {
NL80211_ATTR_S1G_CAPABILITY,
NL80211_ATTR_S1G_CAPABILITY_MASK,
+ NL80211_ATTR_SAE_PWE,
+
+ NL80211_ATTR_RECONNECT_REQUESTED,
+
+ NL80211_ATTR_SAR_SPEC,
+
+ NL80211_ATTR_DISABLE_HE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -5896,6 +5937,19 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
* unsolicited broadcast probe response transmission
*
+ * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate
+ * configuration (AP/mesh) with HE rates.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_LTF: Device supports secure LTF measurement
+ * exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_RTT: Device supports secure RTT measurement
+ * exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management
+ * frame protection for all management frames exchanged during the
+ * negotiation and range measurement procedure.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -5956,6 +6010,10 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
NL80211_EXT_FEATURE_FILS_DISCOVERY,
NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
+ NL80211_EXT_FEATURE_BEACON_RATE_HE,
+ NL80211_EXT_FEATURE_SECURE_LTF,
+ NL80211_EXT_FEATURE_SECURE_RTT,
+ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
@@ -6253,11 +6311,13 @@ struct nl80211_vendor_cmd_info {
* @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
* @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
* @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
+ * @NL80211_TDLS_PEER_HE: TDLS peer is HE capable.
*/
enum nl80211_tdls_peer_capability {
NL80211_TDLS_PEER_HT = 1<<0,
NL80211_TDLS_PEER_VHT = 1<<1,
NL80211_TDLS_PEER_WMM = 1<<2,
+ NL80211_TDLS_PEER_HE = 1<<3,
};
/**
@@ -6849,6 +6909,9 @@ enum nl80211_peer_measurement_ftm_capa {
* if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
* %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
* ranging will be used.
+ * @NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK: negotiate for LMR feedback. Only
+ * valid if either %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED or
+ * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
*
* @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
* @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
@@ -6867,6 +6930,7 @@ enum nl80211_peer_measurement_ftm_req {
NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
+ NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,
/* keep last */
NUM_NL80211_PMSR_FTM_REQ_ATTR,
@@ -7124,4 +7188,115 @@ enum nl80211_unsol_bcast_probe_resp_attr
NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX =
__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1
};
+
+/**
+ * enum nl80211_sae_pwe_mechanism - The mechanism(s) allowed for SAE PWE
+ * derivation. Applicable only when WPA3-Personal SAE authentication is
+ * used.
+ *
+ * @NL80211_SAE_PWE_UNSPECIFIED: not specified, used internally to indicate that
+ * attribute is not present from userspace.
+ * @NL80211_SAE_PWE_HUNT_AND_PECK: hunting-and-pecking loop only
+ * @NL80211_SAE_PWE_HASH_TO_ELEMENT: hash-to-element only
+ * @NL80211_SAE_PWE_BOTH: both hunting-and-pecking loop and hash-to-element
+ * can be used.
+ */
+enum nl80211_sae_pwe_mechanism {
+ NL80211_SAE_PWE_UNSPECIFIED,
+ NL80211_SAE_PWE_HUNT_AND_PECK,
+ NL80211_SAE_PWE_HASH_TO_ELEMENT,
+ NL80211_SAE_PWE_BOTH,
+};
+
+/**
+ * enum nl80211_sar_type - type of SAR specs
+ *
+ * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit
+ *
+ */
+enum nl80211_sar_type {
+ NL80211_SAR_TYPE_POWER,
+
+ /* add new type here */
+
+ /* Keep last */
+ NUM_NL80211_SAR_TYPE,
+};
+
+/**
+ * enum nl80211_sar_attrs - Attributes for SAR spec
+ *
+ * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type.
+ *
+ * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
+ * limit specifications. Each specification contains a set
+ * of %nl80211_sar_specs_attrs.
+ *
+ * For SET operation, it contains array of %NL80211_SAR_ATTR_SPECS_POWER
+ * and %NL80211_SAR_ATTR_SPECS_RANGE_INDEX.
+ *
+ * For sar_capa dump, it contains array of
+ * %NL80211_SAR_ATTR_SPECS_START_FREQ
+ * and %NL80211_SAR_ATTR_SPECS_END_FREQ.
+ *
+ * @__NL80211_SAR_ATTR_LAST: Internal
+ * @NL80211_SAR_ATTR_MAX: highest sar attribute
+ *
+ * These attributes are used with %NL80211_CMD_SET_SAR_SPEC
+ */
+enum nl80211_sar_attrs {
+ __NL80211_SAR_ATTR_INVALID,
+
+ NL80211_SAR_ATTR_TYPE,
+ NL80211_SAR_ATTR_SPECS,
+
+ __NL80211_SAR_ATTR_LAST,
+ NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1,
+};
+
+/**
+ * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs
+ *
+ * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual
+ * power limit value in units of 0.25 dBm if type is
+ * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm).
+ * 0 means userspace doesn't have SAR limitation on this associated range.
+ *
+ * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the
+ * index of exported freq range table and the associated power limitation
+ * is applied to this range.
+ *
+ * Userspace isn't required to set all the ranges advertised by WLAN driver,
+ * and userspace can skip some certain ranges. These skipped ranges don't
+ * have SAR limitations, and they are same as setting the
+ * %NL80211_SAR_ATTR_SPECS_POWER to any unreasonable high value because any
+ * value higher than regulatory allowed value just means SAR power
+ * limitation is removed, but it's required to set at least one range.
+ * It's not allowed to set duplicated range in one SET operation.
+ *
+ * Every SET operation overwrites previous SET operation.
+ *
+ * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start
+ * frequency of this range edge when registering SAR capability to wiphy.
+ * It's not a channel center frequency. The unit is kHz.
+ *
+ * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify the end
+ * frequency of this range edge when registering SAR capability to wiphy.
+ * It's not a channel center frequency. The unit is kHz.
+ *
+ * @__NL80211_SAR_ATTR_SPECS_LAST: Internal
+ * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute
+ */
+enum nl80211_sar_specs_attrs {
+ __NL80211_SAR_ATTR_SPECS_INVALID,
+
+ NL80211_SAR_ATTR_SPECS_POWER,
+ NL80211_SAR_ATTR_SPECS_RANGE_INDEX,
+ NL80211_SAR_ATTR_SPECS_START_FREQ,
+ NL80211_SAR_ATTR_SPECS_END_FREQ,
+
+ __NL80211_SAR_ATTR_SPECS_LAST,
+ NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
+};
+
#endif /* __LINUX_NL80211_H */

12
package/kernel/mac80211/subsys/110-mac80211_keep_keys_on_stop_ap.patch

@ -0,0 +1,12 @@
Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1307,7 +1307,6 @@ static int ieee80211_stop_ap(struct wiph
sdata->vif.bss_conf.ftmr_params = NULL;
__sta_info_flush(sdata, true);
- ieee80211_free_keys(sdata, true);
sdata->vif.bss_conf.enable_beacon = false;
sdata->beacon_rate_set = false;

43
package/kernel/mac80211/subsys/120-cfg80211_allow_perm_addr_change.patch

@ -0,0 +1,43 @@
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -23,18 +23,35 @@ static inline struct cfg80211_registered
return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
}
-#define SHOW_FMT(name, fmt, member) \
+#define SHOW_FMT(name, fmt, member, mode) \
static ssize_t name ## _show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
} \
-static DEVICE_ATTR_RO(name)
+static DEVICE_ATTR_##mode(name)
-SHOW_FMT(index, "%d", wiphy_idx);
-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
+static ssize_t macaddress_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ u8 mac[ETH_ALEN];
+
+ if (!mac_pton(buf, mac))
+ return -EINVAL;
+
+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
+ return -EINVAL;
+
+ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN);
+
+ return strnlen(buf, len);
+}
+
+SHOW_FMT(index, "%d", wiphy_idx, RO);
+SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW);
+SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO);
static ssize_t name_show(struct device *dev,
struct device_attribute *attr,

67
package/kernel/mac80211/subsys/150-disable_addr_notifier.patch

@ -0,0 +1,67 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -321,7 +321,7 @@ void ieee80211_restart_hw(struct ieee802
}
EXPORT_SYMBOL(ieee80211_restart_hw);
-#ifdef CONFIG_INET
+#ifdef __disabled__CONFIG_INET
static int ieee80211_ifa_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
@@ -380,7 +380,7 @@ static int ieee80211_ifa_changed(struct
}
#endif
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
static int ieee80211_ifa6_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
@@ -1315,14 +1315,14 @@ int ieee80211_register_hw(struct ieee802
rtnl_unlock();
-#ifdef CONFIG_INET
+#ifdef __disabled__CONFIG_INET
local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
result = register_inetaddr_notifier(&local->ifa_notifier);
if (result)
goto fail_ifa;
#endif
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
result = register_inet6addr_notifier(&local->ifa6_notifier);
if (result)
@@ -1331,13 +1331,13 @@ int ieee80211_register_hw(struct ieee802
return 0;
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
fail_ifa6:
-#ifdef CONFIG_INET
+#ifdef __disabled__CONFIG_INET
unregister_inetaddr_notifier(&local->ifa_notifier);
#endif
#endif
-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
fail_ifa:
#endif
wiphy_unregister(local->hw.wiphy);
@@ -1365,10 +1365,10 @@ void ieee80211_unregister_hw(struct ieee
tasklet_kill(&local->tx_pending_tasklet);
tasklet_kill(&local->tasklet);
-#ifdef CONFIG_INET
+#ifdef __disabled__CONFIG_INET
unregister_inetaddr_notifier(&local->ifa_notifier);
#endif
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
unregister_inet6addr_notifier(&local->ifa6_notifier);
#endif

11
package/kernel/mac80211/subsys/210-ap_scan.patch

@ -0,0 +1,11 @@
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2463,7 +2463,7 @@ static int ieee80211_scan(struct wiphy *
* the frames sent while scanning on other channel will be
* lost)
*/
- if (sdata->u.ap.beacon &&
+ if (0 && sdata->u.ap.beacon &&
(!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
!(req->flags & NL80211_SCAN_FLAG_AP)))
return -EOPNOTSUPP;

279
package/kernel/mac80211/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch

@ -0,0 +1,279 @@
From: Johannes Berg <[email protected]>
Date: Sun, 6 Dec 2020 14:54:42 +0200
Subject: [PATCH] cfg80211: support immediate reconnect request hint
There are cases where it's necessary to disconnect, but an
immediate reconnection is desired. Support a hint to userspace
that this is the case, by including a new attribute in the
deauth or disassoc event.
Signed-off-by: Luca Coelho <[email protected]>
Link: https://lore.kernel.org/r/iwlwifi.202012[email protected]changeid
Signed-off-by: Johannes Berg <[email protected]>
---
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6410,13 +6410,15 @@ void cfg80211_abandon_assoc(struct net_d
* @dev: network device
* @buf: 802.11 frame (header + body)
* @len: length of the frame data
+ * @reconnect: immediate reconnect is desired (include the nl80211 attribute)
*
* This function is called whenever deauthentication has been processed in
* station mode. This includes both received deauthentication frames and
* locally generated ones. This function may sleep. The caller must hold the
* corresponding wdev's mutex.
*/
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
+ bool reconnect);
/**
* cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect(
};
if (tx)
- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len);
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false);
else
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
@@ -4719,7 +4719,8 @@ void ieee80211_mgd_quiesce(struct ieee80
if (ifmgd->auth_data)
ieee80211_destroy_auth_data(sdata, false);
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- IEEE80211_DEAUTH_FRAME_LEN);
+ IEEE80211_DEAUTH_FRAME_LEN,
+ false);
}
/* This is a bit of a hack - we should find a better and more generic
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -4,7 +4,7 @@
*
* Copyright (c) 2009, Jouni Malinen <[email protected]>
* Copyright (c) 2015 Intel Deutschland GmbH
- * Copyright (C) 2019 Intel Corporation
+ * Copyright (C) 2019-2020 Intel Corporation
*/
#include <linux/kernel.h>
@@ -81,7 +81,8 @@ static void cfg80211_process_auth(struct
}
static void cfg80211_process_deauth(struct wireless_dev *wdev,
- const u8 *buf, size_t len)
+ const u8 *buf, size_t len,
+ bool reconnect)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
@@ -89,7 +90,7 @@ static void cfg80211_process_deauth(stru
u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
- nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
+ nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
if (!wdev->current_bss ||
!ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
@@ -100,7 +101,8 @@ static void cfg80211_process_deauth(stru
}
static void cfg80211_process_disassoc(struct wireless_dev *wdev,
- const u8 *buf, size_t len)
+ const u8 *buf, size_t len,
+ bool reconnect)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
@@ -108,7 +110,8 @@ static void cfg80211_process_disassoc(st
u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
- nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
+ nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect,
+ GFP_KERNEL);
if (WARN_ON(!wdev->current_bss ||
!ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
@@ -133,9 +136,9 @@ void cfg80211_rx_mlme_mgmt(struct net_de
if (ieee80211_is_auth(mgmt->frame_control))
cfg80211_process_auth(wdev, buf, len);
else if (ieee80211_is_deauth(mgmt->frame_control))
- cfg80211_process_deauth(wdev, buf, len);
+ cfg80211_process_deauth(wdev, buf, len, false);
else if (ieee80211_is_disassoc(mgmt->frame_control))
- cfg80211_process_disassoc(wdev, buf, len);
+ cfg80211_process_disassoc(wdev, buf, len, false);
}
EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
@@ -180,22 +183,23 @@ void cfg80211_abandon_assoc(struct net_d
}
EXPORT_SYMBOL(cfg80211_abandon_assoc);
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
+ bool reconnect)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct ieee80211_mgmt *mgmt = (void *)buf;
ASSERT_WDEV_LOCK(wdev);
- trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
+ trace_cfg80211_tx_mlme_mgmt(dev, buf, len, reconnect);
if (WARN_ON(len < 2))
return;
if (ieee80211_is_deauth(mgmt->frame_control))
- cfg80211_process_deauth(wdev, buf, len);
+ cfg80211_process_deauth(wdev, buf, len, reconnect);
else
- cfg80211_process_disassoc(wdev, buf, len);
+ cfg80211_process_disassoc(wdev, buf, len, reconnect);
}
EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -736,6 +736,7 @@ static const struct nla_policy nl80211_p
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
[NL80211_ATTR_S1G_CAPABILITY_MASK] =
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
+ [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
};
/* policy for the key attributes */
@@ -15902,7 +15903,7 @@ static void nl80211_send_mlme_event(stru
const u8 *buf, size_t len,
enum nl80211_commands cmd, gfp_t gfp,
int uapsd_queues, const u8 *req_ies,
- size_t req_ies_len)
+ size_t req_ies_len, bool reconnect)
{
struct sk_buff *msg;
void *hdr;
@@ -15924,6 +15925,9 @@ static void nl80211_send_mlme_event(stru
nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
goto nla_put_failure;
+ if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
+ goto nla_put_failure;
+
if (uapsd_queues >= 0) {
struct nlattr *nla_wmm =
nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
@@ -15952,7 +15956,8 @@ void nl80211_send_rx_auth(struct cfg8021
size_t len, gfp_t gfp)
{
nl80211_send_mlme_event(rdev, netdev, buf, len,
- NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
+ NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
+ false);
}
void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
@@ -15962,23 +15967,25 @@ void nl80211_send_rx_assoc(struct cfg802
{
nl80211_send_mlme_event(rdev, netdev, buf, len,
NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
- req_ies, req_ies_len);
+ req_ies, req_ies_len, false);
}
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *buf,
- size_t len, gfp_t gfp)
+ size_t len, bool reconnect, gfp_t gfp)
{
nl80211_send_mlme_event(rdev, netdev, buf, len,
- NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
+ NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
+ reconnect);
}
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev, const u8 *buf,
- size_t len, gfp_t gfp)
+ size_t len, bool reconnect, gfp_t gfp)
{
nl80211_send_mlme_event(rdev, netdev, buf, len,
- NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
+ NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
+ reconnect);
}
void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
@@ -16009,7 +16016,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct
trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
- NULL, 0);
+ NULL, 0, false);
}
EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Portions of this file
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018, 2020 Intel Corporation
*/
#ifndef __NET_WIRELESS_NL80211_H
#define __NET_WIRELESS_NL80211_H
@@ -69,10 +69,12 @@ void nl80211_send_rx_assoc(struct cfg802
const u8 *req_ies, size_t req_ies_len);
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
- const u8 *buf, size_t len, gfp_t gfp);
+ const u8 *buf, size_t len,
+ bool reconnect, gfp_t gfp);
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
- const u8 *buf, size_t len, gfp_t gfp);
+ const u8 *buf, size_t len,
+ bool reconnect, gfp_t gfp);
void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *addr, gfp_t gfp);
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2684,19 +2684,23 @@ DEFINE_EVENT(netdev_frame_event, cfg8021
);
TRACE_EVENT(cfg80211_tx_mlme_mgmt,
- TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
- TP_ARGS(netdev, buf, len),
+ TP_PROTO(struct net_device *netdev, const u8 *buf, int len,
+ bool reconnect),
+ TP_ARGS(netdev, buf, len, reconnect),
TP_STRUCT__entry(
NETDEV_ENTRY
__dynamic_array(u8, frame, len)
+ __field(int, reconnect)
),
TP_fast_assign(
NETDEV_ASSIGN;
memcpy(__get_dynamic_array(frame), buf, len);
+ __entry->reconnect = reconnect;
),
- TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x",
+ TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x reconnect:%d",
NETDEV_PR_ARG,
- le16_to_cpup((__le16 *)__get_dynamic_array(frame)))
+ le16_to_cpup((__le16 *)__get_dynamic_array(frame)),
+ __entry->reconnect)
);
DECLARE_EVENT_CLASS(netdev_mac_evt,

271
package/kernel/mac80211/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch

@ -0,0 +1,271 @@
From: Johannes Berg <[email protected]>
Date: Sun, 6 Dec 2020 14:54:43 +0200
Subject: [PATCH] mac80211: support driver-based disconnect with reconnect hint
Support the driver indicating that a disconnection needs
to be performed, and pass through the reconnect hint in
this case.
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
Link: https://lore.kernel.org/r/iwlwifi.202012[email protected]changeid
Signed-off-by: Johannes Berg <[email protected]>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5885,6 +5885,17 @@ void ieee80211_beacon_loss(struct ieee80
void ieee80211_connection_loss(struct ieee80211_vif *vif);
/**
+ * ieee80211_disconnect - request disconnection
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @reconnect: immediate reconnect is desired
+ *
+ * Request disconnection from the current network and, if enabled, send a
+ * hint to the higher layers that immediate reconnect is desired.
+ */
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect);
+
+/**
* ieee80211_resume_disconnect - disconnect from AP after resume
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -450,7 +450,9 @@ struct ieee80211_if_managed {
unsigned long probe_timeout;
int probe_send_count;
bool nullfunc_failed;
- bool connection_loss;
+ u8 connection_loss:1,
+ driver_disconnect:1,
+ reconnect:1;
struct cfg80211_bss *associated;
struct ieee80211_mgd_auth_data *auth_data;
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2716,7 +2716,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get)
static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
const u8 *buf, size_t len, bool tx,
- u16 reason)
+ u16 reason, bool reconnect)
{
struct ieee80211_event event = {
.type = MLME_EVENT,
@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect(
};
if (tx)
- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false);
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, reconnect);
else
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
@@ -2747,13 +2747,18 @@ static void __ieee80211_disconnect(struc
tx = !sdata->csa_block_tx;
- /* AP is probably out of range (or not reachable for another reason) so
- * remove the bss struct for that AP.
- */
- cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
+ if (!ifmgd->driver_disconnect) {
+ /*
+ * AP is probably out of range (or not reachable for another
+ * reason) so remove the bss struct for that AP.
+ */
+ cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
+ }
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+ ifmgd->driver_disconnect ?
+ WLAN_REASON_DEAUTH_LEAVING :
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
tx, frame_buf);
mutex_lock(&local->mtx);
sdata->vif.csa_active = false;
@@ -2766,7 +2771,9 @@ static void __ieee80211_disconnect(struc
mutex_unlock(&local->mtx);
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+ ifmgd->reconnect);
+ ifmgd->reconnect = false;
sdata_unlock(sdata);
}
@@ -2785,6 +2792,13 @@ static void ieee80211_beacon_connection_
sdata_info(sdata, "Connection to AP %pM lost\n",
ifmgd->bssid);
__ieee80211_disconnect(sdata);
+ ifmgd->connection_loss = false;
+ } else if (ifmgd->driver_disconnect) {
+ sdata_info(sdata,
+ "Driver requested disconnection from AP %pM\n",
+ ifmgd->bssid);
+ __ieee80211_disconnect(sdata);
+ ifmgd->driver_disconnect = false;
} else {
ieee80211_mgd_probe_ap(sdata, true);
}
@@ -2823,6 +2837,21 @@ void ieee80211_connection_loss(struct ie
}
EXPORT_SYMBOL(ieee80211_connection_loss);
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)
+{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_hw *hw = &sdata->local->hw;
+
+ trace_api_disconnect(sdata, reconnect);
+
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+ return;
+
+ sdata->u.mgd.driver_disconnect = true;
+ sdata->u.mgd.reconnect = reconnect;
+ ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
+}
+EXPORT_SYMBOL(ieee80211_disconnect);
static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
bool assoc)
@@ -3126,7 +3155,7 @@ static void ieee80211_rx_mgmt_deauth(str
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false,
- reason_code);
+ reason_code, false);
return;
}
@@ -3175,7 +3204,8 @@ static void ieee80211_rx_mgmt_disassoc(s
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
- ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code,
+ false);
}
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
@@ -4199,7 +4229,8 @@ static void ieee80211_rx_mgmt_beacon(str
true, deauth_buf);
ieee80211_report_disconnect(sdata, deauth_buf,
sizeof(deauth_buf), true,
- WLAN_REASON_DEAUTH_LEAVING);
+ WLAN_REASON_DEAUTH_LEAVING,
+ false);
return;
}
@@ -4344,7 +4375,7 @@ static void ieee80211_sta_connection_los
tx, frame_buf);
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
- reason);
+ reason, false);
}
static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
@@ -5434,7 +5465,8 @@ int ieee80211_mgd_auth(struct ieee80211_
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
- WLAN_REASON_UNSPECIFIED);
+ WLAN_REASON_UNSPECIFIED,
+ false);
}
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
@@ -5506,7 +5538,8 @@ int ieee80211_mgd_assoc(struct ieee80211
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
- WLAN_REASON_UNSPECIFIED);
+ WLAN_REASON_UNSPECIFIED,
+ false);
}
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
@@ -5809,7 +5842,7 @@ int ieee80211_mgd_deauth(struct ieee8021
ieee80211_destroy_auth_data(sdata, false);
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
- req->reason_code);
+ req->reason_code, false);
return 0;
}
@@ -5829,7 +5862,7 @@ int ieee80211_mgd_deauth(struct ieee8021
ieee80211_destroy_assoc_data(sdata, false, true);
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
- req->reason_code);
+ req->reason_code, false);
return 0;
}
@@ -5844,7 +5877,7 @@ int ieee80211_mgd_deauth(struct ieee8021
req->reason_code, tx, frame_buf);
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
- req->reason_code);
+ req->reason_code, false);
return 0;
}
@@ -5877,7 +5910,7 @@ int ieee80211_mgd_disassoc(struct ieee80
frame_buf);
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
- req->reason_code);
+ req->reason_code, false);
return 0;
}
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH
-* Copyright (C) 2018 - 2019 Intel Corporation
+* Copyright (C) 2018 - 2020 Intel Corporation
*/
#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -2086,6 +2086,27 @@ TRACE_EVENT(api_connection_loss,
)
);
+TRACE_EVENT(api_disconnect,
+ TP_PROTO(struct ieee80211_sub_if_data *sdata, bool reconnect),
+
+ TP_ARGS(sdata, reconnect),
+
+ TP_STRUCT__entry(
+ VIF_ENTRY
+ __field(int, reconnect)
+ ),
+
+ TP_fast_assign(
+ VIF_ASSIGN;
+ __entry->reconnect = reconnect;
+ ),
+
+ TP_printk(
+ VIF_PR_FMT " reconnect:%d",
+ VIF_PR_ARG, __entry->reconnect
+ )
+);
+
TRACE_EVENT(api_cqm_rssi_notify,
TP_PROTO(struct ieee80211_sub_if_data *sdata,
enum nl80211_cqm_rssi_threshold_event rssi_event,

74
package/kernel/mac80211/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch

@ -0,0 +1,74 @@
From: Rohan Dutta <[email protected]>
Date: Tue, 27 Oct 2020 12:09:10 +0200
Subject: [PATCH] cfg80211: Add support to configure SAE PWE value to drivers
Add support to configure SAE PWE preference from userspace to drivers in
both AP and STA modes. This is needed for cases where the driver takes
care of Authentication frame processing (SME in the driver) so that
correct enforcement of the acceptable PWE derivation mechanism can be
performed.
The userspace applications can pass the sae_pwe value using the
NL80211_ATTR_SAE_PWE attribute in the NL80211_CMD_CONNECT and
NL80211_CMD_START_AP commands to the driver. This allows selection
between the hunting-and-pecking loop and hash-to-element options for PWE
derivation. For backwards compatibility, this new attribute is optional
and if not included, the driver is notified of the value being
unspecified.
Signed-off-by: Rohan Dutta <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Johannes Berg <[email protected]>
---
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1009,6 +1009,14 @@ struct survey_info {
* @sae_pwd: password for SAE authentication (for devices supporting SAE
* offload)
* @sae_pwd_len: length of SAE password (for devices supporting SAE offload)
+ * @sae_pwe: The mechanisms allowed for SAE PWE derivation
+ * NL80211_SAE_PWE_UNSPECIFIED: Not-specified, used to indicate userspace
+ * did not specify any preference. The driver should follow its
+ * internal policy in such a scenario.
+ * NL80211_SAE_PWE_HUNT_AND_PECK: Allow hunting-and-pecking loop only
+ * NL80211_SAE_PWE_HASH_TO_ELEMENT: Allow hash-to-element only
+ * NL80211_SAE_PWE_BOTH: Allow either hunting-and-pecking loop
+ * or hash-to-element
*/
struct cfg80211_crypto_settings {
u32 wpa_versions;
@@ -1027,6 +1035,7 @@ struct cfg80211_crypto_settings {
const u8 *psk;
const u8 *sae_pwd;
u8 sae_pwd_len;
+ enum nl80211_sae_pwe_mechanism sae_pwe;
};
/**
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -736,6 +736,9 @@ static const struct nla_policy nl80211_p
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
[NL80211_ATTR_S1G_CAPABILITY_MASK] =
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
+ [NL80211_ATTR_SAE_PWE] =
+ NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
+ NL80211_SAE_PWE_BOTH),
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
};
@@ -9763,6 +9766,12 @@ static int nl80211_crypto_settings(struc
nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
}
+ if (info->attrs[NL80211_ATTR_SAE_PWE])
+ settings->sae_pwe =
+ nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
+ else
+ settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
+
return 0;
}

38
package/kernel/mac80211/subsys/304-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch

@ -0,0 +1,38 @@
From b478e06a16a8baa00c5ecc87c1d636981f2206d5 Mon Sep 17 00:00:00 2001
From: Johannes Berg <[email protected]>
Date: Tue, 29 Oct 2019 10:25:25 +0100
Subject: [PATCH] mac80211: sta: randomize BA session dialog token allocator
We currently always start the dialog token generator at zero,
so the first dialog token we use is always 1. This would be
OK if we had a perfect guarantee that we always do a proper
deauth/re-auth handshake, but in IBSS mode this doesn't always
happen properly.
To make problems with block ack (aggregation) sessions getting
stuck less likely, randomize the dialog token so if we start a
new session but the peer still has old state for us, it can
better detect this.
This is really just a workaround to make things a bit more
robust than they are now - a better fix would be to do a full
authentication handshake in IBSS mode upon having discovered a
new station, and on the receiver resetting the state (removing
and re-adding the station) on receiving the authentication
packet.
Signed-off-by: Johannes Berg <[email protected]>
---
net/mac80211/sta_info.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -357,6 +357,7 @@ struct sta_info *sta_info_alloc(struct i
INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
mutex_init(&sta->ampdu_mlme.mtx);
+ sta->ampdu_mlme.dialog_token_allocator = prandom_u32_max(U8_MAX);
#ifdef CPTCFG_MAC80211_MESH
if (ieee80211_vif_is_mesh(&sdata->vif)) {
sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);

95
package/kernel/mac80211/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch

@ -0,0 +1,95 @@
From: Felix Fietkau <[email protected]>
Date: Wed, 25 Nov 2020 18:03:46 +0100
Subject: [PATCH] net/fq_impl: bulk-free packets from a flow on overmemory
This is similar to what sch_fq_codel does. It also amortizes the worst
case cost of a follow-up patch that changes the selection of the biggest
flow for dropping packets
Signed-off-by: Felix Fietkau <[email protected]>
---
--- a/include/net/fq_impl.h
+++ b/include/net/fq_impl.h
@@ -11,17 +11,25 @@
/* functions that are embedded into includer */
+
+static void
+__fq_adjust_removal(struct fq *fq, struct fq_flow *flow, unsigned int packets,
+ unsigned int bytes, unsigned int truesize)
+{
+ struct fq_tin *tin = flow->tin;
+
+ tin->backlog_bytes -= bytes;
+ tin->backlog_packets -= packets;
+ flow->backlog -= bytes;
+ fq->backlog -= packets;
+ fq->memory_usage -= truesize;
+}
+
static void fq_adjust_removal(struct fq *fq,
struct fq_flow *flow,
struct sk_buff *skb)
{
- struct fq_tin *tin = flow->tin;
-
- tin->backlog_bytes -= skb->len;
- tin->backlog_packets--;
- flow->backlog -= skb->len;
- fq->backlog--;
- fq->memory_usage -= skb->truesize;
+ __fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize);
}
static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
@@ -59,6 +67,34 @@ static struct sk_buff *fq_flow_dequeue(s
return skb;
}
+static int fq_flow_drop(struct fq *fq, struct fq_flow *flow,
+ fq_skb_free_t free_func)
+{
+ unsigned int packets = 0, bytes = 0, truesize = 0;
+ struct fq_tin *tin = flow->tin;
+ struct sk_buff *skb;
+ int pending;
+
+ lockdep_assert_held(&fq->lock);
+
+ pending = min_t(int, 32, skb_queue_len(&flow->queue) / 2);
+ do {
+ skb = __skb_dequeue(&flow->queue);
+ if (!skb)
+ break;
+
+ packets++;
+ bytes += skb->len;
+ truesize += skb->truesize;
+ free_func(fq, tin, flow, skb);
+ } while (packets < pending);
+
+ __fq_adjust_removal(fq, flow, packets, bytes, truesize);
+ fq_rejigger_backlog(fq, flow);
+
+ return packets;
+}
+
static struct sk_buff *fq_tin_dequeue(struct fq *fq,
struct fq_tin *tin,
fq_tin_dequeue_t dequeue_func)
@@ -190,12 +226,9 @@ static void fq_tin_enqueue(struct fq *fq
if (!flow)
return;
- skb = fq_flow_dequeue(fq, flow);
- if (!skb)
+ if (!fq_flow_drop(fq, flow, free_func))
return;
- free_func(fq, flow->tin, flow, skb);
-
flow->tin->overlimit++;
fq->overlimit++;
if (oom) {

144
package/kernel/mac80211/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch

@ -0,0 +1,144 @@
From: Felix Fietkau <[email protected]>
Date: Wed, 25 Nov 2020 18:09:10 +0100
Subject: [PATCH] net/fq_impl: drop get_default_func, move default flow to
fq_tin
Simplifies the code and prepares for a rework of scanning for flows on
overmemory drop.
Signed-off-by: Felix Fietkau <[email protected]>
---
--- a/include/net/fq.h
+++ b/include/net/fq.h
@@ -47,6 +47,7 @@ struct fq_flow {
struct fq_tin {
struct list_head new_flows;
struct list_head old_flows;
+ struct fq_flow default_flow;
u32 backlog_bytes;
u32 backlog_packets;
u32 overlimit;
--- a/include/net/fq_impl.h
+++ b/include/net/fq_impl.h
@@ -151,8 +151,7 @@ static u32 fq_flow_idx(struct fq *fq, st
static struct fq_flow *fq_flow_classify(struct fq *fq,
struct fq_tin *tin, u32 idx,
- struct sk_buff *skb,
- fq_flow_get_default_t get_default_func)
+ struct sk_buff *skb)
{
struct fq_flow *flow;
@@ -160,7 +159,7 @@ static struct fq_flow *fq_flow_classify(
flow = &fq->flows[idx];
if (flow->tin && flow->tin != tin) {
- flow = get_default_func(fq, tin, idx, skb);
+ flow = &tin->default_flow;
tin->collisions++;
fq->collisions++;
}
@@ -192,15 +191,14 @@ static void fq_recalc_backlog(struct fq
static void fq_tin_enqueue(struct fq *fq,
struct fq_tin *tin, u32 idx,
struct sk_buff *skb,
- fq_skb_free_t free_func,
- fq_flow_get_default_t get_default_func)
+ fq_skb_free_t free_func)
{
struct fq_flow *flow;
bool oom;
lockdep_assert_held(&fq->lock);
- flow = fq_flow_classify(fq, tin, idx, skb, get_default_func);
+ flow = fq_flow_classify(fq, tin, idx, skb);
flow->tin = tin;
flow->backlog += skb->len;
@@ -331,6 +329,7 @@ static void fq_tin_init(struct fq_tin *t
{
INIT_LIST_HEAD(&tin->new_flows);
INIT_LIST_HEAD(&tin->old_flows);
+ fq_flow_init(&tin->default_flow);
}
static int fq_init(struct fq *fq, int flows_cnt)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -846,7 +846,6 @@ enum txq_info_flags {
*/
struct txq_info {
struct fq_tin tin;
- struct fq_flow def_flow;
struct codel_vars def_cvars;
struct codel_stats cstats;
struct sk_buff_head frags;
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1322,7 +1322,7 @@ static struct sk_buff *codel_dequeue_fun
fq = &local->fq;
if (cvars == &txqi->def_cvars)
- flow = &txqi->def_flow;
+ flow = &txqi->tin.default_flow;
else
flow = &fq->flows[cvars - local->cvars];
@@ -1365,7 +1365,7 @@ static struct sk_buff *fq_tin_dequeue_fu
cparams = &local->cparams;
}
- if (flow == &txqi->def_flow)
+ if (flow == &tin->default_flow)
cvars = &txqi->def_cvars;
else
cvars = &local->cvars[flow - fq->flows];
@@ -1392,17 +1392,6 @@ static void fq_skb_free_func(struct fq *
ieee80211_free_txskb(&local->hw, skb);
}
-static struct fq_flow *fq_flow_get_default_func(struct fq *fq,
- struct fq_tin *tin,
- int idx,
- struct sk_buff *skb)
-{
- struct txq_info *txqi;
-
- txqi = container_of(tin, struct txq_info, tin);
- return &txqi->def_flow;
-}
-
static void ieee80211_txq_enqueue(struct ieee80211_local *local,
struct txq_info *txqi,
struct sk_buff *skb)
@@ -1415,8 +1404,7 @@ static void ieee80211_txq_enqueue(struct
spin_lock_bh(&fq->lock);
fq_tin_enqueue(fq, tin, flow_idx, skb,
- fq_skb_free_func,
- fq_flow_get_default_func);
+ fq_skb_free_func);
spin_unlock_bh(&fq->lock);
}
@@ -1459,7 +1447,6 @@ void ieee80211_txq_init(struct ieee80211
struct txq_info *txqi, int tid)
{
fq_tin_init(&txqi->tin);
- fq_flow_init(&txqi->def_flow);
codel_vars_init(&txqi->def_cvars);
codel_stats_init(&txqi->cstats);
__skb_queue_head_init(&txqi->frags);
@@ -3332,8 +3319,7 @@ static bool ieee80211_amsdu_aggregate(st
*/
tin = &txqi->tin;
- flow = fq_flow_classify(fq, tin, flow_idx, skb,
- fq_flow_get_default_func);
+ flow = fq_flow_classify(fq, tin, flow_idx, skb);
head = skb_peek_tail(&flow->queue);
if (!head || skb_is_gso(head))
goto out;

317
package/kernel/mac80211/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch

@ -0,0 +1,317 @@
From: Felix Fietkau <[email protected]>
Date: Wed, 25 Nov 2020 18:10:34 +0100
Subject: [PATCH] net/fq_impl: do not maintain a backlog-sorted list of
flows
A sorted flow list is only needed to drop packets in the biggest flow when
hitting the overmemory condition.
By scanning flows only when needed, we can avoid paying the cost of
maintaining the list under normal conditions
In order to avoid scanning lots of empty flows and touching too many cold
cache lines, a bitmap of flows with backlog is maintained
Signed-off-by: Felix Fietkau <[email protected]>
---
--- a/include/net/fq.h
+++ b/include/net/fq.h
@@ -19,8 +19,6 @@ struct fq_tin;
* @flowchain: can be linked to fq_tin's new_flows or old_flows. Used for DRR++
* (deficit round robin) based round robin queuing similar to the one
* found in net/sched/sch_fq_codel.c
- * @backlogchain: can be linked to other fq_flow and fq. Used to keep track of
- * fat flows and efficient head-dropping if packet limit is reached
* @queue: sk_buff queue to hold packets
* @backlog: number of bytes pending in the queue. The number of packets can be
* found in @queue.qlen
@@ -29,7 +27,6 @@ struct fq_tin;
struct fq_flow {
struct fq_tin *tin;
struct list_head flowchain;
- struct list_head backlogchain;
struct sk_buff_head queue;
u32 backlog;
int deficit;
@@ -47,6 +44,7 @@ struct fq_flow {
struct fq_tin {
struct list_head new_flows;
struct list_head old_flows;
+ struct list_head tin_list;
struct fq_flow default_flow;
u32 backlog_bytes;
u32 backlog_packets;
@@ -60,14 +58,14 @@ struct fq_tin {
/**
* struct fq - main container for fair queuing purposes
*
- * @backlogs: linked to fq_flows. Used to maintain fat flows for efficient
- * head-dropping when @backlog reaches @limit
* @limit: max number of packets that can be queued across all flows
* @backlog: number of packets queued across all flows
*/
struct fq {
struct fq_flow *flows;
- struct list_head backlogs;
+ unsigned long *flows_bitmap;
+
+ struct list_head tin_backlog;
spinlock_t lock;
u32 flows_cnt;
u32 limit;
--- a/include/net/fq_impl.h
+++ b/include/net/fq_impl.h
@@ -17,12 +17,24 @@ __fq_adjust_removal(struct fq *fq, struc
unsigned int bytes, unsigned int truesize)
{
struct fq_tin *tin = flow->tin;
+ int idx;
tin->backlog_bytes -= bytes;
tin->backlog_packets -= packets;
flow->backlog -= bytes;
fq->backlog -= packets;
fq->memory_usage -= truesize;
+
+ if (flow->backlog)
+ return;
+
+ if (flow == &tin->default_flow) {
+ list_del_init(&tin->tin_list);
+ return;
+ }
+
+ idx = flow - fq->flows;
+ __clear_bit(idx, fq->flows_bitmap);
}
static void fq_adjust_removal(struct fq *fq,
@@ -32,24 +44,6 @@ static void fq_adjust_removal(struct fq
__fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize);
}
-static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
-{
- struct fq_flow *i;
-
- if (flow->backlog == 0) {
- list_del_init(&flow->backlogchain);
- } else {
- i = flow;
-
- list_for_each_entry_continue(i, &fq->backlogs, backlogchain)
- if (i->backlog < flow->backlog)
- break;
-
- list_move_tail(&flow->backlogchain,
- &i->backlogchain);
- }
-}
-
static struct sk_buff *fq_flow_dequeue(struct fq *fq,
struct fq_flow *flow)
{
@@ -62,7 +56,6 @@ static struct sk_buff *fq_flow_dequeue(s
return NULL;
fq_adjust_removal(fq, flow, skb);
- fq_rejigger_backlog(fq, flow);
return skb;
}
@@ -90,7 +83,6 @@ static int fq_flow_drop(struct fq *fq, s
} while (packets < pending);
__fq_adjust_removal(fq, flow, packets, bytes, truesize);
- fq_rejigger_backlog(fq, flow);
return packets;
}
@@ -170,22 +162,36 @@ static struct fq_flow *fq_flow_classify(
return flow;
}
-static void fq_recalc_backlog(struct fq *fq,
- struct fq_tin *tin,
- struct fq_flow *flow)
-{
- struct fq_flow *i;
-
- if (list_empty(&flow->backlogchain))
- list_add_tail(&flow->backlogchain, &fq->backlogs);
-
- i = flow;
- list_for_each_entry_continue_reverse(i, &fq->backlogs,
- backlogchain)
- if (i->backlog > flow->backlog)
- break;
+static struct fq_flow *fq_find_fattest_flow(struct fq *fq)
+{
+ struct fq_tin *tin;
+ struct fq_flow *flow = NULL;
+ u32 len = 0;
+ int i;
+
+ for_each_set_bit(i, fq->flows_bitmap, fq->flows_cnt) {
+ struct fq_flow *cur = &fq->flows[i];
+ unsigned int cur_len;
+
+ cur_len = cur->backlog;
+ if (cur_len <= len)
+ continue;
+
+ flow = cur;
+ len = cur_len;
+ }
- list_move(&flow->backlogchain, &i->backlogchain);
+ list_for_each_entry(tin, &fq->tin_backlog, tin_list) {
+ unsigned int cur_len = tin->default_flow.backlog;
+
+ if (cur_len <= len)
+ continue;
+
+ flow = &tin->default_flow;
+ len = cur_len;
+ }
+
+ return flow;
}
static void fq_tin_enqueue(struct fq *fq,
@@ -200,6 +206,13 @@ static void fq_tin_enqueue(struct fq *fq
flow = fq_flow_classify(fq, tin, idx, skb);
+ if (!flow->backlog) {
+ if (flow != &tin->default_flow)
+ __set_bit(idx, fq->flows_bitmap);
+ else if (list_empty(&tin->tin_list))
+ list_add(&tin->tin_list, &fq->tin_backlog);
+ }
+
flow->tin = tin;
flow->backlog += skb->len;
tin->backlog_bytes += skb->len;
@@ -207,8 +220,6 @@ static void fq_tin_enqueue(struct fq *fq
fq->memory_usage += skb->truesize;
fq->backlog++;
- fq_recalc_backlog(fq, tin, flow);
-
if (list_empty(&flow->flowchain)) {
flow->deficit = fq->quantum;
list_add_tail(&flow->flowchain,
@@ -218,9 +229,7 @@ static void fq_tin_enqueue(struct fq *fq
__skb_queue_tail(&flow->queue, skb);
oom = (fq->memory_usage > fq->memory_limit);
while (fq->backlog > fq->limit || oom) {
- flow = list_first_entry_or_null(&fq->backlogs,
- struct fq_flow,
- backlogchain);
+ flow = fq_find_fattest_flow(fq);
if (!flow)
return;
@@ -255,8 +264,6 @@ static void fq_flow_filter(struct fq *fq
fq_adjust_removal(fq, flow, skb);
free_func(fq, tin, flow, skb);
}
-
- fq_rejigger_backlog(fq, flow);
}
static void fq_tin_filter(struct fq *fq,
@@ -279,16 +286,18 @@ static void fq_flow_reset(struct fq *fq,
struct fq_flow *flow,
fq_skb_free_t free_func)
{
+ struct fq_tin *tin = flow->tin;
struct sk_buff *skb;
while ((skb = fq_flow_dequeue(fq, flow)))
- free_func(fq, flow->tin, flow, skb);
+ free_func(fq, tin, flow, skb);
- if (!list_empty(&flow->flowchain))
+ if (!list_empty(&flow->flowchain)) {
list_del_init(&flow->flowchain);
-
- if (!list_empty(&flow->backlogchain))
- list_del_init(&flow->backlogchain);
+ if (list_empty(&tin->new_flows) &&
+ list_empty(&tin->old_flows))
+ list_del_init(&tin->tin_list);
+ }
flow->tin = NULL;
@@ -314,6 +323,7 @@ static void fq_tin_reset(struct fq *fq,
fq_flow_reset(fq, flow, free_func);
}
+ WARN_ON_ONCE(!list_empty(&tin->tin_list));
WARN_ON_ONCE(tin->backlog_bytes);
WARN_ON_ONCE(tin->backlog_packets);
}
@@ -321,7 +331,6 @@ static void fq_tin_reset(struct fq *fq,
static void fq_flow_init(struct fq_flow *flow)
{
INIT_LIST_HEAD(&flow->flowchain);
- INIT_LIST_HEAD(&flow->backlogchain);
__skb_queue_head_init(&flow->queue);
}
@@ -329,6 +338,7 @@ static void fq_tin_init(struct fq_tin *t
{
INIT_LIST_HEAD(&tin->new_flows);
INIT_LIST_HEAD(&tin->old_flows);
+ INIT_LIST_HEAD(&tin->tin_list);
fq_flow_init(&tin->default_flow);
}
@@ -337,8 +347,8 @@ static int fq_init(struct fq *fq, int fl
int i;
memset(fq, 0, sizeof(fq[0]));
- INIT_LIST_HEAD(&fq->backlogs);
spin_lock_init(&fq->lock);
+ INIT_LIST_HEAD(&fq->tin_backlog);
fq->flows_cnt = max_t(u32, flows_cnt, 1);
fq->quantum = 300;
fq->limit = 8192;
@@ -348,6 +358,14 @@ static int fq_init(struct fq *fq, int fl
if (!fq->flows)
return -ENOMEM;
+ fq->flows_bitmap = kcalloc(BITS_TO_LONGS(fq->flows_cnt), sizeof(long),
+ GFP_KERNEL);
+ if (!fq->flows_bitmap) {
+ kvfree(fq->flows);
+ fq->flows = NULL;
+ return -ENOMEM;
+ }
+
for (i = 0; i < fq->flows_cnt; i++)
fq_flow_init(&fq->flows[i]);
@@ -364,6 +382,9 @@ static void fq_reset(struct fq *fq,
kvfree(fq->flows);
fq->flows = NULL;
+
+ kfree(fq->flows_bitmap);
+ fq->flows_bitmap = NULL;
}
#endif
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3386,8 +3386,6 @@ out_recalc:
if (head->len != orig_len) {
flow->backlog += head->len - orig_len;
tin->backlog_bytes += head->len - orig_len;
-
- fq_recalc_backlog(fq, tin, flow);
}
out:
spin_unlock_bh(&fq->lock);

570
package/kernel/mac80211/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch

@ -0,0 +1,570 @@
From: Felix Fietkau <[email protected]>
Date: Wed, 16 Dec 2020 21:34:03 +0100
Subject: [PATCH] mac80211: add rx decapsulation offload support
This allows drivers to pass 802.3 frames to mac80211, with some restrictions:
- the skb must be passed with a valid sta
- fast-rx needs to be active for the sta
- monitor mode needs to be disabled
mac80211 will tell the driver when it is safe to enable rx decap offload for
a particular station.
In order to implement support, a driver must:
- call ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD)
- implement ops->sta_set_decap_offload
- mark 802.3 frames with RX_FLAG_8023
If it doesn't want to enable offload for some vif types, it can mask out
IEEE80211_OFFLOAD_DECAP_ENABLED in vif->offload_flags from within the
.add_interface or .update_vif_offload driver ops
Signed-off-by: Felix Fietkau <[email protected]>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1297,6 +1297,8 @@ ieee80211_tx_info_clear_status(struct ie
* the "0-length PSDU" field included there. The value for it is
* in &struct ieee80211_rx_status. Note that if this value isn't
* known the frame shouldn't be reported.
+ * @RX_FLAG_8023: the frame has an 802.3 header (decap offload performed by
+ * hardware or driver)
*/
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = BIT(0),
@@ -1329,6 +1331,7 @@ enum mac80211_rx_flags {
RX_FLAG_RADIOTAP_HE_MU = BIT(27),
RX_FLAG_RADIOTAP_LSIG = BIT(28),
RX_FLAG_NO_PSDU = BIT(29),
+ RX_FLAG_8023 = BIT(30),
};
/**
@@ -1650,11 +1653,15 @@ enum ieee80211_vif_flags {
* The driver supports sending frames passed as 802.3 frames by mac80211.
* It must also support sending 802.11 packets for the same interface.
* @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
+ * @IEEE80211_OFFLOAD_DECAP_ENABLED: rx encapsulation offload is enabled
+ * The driver supports passing received 802.11 frames as 802.3 frames to
+ * mac80211.
*/
enum ieee80211_offload_flags {
IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0),
IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1),
+ IEEE80211_OFFLOAD_DECAP_ENABLED = BIT(2),
};
/**
@@ -2390,6 +2397,9 @@ struct ieee80211_txq {
* @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
* offload
*
+ * @IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD: Hardware supports rx decapsulation
+ * offload
+ *
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@@ -2443,6 +2453,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
+ IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -4196,6 +4207,9 @@ struct ieee80211_ops {
struct ieee80211_vif *vif);
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enabled);
+ void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, bool enabled);
};
/**
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -405,6 +405,7 @@ static const char *hw_flag_names[] = {
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
FLAG(AMPDU_KEYBORDER_SUPPORT),
FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
+ FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
#undef FLAG
};
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -79,6 +79,7 @@ static const char * const sta_flag_names
FLAG(MPSP_RECIPIENT),
FLAG(PS_DELIVER),
FLAG(USES_ENCRYPTION),
+ FLAG(DECAP_OFFLOAD),
#undef FLAG
};
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1413,4 +1413,20 @@ static inline void drv_sta_set_4addr(str
trace_drv_return_void(local);
}
+static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta,
+ bool enabled)
+{
+ sdata = get_bss_sdata(sdata);
+ if (!check_sdata_in_driver(sdata))
+ return;
+
+ trace_drv_sta_set_decap_offload(local, sdata, sta, enabled);
+ if (local->ops->sta_set_decap_offload)
+ local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta,
+ enabled);
+ trace_drv_return_void(local);
+}
+
#endif /* __MAC80211_DRIVER_OPS */
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -856,7 +856,7 @@ static const struct net_device_ops ieee8
};
-static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
+static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)
{
switch (iftype) {
/* P2P GO and client are mapped to AP/STATION types */
@@ -876,7 +876,7 @@ static bool ieee80211_set_sdata_offload_
flags = sdata->vif.offload_flags;
if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
- ieee80211_iftype_supports_encap_offload(sdata->vif.type)) {
+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;
if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
@@ -889,10 +889,21 @@ static bool ieee80211_set_sdata_offload_
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
}
+ if (ieee80211_hw_check(&local->hw, SUPPORTS_RX_DECAP_OFFLOAD) &&
+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
+ flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
+
+ if (local->monitors)
+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
+ } else {
+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
+ }
+
if (sdata->vif.offload_flags == flags)
return false;
sdata->vif.offload_flags = flags;
+ ieee80211_check_fast_rx_iface(sdata);
return true;
}
@@ -910,7 +921,7 @@ static void ieee80211_set_vif_encap_ops(
}
if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
- !ieee80211_iftype_supports_encap_offload(bss->vif.type))
+ !ieee80211_iftype_supports_hdr_offload(bss->vif.type))
return;
enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4195,7 +4195,9 @@ void ieee80211_check_fast_rx(struct sta_
.vif_type = sdata->vif.type,
.control_port_protocol = sdata->control_port_protocol,
}, *old, *new = NULL;
+ bool set_offload = false;
bool assign = false;
+ bool offload;
/* use sparse to check that we don't return without updating */
__acquire(check_fast_rx);
@@ -4308,6 +4310,17 @@ void ieee80211_check_fast_rx(struct sta_
if (assign)
new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);
+ offload = assign &&
+ (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED);
+
+ if (offload)
+ set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
+ else
+ set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
+
+ if (set_offload)
+ drv_sta_set_decap_offload(local, sdata, &sta->sta, assign);
+
spin_lock_bh(&sta->lock);
old = rcu_dereference_protected(sta->fast_rx, true);
rcu_assign_pointer(sta->fast_rx, new);
@@ -4354,6 +4367,108 @@ void ieee80211_check_fast_rx_iface(struc
mutex_unlock(&local->sta_mtx);
}
+static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
+ struct ieee80211_fast_rx *fast_rx,
+ int orig_len)
+{
+ struct ieee80211_sta_rx_stats *stats;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+ struct sta_info *sta = rx->sta;
+ struct sk_buff *skb = rx->skb;
+ void *sa = skb->data + ETH_ALEN;
+ void *da = skb->data;
+
+ stats = &sta->rx_stats;
+ if (fast_rx->uses_rss)
+ stats = this_cpu_ptr(sta->pcpu_rx_stats);
+
+ /* statistics part of ieee80211_rx_h_sta_process() */
+ if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
+ stats->last_signal = status->signal;
+ if (!fast_rx->uses_rss)
+ ewma_signal_add(&sta->rx_stats_avg.signal,
+ -status->signal);
+ }
+
+ if (status->chains) {
+ int i;
+
+ stats->chains = status->chains;
+ for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
+ int signal = status->chain_signal[i];
+
+ if (!(status->chains & BIT(i)))
+ continue;
+
+ stats->chain_signal_last[i] = signal;
+ if (!fast_rx->uses_rss)
+ ewma_signal_add(&sta->rx_stats_avg.chain_signal[i],
+ -signal);
+ }
+ }
+ /* end of statistics */
+
+ stats->last_rx = jiffies;
+ stats->last_rate = sta_stats_encode_rate(status);
+
+ stats->fragments++;
+ stats->packets++;
+
+ skb->dev = fast_rx->dev;
+
+ ieee80211_rx_stats(fast_rx->dev, skb->len);
+
+ /* The seqno index has the same property as needed
+ * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
+ * for non-QoS-data frames. Here we know it's a data
+ * frame, so count MSDUs.
+ */
+ u64_stats_update_begin(&stats->syncp);
+ stats->msdu[rx->seqno_idx]++;
+ stats->bytes += orig_len;
+ u64_stats_update_end(&stats->syncp);
+
+ if (fast_rx->internal_forward) {
+ struct sk_buff *xmit_skb = NULL;
+ if (is_multicast_ether_addr(da)) {
+ xmit_skb = skb_copy(skb, GFP_ATOMIC);
+ } else if (!ether_addr_equal(da, sa) &&
+ sta_info_get(rx->sdata, da)) {
+ xmit_skb = skb;
+ skb = NULL;
+ }
+
+ if (xmit_skb) {
+ /*
+ * Send to wireless media and increase priority by 256
+ * to keep the received priority instead of
+ * reclassifying the frame (see cfg80211_classify8021d).
+ */
+ xmit_skb->priority += 256;
+ xmit_skb->protocol = htons(ETH_P_802_3);
+ skb_reset_network_header(xmit_skb);
+ skb_reset_mac_header(xmit_skb);
+ dev_queue_xmit(xmit_skb);
+ }
+
+ if (!skb)
+ return;
+ }
+
+ /* deliver to local stack */
+ skb->protocol = eth_type_trans(skb, fast_rx->dev);
+ memset(skb->cb, 0, sizeof(skb->cb));
+ if (rx->list)
+#if LINUX_VERSION_IS_GEQ(4,19,0)
+ list_add_tail(&skb->list, rx->list);
+#else
+ __skb_queue_tail(rx->list, skb);
+#endif
+ else
+ netif_receive_skb(skb);
+
+}
+
static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
struct ieee80211_fast_rx *fast_rx)
{
@@ -4374,9 +4489,6 @@ static bool ieee80211_invoke_fast_rx(str
} addrs __aligned(2);
struct ieee80211_sta_rx_stats *stats = &sta->rx_stats;
- if (fast_rx->uses_rss)
- stats = this_cpu_ptr(sta->pcpu_rx_stats);
-
/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
* to a common data structure; drivers can implement that per queue
* but we don't have that information in mac80211
@@ -4450,32 +4562,6 @@ static bool ieee80211_invoke_fast_rx(str
pskb_trim(skb, skb->len - fast_rx->icv_len))
goto drop;
- /* statistics part of ieee80211_rx_h_sta_process() */
- if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
- stats->last_signal = status->signal;
- if (!fast_rx->uses_rss)
- ewma_signal_add(&sta->rx_stats_avg.signal,
- -status->signal);
- }
-
- if (status->chains) {
- int i;
-
- stats->chains = status->chains;
- for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
- int signal = status->chain_signal[i];
-
- if (!(status->chains & BIT(i)))
- continue;
-
- stats->chain_signal_last[i] = signal;
- if (!fast_rx->uses_rss)
- ewma_signal_add(&sta->rx_stats_avg.chain_signal[i],
- -signal);
- }
- }
- /* end of statistics */
-
if (rx->key && !ieee80211_has_protected(hdr->frame_control))
goto drop;
@@ -4487,12 +4573,6 @@ static bool ieee80211_invoke_fast_rx(str
return true;
}
- stats->last_rx = jiffies;
- stats->last_rate = sta_stats_encode_rate(status);
-
- stats->fragments++;
- stats->packets++;
-
/* do the header conversion - first grab the addresses */
ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
@@ -4501,62 +4581,14 @@ static bool ieee80211_invoke_fast_rx(str