aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO2
-rw-r--r--PKGBUILD4
-rw-r--r--iwlwifi-next-patches-through-2020-11-08-5.15.3.patch8714
3 files changed, 8720 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 92bc9ae78217..74b8e9f56de6 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -26,6 +26,7 @@ pkgbase = linux-xanmod-rog
source = x86-change-default-to-spec_store_bypass_disable-prct.patch
source = cfg80211-dont-WARN-if-a-self-managed-device.patch
source = r8152-fix-spurious-wakeups-from-s0i3.patch
+ source = iwlwifi-next-patches-through-2020-11-08-5.15.3.patch
source = HID-asus-Reduce-object-size-by-consolidating-calls.patch
source = v16-asus-wmi-Add-support-for-custom-fan-curves.patch
source = mt76-mt7921-Fix-out-of-order-process-by-invalid-even.patch
@@ -58,6 +59,7 @@ pkgbase = linux-xanmod-rog
sha256sums = cc401107f1bf7b7d8e8a78ee594f9db4b6fa252b7239b6aa88f678aef84d935c
sha256sums = 3d8961438b5c8110588ff0b881d472fc71a4304d306808d78a4055a4150f351e
sha256sums = f47a5a5e329e410a0ae7d46b450707d5575a4deda5b3b58281f5eca14938fb21
+ sha256sums = b12a5bb789e4c854617ca3c7405fcc3121457ddb6564c8f758edfe4633cf24bd
sha256sums = 544464bf0807b324120767d55867f03014a9fda4e1804768ca341be902d7ade4
sha256sums = 0c422d8f420c1518aab1b980c6cdb6e029a4fa9cde1fd99a63670bb105a44f36
sha256sums = 2163cb2e394a013042a40cd3b00dae788603284b20d71e262995366c5534e480
diff --git a/PKGBUILD b/PKGBUILD
index 784cc911363a..292f6238e618 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -143,6 +143,9 @@ source=("https://cdn.kernel.org/pub/linux/kernel/v${_branch}/linux-${_major}.tar
# 5.15: r8169 hwIDs for the G14?/G15
+ # cherry-picked iwlwifi patches from -next
+ "iwlwifi-next-patches-through-2020-11-08-5.15.3.patch"
+
# ASUS ROG enablement
"HID-asus-Reduce-object-size-by-consolidating-calls.patch"
"v16-asus-wmi-Add-support-for-custom-fan-curves.patch"
@@ -185,6 +188,7 @@ sha256sums=('57b2cf6991910e3b67a1b3490022e8a0674b6965c74c12da1e99d138d1991ee8'
'cc401107f1bf7b7d8e8a78ee594f9db4b6fa252b7239b6aa88f678aef84d935c'
'3d8961438b5c8110588ff0b881d472fc71a4304d306808d78a4055a4150f351e'
'f47a5a5e329e410a0ae7d46b450707d5575a4deda5b3b58281f5eca14938fb21'
+ 'b12a5bb789e4c854617ca3c7405fcc3121457ddb6564c8f758edfe4633cf24bd'
'544464bf0807b324120767d55867f03014a9fda4e1804768ca341be902d7ade4'
'0c422d8f420c1518aab1b980c6cdb6e029a4fa9cde1fd99a63670bb105a44f36'
'2163cb2e394a013042a40cd3b00dae788603284b20d71e262995366c5534e480'
diff --git a/iwlwifi-next-patches-through-2020-11-08-5.15.3.patch b/iwlwifi-next-patches-through-2020-11-08-5.15.3.patch
new file mode 100644
index 000000000000..b3b87bd005c3
--- /dev/null
+++ b/iwlwifi-next-patches-through-2020-11-08-5.15.3.patch
@@ -0,0 +1,8714 @@
+From e8ddf43ee1788971c8a052e72e3be43eec570ac2 Mon Sep 17 00:00:00 2001
+From: Scott B <arglebargle@arglebargle.dev>
+Date: Mon, 15 Nov 2021 21:47:57 -0800
+Subject: [PATCH] iwlwifi -next patches through 2020-11-08 (5.15.3)
+
+Squashed commit of the following:
+
+commit 2ac5a26f5326dde18b1d349ed78b0b2ce962bfe4
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 24 18:20:37 2021 +0300
+
+ iwlwifi: bump FW API to 67 for AX devices
+
+ Start supporting API version 67 for AX devices.
+
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.3c0af5832d23.I7c18858604b72bc15cf2047a91531e4aa7c0527a@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 57d35e8df3375773eb913d79c162b2a85f084ee0
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 18:20:36 2021 +0300
+
+ iwlwifi: mvm: extend session protection on association
+
+ When we receive an association response, a significant amount
+ of time might have passed since we sent the corresponding
+ association request (mac80211 will wait up to 500ms for the TX
+ and then 100ms for the response after ACK was received). But
+ the time event is touched only when we send the assoc request,
+ so it might not have much time remaining, more easily causing
+ the (dreaded)
+
+ No beacon heard and the session protection is over already...
+
+ message.
+
+ Refactor iwl_mvm_mac_mgd_prepare_tx() and split out a new
+ function iwl_mvm_protect_assoc(), and call it on successful
+ association to extend the time event to the minimum time if
+ necessary.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.411c174d9e5e.I03c701c2e9e6788f34546e538264763db0ab30ef@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 67e2abb1d41311f6363efcb5fa6d49a2ed1d2261
+Author: Nathan Errera <nathan.errera@intel.com>
+Date: Sun Oct 24 18:20:35 2021 +0300
+
+ iwlwifi: rename CHANNEL_SWITCH_NOA_NOTIF to CHANNEL_SWITCH_START_NOTIF
+
+ There is no relation between the name and the purpose of the
+ notification. This notification is sent from FW when the channel switch
+ starts.
+
+ Signed-off-by: Nathan Errera <nathan.errera@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.24b71b0cb741.I97deb70e18f259de51395a1e7c7e58c7b006c317@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit f74be31340c22811607a1558717fd480fa4464cd
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 18:20:34 2021 +0300
+
+ iwlwifi: mvm: remove session protection on disassoc
+
+ If we somehow get disassociated while still waiting for a beacon
+ during connection, we can end up printing the
+
+ No beacon heard and the session protection is over already...
+
+ message even if we aren't really quite waiting for it anymore.
+ Remove the time event, if it's running, when we get disassociated
+ and don't need to wait for beacons anymore.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.6192e2363784.Ie9c2bfdc30dcfff2c4dd7c393c79e3ac182840a9@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit ff4273c24709c1e7d335fd0581c89169372990a5
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 24 18:20:33 2021 +0300
+
+ iwlwifi: mvm: fix WGDS table print in iwl_mvm_chub_update_mcc()
+
+ WGDS table index 0 means disabled, but we were erroneously checking
+ for < 0 to print that it is disabled. Fix that and make the print
+ more readable by mentioning that it's either disabled or there was an
+ error.
+
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.98a5572bf0f8.I6c112ca80cf427f12b2c752899d293cb6437ba5f@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 1cb255d4deccdadac489f0e6275ad0102e034846
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 24 18:20:32 2021 +0300
+
+ iwlwifi: rename GEO_TX_POWER_LIMIT to PER_CHAIN_LIMIT_OFFSET_CMD
+
+ When this code was implemented, there was no official FW API
+ description yet, so a placeholder name was used (GEO_TX_POWER_LIMIT).
+ But then the command became actually called
+ PER_CHAIN_LIMIT_OFFSET_CMD. Rename the command (and change related
+ comments) to PER_CHAIN_LIMIT_OFFSET_CMD to avoid confusion.
+
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.672fa727ef75.I6572df5d1e3441a0214993a59985da9a9431f3e5@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit b3a18082ba6fda825ec838d1342c0320adc3534d
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 18:20:31 2021 +0300
+
+ iwlwifi: mvm: d3: use internal data representation
+
+ Trying to convert from one firmware data representation to the
+ next version is getting tedious and error-prone, and doesn't
+ lend itself well to new APIs being added. Additionally, the
+ version 11 of the API as defined in the driver doesn't even
+ exist in the firmware.
+
+ Instead of converting to a newer firmware version of the data,
+ convert to an internal representation. This takes a bit more
+ space because the TKIP/AES counters etc. must be kept twice,
+ their representation is different and we don't know which of
+ the ones it is until later, but this is just a temporary use
+ of memory, and the code is clearer this way.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.9e71630627f3.Iad975e15338844ca068683f62a51eb1fcb69e608@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit baffbd30fcca2e3d22b6cdc53030e00001350cce
+Author: Gregory Greenman <gregory.greenman@intel.com>
+Date: Sun Oct 24 18:20:30 2021 +0300
+
+ iwlwifi: mvm: update RFI TLV
+
+ RFI TLV was moved in FW from set3 to set1 due to FW internal
+ dependency. Adjust driver to this change.
+
+ Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.90e42cd8cb37.I89ac9910e38006a2e5c9e87d371a8507f475572d@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit fc3754a5b89d24500ed50c7eeb94a45cf1aa0d8b
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 24 18:20:29 2021 +0300
+
+ iwlwifi: mvm: don't get address of mvm->fwrt just to dereference as a pointer
+
+ The mvm->fwrt element is not a pointer, but an instance of the
+ structure, so we should access its elements with a dot-notation
+ instead of getting the address and dereferencing it as a pointer.
+
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.ce6841093681.I09634a0aa845a0256e79c7895154d9ac35bc26be@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit e13eb098c5223fb574979d67591a40ebf6fd7672
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 24 18:20:28 2021 +0300
+
+ iwlwifi: mvm: read 6E enablement flags from DSM and pass to FW
+
+ We need to call a new DSM function and pass the values to the firmware
+ in order to allow enablement of 6E support by the OEMs via ACPI.
+
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.2fa34d31383c.I6504005c60882c94e6e58f64cab4e42e6481ce08@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 365715806c6a4b8c7bed4c908742da19dfad38c6
+Author: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
+Date: Sun Oct 24 18:20:27 2021 +0300
+
+ iwlwifi: yoyo: support for ROM usniffer
+
+ Add handling of config set TLV for ROM usniffer
+ support.
+
+ Signed-off-by: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.507212be427a.I36acb6ca84095963614be70dc944ba0d98ee770c@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 2fdff3e58cf9ae1e3ff5f3677455fe092b79587d
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 18:20:26 2021 +0300
+
+ iwlwifi: fw: uefi: add missing include guards
+
+ We still don't use #pragma once in the kernel, but even if
+ we did it'd be missing. Add the missing include guards.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Fixes: 84c3c9952afb ("iwlwifi: move UEFI code to a separate file")
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024181719.7fc9988ed49b.I87e300fab664047581e51fb9b02744c75320d08c@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 39bac9eb2e1ca3eb7fefb02c32d7c58cfb2a9821
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 16:55:06 2021 +0300
+
+ iwlwifi: dump host monitor data when NIC doesn't init
+
+ If the NIC cannot be initialized, dump host monitor data
+ so we can analyze properly why it didn't initialize.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.21c90ba4fa5f.I2a30f62aa4685dc7623d3c69838909833c3f435c@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 17f2f95228df28995f646aced70ad3de7296fb90
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 16:55:05 2021 +0300
+
+ iwlwifi: pcie: simplify iwl_pci_find_dev_info()
+
+ We currently match the list of devices from the start to
+ the end, but then find the *last* match, so we need to
+ look at each and every entry. We don't want to change the
+ semantics ("most generic entry must come first"), so just
+ change the order of matching to be back-to-front, then we
+ can break out once we find a match.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.abd85e1391cb.I7681fe90735044cc1c59f120e8591b7ac125535d@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit a4ff0d1baf7678713d025320a219ff6d6c9b57e9
+Author: Ayala Barazani <ayala.barazani@intel.com>
+Date: Sun Oct 24 16:55:04 2021 +0300
+
+ iwlwifi: ACPI: support revision 3 WGDS tables
+
+ There's a new revision of the WGDS table with more data,
+ and corresponding firmware API to pass it through. Add
+ support for both.
+
+ Since we now support 4 different versions, make a table
+ to load them instead of hard-coding it all.
+
+ Signed-off-by: Ayala Barazani <ayala.barazani@intel.com>
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.2f9b8e304f25.If88d2d1309270e659d4845c5b5c22d5e8d8e2caf@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 7e35aeede249526806dc744293a898cefbcb9d48
+Author: Mike Golant <michael.golant@intel.com>
+Date: Sun Oct 24 16:55:03 2021 +0300
+
+ iwlwifi: pcie: update sw error interrupt for BZ family
+
+ The cause for sw error in BZ device family was changed
+
+ Signed-off-by: Mike Golant <michael.golant@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.f674cd409b8e.I519f554d0a22d4711077785ec2bd7c564997241f@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 4f1076a29def7af94bc9af4b7d389cfee0365135
+Author: Yaara Baruch <yaara.baruch@intel.com>
+Date: Sun Oct 24 16:55:02 2021 +0300
+
+ iwlwifi: add new pci SoF with JF
+
+ add new SoF JF device to the driver.
+
+ Signed-off-by: Yaara Baruch <yaara.baruch@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.50e62c8ef85b.I3498879d8c184e42b1578a64aa7b7c99a18b75fb@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 6523738902d64f00c012ba0ab1b60b05cd929ce2
+Author: Ilan Peer <ilan.peer@intel.com>
+Date: Sun Oct 24 16:55:01 2021 +0300
+
+ iwlwifi: mvm: Use all Rx chains for roaming scan
+
+ To improve chances of hearing beacons and probe responses during
+ a scan which (based on the scan request parameters) looks like a
+ roaming scan, enable reception on all chains.
+
+ Signed-off-by: Ilan Peer <ilan.peer@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.f115ad455aca.I5de854fe8ce58c85c21a7adf43526acb29156a08@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 2fdfb992c30688d56381ad84e32891e1de4612d1
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 16:55:00 2021 +0300
+
+ iwlwifi: pcie: remove two duplicate PNJ device entries
+
+ Since PNJ and TH have the same ID (0x32), there are duplicate
+ entries. Remove the duplicates with PNJ since PNJ is only the
+ test device in the first place.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.0ca7c9322e69.Id2f32427795d0713fd7d2722567e604808b219dd@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit de1996132a459c61fb3fcf9d7bff308989ed8dfa
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 16:54:59 2021 +0300
+
+ iwlwifi: pcie: refactor dev_info lookup
+
+ The large condition here is not very clear, refactor the code to
+ a separate function where we can more easily just check each of
+ the pieces separately.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.ef06ed58a26e.Ie9664a94b157c5781c481118d900ae428c26fdb3@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 4a5c01835d4f4061e6f4ce4cfdf36a84a9d32f71
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 16:54:58 2021 +0300
+
+ iwlwifi: pcie: remove duplicate entry
+
+ This entry is literally duplicated, remove one of them.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.239f82fc3737.I5fef3a20fbce77e201dc35d45be0ee526bcd3cd3@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 5b278a707e44bea96eadd1e8cbdae89ccd09111f
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 24 16:54:57 2021 +0300
+
+ iwlwifi: pcie: fix killer name matching for AX200
+
+ The "Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)"
+ and "Killer(R) Wi-Fi 6 AX1650x 160MHz Wireless Network Adapter (200NGW)"
+ names couldn't match properly because the most generic entry needs to be
+ specified last.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.86a430e5b2ff.I7a9e89df7ddfc939690d3718d41afc934a4d4ea0@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 3d0caa9729dffdd75d06c499a4c8de8f2e76aecb
+Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Sun Oct 24 16:54:56 2021 +0300
+
+ iwlwifi: mvm: fix some kerneldoc issues
+
+ A few fields were missing their kerneldoc in the station
+ capabilities.
+
+ Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+ Fixes: c8a2e7a29702 ("iwlwifi: sta: set max HE max A-MPDU according to HE capa")
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211024165252.fecbcd7c2fcc.I7419f102b798ba0cecd93c80f345b241670e0683@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 4848621b626c86f5156120f30cccedb64781d583
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:59:54 2021 +0300
+
+ iwlwifi: pnvm: print out the version properly
+
+ The version really is a git sha1, not a hex number, so we
+ need to print it out with leading zeroes (8 digits) and
+ without 0x prefix.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.83422182774a.I40703fd517534133eb67d644ee16532ba8a67e35@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit f29e29d0467341651bd8933228ffcb34f23f086b
+Author: Rotem Saado <rotem.saado@intel.com>
+Date: Sun Oct 17 16:59:53 2021 +0300
+
+ iwlwifi: dbg: treat non active regions as unsupported regions
+
+ If a region is not active, it means that it was not defined as a region
+ TLV in the FW image. We should treat them as unsupported in that case.
+
+ This saves operational driver memory and run time when collecting debug
+ data by skipping unsupported regions.
+
+ Signed-off-by: Rotem Saado <rotem.saado@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.8025bd29d86a.I3ecb4e273bf714e426d82217e0590264cb763419@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit e256139032338e7eddda2ab9d46f504eb24bb894
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 16:59:52 2021 +0300
+
+ iwlwifi: mvm: Read acpi dsm to get channel activation bitmap
+
+ Read the bitmap from the ACPI and pass it to he FW
+ through LARI_CONFIG_CHANGE_CMD.
+
+ This allows OEMs to override channel state to active
+ as per Geo Location bitmap.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.23d4f2d182c0.I39ac5ff74ac6f2223f393657205eddc1c8e48890@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 0cfc653fae2981b30a8424cb0361b0d9e0f6ca5f
+Author: Yaara Baruch <yaara.baruch@intel.com>
+Date: Sun Oct 17 16:59:51 2021 +0300
+
+ iwlwifi: add new device id 7F70
+
+ Add new 7F70 device to cards id struct.
+ Add new 7F70 DID killers devices.
+
+ Signed-off-by: Yaara Baruch <yaara.baruch@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.d931a48ad8bd.I9b027837cba3478c9bb74c3f07df48eaef70a197@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit b4b4fcc731c4fc4eb370eb38d9b466ea06aaf203
+Author: Gregory Greenman <gregory.greenman@intel.com>
+Date: Sun Oct 17 16:59:50 2021 +0300
+
+ iwlwifi: mvm: improve log when processing CSA
+
+ Sometimes driver fails to detect misbehaving AP since we may
+ miss a few beacons (AP is declared misbehaving only after the second
+ time CSA counter has a wrong jump).
+ Move the print to the start of the function to avoid doubts when
+ analysing this kind of issues.
+
+ Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.8e6b1eb8a436.I5fd6caee968007e91d03b93d6ea84b670ce047e9@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 4774be3d261f2eca11f01be8c63486bfb2c20b74
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:59:49 2021 +0300
+
+ iwlwifi: mvm: set BT-coex high priority for 802.1X/4-way-HS
+
+ Set BT coex high priority during the 802.1X handshake to avoid
+ issues where BT is active enough to kill all the big negotiation
+ frames that we may need to send (e.g. with a large certificate),
+ leading to the connection not being established correctly. Give
+ WiFi priority over BT during this short but critical phase.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.a1825bbba397.I10315577fb41dfcec15c92e8f6785d9655f74c6a@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit e5269171bf377113362fb95b388253f16b8242f5
+Author: Rotem Saado <rotem.saado@intel.com>
+Date: Sun Oct 17 16:59:48 2021 +0300
+
+ iwlwifi: dbg: treat dbgc allocation failure when tlv is missing
+
+ in case allocation tlv is missing for specific dbgc id,
+ treat it as allocation failure.
+ with this behavior we removing later the unsupported regions
+ relating to the failed dbgc allocation.
+ this saves operational driver memory and run time at collecting
+ debug data.
+
+ Signed-off-by: Rotem Saado <rotem.saado@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.4cd241abf1de.I8f6cf00a7266675dfebdc01a73c1ac6e001855b9@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 5da40c65e5159257514d1b90925856f3c632e5be
+Author: Yaara Baruch <yaara.baruch@intel.com>
+Date: Sun Oct 17 16:59:47 2021 +0300
+
+ iwlwifi: add new killer devices to the driver
+
+ Add 1550, 1675 and 1690 killer devices to the driver.
+
+ Signed-off-by: Yaara Baruch <yaara.baruch@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.9a3d01b8c4e9.I9720afa0a6ea72f94ed4a3f3cf88294174ab905b@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 6e8008d8fe8e132c8caf50e4b4625fc30134854d
+Author: Sara Sharon <sara.sharon@intel.com>
+Date: Sun Oct 17 16:59:46 2021 +0300
+
+ iwlwifi: mvm: set inactivity timeouts also for PS-poll
+
+ Code tried to avoid setting ACs for PS-poll by an early return.
+ However as a result the timeouts weren't set as well.
+
+ Inactivity timeout of zero means we will always try to go back to
+ sleep immediately after moving to AM, which doesn't make much sense,
+ and isn't supported by FW.
+
+ Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.dda7f6ba0b22.Ia107bfe496b84e8a2edb33d9f39a5d2b56ed63f7@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 891d6ffa3aaef7fc1181218d074bd760a6d05a0e
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:59:45 2021 +0300
+
+ iwlwifi: pcie: try to grab NIC access early
+
+ Sometimes some NICs may fail to initialize, but if we have
+ such a scenario we may only see an alive timeout (i.e. the
+ firmware doesn't send us the alive message), and that will
+ only cause us to fail the interface up.
+
+ Try to once grab NIC access during device probe to ensure
+ we can properly talk to the hardware at all, and to do all
+ the potential workarounds in that function.
+
+ Since we now finish NIC init here, we can remove it from
+ the later potential read of the RF ID.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017165728.604dfc8f43bd.I07b58a5c9238f75413a91198452ba1268ee79425@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit f460305dfc550fc14fe98e8bbad13c5a3ae8a175
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:26:04 2021 +0300
+
+ iwlwifi: mvm: reduce WARN_ON() in TX status path
+
+ Evidently, it's possible to hit this issue, so reduce the
+ noise from it by just having it print a (rate-limited)
+ message instead. We don't really know yet why we hit it,
+ but there's no value in having a WARN_ON() here.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.8d503387b523.Id2c82d023df5128e553b28c935d30df4d9411917@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit bdce42c3dd26443ea8876965baf5e26544d20359
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:26:03 2021 +0300
+
+ iwlwifi: allow rate-limited error messages
+
+ Sometimes we might want to have an error message for something
+ related to TX/RX, but if that somehow happens frequently it'll
+ overwhelm the logs. Add IWL_ERR_LIMIT() to alleviate that by
+ rate-limiting those messages.
+
+ To do this, rework __iwl_err() a bit to have a mode argument
+ instead of passing yet another (bool) argument to it.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.2cb1e6b75672.Iec5b1c1bcc6ebc87c586921a6c5c2a937f49e83c@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 50168f503b6741492553c2a24fcb0f11f587abc1
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:26:02 2021 +0300
+
+ iwlwifi: mvm: remove session protection after auth/assoc
+
+ When auth/assoc completes, we should remove session protection,
+ except when association is successful, where we need it until a
+ beacon is received from the AP.
+
+ In particular, in the case of assoc comeback, currently the session
+ protection event just times out, leading to confusing messages:
+
+ wlan0: 42:00:00:00:00:00 rejected association temporarily; comeback duration 1000 TU (1024 ms)
+ iwlwifi 0000:00:00.0: Not associated and the session protection is over already...
+ wlan0: Connection to AP 42:00:00:00:00:00 lost
+ wlan0: associate with 42:00:00:00:00:00 (try 2/3)
+
+ mac80211 never does anything on the "Connection ... lost" as it's
+ not even connected.
+
+ Removing the session protection when it's no longer needed removes
+ those confusing messages and lets the device do other things in the
+ allocated time.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.95e4bebb069b.I635280e5d26c70414ac6eb5d62b46fe4bd942818@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit e424a6aaa92d58bae29430c9aa5d3210ef1cbf37
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 16:26:01 2021 +0300
+
+ iwlwifi: remove redundant iwl_finish_nic_init() argument
+
+ We don't need this argument, since in all cases where the
+ function is called, trans->trans_cfg is already set (it's
+ in fact set during allocation). Remove it to avoid any
+ confusion about it.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.cb04580b8521.I7129d4ba3dc689af839761d5807a10f99718893e@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit ebb6e7fd957da8d01b977f9316eba9548e6e5d58
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 16:26:00 2021 +0300
+
+ iwlwifi: mvm: Add RTS and CTS flags to iwl_tx_cmd_flags.
+
+ As part of the new rate_n_flags, the RTS and CTS flags
+ are being removed from it. Instead, we have these flags
+ in the flags field in the TX command.
+ Add to new flags to the iwl_tx_cmd_flags enum.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.b5aaabb04432.I999f86ed6a9d9b99e63a33f724963f83f85fbb44@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 5b80708e9f4dc8981557f2d3a741cedb14f01bcc
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 17 16:25:59 2021 +0300
+
+ iwlwifi: mvm: remove csi from iwl_mvm_pass_packet_to_mac80211()
+
+ Remove the unused csi parameter from
+ iwl_mvm_pass_packet_to_mac80211(). It is not used anymore, but was
+ accidentally left in.
+
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/20211017132604.480251-2-luca@coelho.fi
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 47aa5df93053cc4c7c932b5b62f0797f8dbb732b
+Author: Luca Coelho <luciano.coelho@intel.com>
+Date: Sun Oct 17 16:25:58 2021 +0300
+
+ iwlwifi: mvm: Support new rate_n_flags for REPLY_RX_MPDU_CMD and RX_NO_DATA_NOTIF
+
+ As part of the new rate_n_flags this two APIs
+ may use the new rate. Add support for the new rate.
+ These two APIs were updated in one patch because both of them
+ are using the same functions which were changed.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.7eb6240b8079.I1e804e70a8ebd23840a9431fc5d2a56ad8d5d1a2@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 0653fdb908a4fcaeb6c8178b30b09c22937a8914
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 16:25:57 2021 +0300
+
+ iwlwifi: mvm: Support new TX_RSP and COMPRESSED_BA_RES versions
+
+ As part of the new rate_n_flags, a new version of this
+ structures was added in the FW. Add support for this new
+ version and for the new rate_n_flags in this API.
+ Both these APIs were updated in one patch since they are
+ using the same functions.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.a28e7a92f558.I19f72735c674f815c6e7c11cecfad6230b4510ef@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit b34eea65959534764c8affad2622ab3a22719e45
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 16:25:56 2021 +0300
+
+ iwlwifi: mvm: Support new version of BEACON_TEMPLATE_CMD.
+
+ As part of the new rate_n_flags, a new version of
+ BEACON_TEMPLATE_CMD was added in FW in order to support
+ the new rate_n_flags.
+ Add support for the new version.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.b42e67f14293.Ic3f1ed8cb3a31cfaa51174497dd993936b00d398@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 95857e48fa0b5182e1098ff829e41a6d544f8ae1
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 16:25:55 2021 +0300
+
+ iwlwifi: mvm: Add support for new rate_n_flags in tx_cmd.
+
+ As part of the new rate_n_flags, tx_cmd API has changed.
+ Add support for these changes.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.26efa51624b1.Ic96ae4d81b3ff07fb514df2b5f6a8e470e4d3778@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 6284111deb1d88c2c17b81f6f2dfaea478a8aca7
+Author: Roee Goldfiner <roee.h.goldfiner@intel.com>
+Date: Sun Oct 17 16:25:54 2021 +0300
+
+ iwlwifi: BZ Family SW reset support
+
+ Previously added BZ reset wasn't taking into account the
+ call to iwl_trans_pcie_sw_reset which used a pre-BZ logic
+ to reset the device - enabling iwl_trans_pcie_sw_reset to
+ support BZ family made this reset redundant.
+
+ MAC_ACCESS clear shouldn't be called here but only when calling
+ _iwl_trans_pcie_stop_device which now support also BZ family.
+
+ Signed-off-by: Roee Goldfiner <roee.h.goldfiner@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.648931fe07e2.Ibf30f9b8e70536da93c4a574ace33d325d3f8da4@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit a157c0dc988e72a827f3e46fa9da93806d11aa85
+Author: Roee Goldfiner <roee.h.goldfiner@intel.com>
+Date: Sun Oct 17 16:25:53 2021 +0300
+
+ iwlwifi: BZ Family BUS_MASTER_DISABLE_REQ code duplication
+
+ Remove redundant code which occurs anyway in a later stage and add
+ msleep(100) which is required after disable request.
+
+ Signed-off-by: Roee Goldfiner <roee.h.goldfiner@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017162352.46183bcd6549.Ie05161496810d3f28fb9d1fecb5f8593889ed2c6@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 58cfcaa85b494681c3b87761ab2c2724bb5e5142
+Author: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
+Date: Sun Oct 17 12:40:19 2021 +0300
+
+ iwlwifi: yoyo: fw debug config from context info and preset
+
+ Add new TLV for debug config set to read preset
+ based on TLV is set in context info.
+ This is needed to set the preset based on ucode in early
+ trigger point.
+ Add DRAM frag allocation info in first fragment of
+ DBGC1 with all details.
+ New capability from FW for DBGC frag debug support is
+ added and BUFFER_ALLOCATION_CMD is disabled in capability
+ is supported.
+
+ Signed-off-by: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.cacf0babc521.If3704b5fda09b344e3e438252360898a3f2e90fa@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 56445414938c49a5f8dd21c57d85adfccfbe0879
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 12:40:18 2021 +0300
+
+ iwlwifi: mvm: Support new version of ranging response notification
+
+ As part of the new rate_n_flags, FW added a new version for
+ LOCATION_RANGE_RSP_NTFY, and it's internal structure -
+ LOCATION_RANGE_RSP_AP_ETRY_NTFY. Add support for this.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.c5c6c863631e.I4b493f4eeabbfa1dc965ae012b72fc57de7d5f4f@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit d450c79eba3399404fd68f79164bb3a688480361
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 12:40:17 2021 +0300
+
+ iwlwifi: mvm: Support version 3 of tlc_update_notif.
+
+ As part of the new rate_n_flags, a new version of tlc_update_notif
+ was added in FW in order to support the new rate_n_flags.
+ Add support for the new version, and move the all API to use the
+ new rate_n_flags only (if FW supports the old one - convert it).
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.9fc0cb5d5898.I1f88e02317f79f1be7f792c01236d836045a44b3@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 70086e2397ce0478bec67f0c65b68def86989012
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 12:40:16 2021 +0300
+
+ iwlwifi: mvm: convert old rate & flags to the new format.
+
+ As part of the new rate & flags, convert an old format rate to
+ the new. This is needed if the driver supports the new format
+ but the FW supports the old one.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.1ea5263dafec.Iadffe7cb26554d4c23c9242eb2ec8326306202a9@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 7facc384683d996853fe7afcb316e79fa7ae5b15
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 12:40:15 2021 +0300
+
+ iwlwifi: mvm: add definitions for new rate & flags
+
+ As a part of preparing to the new rate & flags,
+ add new needed definitions.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.41563bea6610.I51a886fa75cca723c81877b386ba41b2a9db1122@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit b2c5d0cbeb58bcb8cf8c36fb1c72d6667f976062
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 12:40:14 2021 +0300
+
+ iwlwifi: mvm: update definitions due to new rate & flags
+
+ As a part of preparing to the new rate & flags version
+ Update the relevant definitions and use them.
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.5862bf4f14c4.Ib476b5443faa085539b79d49a0aebd81a213b42f@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 3c27ef303ca6d95e9e649ce51783a82f984901ed
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 12:40:13 2021 +0300
+
+ iwlwifi: mvm: scrub key material in firmware dumps
+
+ Use the previously added infrastructure to scrub key material
+ in firmware dumps:
+ * in the TX FIFO data, just search for each key that we
+ know about and override such data
+ * scrub various commands that we sent to the firmware if
+ they're present
+ * in firmware memory, where advertised by firmware TLVs
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.d1514964e6a7.I18f8c2ce8082952af7cfe5f8fe75fe51851b8853@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 217045fac75b25902145809577d0eb9ed17fd5e8
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 12:40:12 2021 +0300
+
+ iwlwifi: parse debug exclude data from firmware file
+
+ Parse the memory dump exclusion TLVs from the firmware file
+ and save the data to be able to apply them later upon dump.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.ec280bcb32cb.Iac0da0e22d7c3c0e237867c9113a06ddd95c7a51@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 709d1523c7857bf1364c7385a45755fc576dac59
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 12:40:11 2021 +0300
+
+ iwlwifi: fw dump: add infrastructure for dump scrubbing
+
+ In firmware dumps, currently all kinds of key material may be
+ included, e.g. in host commands (if firmware crashes during the
+ processing of a key-related command) or in the TX FIFO(s) if
+ we have been using in-TX-command key material.
+
+ Additionally, some firmware versions will advertise sections
+ of their internal data to not dump, due to them containing some
+ sensitive data.
+
+ Add some infrastructure to allow scrubbing this data out, as
+ dependent on the opmode's idea of what will need to be done.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.360cc8fe55b1.Ie3bd3ece38043969f7e116e61a6ec1197a58d78b@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 93de7e9817a60a78a467f9b9259a1c1ab9de7b96
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 12:40:10 2021 +0300
+
+ iwlwifi: mvm: correct sta-state logic for TDLS
+
+ For TDLS stations, much of the sta-state logic shouldn't apply,
+ since they don't affect the link to the AP. Fix that.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.954001ec079f.I9deb8bc7520ad569a453f72c8d99adc9c99c9be3@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 96abb4f81c7cd95a63a85c39bec13376affc5cd5
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 12:40:09 2021 +0300
+
+ iwlwifi: api: fix struct iwl_wowlan_status_v7 kernel-doc
+
+ This was mislabeled as struct iwl_wowlan_status, fix that.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.f2ff92fcbe4d.Id2b8edd2160d9a703a7a2744e1139017cfd958c0@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 70ca5ce860a148456ed0ed4acc70fbfd0dd973fd
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 12:40:08 2021 +0300
+
+ iwlwifi: fix fw/img.c license statement
+
+ We still had the entire license statement here, but with BSD,
+ so the SPDX tag was not matching the actual text. Fix that
+ and remove all the texts since they're no longer needed.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017123741.328c2b33081c.Ib3570e8f214538a878204cc2b0b612b5ed0571b3@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 794f814044e778f86957f3f80cb7fb98ed9c4fcb
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 11:43:48 2021 +0300
+
+ iwlwifi: remove contact information
+
+ The list address is going away, and the postal address isn't
+ useful, remove all the contact information.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.f73e3b6384cb.I967fd394995461277eafa149bb25cefd1673751e@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 49245fb5234657a5e674580117196510659d55ea
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 11:43:47 2021 +0300
+
+ iwlwifi: remove MODULE_AUTHOR() statements
+
+ Consensus seems to be emerging that corporations or groups
+ shouldn't be listed as module authors, and we will not
+ maintain this email address any longer. Just remove it.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.32109514aad0.I91a7d745f4ab50ee8ef918ece00dda8251541595@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 0d337e231323c29e17fb1d7942ae12e149cdef9c
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 11:43:46 2021 +0300
+
+ iwlwifi: api: remove unused RX status bits
+
+ These bits are unused and don't actually exist in the firmware
+ API any longer. Remove them.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.022a9f87fdbd.Iae7b8a0196b6e94f9dc525e92a541a28374b0cac@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit c2184058d9dbbad7c2b6db4b95dd85ae35ff9c82
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 11:43:45 2021 +0300
+
+ iwlwifi: add some missing kernel-doc in struct iwl_fw
+
+ The phy integration string members were missed, add them.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.8aa65feeda5f.Idf492c939f7f8856da09c5017c16b8b88438395d@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 4bfc2095f257387e72d976ea7b529826377d0ce9
+Author: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Date: Sun Oct 17 11:43:44 2021 +0300
+
+ iwlwifi: mvm: Remove antenna c references
+
+ Since antenna c is not in use and won't be relevant after the new rate &
+ flags, remove all it's references
+
+ Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.5e39106ec75b.I4281edc844f734bf9591396a5cc8009ad37ccda8@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 835139ffad331fce99a1af0f5587eb411a6fe40f
+Author: Avraham Stern <avraham.stern@intel.com>
+Date: Sun Oct 17 11:43:43 2021 +0300
+
+ iwlwifi: mvm: add support for 160Mhz in ranging measurements
+
+ Add support for 160Mhz bandwidth in ranging measurements for
+ initiator and responder. Advertise 160Mhz in the supported
+ bandwidths for ranging.
+
+ Signed-off-by: Avraham Stern <avraham.stern@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.32a13ac0f4d4.I883492648518cc5067a2f91b7ecf8bfa55f6876a@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 474ef5005c0e5c9ea55339a2d4414b0c714861b3
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 11:43:42 2021 +0300
+
+ iwlwifi: add vendor specific capabilities for some RFs
+
+ On some RFs we want to advertise vendor specific capabilities to
+ indicate support for improved beamforming rates and/or on 160 MHz,
+ some APs where Intel has collaborated with the vendor will use it
+ to improve behaviour. Add these elements where relevant, i.e. for
+ HR and GF RFs.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.510f0ef9c2d5.If99bdb9009583ac7cc6cbb708e871a67df836dbe@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit c8b03b67838d34db08321ea221908231d842001a
+Author: Mordechay Goodstein <mordechay.goodstein@intel.com>
+Date: Sun Oct 17 11:43:41 2021 +0300
+
+ iwlwifi: mvm: add lmac/umac PC info in case of error
+
+ Currently it's only added to 22000 family in this patch we also add
+ it to 9000 family where it's also relevant.
+
+ Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.e51c61b31037.I118299d9d6eeef211cc8d4ee72193fdddc54d446@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 2e430d16e070bd405766ca22be54ef3209e57aa4
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sun Oct 17 11:43:39 2021 +0300
+
+ iwlwifi: mvm: fix ieee80211_get_he_iftype_cap() iftype
+
+ We should consider the P2P interface type, which isn't in
+ vif->type due to mac80211's special handling of that. Use
+ ieee80211_vif_type_p2p() to convert appropriately.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20211017113927.8e992a3beee2.I4231ac8a7ae8f844e35a1ec221baf3e2b676e765@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 10678a71cc610cd5d83d95442ae362711657b217
+Author: Matti Gottlieb <matti.gottlieb@intel.com>
+Date: Thu Aug 26 22:47:48 2021 +0300
+
+ iwlwifi: Start scratch debug register for Bz family
+
+ Start scratch debug register for Bz family.
+ This register is used for FW debug, and the driver
+ should start this register with a fixed value, during
+ init, and upon an error, should read it, and add it to
+ the dump.
+
+ Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20210826224715.609ad58a49f3.I05c351233601ecc51dddfa5df69ace292216eb95@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 10176ddc94776dc80db1c0e3585ed0c8e61f44d2
+Author: Matti Gottlieb <matti.gottlieb@intel.com>
+Date: Thu Aug 26 22:47:47 2021 +0300
+
+ iwlwifi: Add support for more BZ HWs
+
+ Add support for GA and for BZ with FM rf.
+
+ Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20210826224715.64ab5278fb9f.I4f2a547dc04c3d14cacdbc739da0b056fc04923d@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit 37563a9add85c5fb2f77aef2c003b9f95f6264aa
+Author: Matti Gottlieb <matti.gottlieb@intel.com>
+Date: Thu Aug 26 22:47:46 2021 +0300
+
+ iwlwifi: Add support for getting rf id with blank otp
+
+ When having a blank OTP the only way to get the rf id
+ and the cdb info is from prph registers.
+
+ Currently there is some implementation for this, but it
+ is located in the wrong place in the code (should be before
+ trying to understand what HW is connected and not after),
+ and it has a partial implementation.
+
+ Signed-off-by: Matti Gottlieb <matti.gottlieb@intel.com>
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Link: https://lore.kernel.org/r/iwlwifi.20210826224715.820c2ae18c2b.Iec9b2e2615ce65e6aff5ce896589227a7030f4cf@changeid
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+
+commit d883735c454058e12945a35f715676c1dcd03279
+Author: Johannes Berg <johannes.berg@intel.com>
+Date: Sat Oct 16 11:43:59 2021 +0300
+
+ iwlwifi: cfg: set low-latency-xtal for some integrated So devices
+
+ The integrated So devices covered by the iwl_so_long_latency_trans_cfg
+ configuration should all have low-latency-xtal enabled, so do that.
+ While at it, remove the TODO, I've checked the other values as well.
+
+ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+ Fixes: 6f60fb03c8e7 ("iwlwifi: move SnJ and So rules to the new tables")
+ Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+ Link: https://lore.kernel.org/r/iwlwifi.20211016114029.8b5480113f53.I80b5b4ebea84e56f3b3143fc1ee7097be8b4ae78@changeid
+---
+ drivers/net/wireless/intel/iwlwifi/Makefile | 2 +-
+ drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 5 -
+ .../net/wireless/intel/iwlwifi/cfg/22000.c | 35 +-
+ drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/agn.h | 11 +-
+ .../net/wireless/intel/iwlwifi/dvm/debugfs.c | 4 -
+ drivers/net/wireless/intel/iwlwifi/dvm/dev.h | 5 -
+ .../net/wireless/intel/iwlwifi/dvm/devices.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/led.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/led.h | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/lib.c | 5 -
+ .../net/wireless/intel/iwlwifi/dvm/mac80211.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/main.c | 6 -
+ .../net/wireless/intel/iwlwifi/dvm/power.c | 4 -
+ .../net/wireless/intel/iwlwifi/dvm/power.h | 4 -
+ drivers/net/wireless/intel/iwlwifi/dvm/rs.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/rs.h | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/rx.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/rxon.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/scan.c | 4 -
+ drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/dvm/tt.c | 4 -
+ drivers/net/wireless/intel/iwlwifi/dvm/tt.h | 4 -
+ drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 5 -
+ .../net/wireless/intel/iwlwifi/dvm/ucode.c | 5 -
+ drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 150 ++++---
+ drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 43 +-
+ .../net/wireless/intel/iwlwifi/fw/api/d3.h | 45 +--
+ .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 57 +++
+ .../net/wireless/intel/iwlwifi/fw/api/debug.h | 35 ++
+ .../wireless/intel/iwlwifi/fw/api/location.h | 10 +-
+ .../wireless/intel/iwlwifi/fw/api/mac-cfg.h | 10 +-
+ .../net/wireless/intel/iwlwifi/fw/api/mac.h | 3 +
+ .../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 23 ++
+ .../net/wireless/intel/iwlwifi/fw/api/phy.h | 6 +-
+ .../net/wireless/intel/iwlwifi/fw/api/power.h | 55 ++-
+ .../net/wireless/intel/iwlwifi/fw/api/rs.h | 234 +++++++++--
+ .../net/wireless/intel/iwlwifi/fw/api/rx.h | 31 +-
+ .../net/wireless/intel/iwlwifi/fw/api/sta.h | 2 +
+ .../net/wireless/intel/iwlwifi/fw/api/tx.h | 40 +-
+ drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 46 ++-
+ drivers/net/wireless/intel/iwlwifi/fw/dump.c | 9 +-
+ .../wireless/intel/iwlwifi/fw/error-dump.h | 4 -
+ drivers/net/wireless/intel/iwlwifi/fw/file.h | 12 +-
+ drivers/net/wireless/intel/iwlwifi/fw/img.c | 58 +--
+ drivers/net/wireless/intel/iwlwifi/fw/img.h | 12 +
+ drivers/net/wireless/intel/iwlwifi/fw/init.c | 6 +-
+ .../net/wireless/intel/iwlwifi/fw/paging.c | 4 +-
+ drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 2 +-
+ drivers/net/wireless/intel/iwlwifi/fw/rs.c | 252 ++++++++++++
+ .../net/wireless/intel/iwlwifi/fw/runtime.h | 7 +-
+ drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 5 +-
+ .../net/wireless/intel/iwlwifi/iwl-config.h | 8 +-
+ .../intel/iwlwifi/iwl-context-info-gen3.h | 4 +-
+ drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 8 +
+ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 228 ++++++++++-
+ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 2 +
+ .../net/wireless/intel/iwlwifi/iwl-debug.c | 24 +-
+ .../net/wireless/intel/iwlwifi/iwl-debug.h | 26 +-
+ .../intel/iwlwifi/iwl-devtrace-data.h | 5 -
+ .../wireless/intel/iwlwifi/iwl-devtrace-io.h | 5 -
+ .../intel/iwlwifi/iwl-devtrace-iwlwifi.h | 5 -
+ .../wireless/intel/iwlwifi/iwl-devtrace-msg.h | 5 -
+ .../intel/iwlwifi/iwl-devtrace-ucode.h | 5 -
+ .../net/wireless/intel/iwlwifi/iwl-devtrace.c | 5 -
+ .../net/wireless/intel/iwlwifi/iwl-devtrace.h | 5 -
+ drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 44 ++-
+ drivers/net/wireless/intel/iwlwifi/iwl-drv.h | 3 +-
+ .../wireless/intel/iwlwifi/iwl-eeprom-read.c | 4 +-
+ drivers/net/wireless/intel/iwlwifi/iwl-io.c | 50 ++-
+ drivers/net/wireless/intel/iwlwifi/iwl-io.h | 5 +-
+ .../wireless/intel/iwlwifi/iwl-nvm-parse.c | 17 +
+ drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 36 ++
+ .../net/wireless/intel/iwlwifi/iwl-trans.h | 30 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 371 +++++++++++-------
+ .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 19 +-
+ .../intel/iwlwifi/mvm/ftm-initiator.c | 15 +-
+ .../intel/iwlwifi/mvm/ftm-responder.c | 15 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 106 +++--
+ .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 44 ++-
+ .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 271 ++++++++-----
+ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 17 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 5 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 194 ++++++++-
+ .../net/wireless/intel/iwlwifi/mvm/power.c | 28 +-
+ .../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 16 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 182 +++------
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 17 -
+ drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 39 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 119 +++---
+ drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 10 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 121 ++++--
+ .../net/wireless/intel/iwlwifi/mvm/utils.c | 51 +--
+ .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 4 +
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 300 +++++++++++---
+ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 9 +-
+ .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 38 +-
+ .../net/wireless/intel/iwlwifi/pcie/trans.c | 96 +++--
+ 100 files changed, 2757 insertions(+), 1178 deletions(-)
+ create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/rs.c
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile
+index d86918d162aa..0d4656efe908 100644
+--- a/drivers/net/wireless/intel/iwlwifi/Makefile
++++ b/drivers/net/wireless/intel/iwlwifi/Makefile
+@@ -15,7 +15,7 @@ iwlwifi-objs += iwl-dbg-tlv.o
+ iwlwifi-objs += iwl-trans.o
+ iwlwifi-objs += queue/tx.o
+
+-iwlwifi-objs += fw/img.o fw/notif-wait.o
++iwlwifi-objs += fw/img.o fw/notif-wait.o fw/rs.o
+ iwlwifi-objs += fw/dbg.o fw/pnvm.o fw/dump.o
+ iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o
+ iwlwifi-$(CONFIG_ACPI) += fw/acpi.o
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+index 44c4fe975390..116defb15afb 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+index df6ac00340b2..ab2038a3fbe2 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+index d8231cc821ae..1572097bccf1 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+@@ -9,7 +9,7 @@
+ #include "iwl-prph.h"
+
+ /* Highest firmware API version supported */
+-#define IWL_22000_UCODE_API_MAX 66
++#define IWL_22000_UCODE_API_MAX 67
+
+ /* Lowest firmware API version supported */
+ #define IWL_22000_UCODE_API_MIN 39
+@@ -53,6 +53,9 @@
+ #define IWL_BZ_A_GF_A_FW_PRE "iwlwifi-bz-a0-gf-a0-"
+ #define IWL_BZ_A_GF4_A_FW_PRE "iwlwifi-bz-a0-gf4-a0-"
+ #define IWL_BZ_A_MR_A_FW_PRE "iwlwifi-bz-a0-mr-a0-"
++#define IWL_BZ_A_FM_A_FW_PRE "iwlwifi-bz-a0-fm-a0-"
++#define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm7-a0-"
++
+
+ #define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
+ IWL_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
+@@ -106,6 +109,10 @@
+ IWL_BZ_A_GF4_A_FW_PRE __stringify(api) ".ucode"
+ #define IWL_BZ_A_MR_A_MODULE_FIRMWARE(api) \
+ IWL_BZ_A_MR_A_FW_PRE __stringify(api) ".ucode"
++#define IWL_BZ_A_FM_A_MODULE_FIRMWARE(api) \
++ IWL_BZ_A_FM_A_FW_PRE __stringify(api) ".ucode"
++#define IWL_GL_A_FM_A_MODULE_FIRMWARE(api) \
++ IWL_GL_A_FM_A_FW_PRE __stringify(api) ".ucode"
+
+ static const struct iwl_base_params iwl_22000_base_params = {
+ .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
+@@ -355,7 +362,7 @@ const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg = {
+ .base_params = &iwl_ax210_base_params,
+ .umac_prph_offset = 0x300000,
+ .integrated = true,
+- /* TODO: the following values need to be checked */
++ .low_latency_xtal = true,
+ .xtal_latency = 12000,
+ .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
+ };
+@@ -469,6 +476,14 @@ const char iwl_ax210_killer_1675w_name[] =
+ "Killer(R) Wi-Fi 6E AX1675w 160MHz Wireless Network Adapter (210D2W)";
+ const char iwl_ax210_killer_1675x_name[] =
+ "Killer(R) Wi-Fi 6E AX1675x 160MHz Wireless Network Adapter (210NGW)";
++const char iwl_ax211_killer_1675s_name[] =
++ "Killer(R) Wi-Fi 6E AX1675s 160MHz Wireless Network Adapter (211NGW)";
++const char iwl_ax211_killer_1675i_name[] =
++ "Killer(R) Wi-Fi 6E AX1675i 160MHz Wireless Network Adapter (211NGW)";
++const char iwl_ax411_killer_1690s_name[] =
++ "Killer(R) Wi-Fi 6E AX1690s 160MHz Wireless Network Adapter (411D2W)";
++const char iwl_ax411_killer_1690i_name[] =
++ "Killer(R) Wi-Fi 6E AX1690i 160MHz Wireless Network Adapter (411NGW)";
+
+ const struct iwl_cfg iwl_qu_b0_hr1_b0 = {
+ .fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
+@@ -850,6 +865,20 @@ const struct iwl_cfg iwl_cfg_bz_a0_mr_a0 = {
+ .num_rbds = IWL_NUM_RBDS_AX210_HE,
+ };
+
++const struct iwl_cfg iwl_cfg_bz_a0_fm_a0 = {
++ .fw_name_pre = IWL_BZ_A_FM_A_FW_PRE,
++ .uhb_supported = true,
++ IWL_DEVICE_BZ,
++ .num_rbds = IWL_NUM_RBDS_AX210_HE,
++};
++
++const struct iwl_cfg iwl_cfg_gl_a0_fm_a0 = {
++ .fw_name_pre = IWL_GL_A_FM_A_FW_PRE,
++ .uhb_supported = true,
++ IWL_DEVICE_BZ,
++ .num_rbds = IWL_NUM_RBDS_AX210_HE,
++};
++
+ MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+@@ -876,3 +905,5 @@ MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL_BZ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL_BZ_A_GF4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL_BZ_A_MR_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
++MODULE_FIRMWARE(IWL_BZ_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
++MODULE_FIRMWARE(IWL_GL_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
+index 6cdd7d983bda..e2e23d2bc1fe 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+index 541a3ec85777..20929e59c2f4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h
+index 1276df1c7a55..abb8696ba294 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2005-2014 Intel Corporation
++ * Copyright (C) 2005-2014, 2021 Intel Corporation
+ */
+ #ifndef __iwl_agn_h__
+ #define __iwl_agn_h__
+@@ -398,8 +398,10 @@ do { \
+ if (!iwl_is_rfkill((m))) \
+ IWL_ERR(m, fmt, ##args); \
+ else \
+- __iwl_err((m)->dev, true, \
+- !iwl_have_debug_level(IWL_DL_RADIO), \
++ __iwl_err((m)->dev, \
++ iwl_have_debug_level(IWL_DL_RADIO) ? \
++ IWL_ERR_MODE_RFKILL : \
++ IWL_ERR_MODE_TRACE_ONLY, \
+ fmt, ##args); \
+ } while (0)
+ #else
+@@ -408,7 +410,8 @@ do { \
+ if (!iwl_is_rfkill((m))) \
+ IWL_ERR(m, fmt, ##args); \
+ else \
+- __iwl_err((m)->dev, true, true, fmt, ##args); \
++ __iwl_err((m)->dev, IWL_ERR_MODE_TRACE_ONLY, \
++ fmt, ##args); \
+ } while (0)
+ #endif /* CONFIG_IWLWIFI_DEBUG */
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
+index 911049201838..b246dbd371b3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
+@@ -3,10 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2018 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+ #include <linux/slab.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h
+index 4bd792c06ff6..bbd574091201 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2003 - 2014, 2020 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+ /*
+ * Please use this file (dev.h) for driver implementation definitions.
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
+index c3e25885d194..39e40901fa46 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/units.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c
+index e8a4d604b910..71f67a019cf6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.h b/drivers/net/wireless/intel/iwlwifi/dvm/led.h
+index 6fe20180dc87..5038fc378a1f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/led.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #ifndef __iwl_leds_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c
+index 3b937a7dd403..40d790b36d85 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+ #include <linux/etherdevice.h>
+ #include <linux/kernel.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+index 75e7665773c5..754876cd27ce 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+@@ -6,11 +6,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+index cc7b69fd14d3..14c333bffe67 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+@@ -6,11 +6,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+@@ -52,7 +47,6 @@
+
+ #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
+ MODULE_DESCRIPTION(DRV_DESCRIPTION);
+-MODULE_AUTHOR(DRV_AUTHOR);
+ MODULE_LICENSE("GPL");
+
+ /* Please keep this array *SORTED* by hex value.
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c
+index 93ef023905c9..6d16a7105656 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c
+@@ -6,10 +6,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.h b/drivers/net/wireless/intel/iwlwifi/dvm/power.h
+index 3f8db1fc4b59..f38201ce1e99 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/power.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.h
+@@ -5,10 +5,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+ #ifndef __iwl_power_setting_h__
+ #define __iwl_power_setting_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
+index 548540dd0c0f..b7c8b209bfea 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/skbuff.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
+index 68a840d739e8..0b47f1993c5d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #ifndef __iwl_agn_rs_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
+index 3cd7b423c588..db0c41bbeb0e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
+@@ -7,11 +7,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portionhelp of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/etherdevice.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
+index 12a3d464ae64..70338bc7bb54 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/etherdevice.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
+index c4ecf6ed2186..2d38227dfdd2 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
+@@ -3,10 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+ #include <linux/slab.h>
+ #include <linux/types.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+index ddc14059b07d..8f7a0f36c276 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+@@ -5,11 +5,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+ #include <linux/etherdevice.h>
+ #include <net/mac80211.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
+index 2684a924ba57..43e8d04d5a8b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
+@@ -6,10 +6,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h
+index 3b0ff458a158..7ace052fc78a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h
+@@ -5,10 +5,6 @@
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+ #ifndef __iwl_tt_setting_h__
+ #define __iwl_tt_setting_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+index 847b8e07f81c..60a7b61d59aa 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/kernel.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
+index 24194c791218..4b27a53d0bb4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/kernel.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+index 1efac0b2a94d..bf431fa4fe81 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+@@ -184,9 +184,11 @@ int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
+ }
+ IWL_EXPORT_SYMBOL(iwl_acpi_get_dsm_u32);
+
+-union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
+- union acpi_object *data,
+- int data_size, int *tbl_rev)
++union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev,
++ union acpi_object *data,
++ int min_data_size,
++ int max_data_size,
++ int *tbl_rev)
+ {
+ int i;
+ union acpi_object *wifi_pkg;
+@@ -196,7 +198,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
+ * describes the domain, and one more entry, otherwise there's
+ * no point in reading it.
+ */
+- if (WARN_ON_ONCE(data_size < 2))
++ if (WARN_ON_ONCE(min_data_size < 2 || min_data_size > max_data_size))
+ return ERR_PTR(-EINVAL);
+
+ /*
+@@ -222,7 +224,8 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
+
+ /* skip entries that are not a package with the right size */
+ if (wifi_pkg->type != ACPI_TYPE_PACKAGE ||
+- wifi_pkg->package.count != data_size)
++ wifi_pkg->package.count < min_data_size ||
++ wifi_pkg->package.count > max_data_size)
+ continue;
+
+ domain = &wifi_pkg->package.elements[0];
+@@ -236,7 +239,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
+ found:
+ return wifi_pkg;
+ }
+-IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg);
++IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg_range);
+
+ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
+ __le32 *block_list_array,
+@@ -707,49 +710,103 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
+ {
+ union acpi_object *wifi_pkg, *data;
+ int i, j, k, ret, tbl_rev;
+- int idx = 1; /* start from one to skip the domain */
+- u8 num_bands;
++ u8 num_bands, num_profiles;
++ static const struct {
++ u8 revisions;
++ u8 bands;
++ u8 profiles;
++ u8 min_profiles;
++ } rev_data[] = {
++ {
++ .revisions = BIT(3),
++ .bands = ACPI_GEO_NUM_BANDS_REV2,
++ .profiles = ACPI_NUM_GEO_PROFILES_REV3,
++ .min_profiles = 3,
++ },
++ {
++ .revisions = BIT(2),
++ .bands = ACPI_GEO_NUM_BANDS_REV2,
++ .profiles = ACPI_NUM_GEO_PROFILES,
++ },
++ {
++ .revisions = BIT(0) | BIT(1),
++ .bands = ACPI_GEO_NUM_BANDS_REV0,
++ .profiles = ACPI_NUM_GEO_PROFILES,
++ },
++ };
++ int idx;
++ /* start from one to skip the domain */
++ int entry_idx = 1;
++
++ BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES_REV3 != IWL_NUM_GEO_PROFILES_V3);
++ BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES != IWL_NUM_GEO_PROFILES);
+
+ data = iwl_acpi_get_object(fwrt->dev, ACPI_WGDS_METHOD);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+- /* start by trying to read revision 2 */
+- wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
+- ACPI_WGDS_WIFI_DATA_SIZE_REV2,
+- &tbl_rev);
+- if (!IS_ERR(wifi_pkg)) {
+- if (tbl_rev != 2) {
+- ret = PTR_ERR(wifi_pkg);
+- goto out_free;
++ /* read the highest revision we understand first */
++ for (idx = 0; idx < ARRAY_SIZE(rev_data); idx++) {
++ /* min_profiles != 0 requires num_profiles header */
++ u32 hdr_size = 1 + !!rev_data[idx].min_profiles;
++ u32 profile_size = ACPI_GEO_PER_CHAIN_SIZE *
++ rev_data[idx].bands;
++ u32 max_size = hdr_size + profile_size * rev_data[idx].profiles;
++ u32 min_size;
++
++ if (!rev_data[idx].min_profiles)
++ min_size = max_size;
++ else
++ min_size = hdr_size +
++ profile_size * rev_data[idx].min_profiles;
++
++ wifi_pkg = iwl_acpi_get_wifi_pkg_range(fwrt->dev, data,
++ min_size, max_size,
++ &tbl_rev);
++ if (!IS_ERR(wifi_pkg)) {
++ if (!(BIT(tbl_rev) & rev_data[idx].revisions))
++ continue;
++
++ num_bands = rev_data[idx].bands;
++ num_profiles = rev_data[idx].profiles;
++
++ if (rev_data[idx].min_profiles) {
++ /* read header that says # of profiles */
++ union acpi_object *entry;
++
++ entry = &wifi_pkg->package.elements[entry_idx];
++ entry_idx++;
++ if (entry->type != ACPI_TYPE_INTEGER ||
++ entry->integer.value > num_profiles) {
++ ret = -EINVAL;
++ goto out_free;
++ }
++ num_profiles = entry->integer.value;
++
++ /*
++ * this also validates >= min_profiles since we
++ * otherwise wouldn't have gotten the data when
++ * looking up in ACPI
++ */
++ if (wifi_pkg->package.count !=
++ min_size + profile_size * num_profiles) {
++ ret = -EINVAL;
++ goto out_free;
++ }
++ }
++ goto read_table;
+ }
+-
+- num_bands = ACPI_GEO_NUM_BANDS_REV2;
+-
+- goto read_table;
+ }
+
+- /* then try revision 0 (which is the same as 1) */
+- wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
+- ACPI_WGDS_WIFI_DATA_SIZE_REV0,
+- &tbl_rev);
+- if (!IS_ERR(wifi_pkg)) {
+- if (tbl_rev != 0 && tbl_rev != 1) {
+- ret = PTR_ERR(wifi_pkg);
+- goto out_free;
+- }
+-
+- num_bands = ACPI_GEO_NUM_BANDS_REV0;
+-
+- goto read_table;
+- }
+-
+- ret = PTR_ERR(wifi_pkg);
++ if (idx < ARRAY_SIZE(rev_data))
++ ret = PTR_ERR(wifi_pkg);
++ else
++ ret = -ENOENT;
+ goto out_free;
+
+ read_table:
+ fwrt->geo_rev = tbl_rev;
+- for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
++ for (i = 0; i < num_profiles; i++) {
+ for (j = 0; j < ACPI_GEO_NUM_BANDS_REV2; j++) {
+ union acpi_object *entry;
+
+@@ -762,7 +819,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
+ fwrt->geo_profiles[i].bands[j].max =
+ fwrt->geo_profiles[i].bands[1].max;
+ } else {
+- entry = &wifi_pkg->package.elements[idx++];
++ entry = &wifi_pkg->package.elements[entry_idx];
++ entry_idx++;
+ if (entry->type != ACPI_TYPE_INTEGER ||
+ entry->integer.value > U8_MAX) {
+ ret = -EINVAL;
+@@ -779,7 +837,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
+ fwrt->geo_profiles[i].bands[j].chains[k] =
+ fwrt->geo_profiles[i].bands[1].chains[k];
+ } else {
+- entry = &wifi_pkg->package.elements[idx++];
++ entry = &wifi_pkg->package.elements[entry_idx];
++ entry_idx++;
+ if (entry->type != ACPI_TYPE_INTEGER ||
+ entry->integer.value > U8_MAX) {
+ ret = -EINVAL;
+@@ -803,10 +862,10 @@ IWL_EXPORT_SYMBOL(iwl_sar_get_wgds_table);
+ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
+ {
+ /*
+- * The GEO_TX_POWER_LIMIT command is not supported on earlier
+- * firmware versions. Unfortunately, we don't have a TLV API
+- * flag to rely on, so rely on the major version which is in
+- * the first byte of ucode_ver. This was implemented
++ * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on
++ * earlier firmware versions. Unfortunately, we don't have a
++ * TLV API flag to rely on, so rely on the major version which
++ * is in the first byte of ucode_ver. This was implemented
+ * initially on version 38 and then backported to 17. It was
+ * also backported to 29, but only for 7265D devices. The
+ * intention was to have it in 36 as well, but not all 8000
+@@ -822,14 +881,15 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
+ IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
+
+ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
+- struct iwl_per_chain_offset *table, u32 n_bands)
++ struct iwl_per_chain_offset *table,
++ u32 n_bands, u32 n_profiles)
+ {
+ int i, j;
+
+ if (!iwl_sar_geo_support(fwrt))
+ return -EOPNOTSUPP;
+
+- for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
++ for (i = 0; i < n_profiles; i++) {
+ for (j = 0; j < n_bands; j++) {
+ struct iwl_per_chain_offset *chain =
+ &table[i * n_bands + j];
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+index 16ed0995b51e..4aaa8a6b071b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+@@ -29,6 +29,7 @@
+ #define ACPI_SAR_PROFILE_NUM 4
+
+ #define ACPI_NUM_GEO_PROFILES 3
++#define ACPI_NUM_GEO_PROFILES_REV3 8
+ #define ACPI_GEO_PER_CHAIN_SIZE 3
+
+ #define ACPI_SAR_NUM_CHAINS_REV0 2
+@@ -59,13 +60,6 @@
+ #define ACPI_GEO_NUM_BANDS_REV2 3
+ #define ACPI_GEO_NUM_CHAINS 2
+
+-#define ACPI_WGDS_WIFI_DATA_SIZE_REV0 (ACPI_NUM_GEO_PROFILES * \
+- ACPI_GEO_NUM_BANDS_REV0 * \
+- ACPI_GEO_PER_CHAIN_SIZE + 1)
+-#define ACPI_WGDS_WIFI_DATA_SIZE_REV2 (ACPI_NUM_GEO_PROFILES * \
+- ACPI_GEO_NUM_BANDS_REV2 * \
+- ACPI_GEO_PER_CHAIN_SIZE + 1)
+-
+ #define ACPI_WRDD_WIFI_DATA_SIZE 2
+ #define ACPI_SPLC_WIFI_DATA_SIZE 2
+ #define ACPI_ECKV_WIFI_DATA_SIZE 2
+@@ -115,8 +109,10 @@ enum iwl_dsm_funcs_rev_0 {
+ DSM_FUNC_QUERY = 0,
+ DSM_FUNC_DISABLE_SRD = 1,
+ DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
++ DSM_FUNC_ENABLE_6E = 3,
+ DSM_FUNC_11AX_ENABLEMENT = 6,
+- DSM_FUNC_ENABLE_UNII4_CHAN = 7
++ DSM_FUNC_ENABLE_UNII4_CHAN = 7,
++ DSM_FUNC_ACTIVATE_CHANNEL = 8
+ };
+
+ enum iwl_dsm_values_srd {
+@@ -158,10 +154,11 @@ int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func,
+ int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
+ const guid_t *guid, u32 *value);
+
+-union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
+- union acpi_object *data,
+- int data_size, int *tbl_rev);
+-
++union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev,
++ union acpi_object *data,
++ int min_data_size,
++ int max_data_size,
++ int *tbl_rev);
+ /**
+ * iwl_acpi_get_mcc - read MCC from ACPI, if available
+ *
+@@ -198,7 +195,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt);
+ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
+
+ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
+- struct iwl_per_chain_offset *table, u32 n_bands);
++ struct iwl_per_chain_offset *table,
++ u32 n_bands, u32 n_profiles);
+
+ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array,
+ int *block_list_size);
+@@ -230,10 +228,11 @@ static inline int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
+ return -ENOENT;
+ }
+
+-static inline union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
+- union acpi_object *data,
+- int data_size,
+- int *tbl_rev)
++static inline union acpi_object *
++iwl_acpi_get_wifi_pkg_range(struct device *dev,
++ union acpi_object *data,
++ int min_data_size, int max_data_size,
++ int *tbl_rev)
+ {
+ return ERR_PTR(-ENOENT);
+ }
+@@ -293,4 +292,14 @@ static inline __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt
+ }
+
+ #endif /* CONFIG_ACPI */
++
++static inline union acpi_object *
++iwl_acpi_get_wifi_pkg(struct device *dev,
++ union acpi_object *data,
++ int data_size, int *tbl_rev)
++{
++ return iwl_acpi_get_wifi_pkg_range(dev, data, data_size, data_size,
++ tbl_rev);
++}
++
+ #endif /* __iwl_fw_acpi__ */
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+index 3ec82cae3981..1503119ea910 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+@@ -624,7 +624,7 @@ struct iwl_wowlan_status_v6 {
+ } __packed; /* WOWLAN_STATUSES_API_S_VER_6 */
+
+ /**
+- * struct iwl_wowlan_status - WoWLAN status
++ * struct iwl_wowlan_status_v7 - WoWLAN status
+ * @gtk: GTK data
+ * @igtk: IGTK data
+ * @replay_ctr: GTK rekey replay counter
+@@ -693,49 +693,6 @@ struct iwl_wowlan_status_v9 {
+ u8 wake_packet[]; /* can be truncated from _length to _bufsize */
+ } __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */
+
+-/**
+- * struct iwl_wowlan_status - WoWLAN status
+- * @gtk: GTK data
+- * @igtk: IGTK data
+- * @bigtk: BIGTK data
+- * @replay_ctr: GTK rekey replay counter
+- * @pattern_number: number of the matched pattern
+- * @non_qos_seq_ctr: non-QoS sequence counter to use next
+- * @qos_seq_ctr: QoS sequence counters to use next
+- * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
+- * @num_of_gtk_rekeys: number of GTK rekeys
+- * @tid_tear_down: bitmap of TIDs torn down
+- * @reserved: reserved
+- * @received_beacons: number of received beacons
+- * @wake_packet_length: wakeup packet length
+- * @wake_packet_bufsize: wakeup packet buffer size
+- * @tid_tear_down: bit mask of tids whose BA sessions were closed
+- * in suspend state
+- * @wake_packet: wakeup packet
+- */
+-struct iwl_wowlan_status {
+- struct iwl_wowlan_gtk_status gtk[1];
+- struct iwl_wowlan_igtk_status igtk[1];
+- struct iwl_wowlan_igtk_status bigtk[WOWLAN_IGTK_KEYS_NUM];
+- __le64 replay_ctr;
+- __le16 pattern_number;
+- __le16 non_qos_seq_ctr;
+- __le16 qos_seq_ctr[8];
+- __le32 wakeup_reasons;
+- __le32 num_of_gtk_rekeys;
+- u8 tid_tear_down;
+- u8 reserved[3];
+- __le32 received_beacons;
+- __le32 wake_packet_length;
+- __le32 wake_packet_bufsize;
+- u8 wake_packet[]; /* can be truncated from _length to _bufsize */
+-} __packed; /* WOWLAN_STATUSES_API_S_VER_11 */
+-
+-static inline u8 iwlmvm_wowlan_gtk_idx(struct iwl_wowlan_gtk_status *gtk)
+-{
+- return gtk->key_flags & IWL_WOWLAN_GTK_IDX_MASK;
+-}
+-
+ /* TODO: NetDetect API */
+
+ #endif /* __iwl_fw_api_d3_h__ */
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+index d8b5870d6e9a..3988f5fea33a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+@@ -7,6 +7,7 @@
+
+ #include <linux/bitops.h>
+
++#define IWL_FW_INI_HW_SMEM_REGION_ID 15
+ #define IWL_FW_INI_MAX_REGION_ID 64
+ #define IWL_FW_INI_MAX_NAME 32
+ #define IWL_FW_INI_MAX_CFG_NAME 64
+@@ -242,6 +243,62 @@ struct iwl_fw_ini_hcmd_tlv {
+ struct iwl_fw_ini_hcmd hcmd;
+ } __packed; /* FW_TLV_DEBUG_HCMD_API_S_VER_1 */
+
++/**
++* struct iwl_fw_ini_conf_tlv - preset configuration TLV
++*
++* @address: the base address
++* @value: value to set at address
++
++*/
++struct iwl_fw_ini_addr_val {
++ __le32 address;
++ __le32 value;
++} __packed; /* FW_TLV_DEBUG_ADDR_VALUE_VER_1 */
++
++/**
++ * struct iwl_fw_ini_conf_tlv - configuration TLV to set register/memory.
++ *
++ * @hdr: debug header
++ * @time_point: time point to apply config. One of &enum iwl_fw_ini_time_point
++ * @set_type: write access type preset token for time point.
++ * one of &enum iwl_fw_ini_config_set_type
++ * @addr_offset: the offset to add to any item in address[0] field
++ * @addr_val: address value pair
++ */
++struct iwl_fw_ini_conf_set_tlv {
++ struct iwl_fw_ini_header hdr;
++ __le32 time_point;
++ __le32 set_type;
++ __le32 addr_offset;
++ struct iwl_fw_ini_addr_val addr_val[0];
++} __packed; /* FW_TLV_DEBUG_CONFIG_SET_API_S_VER_1 */
++
++/**
++ * enum iwl_fw_ini_config_set_type
++ *
++ * @IWL_FW_INI_CONFIG_SET_TYPE_INVALID: invalid config set
++ * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: for PERIPHERY MAC configuration
++ * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_PHY: for PERIPHERY PHY configuration
++ * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_AUX: for PERIPHERY AUX configuration
++ * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY: for DEVICE MEMORY configuration
++ * @IWL_FW_INI_CONFIG_SET_TYPE_CSR: for CSR configuration
++ * @IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: for DBGC_DRAM_ADDR configuration
++ * @IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: for PERIPH SCRATCH HWM configuration
++ * @IWL_FW_INI_ALLOCATION_NUM: max number of configuration supported
++*/
++
++enum iwl_fw_ini_config_set_type {
++ IWL_FW_INI_CONFIG_SET_TYPE_INVALID = 0,
++ IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC,
++ IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_PHY,
++ IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_AUX,
++ IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY,
++ IWL_FW_INI_CONFIG_SET_TYPE_CSR,
++ IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR,
++ IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM,
++ IWL_FW_INI_CONFIG_SET_TYPE_MAX_NUM,
++} __packed;
++
+ /**
+ * enum iwl_fw_ini_allocation_id
+ *
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
+index 8adccd5da095..029ae64bf2b2 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
+@@ -361,6 +361,41 @@ struct iwl_buf_alloc_cmd {
+ struct iwl_buf_alloc_frag frags[BUF_ALLOC_MAX_NUM_FRAGS];
+ } __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_2 */
+
++#define DRAM_INFO_FIRST_MAGIC_WORD 0x76543210
++#define DRAM_INFO_SECOND_MAGIC_WORD 0x89ABCDEF
++
++/**
++ * struct iwL_dram_info - DRAM fragments allocation struct
++ *
++ * Driver will fill in the first 1K(+) of the pointed DRAM fragment
++ *
++ * @first_word: magic word value
++ * @second_word: magic word value
++ * @framfrags: DRAM fragmentaion detail
++*/
++struct iwl_dram_info {
++ __le32 first_word;
++ __le32 second_word;
++ struct iwl_buf_alloc_cmd dram_frags[IWL_FW_INI_ALLOCATION_NUM - 1];
++} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */
++
++/**
++ * struct iwl_dbgc1_info - DBGC1 address and size
++ *
++ * Driver will fill the dbcg1 address and size at address based on config TLV.
++ *
++ * @first_word: all 0 set as identifier
++ * @dbgc1_add_lsb: LSB bits of DBGC1 physical address
++ * @dbgc1_add_msb: MSB bits of DBGC1 physical address
++ * @dbgc1_size: DBGC1 size
++*/
++struct iwl_dbgc1_info {
++ __le32 first_word;
++ __le32 dbgc1_add_lsb;
++ __le32 dbgc1_add_msb;
++ __le32 dbgc1_size;
++} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */
++
+ /**
+ * struct iwl_dbg_host_event_cfg_cmd
+ * @enabled_severities: enabled severities
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
+index 6bbb8b8c91cd..12af94e166ed 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
+@@ -206,7 +206,7 @@ enum iwl_tof_responder_cfg_flags {
+ IWL_TOF_RESPONDER_FLAGS_SPECIFIC_CALIB_MODE = BIT(8),
+ IWL_TOF_RESPONDER_FLAGS_FAST_ALGO_SUPPORT = BIT(9),
+ IWL_TOF_RESPONDER_FLAGS_RETRY_ON_ALGO_FAIL = BIT(10),
+- IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_ABC_MSK,
++ IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_AB_MSK,
+ IWL_TOF_RESPONDER_FLAGS_NDP_SUPPORT = BIT(24),
+ IWL_TOF_RESPONDER_FLAGS_LMR_FEEDBACK = BIT(25),
+ IWL_TOF_RESPONDER_FLAGS_SESSION_ID = BIT(27),
+@@ -629,6 +629,7 @@ enum iwl_location_bw {
+ IWL_LOCATION_BW_20MHZ,
+ IWL_LOCATION_BW_40MHZ,
+ IWL_LOCATION_BW_80MHZ,
++ IWL_LOCATION_BW_160MHZ,
+ };
+
+ #define TK_11AZ_LEN 32
+@@ -1500,7 +1501,9 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v6 {
+ u8 reserved[3];
+ u8 rx_pn[IEEE80211_CCMP_PN_LEN];
+ u8 tx_pn[IEEE80211_CCMP_PN_LEN];
+-} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6 */
++} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6,
++ LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_7 */
++
+
+ /**
+ * enum iwl_tof_response_status - tof response status
+@@ -1581,7 +1584,8 @@ struct iwl_tof_range_rsp_ntfy_v8 {
+ u8 last_report;
+ u8 reserved;
+ struct iwl_tof_range_rsp_ap_entry_ntfy_v6 ap[IWL_MVM_TOF_MAX_APS];
+-} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8 */
++} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8,
++ LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */
+
+ #define IWL_MVM_TOF_MCSI_BUF_SIZE (245)
+ /**
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
+index 6610d1234f74..d088c820b1a9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2012-2014, 2018-2019 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
+ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2016-2017 Intel Deutschland GmbH
+ */
+@@ -39,9 +39,9 @@ enum iwl_mac_conf_subcmd_ids {
+ PROBE_RESPONSE_DATA_NOTIF = 0xFC,
+
+ /**
+- * @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
++ * @CHANNEL_SWITCH_START_NOTIF: &struct iwl_channel_switch_start_notif
+ */
+- CHANNEL_SWITCH_NOA_NOTIF = 0xFF,
++ CHANNEL_SWITCH_START_NOTIF = 0xFF,
+ };
+
+ #define IWL_P2P_NOA_DESC_COUNT (2)
+@@ -102,11 +102,11 @@ struct iwl_missed_vap_notif {
+ } __packed; /* MISSED_VAP_NTFY_API_S_VER_1 */
+
+ /**
+- * struct iwl_channel_switch_noa_notif - Channel switch NOA notification
++ * struct iwl_channel_switch_start_notif - Channel switch start notification
+ *
+ * @id_and_color: ID and color of the MAC
+ */
+-struct iwl_channel_switch_noa_notif {
++struct iwl_channel_switch_start_notif {
+ __le32 id_and_color;
+ } __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
+index 7be7715b431d..11f0bd283e49 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
+@@ -138,6 +138,8 @@ struct iwl_mac_data_ibss {
+ * @FLEXIBLE_TWT_SUPPORTED: AP supports flexible TWT schedule
+ * @PROTECTED_TWT_SUPPORTED: AP supports protected TWT frames (with 11w)
+ * @BROADCAST_TWT_SUPPORTED: AP and STA support broadcast TWT
++ * @COEX_HIGH_PRIORITY_ENABLE: high priority mode for BT coex, to be used
++ * during 802.1X negotiation (and allowed during 4-way-HS)
+ */
+ enum iwl_mac_data_policy {
+ TWT_SUPPORTED = BIT(0),
+@@ -145,6 +147,7 @@ enum iwl_mac_data_policy {
+ FLEXIBLE_TWT_SUPPORTED = BIT(2),
+ PROTECTED_TWT_SUPPORTED = BIT(3),
+ BROADCAST_TWT_SUPPORTED = BIT(4),
++ COEX_HIGH_PRIORITY_ENABLE = BIT(5),
+ };
+
+ /**
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+index cf48c6fa8f65..3551a3f1c1aa 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+@@ -471,6 +471,29 @@ struct iwl_lari_config_change_cmd_v4 {
+ __le32 oem_unii4_allow_bitmap;
+ } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_4 */
+
++/**
++ * struct iwl_lari_config_change_cmd_v5 - change LARI configuration
++ * @config_bitmap: Bitmap of the config commands. Each bit will trigger a
++ * different predefined FW config operation.
++ * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets.
++ * @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits
++ * per country, one to indicate whether to override and the other to
++ * indicate the value to use.
++ * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
++ * per country, one to indicate whether to override and the other to
++ * indicate allow/disallow unii4 channels.
++ * @chan_state_active_bitmap: Bitmap for overriding channel state to active.
++ * Each bit represents a country or region to activate, according to the BIOS
++ * definitions.
++ */
++struct iwl_lari_config_change_cmd_v5 {
++ __le32 config_bitmap;
++ __le32 oem_uhb_allow_bitmap;
++ __le32 oem_11ax_allow_bitmap;
++ __le32 oem_unii4_allow_bitmap;
++ __le32 chan_state_active_bitmap;
++} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_5 */
++
+ /**
+ * struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete
+ * @status: PNVM image loading status
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
+index d07a632f1af7..c04f2521fcb3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2012-2014, 2019-2020 Intel Corporation
++ * Copyright (C) 2012-2014, 2019-2021 Intel Corporation
+ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2016-2017 Intel Deutschland GmbH
+ */
+@@ -29,9 +29,9 @@ enum iwl_phy_ops_subcmd_ids {
+ TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
+
+ /**
+- * @GEO_TX_POWER_LIMIT: &struct iwl_geo_tx_power_profiles_cmd
++ * @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd
+ */
+- GEO_TX_POWER_LIMIT = 0x05,
++ PER_CHAIN_LIMIT_OFFSET_CMD = 0x05,
+
+ /**
+ * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+index 86445385f072..4d671c878bb7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
+ * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
+ * Copyright (C) 2015-2017 Intel Deutschland GmbH
+ */
+@@ -378,9 +378,10 @@ struct iwl_dev_tx_power_cmd {
+ };
+ };
+
+-#define IWL_NUM_GEO_PROFILES 3
+-#define IWL_NUM_BANDS_PER_CHAIN_V1 2
+-#define IWL_NUM_BANDS_PER_CHAIN_V2 3
++#define IWL_NUM_GEO_PROFILES 3
++#define IWL_NUM_GEO_PROFILES_V3 8
++#define IWL_NUM_BANDS_PER_CHAIN_V1 2
++#define IWL_NUM_BANDS_PER_CHAIN_V2 3
+
+ /**
+ * enum iwl_geo_per_chain_offset_operation - type of operation
+@@ -390,10 +391,10 @@ struct iwl_dev_tx_power_cmd {
+ enum iwl_geo_per_chain_offset_operation {
+ IWL_PER_CHAIN_OFFSET_SET_TABLES,
+ IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE,
+-}; /* GEO_TX_POWER_LIMIT FLAGS TYPE */
++}; /* PER_CHAIN_OFFSET_OPERATION_E */
+
+ /**
+- * struct iwl_per_chain_offset - embedded struct for GEO_TX_POWER_LIMIT.
++ * struct iwl_per_chain_offset - embedded struct for PER_CHAIN_LIMIT_OFFSET_CMD.
+ * @max_tx_power: maximum allowed tx power.
+ * @chain_a: tx power offset for chain a.
+ * @chain_b: tx power offset for chain b.
+@@ -405,17 +406,17 @@ struct iwl_per_chain_offset {
+ } __packed; /* PER_CHAIN_LIMIT_OFFSET_PER_CHAIN_S_VER_1 */
+
+ /**
+- * struct iwl_geo_tx_power_profile_cmd_v1 - struct for GEO_TX_POWER_LIMIT cmd.
++ * struct iwl_geo_tx_power_profile_cmd_v1 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
+ * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
+ * @table: offset profile per band.
+ */
+ struct iwl_geo_tx_power_profiles_cmd_v1 {
+ __le32 ops;
+ struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V1];
+-} __packed; /* GEO_TX_POWER_LIMIT_VER_1 */
++} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_1 */
+
+ /**
+- * struct iwl_geo_tx_power_profile_cmd_v2 - struct for GEO_TX_POWER_LIMIT cmd.
++ * struct iwl_geo_tx_power_profile_cmd_v2 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
+ * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
+ * @table: offset profile per band.
+ * @table_revision: BIOS table revision.
+@@ -424,10 +425,10 @@ struct iwl_geo_tx_power_profiles_cmd_v2 {
+ __le32 ops;
+ struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V1];
+ __le32 table_revision;
+-} __packed; /* GEO_TX_POWER_LIMIT_VER_2 */
++} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_2 */
+
+ /**
+- * struct iwl_geo_tx_power_profile_cmd_v3 - struct for GEO_TX_POWER_LIMIT cmd.
++ * struct iwl_geo_tx_power_profile_cmd_v3 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
+ * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
+ * @table: offset profile per band.
+ * @table_revision: BIOS table revision.
+@@ -436,21 +437,47 @@ struct iwl_geo_tx_power_profiles_cmd_v3 {
+ __le32 ops;
+ struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V2];
+ __le32 table_revision;
+-} __packed; /* GEO_TX_POWER_LIMIT_VER_3 */
++} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_3 */
++
++/**
++ * struct iwl_geo_tx_power_profile_cmd_v4 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
++ * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
++ * @table: offset profile per band.
++ * @table_revision: BIOS table revision.
++ */
++struct iwl_geo_tx_power_profiles_cmd_v4 {
++ __le32 ops;
++ struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V1];
++ __le32 table_revision;
++} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_4 */
++
++/**
++ * struct iwl_geo_tx_power_profile_cmd_v5 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
++ * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
++ * @table: offset profile per band.
++ * @table_revision: BIOS table revision.
++ */
++struct iwl_geo_tx_power_profiles_cmd_v5 {
++ __le32 ops;
++ struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V2];
++ __le32 table_revision;
++} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_5 */
+
+ union iwl_geo_tx_power_profiles_cmd {
+ struct iwl_geo_tx_power_profiles_cmd_v1 v1;
+ struct iwl_geo_tx_power_profiles_cmd_v2 v2;
+ struct iwl_geo_tx_power_profiles_cmd_v3 v3;
++ struct iwl_geo_tx_power_profiles_cmd_v4 v4;
++ struct iwl_geo_tx_power_profiles_cmd_v5 v5;
+ };
+
+ /**
+- * struct iwl_geo_tx_power_profiles_resp - response to GEO_TX_POWER_LIMIT cmd
++ * struct iwl_geo_tx_power_profiles_resp - response to PER_CHAIN_LIMIT_OFFSET_CMD cmd
+ * @profile_idx: current geo profile in use
+ */
+ struct iwl_geo_tx_power_profiles_resp {
+ __le32 profile_idx;
+-} __packed; /* GEO_TX_POWER_LIMIT_RESP */
++} __packed; /* PER_CHAIN_LIMIT_OFFSET_RSP */
+
+ /**
+ * union iwl_ppag_table_cmd - union for all versions of PPAG command
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
+index fc2fa49e9825..a09081d7ed45 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
+@@ -184,6 +184,14 @@ struct iwl_tlc_update_notif {
+ __le32 amsdu_enabled;
+ } __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */
+
++
++#define IWL_MAX_MCS_DISPLAY_SIZE 12
++
++struct iwl_rate_mcs_info {
++ char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
++ char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
++};
++
+ /*
+ * These serve as indexes into
+ * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
+@@ -226,6 +234,8 @@ enum {
+ IWL_LAST_HE_RATE = IWL_RATE_MCS_11_INDEX,
+ IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1,
+ IWL_RATE_COUNT = IWL_LAST_HE_RATE + 1,
++ IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
++ IWL_RATE_INVALID = IWL_RATE_COUNT,
+ };
+
+ #define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
+@@ -248,7 +258,7 @@ enum {
+ };
+
+ /*
+- * rate_n_flags bit fields
++ * rate_n_flags bit fields version 1
+ *
+ * The 32-bit value has different layouts in the low 8 bites depending on the
+ * format. There are three formats, HT, VHT and legacy (11abg, with subformats
+@@ -266,15 +276,15 @@ enum {
+
+ /* Bit 8: (1) HT format, (0) legacy or VHT format */
+ #define RATE_MCS_HT_POS 8
+-#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS)
++#define RATE_MCS_HT_MSK_V1 BIT(RATE_MCS_HT_POS)
+
+ /* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */
+-#define RATE_MCS_CCK_POS 9
+-#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS)
++#define RATE_MCS_CCK_POS_V1 9
++#define RATE_MCS_CCK_MSK_V1 BIT(RATE_MCS_CCK_POS_V1)
+
+ /* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */
+-#define RATE_MCS_VHT_POS 26
+-#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS)
++#define RATE_MCS_VHT_POS_V1 26
++#define RATE_MCS_VHT_MSK_V1 BIT(RATE_MCS_VHT_POS_V1)
+
+
+ /*
+@@ -300,15 +310,16 @@ enum {
+ * streams and 16-23 have three streams. We could also support MCS 32
+ * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
+ */
+-#define RATE_HT_MCS_RATE_CODE_MSK 0x7
+-#define RATE_HT_MCS_NSS_POS 3
+-#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS)
++#define RATE_HT_MCS_RATE_CODE_MSK_V1 0x7
++#define RATE_HT_MCS_NSS_POS_V1 3
++#define RATE_HT_MCS_NSS_MSK_V1 (3 << RATE_HT_MCS_NSS_POS_V1)
++#define RATE_HT_MCS_MIMO2_MSK BIT(RATE_HT_MCS_NSS_POS_V1)
+
+ /* Bit 10: (1) Use Green Field preamble */
+ #define RATE_HT_MCS_GF_POS 10
+ #define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS)
+
+-#define RATE_HT_MCS_INDEX_MSK 0x3f
++#define RATE_HT_MCS_INDEX_MSK_V1 0x3f
+
+ /*
+ * Very High-throughput (VHT) rate format for bits 7:0
+@@ -324,6 +335,7 @@ enum {
+ #define RATE_VHT_MCS_RATE_CODE_MSK 0xf
+ #define RATE_VHT_MCS_NSS_POS 4
+ #define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS)
++#define RATE_VHT_MCS_MIMO2_MSK BIT(RATE_VHT_MCS_NSS_POS)
+
+ /*
+ * Legacy OFDM rate format for bits 7:0
+@@ -347,37 +359,30 @@ enum {
+ * 110) 11 Mbps
+ * (bit 7 is 0)
+ */
+-#define RATE_LEGACY_RATE_MSK 0xff
++#define RATE_LEGACY_RATE_MSK_V1 0xff
+
+ /* Bit 10 - OFDM HE */
+-#define RATE_MCS_HE_POS 10
+-#define RATE_MCS_HE_MSK BIT(RATE_MCS_HE_POS)
++#define RATE_MCS_HE_POS_V1 10
++#define RATE_MCS_HE_MSK_V1 BIT(RATE_MCS_HE_POS_V1)
+
+ /*
+ * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz
+ * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT
+ */
+ #define RATE_MCS_CHAN_WIDTH_POS 11
+-#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS)
+-#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS)
+-#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS)
+-#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS)
+-#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS)
++#define RATE_MCS_CHAN_WIDTH_MSK_V1 (3 << RATE_MCS_CHAN_WIDTH_POS)
+
+ /* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */
+-#define RATE_MCS_SGI_POS 13
+-#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS)
++#define RATE_MCS_SGI_POS_V1 13
++#define RATE_MCS_SGI_MSK_V1 BIT(RATE_MCS_SGI_POS_V1)
+
+ /* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */
+ #define RATE_MCS_ANT_POS 14
+ #define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS)
+ #define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS)
+-#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS)
+ #define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \
+ RATE_MCS_ANT_B_MSK)
+-#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \
+- RATE_MCS_ANT_C_MSK)
+-#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK
++#define RATE_MCS_ANT_MSK RATE_MCS_ANT_AB_MSK
+
+ /* Bit 17: (0) SS, (1) SS*2 */
+ #define RATE_MCS_STBC_POS 17
+@@ -411,27 +416,27 @@ enum {
+ * 3 (does not occur)
+ */
+ #define RATE_MCS_HE_GI_LTF_POS 20
+-#define RATE_MCS_HE_GI_LTF_MSK (3 << RATE_MCS_HE_GI_LTF_POS)
++#define RATE_MCS_HE_GI_LTF_MSK_V1 (3 << RATE_MCS_HE_GI_LTF_POS)
+
+ /* Bit 22-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */
+-#define RATE_MCS_HE_TYPE_POS 22
+-#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS)
+-#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS)
+-#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS)
+-#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS)
+-#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS)
++#define RATE_MCS_HE_TYPE_POS_V1 22
++#define RATE_MCS_HE_TYPE_SU_V1 (0 << RATE_MCS_HE_TYPE_POS_V1)
++#define RATE_MCS_HE_TYPE_EXT_SU_V1 BIT(RATE_MCS_HE_TYPE_POS_V1)
++#define RATE_MCS_HE_TYPE_MU_V1 (2 << RATE_MCS_HE_TYPE_POS_V1)
++#define RATE_MCS_HE_TYPE_TRIG_V1 (3 << RATE_MCS_HE_TYPE_POS_V1)
++#define RATE_MCS_HE_TYPE_MSK_V1 (3 << RATE_MCS_HE_TYPE_POS_V1)
+
+ /* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */
+-#define RATE_MCS_DUP_POS 24
+-#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS)
++#define RATE_MCS_DUP_POS_V1 24
++#define RATE_MCS_DUP_MSK_V1 (3 << RATE_MCS_DUP_POS_V1)
+
+ /* Bit 27: (1) LDPC enabled, (0) LDPC disabled */
+-#define RATE_MCS_LDPC_POS 27
+-#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS)
++#define RATE_MCS_LDPC_POS_V1 27
++#define RATE_MCS_LDPC_MSK_V1 BIT(RATE_MCS_LDPC_POS_V1)
+
+ /* Bit 28: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */
+-#define RATE_MCS_HE_106T_POS 28
+-#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS)
++#define RATE_MCS_HE_106T_POS_V1 28
++#define RATE_MCS_HE_106T_MSK_V1 BIT(RATE_MCS_HE_106T_POS_V1)
+
+ /* Bit 30-31: (1) RTS, (2) CTS */
+ #define RATE_MCS_RTS_REQUIRED_POS (30)
+@@ -440,6 +445,152 @@ enum {
+ #define RATE_MCS_CTS_REQUIRED_POS (31)
+ #define RATE_MCS_CTS_REQUIRED_MSK (0x1 << RATE_MCS_CTS_REQUIRED_POS)
+
++/* rate_n_flags bit field version 2
++ *
++ * The 32-bit value has different layouts in the low 8 bits depending on the
++ * format. There are three formats, HT, VHT and legacy (11abg, with subformats
++ * for CCK and OFDM).
++ *
++ */
++
++/* Bits 10-8: rate format
++ * (0) Legacy CCK (1) Legacy OFDM (2) High-throughput (HT)
++ * (3) Very High-throughput (VHT) (4) High-efficiency (HE)
++ * (5) Extremely High-throughput (EHT)
++ */
++#define RATE_MCS_MOD_TYPE_POS 8
++#define RATE_MCS_MOD_TYPE_MSK (0x7 << RATE_MCS_MOD_TYPE_POS)
++#define RATE_MCS_CCK_MSK (0 << RATE_MCS_MOD_TYPE_POS)
++#define RATE_MCS_LEGACY_OFDM_MSK (1 << RATE_MCS_MOD_TYPE_POS)
++#define RATE_MCS_HT_MSK (2 << RATE_MCS_MOD_TYPE_POS)
++#define RATE_MCS_VHT_MSK (3 << RATE_MCS_MOD_TYPE_POS)
++#define RATE_MCS_HE_MSK (4 << RATE_MCS_MOD_TYPE_POS)
++#define RATE_MCS_EHT_MSK (5 << RATE_MCS_MOD_TYPE_POS)
++
++/*
++ * Legacy CCK rate format for bits 0:3:
++ *
++ * (0) 0xa - 1 Mbps
++ * (1) 0x14 - 2 Mbps
++ * (2) 0x37 - 5.5 Mbps
++ * (3) 0x6e - 11 nbps
++ *
++ * Legacy OFDM rate format for bis 3:0:
++ *
++ * (0) 6 Mbps
++ * (1) 9 Mbps
++ * (2) 12 Mbps
++ * (3) 18 Mbps
++ * (4) 24 Mbps
++ * (5) 36 Mbps
++ * (6) 48 Mbps
++ * (7) 54 Mbps
++ *
++ */
++#define RATE_LEGACY_RATE_MSK 0x7
++
++/*
++ * HT, VHT, HE, EHT rate format for bits 3:0
++ * 3-0: MCS
++ *
++ */
++#define RATE_HT_MCS_CODE_MSK 0x7
++#define RATE_MCS_NSS_POS 4
++#define RATE_MCS_NSS_MSK (1 << RATE_MCS_NSS_POS)
++#define RATE_MCS_CODE_MSK 0xf
++#define RATE_HT_MCS_INDEX(r) ((((r) & RATE_MCS_NSS_MSK) >> 1) | \
++ ((r) & RATE_HT_MCS_CODE_MSK))
++
++/* Bits 7-5: reserved */
++
++/*
++ * Bits 13-11: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz, (4) 320MHz
++ */
++#define RATE_MCS_CHAN_WIDTH_MSK (0x7 << RATE_MCS_CHAN_WIDTH_POS)
++#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS)
++#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS)
++#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS)
++#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS)
++#define RATE_MCS_CHAN_WIDTH_320 (4 << RATE_MCS_CHAN_WIDTH_POS)
++
++/* Bit 15-14: Antenna selection:
++ * Bit 14: Ant A active
++ * Bit 15: Ant B active
++ *
++ * All relevant definitions are same as in v1
++ */
++
++/* Bit 16 (1) LDPC enables, (0) LDPC disabled */
++#define RATE_MCS_LDPC_POS 16
++#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS)
++
++/* Bit 17: (0) SS, (1) SS*2 (same as v1) */
++
++/* Bit 18: OFDM-HE dual carrier mode (same as v1) */
++
++/* Bit 19: (0) Beamforming is off, (1) Beamforming is on (same as v1) */
++
++/*
++ * Bit 22-20: HE LTF type and guard interval
++ * CCK:
++ * 0 long preamble
++ * 1 short preamble
++ * HT/VHT:
++ * 0 0.8us
++ * 1 0.4us
++ * HE (ext) SU:
++ * 0 1xLTF+0.8us
++ * 1 2xLTF+0.8us
++ * 2 2xLTF+1.6us
++ * 3 4xLTF+3.2us
++ * 4 4xLTF+0.8us
++ * HE MU:
++ * 0 4xLTF+0.8us
++ * 1 2xLTF+0.8us
++ * 2 2xLTF+1.6us
++ * 3 4xLTF+3.2us
++ * HE TRIG:
++ * 0 1xLTF+1.6us
++ * 1 2xLTF+1.6us
++ * 2 4xLTF+3.2us
++ * */
++#define RATE_MCS_HE_GI_LTF_MSK (0x7 << RATE_MCS_HE_GI_LTF_POS)
++#define RATE_MCS_SGI_POS RATE_MCS_HE_GI_LTF_POS
++#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS)
++#define RATE_MCS_HE_SU_4_LTF 3
++#define RATE_MCS_HE_SU_4_LTF_08_GI 4
++
++/* Bit 24-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */
++#define RATE_MCS_HE_TYPE_POS 23
++#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS)
++#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS)
++#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS)
++#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS)
++#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS)
++
++/* Bit 25: duplicate channel enabled
++ *
++ * if this bit is set, duplicate is according to BW (bits 11-13):
++ *
++ * CCK: 2x 20MHz
++ * OFDM Legacy: N x 20Mhz, (N = BW \ 2 , either 2, 4, 8, 16)
++ * EHT: 2 x BW/2, (80 - 2x40, 160 - 2x80, 320 - 2x160)
++ * */
++#define RATE_MCS_DUP_POS 25
++#define RATE_MCS_DUP_MSK (1 << RATE_MCS_DUP_POS)
++
++/* Bit 26: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */
++#define RATE_MCS_HE_106T_POS 26
++#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS)
++
++/* Bit 27: EHT extra LTF:
++ * instead of 1 LTF for SISO use 2 LTFs,
++ * instead of 2 LTFs for NSTS=2 use 4 LTFs*/
++#define RATE_MCS_EHT_EXTRA_LTF_POS 27
++#define RATE_MCS_EHT_EXTRA_LTF_MSK (1 << RATE_MCS_EHT_EXTRA_LTF_POS)
++
++/* Bit 31-28: reserved */
++
+ /* Link Quality definitions */
+
+ /* # entries in rate scale table to support Tx retries */
+@@ -557,4 +708,13 @@ struct iwl_lq_cmd {
+ __le32 ss_params;
+ }; /* LINK_QUALITY_CMD_API_S_VER_1 */
+
++u8 iwl_fw_rate_idx_to_plcp(int idx);
++u32 iwl_new_rate_from_v1(u32 rate_v1);
++u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags);
++const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx);
++const char *iwl_rs_pretty_ant(u8 ant);
++const char *iwl_rs_pretty_bw(int bw);
++int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);
++bool iwl_he_is_sgi(u32 rate_n_flags);
++
+ #endif /* __iwl_fw_api_rs_h__ */
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+index 3f13b572915a..1989b270862b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
+ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2015-2017 Intel Deutschland GmbH
+ */
+@@ -13,7 +13,6 @@
+ #define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1
+ #define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff
+ #define IWL_RX_INFO_ENERGY_ANT_B_MSK 0x0000ff00
+-#define IWL_RX_INFO_ENERGY_ANT_C_MSK 0x00ff0000
+ #define IWL_RX_INFO_ENERGY_ANT_A_POS 0
+ #define IWL_RX_INFO_ENERGY_ANT_B_POS 8
+ #define IWL_RX_INFO_ENERGY_ANT_C_POS 16
+@@ -126,14 +125,12 @@ enum iwl_rx_phy_flags {
+ * @RX_MPDU_RES_STATUS_OVERRUN_OK: there was no RXE overflow
+ * @RX_MPDU_RES_STATUS_SRC_STA_FOUND: station was found
+ * @RX_MPDU_RES_STATUS_KEY_VALID: key was valid
+- * @RX_MPDU_RES_STATUS_KEY_PARAM_OK: key parameters were usable
+ * @RX_MPDU_RES_STATUS_ICV_OK: ICV is fine, if not, the packet is destroyed
+ * @RX_MPDU_RES_STATUS_MIC_OK: used for CCM alg only. TKIP MIC is checked
+ * in the driver.
+ * @RX_MPDU_RES_STATUS_TTAK_OK: TTAK is fine
+ * @RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR: valid for alg = CCM_CMAC or
+- * alg = CCM only. Checks replay attack for 11w frames. Relevant only if
+- * %RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME is set.
++ * alg = CCM only. Checks replay attack for 11w frames.
+ * @RX_MPDU_RES_STATUS_SEC_NO_ENC: this frame is not encrypted
+ * @RX_MPDU_RES_STATUS_SEC_WEP_ENC: this frame is encrypted using WEP
+ * @RX_MPDU_RES_STATUS_SEC_CCM_ENC: this frame is encrypted using CCM
+@@ -145,9 +142,6 @@ enum iwl_rx_phy_flags {
+ * @RX_MPDU_RES_STATUS_SEC_ENC_ERR: this frame couldn't be decrypted
+ * @RX_MPDU_RES_STATUS_SEC_ENC_MSK: bitmask of the encryption algorithm
+ * @RX_MPDU_RES_STATUS_DEC_DONE: this frame has been successfully decrypted
+- * @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP: extended IV (set with TKIP)
+- * @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT: key ID comparison done
+- * @RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME: this frame is an 11w management frame
+ * @RX_MPDU_RES_STATUS_CSUM_DONE: checksum was done by the hw
+ * @RX_MPDU_RES_STATUS_CSUM_OK: checksum found no errors
+ * @RX_MPDU_RES_STATUS_STA_ID_MSK: station ID mask
+@@ -158,7 +152,6 @@ enum iwl_mvm_rx_status {
+ RX_MPDU_RES_STATUS_OVERRUN_OK = BIT(1),
+ RX_MPDU_RES_STATUS_SRC_STA_FOUND = BIT(2),
+ RX_MPDU_RES_STATUS_KEY_VALID = BIT(3),
+- RX_MPDU_RES_STATUS_KEY_PARAM_OK = BIT(4),
+ RX_MPDU_RES_STATUS_ICV_OK = BIT(5),
+ RX_MPDU_RES_STATUS_MIC_OK = BIT(6),
+ RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
+@@ -172,9 +165,6 @@ enum iwl_mvm_rx_status {
+ RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8),
+ RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8),
+ RX_MPDU_RES_STATUS_DEC_DONE = BIT(11),
+- RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP = BIT(13),
+- RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT = BIT(14),
+- RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME = BIT(15),
+ RX_MPDU_RES_STATUS_CSUM_DONE = BIT(16),
+ RX_MPDU_RES_STATUS_CSUM_OK = BIT(17),
+ RX_MDPU_RES_STATUS_STA_ID_SHIFT = 24,
+@@ -236,7 +226,6 @@ enum iwl_rx_mpdu_status {
+ IWL_RX_MPDU_STATUS_OVERRUN_OK = BIT(1),
+ IWL_RX_MPDU_STATUS_SRC_STA_FOUND = BIT(2),
+ IWL_RX_MPDU_STATUS_KEY_VALID = BIT(3),
+- IWL_RX_MPDU_STATUS_KEY_PARAM_OK = BIT(4),
+ IWL_RX_MPDU_STATUS_ICV_OK = BIT(5),
+ IWL_RX_MPDU_STATUS_MIC_OK = BIT(6),
+ IWL_RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
+@@ -251,12 +240,8 @@ enum iwl_rx_mpdu_status {
+ IWL_RX_MPDU_STATUS_SEC_EXT_ENC = 0x4 << 8,
+ IWL_RX_MPDU_STATUS_SEC_GCM = 0x5 << 8,
+ IWL_RX_MPDU_STATUS_DECRYPTED = BIT(11),
+- IWL_RX_MPDU_STATUS_WEP_MATCH = BIT(12),
+- IWL_RX_MPDU_STATUS_EXT_IV_MATCH = BIT(13),
+- IWL_RX_MPDU_STATUS_KEY_ID_MATCH = BIT(14),
+ IWL_RX_MPDU_STATUS_ROBUST_MNG_FRAME = BIT(15),
+
+- IWL_RX_MPDU_STATUS_KEY = 0x3f0000,
+ IWL_RX_MPDU_STATUS_DUPLICATE = BIT(22),
+
+ IWL_RX_MPDU_STATUS_STA_ID = 0x1f000000,
+@@ -460,7 +445,7 @@ struct iwl_rx_mpdu_desc_v1 {
+ __le32 phy_data1;
+ };
+ };
+-} __packed;
++} __packed; /* RX_MPDU_RES_START_API_S_VER_4 */
+
+ /**
+ * struct iwl_rx_mpdu_desc_v3 - RX MPDU descriptor
+@@ -560,7 +545,8 @@ struct iwl_rx_mpdu_desc_v3 {
+ * @reserved: reserved
+ */
+ __le32 reserved[2];
+-} __packed; /* RX_MPDU_RES_START_API_S_VER_3 */
++} __packed; /* RX_MPDU_RES_START_API_S_VER_3,
++ RX_MPDU_RES_START_API_S_VER_5 */
+
+ /**
+ * struct iwl_rx_mpdu_desc - RX MPDU descriptor
+@@ -625,7 +611,9 @@ struct iwl_rx_mpdu_desc {
+ struct iwl_rx_mpdu_desc_v1 v1;
+ struct iwl_rx_mpdu_desc_v3 v3;
+ };
+-} __packed; /* RX_MPDU_RES_START_API_S_VER_3 */
++} __packed; /* RX_MPDU_RES_START_API_S_VER_3,
++ RX_MPDU_RES_START_API_S_VER_4,
++ RX_MPDU_RES_START_API_S_VER_5 */
+
+ #define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1)
+
+@@ -679,7 +667,8 @@ struct iwl_rx_no_data {
+ __le32 rate;
+ __le32 phy_info[2];
+ __le32 rx_vec[2];
+-} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1 */
++} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1,
++ TX_NO_DATA_NTFY_API_S_VER_2 */
+
+ struct iwl_frame_release {
+ u8 baid;
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
+index f1a3e14880e7..5edbe27c0922 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
+@@ -28,6 +28,8 @@
+ * @STA_FLG_MAX_AGG_SIZE_256K: maximal size for A-MPDU (256k supported)
+ * @STA_FLG_MAX_AGG_SIZE_512K: maximal size for A-MPDU (512k supported)
+ * @STA_FLG_MAX_AGG_SIZE_1024K: maximal size for A-MPDU (1024k supported)
++ * @STA_FLG_MAX_AGG_SIZE_2M: maximal size for A-MPDU (2M supported)
++ * @STA_FLG_MAX_AGG_SIZE_4M: maximal size for A-MPDU (4M supported)
+ * @STA_FLG_AGG_MPDU_DENS_MSK: maximal MPDU density for Tx aggregation
+ * @STA_FLG_FAT_EN_MSK: support for channel width (for Tx). This flag is
+ * initialised by driver and can be updated by fw upon reception of
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+index 24e4a82a55da..9b3bce83efb6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
+ * Copyright (C) 2016-2017 Intel Deutschland GmbH
+ */
+ #ifndef __iwl_fw_api_tx_h__
+@@ -81,6 +81,10 @@ enum iwl_tx_cmd_flags {
+ IWL_TX_FLAGS_CMD_RATE = BIT(0),
+ IWL_TX_FLAGS_ENCRYPT_DIS = BIT(1),
+ IWL_TX_FLAGS_HIGH_PRI = BIT(2),
++ /* Use these flags only from
++ * TX_FLAGS_BITS_API_S_VER_4 and above */
++ IWL_TX_FLAGS_RTS = BIT(3),
++ IWL_TX_FLAGS_CTS = BIT(4),
+ }; /* TX_FLAGS_BITS_API_S_VER_3 */
+
+ /**
+@@ -267,7 +271,8 @@ struct iwl_tx_cmd_gen2 {
+ struct iwl_dram_sec_info dram_info;
+ __le32 rate_n_flags;
+ struct ieee80211_hdr hdr[];
+-} __packed; /* TX_CMD_API_S_VER_7 */
++} __packed; /* TX_CMD_API_S_VER_7,
++ TX_CMD_API_S_VER_9 */
+
+ /**
+ * struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices
+@@ -290,7 +295,8 @@ struct iwl_tx_cmd_gen3 {
+ __le32 rate_n_flags;
+ __le64 ttl;
+ struct ieee80211_hdr hdr[];
+-} __packed; /* TX_CMD_API_S_VER_8 */
++} __packed; /* TX_CMD_API_S_VER_8,
++ TX_CMD_API_S_VER_10 */
+
+ /*
+ * TX response related data
+@@ -591,7 +597,8 @@ struct iwl_mvm_tx_resp {
+ __le16 tx_queue;
+ __le16 reserved2;
+ struct agg_tx_status status;
+-} __packed; /* TX_RSP_API_S_VER_6 */
++} __packed; /* TX_RSP_API_S_VER_6,
++ TX_RSP_API_S_VER_7 */
+
+ /**
+ * struct iwl_mvm_ba_notif - notifies about reception of BA
+@@ -715,7 +722,8 @@ struct iwl_mvm_compressed_ba_notif {
+ __le16 ra_tid_cnt;
+ struct iwl_mvm_compressed_ba_ratid ra_tid[0];
+ struct iwl_mvm_compressed_ba_tfd tfd[];
+-} __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */
++} __packed; /* COMPRESSED_BA_RES_API_S_VER_4,
++ COMPRESSED_BA_RES_API_S_VER_5 */
+
+ /**
+ * struct iwl_mac_beacon_cmd_v6 - beacon template command
+@@ -755,12 +763,20 @@ struct iwl_mac_beacon_cmd_v7 {
+ struct ieee80211_hdr frame[];
+ } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
+
++/* Bit flags for BEACON_TEMPLATE_CMD_API until version 10 */
++enum iwl_mac_beacon_flags_v1 {
++ IWL_MAC_BEACON_CCK_V1 = BIT(8),
++ IWL_MAC_BEACON_ANT_A_V1 = BIT(9),
++ IWL_MAC_BEACON_ANT_B_V1 = BIT(10),
++ IWL_MAC_BEACON_FILS_V1 = BIT(12),
++};
++
++/* Bit flags for BEACON_TEMPLATE_CMD_API version 11 and above */
+ enum iwl_mac_beacon_flags {
+- IWL_MAC_BEACON_CCK = BIT(8),
+- IWL_MAC_BEACON_ANT_A = BIT(9),
+- IWL_MAC_BEACON_ANT_B = BIT(10),
+- IWL_MAC_BEACON_ANT_C = BIT(11),
+- IWL_MAC_BEACON_FILS = BIT(12),
++ IWL_MAC_BEACON_CCK = BIT(5),
++ IWL_MAC_BEACON_ANT_A = BIT(6),
++ IWL_MAC_BEACON_ANT_B = BIT(7),
++ IWL_MAC_BEACON_FILS = BIT(8),
+ };
+
+ /**
+@@ -788,7 +804,9 @@ struct iwl_mac_beacon_cmd {
+ __le32 ecsa_offset;
+ __le32 csa_offset;
+ struct ieee80211_hdr frame[];
+-} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */
++} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10,
++ BEACON_TEMPLATE_CMD_API_S_VER_11,
++ BEACON_TEMPLATE_CMD_API_S_VER_12 */
+
+ struct iwl_beacon_notif {
+ struct iwl_mvm_tx_resp beacon_notify_hdr;
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+index 6dcafd0a3d4b..a39013c401c9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+@@ -159,11 +159,15 @@ static void iwl_fwrt_dump_txf(struct iwl_fw_runtime *fwrt,
+ iwl_trans_read_prph(fwrt->trans, TXF_READ_MODIFY_DATA + offset);
+
+ /* Read FIFO */
+- fifo_len /= sizeof(u32); /* Size in DWORDS */
+- for (i = 0; i < fifo_len; i++)
++ for (i = 0; i < fifo_len / sizeof(u32); i++)
+ fifo_data[i] = iwl_trans_read_prph(fwrt->trans,
+ TXF_READ_MODIFY_DATA +
+ offset);
++
++ if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
++ fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
++ fifo_data, fifo_len);
++
+ *dump_data = iwl_fw_error_next_data(*dump_data);
+ }
+
+@@ -659,6 +663,10 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
+ iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
+ *dump_data = iwl_fw_error_next_data(*dump_data);
+
++ if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
++ fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, ofs,
++ dump_mem->data, len);
++
+ IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
+ }
+
+@@ -752,6 +760,12 @@ static void iwl_dump_paging(struct iwl_fw_runtime *fwrt,
+ PAGING_BLOCK_SIZE,
+ DMA_BIDIRECTIONAL);
+ (*data) = iwl_fw_error_next_data(*data);
++
++ if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
++ fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx,
++ fwrt->fw_paging_db[i].fw_offs,
++ paging->data,
++ PAGING_BLOCK_SIZE);
+ }
+ }
+
+@@ -980,6 +994,11 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
+ dump_data->data + data_size,
+ data_size);
+
++ if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
++ fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, addr,
++ dump_data->data + data_size,
++ data_size);
++
+ dump_data = iwl_fw_error_next_data(dump_data);
+ }
+
+@@ -1146,6 +1165,13 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
+ iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
+ le32_to_cpu(reg->dev_addr.size));
+
++ if ((le32_to_cpu(reg->id) & IWL_FW_INI_REGION_V2_MASK) ==
++ IWL_FW_INI_HW_SMEM_REGION_ID &&
++ fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
++ fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
++ range->data,
++ le32_to_cpu(reg->dev_addr.size));
++
+ return sizeof(*range) + le32_to_cpu(range->range_data_size);
+ }
+
+@@ -1338,6 +1364,10 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
+ for (i = 0; i < iter->fifo_size; i += sizeof(*data))
+ *data++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
+
++ if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
++ fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
++ reg_dump, iter->fifo_size);
++
+ out:
+ iwl_trans_release_nic_access(fwrt->trans);
+
+@@ -2077,7 +2107,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
+ */
+ hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev);
+ if (hw_type == IWL_AX210_HW_TYPE) {
+- u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR);
++ u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR_GEN2);
+ u32 is_jacket = !!(prph_val & WFPM_OTP_CFG1_IS_JACKET_BIT);
+ u32 is_cdb = !!(prph_val & WFPM_OTP_CFG1_IS_CDB_BIT);
+ u32 masked_bits = is_jacket | (is_cdb << 1);
+@@ -2360,7 +2390,9 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
+ if (dump_data->monitor_only)
+ dump_mask &= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR);
+
+- fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
++ fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask,
++ fwrt->sanitize_ops,
++ fwrt->sanitize_ctx);
+ file_len = le32_to_cpu(dump_file->file_len);
+ fw_error_dump.fwrt_len = file_len;
+
+@@ -2788,6 +2820,12 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
+ iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr,
+ fwrt->dump.d3_debug_data,
+ cfg->d3_debug_data_length);
++
++ if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
++ fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx,
++ cfg->d3_debug_data_base_addr,
++ fwrt->dump.d3_debug_data,
++ cfg->d3_debug_data_length);
+ }
+ IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c
+index a1842205e86a..016b3a4c5f51 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c
+@@ -214,7 +214,7 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu
+ /* reset the device */
+ iwl_trans_sw_reset(trans);
+
+- err = iwl_finish_nic_init(trans, trans->trans_cfg);
++ err = iwl_finish_nic_init(trans);
+ if (err)
+ return;
+ }
+@@ -328,6 +328,13 @@ static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt)
+ for (i = 0; i < ARRAY_SIZE(table.sw_status); i++)
+ IWL_ERR(fwrt, "0x%08X | tcm SW status[%d]\n",
+ table.sw_status[i], i);
++
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
++ u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH);
++
++ IWL_ERR(fwrt, "Function Scratch status:\n");
++ IWL_ERR(fwrt, "0x%08X | Func Scratch\n", scratch);
++ }
+ }
+
+ static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt)
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+index 521ca2bb0e92..9036b32ec765 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+@@ -342,10 +342,6 @@ struct iwl_fw_ini_dump_cfg_name {
+ #define IWL_AX210_HW_TYPE 0x42
+ /* How many bits to roll when adding to the HW type of AX210 HW */
+ #define IWL_AX210_HW_TYPE_ADDITION_SHIFT 12
+-/* This prph is used to tell apart HW_TYPE == 0x42 NICs */
+-#define WFPM_OTP_CFG1_ADDR 0xd03098
+-#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4)
+-#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5)
+
+ /* struct iwl_fw_ini_dump_info - ini dump information
+ * @version: dump version
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
+index 6c8e9f3a6af2..3d572f5024bb 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
+@@ -100,6 +100,9 @@ enum iwl_ucode_tlv_type {
+ IWL_UCODE_TLV_PNVM_SKU = 64,
+ IWL_UCODE_TLV_TCM_DEBUG_ADDRS = 65,
+
++ IWL_UCODE_TLV_SEC_TABLE_ADDR = 66,
++ IWL_UCODE_TLV_D3_KEK_KCK_ADDR = 67,
++
+ IWL_UCODE_TLV_FW_NUM_STATIONS = IWL_UCODE_TLV_CONST_BASE + 0,
+
+ IWL_UCODE_TLV_TYPE_DEBUG_INFO = IWL_UCODE_TLV_DEBUG_BASE + 0,
+@@ -107,6 +110,7 @@ enum iwl_ucode_tlv_type {
+ IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_TLV_DEBUG_BASE + 2,
+ IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_TLV_DEBUG_BASE + 3,
+ IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_TLV_DEBUG_BASE + 4,
++ IWL_UCODE_TLV_TYPE_CONF_SET = IWL_UCODE_TLV_DEBUG_BASE + 5,
+ IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS,
+
+ /* TLVs 0x1000-0x2000 are for internal driver usage */
+@@ -416,6 +420,8 @@ enum iwl_ucode_tlv_capa {
+ IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)58,
+ IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)59,
+ IWL_UCODE_TLV_CAPA_BROADCAST_TWT = (__force iwl_ucode_tlv_capa_t)60,
++ IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO = (__force iwl_ucode_tlv_capa_t)61,
++ IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)62,
+
+ /* set 2 */
+ IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
+@@ -449,7 +455,7 @@ enum iwl_ucode_tlv_capa {
+ IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)98,
+
+ IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100,
+- IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)102,
++ IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT = (__force iwl_ucode_tlv_capa_t)104,
+
+ #ifdef __CHECKER__
+ /* sparse says it cannot increment the previous enum member */
+@@ -956,6 +962,10 @@ struct iwl_fw_tcm_error_addr {
+ __le32 addr;
+ }; /* FW_TLV_TCM_ERROR_INFO_ADDRS_S */
+
++struct iwl_fw_dump_exclude {
++ __le32 addr, size;
++};
++
+ static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,
+ size_t fixed_size, size_t var_size)
+ {
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.c b/drivers/net/wireless/intel/iwlwifi/fw/img.c
+index c2a4e60518bc..24a966673691 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/img.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/img.c
+@@ -1,59 +1,7 @@
+-/******************************************************************************
+- *
+- * This file is provided under a dual BSD/GPLv2 license. When using or
+- * redistributing this file, you may do so under either license.
+- *
+- * GPL LICENSE SUMMARY
+- *
++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
++/*
+ * Copyright(c) 2019 - 2020 Intel Corporation
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of version 2 of the GNU General Public License as
+- * published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- * General Public License for more details.
+- *
+- * The full GNU General Public License is included in this distribution
+- * in the file called COPYING.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+- * BSD LICENSE
+- *
+- * Copyright(c) 2019 - 2020 Intel Corporation
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- *
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in
+- * the documentation and/or other materials provided with the
+- * distribution.
+- * * Neither the name Intel Corporation nor the names of its
+- * contributors may be used to endorse or promote products derived
+- * from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *****************************************************************************/
++ */
+
+ #include "img.h"
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
+index 153a3529e77a..993bda17fa30 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
+@@ -124,11 +124,13 @@ struct fw_img {
+ * @fw_paging_phys: page phy pointer
+ * @fw_paging_block: pointer to the allocated block
+ * @fw_paging_size: page size
++ * @fw_offs: offset in the device
+ */
+ struct iwl_fw_paging {
+ dma_addr_t fw_paging_phys;
+ struct page *fw_paging_block;
+ u32 fw_paging_size;
++ u32 fw_offs;
+ };
+
+ /**
+@@ -174,6 +176,10 @@ struct iwl_fw_dbg {
+ u32 dump_mask;
+ };
+
++struct iwl_dump_exclude {
++ u32 addr, size;
++};
++
+ /**
+ * struct iwl_fw - variables associated with the firmware
+ *
+@@ -194,6 +200,10 @@ struct iwl_fw_dbg {
+ * @cipher_scheme: optional external cipher scheme.
+ * @human_readable: human readable version
+ * we get the ALIVE from the uCode
++ * @phy_integration_ver: PHY integration version string
++ * @phy_integration_ver_len: length of @phy_integration_ver
++ * @dump_excl: image dump exclusion areas for RT image
++ * @dump_excl_wowlan: image dump exclusion areas for WoWLAN image
+ */
+ struct iwl_fw {
+ u32 ucode_ver;
+@@ -225,6 +235,8 @@ struct iwl_fw {
+
+ u8 *phy_integration_ver;
+ u32 phy_integration_ver_len;
++
++ struct iwl_dump_exclude dump_excl[2], dump_excl_wowlan[2];
+ };
+
+ static inline const char *get_fw_dbg_mode_string(int mode)
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c
+index 2ecec00db9da..566957ac4539 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/init.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c
+@@ -1,7 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+ * Copyright (C) 2017 Intel Deutschland GmbH
+- * Copyright (C) 2019-2020 Intel Corporation
++ * Copyright (C) 2019-2021 Intel Corporation
+ */
+ #include "iwl-drv.h"
+ #include "runtime.h"
+@@ -16,6 +16,8 @@
+ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
+ const struct iwl_fw *fw,
+ const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
++ const struct iwl_dump_sanitize_ops *sanitize_ops,
++ void *sanitize_ctx,
+ struct dentry *dbgfs_dir)
+ {
+ int i;
+@@ -26,6 +28,8 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
+ fwrt->dev = trans->dev;
+ fwrt->dump.conf = FW_DBG_INVALID;
+ fwrt->ops = ops;
++ fwrt->sanitize_ops = sanitize_ops;
++ fwrt->sanitize_ctx = sanitize_ctx;
+ fwrt->ops_ctx = ops_ctx;
+ for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
+ fwrt->dump.wks[i].idx = i;
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
+index 4a8fe9641a32..58ca3849d1f3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2012-2014, 2018-2019 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
+ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2016-2017 Intel Deutschland GmbH
+ */
+@@ -152,6 +152,7 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
+ memcpy(page_address(fwrt->fw_paging_db[0].fw_paging_block),
+ image->sec[sec_idx].data,
+ image->sec[sec_idx].len);
++ fwrt->fw_paging_db[0].fw_offs = image->sec[sec_idx].offset;
+ dma_sync_single_for_device(fwrt->trans->dev,
+ fwrt->fw_paging_db[0].fw_paging_phys,
+ fwrt->fw_paging_db[0].fw_paging_size,
+@@ -197,6 +198,7 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
+
+ memcpy(page_address(block->fw_paging_block),
+ image->sec[sec_idx].data + offset, len);
++ block->fw_offs = image->sec[sec_idx].offset + offset;
+ dma_sync_single_for_device(fwrt->trans->dev,
+ block->fw_paging_phys,
+ block->fw_paging_size,
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+index 069fcbc46d2b..7d4aa398729a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+@@ -162,7 +162,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
+ goto out;
+ }
+
+- IWL_INFO(trans, "loaded PNVM version 0x%0x\n", sha1);
++ IWL_INFO(trans, "loaded PNVM version %08x\n", sha1);
+
+ ret = iwl_trans_set_pnvm(trans, pnvm_data, size);
+ out:
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/rs.c b/drivers/net/wireless/intel/iwlwifi/fw/rs.c
+new file mode 100644
+index 000000000000..a21c3befd93b
+--- /dev/null
++++ b/drivers/net/wireless/intel/iwlwifi/fw/rs.c
+@@ -0,0 +1,252 @@
++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
++/*
++ * Copyright (C) 2021 Intel Corporation
++ */
++
++#include <net/mac80211.h>
++#include "fw/api/rs.h"
++#include "iwl-drv.h"
++#include "iwl-config.h"
++
++#define IWL_DECLARE_RATE_INFO(r) \
++ [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
++
++/*
++ * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
++ * */
++static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
++ IWL_DECLARE_RATE_INFO(1),
++ IWL_DECLARE_RATE_INFO(2),
++ IWL_DECLARE_RATE_INFO(5),
++ IWL_DECLARE_RATE_INFO(11),
++ IWL_DECLARE_RATE_INFO(6),
++ IWL_DECLARE_RATE_INFO(9),
++ IWL_DECLARE_RATE_INFO(12),
++ IWL_DECLARE_RATE_INFO(18),
++ IWL_DECLARE_RATE_INFO(24),
++ IWL_DECLARE_RATE_INFO(36),
++ IWL_DECLARE_RATE_INFO(48),
++ IWL_DECLARE_RATE_INFO(54),
++};
++
++/* mbps, mcs */
++static const struct iwl_rate_mcs_info rate_mcs[IWL_RATE_COUNT] = {
++ { "1", "BPSK DSSS"},
++ { "2", "QPSK DSSS"},
++ {"5.5", "BPSK CCK"},
++ { "11", "QPSK CCK"},
++ { "6", "BPSK 1/2"},
++ { "9", "BPSK 1/2"},
++ { "12", "QPSK 1/2"},
++ { "18", "QPSK 3/4"},
++ { "24", "16QAM 1/2"},
++ { "36", "16QAM 3/4"},
++ { "48", "64QAM 2/3"},
++ { "54", "64QAM 3/4"},
++ { "60", "64QAM 5/6"},
++};
++
++static const char * const ant_name[] = {
++ [ANT_NONE] = "None",
++ [ANT_A] = "A",
++ [ANT_B] = "B",
++ [ANT_AB] = "AB",
++};
++
++static const char * const pretty_bw[] = {
++ "20Mhz",
++ "40Mhz",
++ "80Mhz",
++ "160 Mhz",
++ "320Mhz",
++};
++
++u8 iwl_fw_rate_idx_to_plcp(int idx)
++{
++ return fw_rate_idx_to_plcp[idx];
++}
++IWL_EXPORT_SYMBOL(iwl_fw_rate_idx_to_plcp);
++
++const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx)
++{
++ return &rate_mcs[idx];
++}
++IWL_EXPORT_SYMBOL(iwl_rate_mcs);
++
++const char *iwl_rs_pretty_ant(u8 ant)
++{
++ if (ant >= ARRAY_SIZE(ant_name))
++ return "UNKNOWN";
++
++ return ant_name[ant];
++}
++IWL_EXPORT_SYMBOL(iwl_rs_pretty_ant);
++
++const char *iwl_rs_pretty_bw(int bw)
++{
++ if (bw >= ARRAY_SIZE(pretty_bw))
++ return "unknown bw";
++
++ return pretty_bw[bw];
++}
++IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw);
++
++u32 iwl_new_rate_from_v1(u32 rate_v1)
++{
++ u32 rate_v2 = 0;
++ u32 dup = 0;
++
++ if (rate_v1 == 0)
++ return rate_v1;
++ /* convert rate */
++ if (rate_v1 & RATE_MCS_HT_MSK_V1) {
++ u32 nss = 0;
++
++ rate_v2 |= RATE_MCS_HT_MSK;
++ rate_v2 |=
++ rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1;
++ nss = (rate_v1 & RATE_HT_MCS_MIMO2_MSK) >>
++ RATE_HT_MCS_NSS_POS_V1;
++ rate_v2 |= nss << RATE_MCS_NSS_POS;
++ } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 ||
++ rate_v1 & RATE_MCS_HE_MSK_V1) {
++ rate_v2 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK;
++
++ rate_v2 |= rate_v1 & RATE_VHT_MCS_MIMO2_MSK;
++
++ if (rate_v1 & RATE_MCS_HE_MSK_V1) {
++ u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1;
++ u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1;
++ u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >>
++ RATE_MCS_HE_106T_POS_V1;
++ u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >>
++ RATE_MCS_HE_GI_LTF_POS;
++
++ if ((he_type_bits == RATE_MCS_HE_TYPE_SU ||
++ he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) &&
++ he_gi_ltf == RATE_MCS_HE_SU_4_LTF)
++ /* the new rate have an additional bit to
++ * represent the value 4 rather then using SGI
++ * bit for this purpose - as it was done in the old
++ * rate */
++ he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >>
++ RATE_MCS_SGI_POS_V1;
++
++ rate_v2 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS;
++ rate_v2 |= he_type << RATE_MCS_HE_TYPE_POS;
++ rate_v2 |= he_106t << RATE_MCS_HE_106T_POS;
++ rate_v2 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK;
++ rate_v2 |= RATE_MCS_HE_MSK;
++ } else {
++ rate_v2 |= RATE_MCS_VHT_MSK;
++ }
++ /* if legacy format */
++ } else {
++ u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1);
++
++ WARN_ON(legacy_rate < 0);
++ rate_v2 |= legacy_rate;
++ if (!(rate_v1 & RATE_MCS_CCK_MSK_V1))
++ rate_v2 |= RATE_MCS_LEGACY_OFDM_MSK;
++ }
++
++ /* convert flags */
++ if (rate_v1 & RATE_MCS_LDPC_MSK_V1)
++ rate_v2 |= RATE_MCS_LDPC_MSK;
++ rate_v2 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) |
++ (rate_v1 & RATE_MCS_ANT_AB_MSK) |
++ (rate_v1 & RATE_MCS_STBC_MSK) |
++ (rate_v1 & RATE_MCS_BF_MSK);
++
++ dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1;
++ if (dup) {
++ rate_v2 |= RATE_MCS_DUP_MSK;
++ rate_v2 |= dup << RATE_MCS_CHAN_WIDTH_POS;
++ }
++
++ if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) &&
++ (rate_v1 & RATE_MCS_SGI_MSK_V1))
++ rate_v2 |= RATE_MCS_SGI_MSK;
++
++ return rate_v2;
++}
++IWL_EXPORT_SYMBOL(iwl_new_rate_from_v1);
++
++u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
++{
++ int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
++ int idx;
++ bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1);
++ int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0;
++ int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
++
++ for (idx = offset; idx < last; idx++)
++ if (iwl_fw_rate_idx_to_plcp(idx) == rate)
++ return idx - offset;
++ return -1;
++}
++
++int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
++{
++ char *type;
++ u8 mcs = 0, nss = 0;
++ u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
++ u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK) >>
++ RATE_MCS_CHAN_WIDTH_POS;
++ u32 format = rate & RATE_MCS_MOD_TYPE_MSK;
++ bool sgi;
++
++ if (format == RATE_MCS_CCK_MSK ||
++ format == RATE_MCS_LEGACY_OFDM_MSK) {
++ int legacy_rate = rate & RATE_LEGACY_RATE_MSK;
++ int index = format == RATE_MCS_CCK_MSK ?
++ legacy_rate :
++ legacy_rate + IWL_FIRST_OFDM_RATE;
++
++ return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps",
++ iwl_rs_pretty_ant(ant),
++ index == IWL_RATE_INVALID ? "BAD" :
++ iwl_rate_mcs(index)->mbps);
++ }
++
++ if (format == RATE_MCS_VHT_MSK)
++ type = "VHT";
++ else if (format == RATE_MCS_HT_MSK)
++ type = "HT";
++ else if (format == RATE_MCS_HE_MSK)
++ type = "HE";
++ else
++ type = "Unknown"; /* shouldn't happen */
++
++ mcs = format == RATE_MCS_HT_MSK ?
++ RATE_HT_MCS_INDEX(rate) :
++ rate & RATE_MCS_CODE_MSK;
++ nss = ((rate & RATE_MCS_NSS_MSK)
++ >> RATE_MCS_NSS_POS) + 1;
++ sgi = format == RATE_MCS_HE_MSK ?
++ iwl_he_is_sgi(rate) :
++ rate & RATE_MCS_SGI_MSK;
++
++ return scnprintf(buf, bufsz,
++ "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s",
++ rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss,
++ (sgi) ? "SGI " : "NGI ",
++ (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
++ (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
++ (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "",
++ (rate & RATE_MCS_BF_MSK) ? "BF " : "");
++}
++IWL_EXPORT_SYMBOL(rs_pretty_print_rate);
++
++bool iwl_he_is_sgi(u32 rate_n_flags)
++{
++ u32 type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
++ u32 ltf_gi = rate_n_flags & RATE_MCS_HE_GI_LTF_MSK;
++
++ if (type == RATE_MCS_HE_TYPE_SU ||
++ type == RATE_MCS_HE_TYPE_EXT_SU)
++ return ltf_gi == RATE_MCS_HE_SU_4_LTF_08_GI;
++ return false;
++}
++IWL_EXPORT_SYMBOL(iwl_he_is_sgi);
++
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+index 35af85a5430b..69799f1ed2c4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+@@ -105,6 +105,9 @@ struct iwl_fw_runtime {
+ const struct iwl_fw_runtime_ops *ops;
+ void *ops_ctx;
+
++ const struct iwl_dump_sanitize_ops *sanitize_ops;
++ void *sanitize_ctx;
++
+ /* Paging */
+ struct iwl_fw_paging fw_paging_db[NUM_OF_FW_PAGING_BLOCKS];
+ u16 num_of_paging_blk;
+@@ -151,7 +154,7 @@ struct iwl_fw_runtime {
+ struct iwl_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
+ u8 sar_chain_a_profile;
+ u8 sar_chain_b_profile;
+- struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
++ struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3];
+ u32 geo_rev;
+ union iwl_ppag_table_cmd ppag_table;
+ u32 ppag_ver;
+@@ -161,6 +164,8 @@ struct iwl_fw_runtime {
+ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
+ const struct iwl_fw *fw,
+ const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
++ const struct iwl_dump_sanitize_ops *sanitize_ops,
++ void *sanitize_ctx,
+ struct dentry *dbgfs_dir);
+
+ static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
+index 45d0b36d79b5..d552c656ac9f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
++++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
+@@ -2,7 +2,8 @@
+ /*
+ * Copyright(c) 2021 Intel Corporation
+ */
+-
++#ifndef __iwl_fw_uefi__
++#define __iwl_fw_uefi__
+
+ #define IWL_UEFI_OEM_PNVM_NAME L"UefiCnvWlanOemSignedPnvm"
+ #define IWL_UEFI_REDUCED_POWER_NAME L"UefiCnvWlanReducedPower"
+@@ -40,3 +41,5 @@ void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+ #endif /* CONFIG_EFI */
++
++#endif /* __iwl_fw_uefi__ */
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+index 7eb534df5331..665167a223f6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+@@ -95,7 +95,6 @@ enum iwl_nvm_type {
+ #define ANT_AC (ANT_A | ANT_C)
+ #define ANT_BC (ANT_B | ANT_C)
+ #define ANT_ABC (ANT_A | ANT_B | ANT_C)
+-#define MAX_ANT_NUM 3
+
+
+ static inline u8 num_of_ant(u8 mask)
+@@ -420,6 +419,7 @@ struct iwl_cfg {
+ #define IWL_CFG_MAC_TYPE_SOF 0x43
+ #define IWL_CFG_MAC_TYPE_MA 0x44
+ #define IWL_CFG_MAC_TYPE_BZ 0x46
++#define IWL_CFG_MAC_TYPE_GL 0x47
+
+ #define IWL_CFG_RF_TYPE_TH 0x105
+ #define IWL_CFG_RF_TYPE_TH1 0x108
+@@ -511,6 +511,10 @@ extern const char iwl_ax210_killer_1675w_name[];
+ extern const char iwl_ax210_killer_1675x_name[];
+ extern const char iwl9560_killer_1550i_160_name[];
+ extern const char iwl9560_killer_1550s_160_name[];
++extern const char iwl_ax211_killer_1675s_name[];
++extern const char iwl_ax211_killer_1675i_name[];
++extern const char iwl_ax411_killer_1690s_name[];
++extern const char iwl_ax411_killer_1690i_name[];
+ extern const char iwl_ax211_name[];
+ extern const char iwl_ax221_name[];
+ extern const char iwl_ax231_name[];
+@@ -628,6 +632,8 @@ extern const struct iwl_cfg iwl_cfg_bz_a0_hr_b0;
+ extern const struct iwl_cfg iwl_cfg_bz_a0_gf_a0;
+ extern const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0;
+ extern const struct iwl_cfg iwl_cfg_bz_a0_mr_a0;
++extern const struct iwl_cfg iwl_cfg_bz_a0_fm_a0;
++extern const struct iwl_cfg iwl_cfg_gl_a0_fm_a0;
+ #endif /* CONFIG_IWLMVM */
+
+ #endif /* __IWL_CONFIG_H__ */
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
+index e1fec23ac07f..5adf485db38e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
+@@ -109,12 +109,12 @@ struct iwl_prph_scratch_pnvm_cfg {
+ * struct iwl_prph_scratch_hwm_cfg - hwm config
+ * @hwm_base_addr: hwm start address
+ * @hwm_size: hwm size in DWs
+- * @reserved: reserved
++ * @debug_token_config: debug preset
+ */
+ struct iwl_prph_scratch_hwm_cfg {
+ __le64 hwm_base_addr;
+ __le32 hwm_size;
+- __le32 reserved;
++ __le32 debug_token_config;
+ } __packed; /* PERIPH_SCRATCH_HWM_CFG_S */
+
+ /*
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+index cf796403c45c..ff79a2ecb242 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+@@ -34,6 +34,7 @@
+ #define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */
+ #define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
+ #define CSR_GP_CNTRL (CSR_BASE+0x024)
++#define CSR_FUNC_SCRATCH (CSR_BASE+0x02c) /* Scratch register - used for FW dbg */
+
+ /* 2nd byte of CSR_INT_COALESCING, not accessible via iwl_write32()! */
+ #define CSR_INT_PERIODIC_REG (CSR_BASE+0x005)
+@@ -135,6 +136,12 @@
+ #define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240)
+ #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250)
+
++/*
++ * Scratch register initial configuration - this is set on init, and read
++ * during a error FW error.
++ */
++#define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101)
++
+ /* Bits for CSR_HW_IF_CONFIG_REG */
+ #define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003)
+ #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C)
+@@ -598,6 +605,7 @@ enum msix_hw_int_causes {
+ MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1),
+ MSIX_HW_INT_CAUSES_REG_IML = BIT(1),
+ MSIX_HW_INT_CAUSES_REG_RESET_DONE = BIT(2),
++ MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ = BIT(5),
+ MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6),
+ MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7),
+ MSIX_HW_INT_CAUSES_REG_PERIODIC = BIT(8),
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+index 125479b5c0d6..7ab98b419cc1 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+@@ -16,6 +16,7 @@
+ * @IWL_DBG_TLV_TYPE_HCMD: host command TLV
+ * @IWL_DBG_TLV_TYPE_REGION: region TLV
+ * @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV
++ * @IWL_DBG_TLV_TYPE_CONF_SET: conf set TLV
+ * @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs
+ */
+ enum iwl_dbg_tlv_type {
+@@ -25,6 +26,7 @@ enum iwl_dbg_tlv_type {
+ IWL_DBG_TLV_TYPE_HCMD,
+ IWL_DBG_TLV_TYPE_REGION,
+ IWL_DBG_TLV_TYPE_TRIGGER,
++ IWL_DBG_TLV_TYPE_CONF_SET,
+ IWL_DBG_TLV_TYPE_NUM,
+ };
+
+@@ -59,6 +61,7 @@ dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
+ [IWL_DBG_TLV_TYPE_HCMD] = {.min_ver = 1, .max_ver = 1,},
+ [IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 2,},
+ [IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,},
++ [IWL_DBG_TLV_TYPE_CONF_SET] = {.min_ver = 1, .max_ver = 1,},
+ };
+
+ static int iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv,
+@@ -260,6 +263,30 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans,
+ return ret;
+ }
+
++static int iwl_dbg_tlv_config_set(struct iwl_trans *trans,
++ const struct iwl_ucode_tlv *tlv)
++{
++ struct iwl_fw_ini_conf_set_tlv *conf_set = (void *)tlv->data;
++ u32 tp = le32_to_cpu(conf_set->time_point);
++ u32 type = le32_to_cpu(conf_set->set_type);
++
++ if (tp <= IWL_FW_INI_TIME_POINT_INVALID ||
++ tp >= IWL_FW_INI_TIME_POINT_NUM) {
++ IWL_DEBUG_FW(trans,
++ "WRT: Invalid time point %u for config set TLV\n", tp);
++ return -EINVAL;
++ }
++
++ if (type <= IWL_FW_INI_CONFIG_SET_TYPE_INVALID ||
++ type >= IWL_FW_INI_CONFIG_SET_TYPE_MAX_NUM) {
++ IWL_DEBUG_FW(trans,
++ "WRT: Invalid config set type %u for config set TLV\n", type);
++ return -EINVAL;
++ }
++
++ return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].config_list);
++}
++
+ static int (*dbg_tlv_alloc[])(struct iwl_trans *trans,
+ const struct iwl_ucode_tlv *tlv) = {
+ [IWL_DBG_TLV_TYPE_DEBUG_INFO] = iwl_dbg_tlv_alloc_debug_info,
+@@ -267,6 +294,7 @@ static int (*dbg_tlv_alloc[])(struct iwl_trans *trans,
+ [IWL_DBG_TLV_TYPE_HCMD] = iwl_dbg_tlv_alloc_hcmd,
+ [IWL_DBG_TLV_TYPE_REGION] = iwl_dbg_tlv_alloc_region,
+ [IWL_DBG_TLV_TYPE_TRIGGER] = iwl_dbg_tlv_alloc_trigger,
++ [IWL_DBG_TLV_TYPE_CONF_SET] = iwl_dbg_tlv_config_set,
+ };
+
+ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, const struct iwl_ucode_tlv *tlv,
+@@ -399,6 +427,13 @@ void iwl_dbg_tlv_free(struct iwl_trans *trans)
+ list_del(&tlv_node->list);
+ kfree(tlv_node);
+ }
++
++ list_for_each_entry_safe(tlv_node, tlv_node_tmp,
++ &tp->config_list, list) {
++ list_del(&tlv_node->list);
++ kfree(tlv_node);
++ }
++
+ }
+
+ for (i = 0; i < ARRAY_SIZE(trans->dbg.fw_mon_ini); i++)
+@@ -466,6 +501,7 @@ void iwl_dbg_tlv_init(struct iwl_trans *trans)
+ INIT_LIST_HEAD(&tp->trig_list);
+ INIT_LIST_HEAD(&tp->hcmd_list);
+ INIT_LIST_HEAD(&tp->active_trig_list);
++ INIT_LIST_HEAD(&tp->config_list);
+ }
+ }
+
+@@ -649,6 +685,10 @@ static void iwl_dbg_tlv_apply_buffers(struct iwl_fw_runtime *fwrt)
+ {
+ int ret, i;
+
++ if (fw_has_capa(&fwrt->fw->ucode_capa,
++ IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT))
++ return;
++
+ for (i = 0; i < IWL_FW_INI_ALLOCATION_NUM; i++) {
+ ret = iwl_dbg_tlv_apply_buffer(fwrt, i);
+ if (ret)
+@@ -658,6 +698,87 @@ static void iwl_dbg_tlv_apply_buffers(struct iwl_fw_runtime *fwrt)
+ }
+ }
+
++static int iwl_dbg_tlv_update_dram(struct iwl_fw_runtime *fwrt,
++ enum iwl_fw_ini_allocation_id alloc_id,
++ struct iwl_dram_info *dram_info)
++{
++ struct iwl_fw_mon *fw_mon;
++ u32 remain_frags, num_frags;
++ int j, fw_mon_idx = 0;
++ struct iwl_buf_alloc_cmd *data;
++
++ if (le32_to_cpu(fwrt->trans->dbg.fw_mon_cfg[alloc_id].buf_location) !=
++ IWL_FW_INI_LOCATION_DRAM_PATH) {
++ IWL_DEBUG_FW(fwrt, "DRAM_PATH is not supported alloc_id %u\n", alloc_id);
++ return -1;
++ }
++
++ fw_mon = &fwrt->trans->dbg.fw_mon_ini[alloc_id];
++
++ /* the first fragment of DBGC1 is given to the FW via register
++ * or context info
++ */
++ if (alloc_id == IWL_FW_INI_ALLOCATION_ID_DBGC1)
++ fw_mon_idx++;
++
++ remain_frags = fw_mon->num_frags - fw_mon_idx;
++ if (!remain_frags)
++ return -1;
++
++ num_frags = min_t(u32, remain_frags, BUF_ALLOC_MAX_NUM_FRAGS);
++ data = &dram_info->dram_frags[alloc_id - 1];
++ data->alloc_id = cpu_to_le32(alloc_id);
++ data->num_frags = cpu_to_le32(num_frags);
++ data->buf_location = cpu_to_le32(IWL_FW_INI_LOCATION_DRAM_PATH);
++
++ IWL_DEBUG_FW(fwrt, "WRT: DRAM buffer details alloc_id=%u, num_frags=%u\n",
++ cpu_to_le32(alloc_id), cpu_to_le32(num_frags));
++
++ for (j = 0; j < num_frags; j++) {
++ struct iwl_buf_alloc_frag *frag = &data->frags[j];
++ struct iwl_dram_data *fw_mon_frag = &fw_mon->frags[fw_mon_idx++];
++
++ frag->addr = cpu_to_le64(fw_mon_frag->physical);
++ frag->size = cpu_to_le32(fw_mon_frag->size);
++ IWL_DEBUG_FW(fwrt, "WRT: DRAM fragment details\n");
++ IWL_DEBUG_FW(fwrt, "frag=%u, addr=0x%016llx, size=0x%x)\n",
++ j, cpu_to_le64(fw_mon_frag->physical),
++ cpu_to_le32(fw_mon_frag->size));
++ }
++ return 0;
++}
++
++static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt)
++{
++ int ret, i, dram_alloc = 0;
++ struct iwl_dram_info dram_info;
++ struct iwl_dram_data *frags =
++ &fwrt->trans->dbg.fw_mon_ini[IWL_FW_INI_ALLOCATION_ID_DBGC1].frags[0];
++
++ if (!fw_has_capa(&fwrt->fw->ucode_capa,
++ IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT))
++ return;
++
++ dram_info.first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD);
++ dram_info.second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD);
++
++ for (i = IWL_FW_INI_ALLOCATION_ID_DBGC1;
++ i <= IWL_FW_INI_ALLOCATION_ID_DBGC3; i++) {
++ ret = iwl_dbg_tlv_update_dram(fwrt, i, &dram_info);
++ if (!ret)
++ dram_alloc++;
++ else
++ IWL_WARN(fwrt,
++ "WRT: Failed to set DRAM buffer for alloc id %d, ret=%d\n",
++ i, ret);
++ }
++ if (dram_alloc) {
++ memcpy(frags->block, &dram_info, sizeof(dram_info));
++ IWL_DEBUG_FW(fwrt, "block data after %016x\n",
++ *((int *)fwrt->trans->dbg.fw_mon_ini[1].frags[0].block));
++ }
++}
++
+ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt,
+ struct list_head *hcmd_list)
+ {
+@@ -677,6 +798,97 @@ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt,
+ }
+ }
+
++static void iwl_dbg_tlv_apply_config(struct iwl_fw_runtime *fwrt,
++ struct list_head *config_list)
++{
++ struct iwl_dbg_tlv_node *node;
++
++ list_for_each_entry(node, config_list, list) {
++ struct iwl_fw_ini_conf_set_tlv *config_list = (void *)node->tlv.data;
++ u32 count, address, value;
++ u32 len = (le32_to_cpu(node->tlv.length) - sizeof(*config_list)) / 8;
++ u32 type = le32_to_cpu(config_list->set_type);
++ u32 offset = le32_to_cpu(config_list->addr_offset);
++
++ switch (type) {
++ case IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: {
++ if (!iwl_trans_grab_nic_access(fwrt->trans)) {
++ IWL_DEBUG_FW(fwrt, "WRT: failed to get nic access\n");
++ IWL_DEBUG_FW(fwrt, "WRT: skipping MAC PERIPHERY config\n");
++ continue;
++ }
++ IWL_DEBUG_FW(fwrt, "WRT: MAC PERIPHERY config len: len %u\n", len);
++ for (count = 0; count < len; count++) {
++ address = le32_to_cpu(config_list->addr_val[count].address);
++ value = le32_to_cpu(config_list->addr_val[count].value);
++ iwl_trans_write_prph(fwrt->trans, address + offset, value);
++ }
++ iwl_trans_release_nic_access(fwrt->trans);
++ break;
++ }
++ case IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY: {
++ for (count = 0; count < len; count++) {
++ address = le32_to_cpu(config_list->addr_val[count].address);
++ value = le32_to_cpu(config_list->addr_val[count].value);
++ iwl_trans_write_mem32(fwrt->trans, address + offset, value);
++ IWL_DEBUG_FW(fwrt, "WRT: DEV_MEM: count %u, add: %u val: %u\n",
++ count, address, value);
++ }
++ break;
++ }
++ case IWL_FW_INI_CONFIG_SET_TYPE_CSR: {
++ for (count = 0; count < len; count++) {
++ address = le32_to_cpu(config_list->addr_val[count].address);
++ value = le32_to_cpu(config_list->addr_val[count].value);
++ iwl_write32(fwrt->trans, address + offset, value);
++ IWL_DEBUG_FW(fwrt, "WRT: CSR: count %u, add: %u val: %u\n",
++ count, address, value);
++ }
++ break;
++ }
++ case IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: {
++ struct iwl_dbgc1_info dram_info = {};
++ struct iwl_dram_data *frags = &fwrt->trans->dbg.fw_mon_ini[1].frags[0];
++ __le64 dram_base_addr = cpu_to_le64(frags->physical);
++ __le32 dram_size = cpu_to_le32(frags->size);
++ u64 dram_addr = le64_to_cpu(dram_base_addr);
++ u32 ret;
++
++ IWL_DEBUG_FW(fwrt, "WRT: dram_base_addr 0x%016llx, dram_size 0x%x\n",
++ dram_base_addr, dram_size);
++ IWL_DEBUG_FW(fwrt, "WRT: config_list->addr_offset: %u\n",
++ le32_to_cpu(config_list->addr_offset));
++ for (count = 0; count < len; count++) {
++ address = le32_to_cpu(config_list->addr_val[count].address);
++ dram_info.dbgc1_add_lsb =
++ cpu_to_le32((dram_addr & 0x00000000FFFFFFFFULL) + 0x400);
++ dram_info.dbgc1_add_msb =
++ cpu_to_le32((dram_addr & 0xFFFFFFFF00000000ULL) >> 32);
++ dram_info.dbgc1_size = cpu_to_le32(le32_to_cpu(dram_size) - 0x400);
++ ret = iwl_trans_write_mem(fwrt->trans,
++ address + offset, &dram_info, 4);
++ if (ret) {
++ IWL_ERR(fwrt, "Failed to write dram_info to HW_SMEM\n");
++ break;
++ }
++ }
++ break;
++ }
++ case IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: {
++ u32 debug_token_config =
++ le32_to_cpu(config_list->addr_val[0].value);
++
++ IWL_DEBUG_FW(fwrt, "WRT: Setting HWM debug token config: %u\n",
++ debug_token_config);
++ fwrt->trans->dbg.ucode_preset = debug_token_config;
++ break;
++ }
++ default:
++ break;
++ }
++ }
++}
++
+ static void iwl_dbg_tlv_periodic_trig_handler(struct timer_list *t)
+ {
+ struct iwl_dbg_tlv_timer_node *timer_node =
+@@ -996,8 +1208,10 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
+ &fwrt->trans->dbg.fw_mon_cfg[i];
+ u32 dest = le32_to_cpu(fw_mon_cfg->buf_location);
+
+- if (dest == IWL_FW_INI_LOCATION_INVALID)
++ if (dest == IWL_FW_INI_LOCATION_INVALID) {
++ failed_alloc |= BIT(i);
+ continue;
++ }
+
+ if (*ini_dest == IWL_FW_INI_LOCATION_INVALID)
+ *ini_dest = dest;
+@@ -1024,8 +1238,10 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
+ &fwrt->trans->dbg.active_regions[i];
+ u32 reg_type;
+
+- if (!*active_reg)
++ if (!*active_reg) {
++ fwrt->trans->dbg.unsupported_region_msk |= BIT(i);
+ continue;
++ }
+
+ reg = (void *)(*active_reg)->data;
+ reg_type = le32_to_cpu(reg->type);
+@@ -1051,7 +1267,7 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
+ union iwl_dbg_tlv_tp_data *tp_data,
+ bool sync)
+ {
+- struct list_head *hcmd_list, *trig_list;
++ struct list_head *hcmd_list, *trig_list, *conf_list;
+
+ if (!iwl_trans_dbg_ini_valid(fwrt->trans) ||
+ tp_id == IWL_FW_INI_TIME_POINT_INVALID ||
+@@ -1060,15 +1276,19 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
+
+ hcmd_list = &fwrt->trans->dbg.time_point[tp_id].hcmd_list;
+ trig_list = &fwrt->trans->dbg.time_point[tp_id].active_trig_list;
++ conf_list = &fwrt->trans->dbg.time_point[tp_id].config_list;
+
+ switch (tp_id) {
+ case IWL_FW_INI_TIME_POINT_EARLY:
+ iwl_dbg_tlv_init_cfg(fwrt);
++ iwl_dbg_tlv_apply_config(fwrt, conf_list);
++ iwl_dbg_tlv_update_drams(fwrt);
+ iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
+ break;
+ case IWL_FW_INI_TIME_POINT_AFTER_ALIVE:
+ iwl_dbg_tlv_apply_buffers(fwrt);
+ iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
++ iwl_dbg_tlv_apply_config(fwrt, conf_list);
+ iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
+ break;
+ case IWL_FW_INI_TIME_POINT_PERIODIC:
+@@ -1079,11 +1299,13 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
+ case IWL_FW_INI_TIME_POINT_MISSED_BEACONS:
+ case IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFICATION:
+ iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
++ iwl_dbg_tlv_apply_config(fwrt, conf_list);
+ iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data,
+ iwl_dbg_tlv_check_fw_pkt);
+ break;
+ default:
+ iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
++ iwl_dbg_tlv_apply_config(fwrt, conf_list);
+ iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
+ break;
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
+index c12b1fd3f479..79287708bd6e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
+@@ -33,11 +33,13 @@ union iwl_dbg_tlv_tp_data {
+ * @trig_list: list of triggers
+ * @active_trig_list: list of active triggers
+ * @hcmd_list: list of host commands
++ * @config_list: list of configuration
+ */
+ struct iwl_dbg_tlv_time_point_data {
+ struct list_head trig_list;
+ struct list_head active_trig_list;
+ struct list_head hcmd_list;
++ struct list_head config_list;
+ };
+
+ struct iwl_trans;
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c
+index f6ca2fc37c40..ae4c2a3d63d5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2005-2011 Intel Corporation
++ * Copyright (C) 2005-2011, 2021 Intel Corporation
+ */
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+@@ -31,21 +31,31 @@ IWL_EXPORT_SYMBOL(__iwl_info);
+ __iwl_fn(crit)
+ IWL_EXPORT_SYMBOL(__iwl_crit);
+
+-void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
+- const char *fmt, ...)
++void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
+ {
+ struct va_format vaf = {
+ .fmt = fmt,
+ };
+- va_list args;
++ va_list args, args2;
+
+ va_start(args, fmt);
+- vaf.va = &args;
+- if (!trace_only) {
+- if (rfkill_prefix)
++ switch (mode) {
++ case IWL_ERR_MODE_RATELIMIT:
++ if (net_ratelimit())
++ break;
++ fallthrough;
++ case IWL_ERR_MODE_REGULAR:
++ case IWL_ERR_MODE_RFKILL:
++ va_copy(args2, args);
++ vaf.va = &args2;
++ if (mode == IWL_ERR_MODE_RFKILL)
+ dev_err(dev, "(RFKILL) %pV", &vaf);
+ else
+ dev_err(dev, "%pV", &vaf);
++ va_end(args2);
++ break;
++ default:
++ break;
+ }
+ trace_iwlwifi_err(&vaf);
+ va_end(args);
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
+index 528eba441926..1b9f16a31b54 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
+@@ -2,14 +2,9 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+- * Copyright(c) 2018 - 2020 Intel Corporation
++ * Copyright(c) 2018 - 2021 Intel Corporation
+ *
+ * Portions of this file are derived from the ipw3945 project.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #ifndef __iwl_debug_h__
+@@ -27,9 +22,16 @@ static inline bool iwl_have_debug_level(u32 level)
+ #endif
+ }
+
++enum iwl_err_mode {
++ IWL_ERR_MODE_REGULAR,
++ IWL_ERR_MODE_RFKILL,
++ IWL_ERR_MODE_TRACE_ONLY,
++ IWL_ERR_MODE_RATELIMIT,
++};
++
+ struct device;
+-void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
+- const char *fmt, ...) __printf(4, 5);
++void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
++ __printf(3, 4);
+ void __iwl_warn(struct device *dev, const char *fmt, ...) __printf(2, 3);
+ void __iwl_info(struct device *dev, const char *fmt, ...) __printf(2, 3);
+ void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3);
+@@ -38,13 +40,17 @@ void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3);
+ #define CHECK_FOR_NEWLINE(f) BUILD_BUG_ON(f[sizeof(f) - 2] != '\n')
+
+ /* No matter what is m (priv, bus, trans), this will work */
+-#define IWL_ERR_DEV(d, f, a...) \
++#define __IWL_ERR_DEV(d, mode, f, a...) \
+ do { \
+ CHECK_FOR_NEWLINE(f); \
+- __iwl_err((d), false, false, f, ## a); \
++ __iwl_err((d), mode, f, ## a); \
+ } while (0)
++#define IWL_ERR_DEV(d, f, a...) \
++ __IWL_ERR_DEV(d, IWL_ERR_MODE_REGULAR, f, ## a)
+ #define IWL_ERR(m, f, a...) \
+ IWL_ERR_DEV((m)->dev, f, ## a)
++#define IWL_ERR_LIMIT(m, f, a...) \
++ __IWL_ERR_DEV((m)->dev, IWL_ERR_MODE_RATELIMIT, f, ## a)
+ #define IWL_WARN(m, f, a...) \
+ do { \
+ CHECK_FOR_NEWLINE(f); \
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+index 1bc6ecc32140..347fd95c4e3a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+@@ -4,11 +4,6 @@
+ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2018 - 2019 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #if !defined(__IWLWIFI_DEVICE_TRACE_DATA) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h
+index a57019241a78..0af9d8362c5b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2016-2017 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #if !defined(__IWLWIFI_DEVICE_TRACE_IO) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+index 72ca882daed5..46ed723f138a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+@@ -5,11 +5,6 @@
+ * Copyright(c) 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #if !defined(__IWLWIFI_DEVICE_TRACE_IWLWIFI) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
+index d0467da5af03..7dd70011fd1e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #if !defined(__IWLWIFI_DEVICE_TRACE_MSG) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h
+index 2228faefffbc..3ec0205ac9f9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+ *
+ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #if !defined(__IWLWIFI_DEVICE_TRACE_UCODE) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
+index b5037db0c381..999b7c652289 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
+@@ -3,11 +3,6 @@
+ *
+ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2018 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+index fc8bc212ee84..1455b578358b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+@@ -4,11 +4,6 @@
+ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(C) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #ifndef __IWLWIFI_DEVICE_TRACE
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+index 77124b8b235e..36196e07b1a0 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+@@ -31,7 +31,6 @@
+
+ #define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux"
+ MODULE_DESCRIPTION(DRV_DESCRIPTION);
+-MODULE_AUTHOR(DRV_AUTHOR);
+ MODULE_LICENSE("GPL");
+
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+@@ -550,6 +549,43 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
+ return 0;
+ }
+
++static void iwl_drv_set_dump_exclude(struct iwl_drv *drv,
++ enum iwl_ucode_tlv_type tlv_type,
++ const void *tlv_data, u32 tlv_len)
++{
++ const struct iwl_fw_dump_exclude *fw = tlv_data;
++ struct iwl_dump_exclude *excl;
++
++ if (tlv_len < sizeof(*fw))
++ return;
++
++ if (tlv_type == IWL_UCODE_TLV_SEC_TABLE_ADDR) {
++ excl = &drv->fw.dump_excl[0];
++
++ /* second time we find this, it's for WoWLAN */
++ if (excl->addr)
++ excl = &drv->fw.dump_excl_wowlan[0];
++ } else if (fw_has_capa(&drv->fw.ucode_capa,
++ IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG)) {
++ /* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is regular image */
++ excl = &drv->fw.dump_excl[0];
++ } else {
++ /* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is WoWLAN image */
++ excl = &drv->fw.dump_excl_wowlan[0];
++ }
++
++ if (excl->addr)
++ excl++;
++
++ if (excl->addr) {
++ IWL_DEBUG_FW_INFO(drv, "found too many excludes in fw file\n");
++ return;
++ }
++
++ excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL;
++ excl->size = le32_to_cpu(fw->size);
++}
++
+ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
+ const struct firmware *ucode_raw,
+ struct iwl_firmware_pieces *pieces,
+@@ -1133,6 +1169,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
+ case IWL_UCODE_TLV_TYPE_HCMD:
+ case IWL_UCODE_TLV_TYPE_REGIONS:
+ case IWL_UCODE_TLV_TYPE_TRIGGERS:
++ case IWL_UCODE_TLV_TYPE_CONF_SET:
+ if (iwlwifi_mod_params.enable_ini)
+ iwl_dbg_tlv_alloc(drv->trans, tlv, false);
+ break;
+@@ -1166,6 +1203,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
+ return -ENOMEM;
+ drv->fw.phy_integration_ver_len = tlv_len;
+ break;
++ case IWL_UCODE_TLV_SEC_TABLE_ADDR:
++ case IWL_UCODE_TLV_D3_KEK_KCK_ADDR:
++ iwl_drv_set_dump_exclude(drv, tlv_type,
++ tlv_data, tlv_len);
++ break;
+ default:
+ IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
+ break;
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h
+index b6442df0c643..2e2d60a58692 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2005-2014, 2020 Intel Corporation
++ * Copyright (C) 2005-2014, 2020-2021 Intel Corporation
+ * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
+ */
+ #ifndef __iwl_drv_h__
+@@ -9,7 +9,6 @@
+
+ /* for all modules */
+ #define DRV_NAME "iwlwifi"
+-#define DRV_AUTHOR "Intel Corporation <linuxwifi@intel.com>"
+
+ /* radio config bits (actual values from NVM definition) */
+ #define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
+index dbab2f10d750..b9e86bf972e5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2005-2014, 2018-2019 Intel Corporation
++ * Copyright (C) 2005-2014, 2018-2019, 2021 Intel Corporation
+ */
+ #include <linux/types.h>
+ #include <linux/slab.h>
+@@ -139,7 +139,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
+ {
+ int ret;
+
+- ret = iwl_finish_nic_init(trans, trans->trans_cfg);
++ ret = iwl_finish_nic_init(trans);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
+index 2517c4ae07ab..46917b4216b3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
+@@ -398,9 +398,50 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
+ return 0;
+ }
+
+-int iwl_finish_nic_init(struct iwl_trans *trans,
+- const struct iwl_cfg_trans_params *cfg_trans)
++#define IWL_HOST_MON_BLOCK_PEMON 0x00
++#define IWL_HOST_MON_BLOCK_HIPM 0x22
++
++#define IWL_HOST_MON_BLOCK_PEMON_VEC0 0x00
++#define IWL_HOST_MON_BLOCK_PEMON_VEC1 0x01
++#define IWL_HOST_MON_BLOCK_PEMON_WFPM 0x06
++
++static void iwl_dump_host_monitor_block(struct iwl_trans *trans,
++ u32 block, u32 vec, u32 iter)
+ {
++ int i;
++
++ IWL_ERR(trans, "Host monitor block 0x%x vector 0x%x\n", block, vec);
++ iwl_write32(trans, CSR_MONITOR_CFG_REG, (block << 8) | vec);
++ for (i = 0; i < iter; i++)
++ IWL_ERR(trans, " value [iter %d]: 0x%08x\n",
++ i, iwl_read32(trans, CSR_MONITOR_STATUS_REG));
++}
++
++static void iwl_dump_host_monitor(struct iwl_trans *trans)
++{
++ switch (trans->trans_cfg->device_family) {
++ case IWL_DEVICE_FAMILY_22000:
++ case IWL_DEVICE_FAMILY_AX210:
++ IWL_ERR(trans, "CSR_RESET = 0x%x\n",
++ iwl_read32(trans, CSR_RESET));
++ iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON,
++ IWL_HOST_MON_BLOCK_PEMON_VEC0, 15);
++ iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON,
++ IWL_HOST_MON_BLOCK_PEMON_VEC1, 15);
++ iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON,
++ IWL_HOST_MON_BLOCK_PEMON_WFPM, 15);
++ iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_HIPM,
++ IWL_HOST_MON_BLOCK_PEMON_VEC0, 1);
++ break;
++ default:
++ /* not supported yet */
++ return;
++ }
++}
++
++int iwl_finish_nic_init(struct iwl_trans *trans)
++{
++ const struct iwl_cfg_trans_params *cfg_trans = trans->trans_cfg;
+ u32 poll_ready;
+ int err;
+
+@@ -433,9 +474,12 @@ int iwl_finish_nic_init(struct iwl_trans *trans,
+ * and accesses to uCode SRAM.
+ */
+ err = iwl_poll_bit(trans, CSR_GP_CNTRL, poll_ready, poll_ready, 25000);
+- if (err < 0)
++ if (err < 0) {
+ IWL_DEBUG_INFO(trans, "Failed to wake NIC\n");
+
++ iwl_dump_host_monitor(trans);
++ }
++
+ if (cfg_trans->bisr_workaround) {
+ /* ensure BISR shift has finished */
+ udelay(200);
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h
+index 3c21c0e081f8..37b3bd62897e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2018-2020 Intel Corporation
++ * Copyright (C) 2018-2021 Intel Corporation
+ */
+ #ifndef __iwl_io_h__
+ #define __iwl_io_h__
+@@ -52,8 +52,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
+ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
+ void iwl_force_nmi(struct iwl_trans *trans);
+
+-int iwl_finish_nic_init(struct iwl_trans *trans,
+- const struct iwl_cfg_trans_params *cfg_trans);
++int iwl_finish_nic_init(struct iwl_trans *trans);
+
+ /* Error handling */
+ int iwl_dump_fh(struct iwl_trans *trans, char **buf);
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+index 475f951d4b1e..f470f9aea50f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+@@ -534,6 +534,17 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
+ cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
+ }
+
++static const u8 iwl_vendor_caps[] = {
++ 0xdd, /* vendor element */
++ 0x06, /* length */
++ 0x00, 0x17, 0x35, /* Intel OUI */
++ 0x08, /* type (Intel Capabilities) */
++ /* followed by 16 bits of capabilities */
++#define IWL_VENDOR_CAP_IMPROVED_BF_FDBK_HE BIT(0)
++ IWL_VENDOR_CAP_IMPROVED_BF_FDBK_HE,
++ 0x00
++};
++
+ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
+ {
+ .types_mask = BIT(NL80211_IFTYPE_STATION),
+@@ -781,6 +792,12 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
+ if (fw_has_capa(&fw->ucode_capa, IWL_UCODE_TLV_CAPA_BROADCAST_TWT))
+ iftype_data->he_cap.he_cap_elem.mac_cap_info[2] |=
+ IEEE80211_HE_MAC_CAP2_BCAST_TWT;
++
++ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 &&
++ !is_ap) {
++ iftype_data->vendor_elems.data = iwl_vendor_caps;
++ iftype_data->vendor_elems.len = ARRAY_SIZE(iwl_vendor_caps);
++ }
+ }
+
+ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+index d0a7d58336a9..a84ab02cf9d7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+@@ -347,6 +347,12 @@
+ #define RADIO_REG_SYS_MANUAL_DFT_0 0xAD4078
+ #define RFIC_REG_RD 0xAD0470
+ #define WFPM_CTRL_REG 0xA03030
++#define WFPM_CTRL_REG_GEN2 0xd03030
++#define WFPM_OTP_CFG1_ADDR 0x00a03098
++#define WFPM_OTP_CFG1_ADDR_GEN2 0x00d03098
++#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4)
++#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5)
++
+ #define WFPM_GP2 0xA030B4
+
+ /* DBGI SRAM Register details */
+@@ -399,10 +405,40 @@ enum {
+ LMPM_PAGE_PASS_NOTIF_POS = BIT(20),
+ };
+
++/*
++ * CRF ID register
++ *
++ * type: bits 0-11
++ * reserved: bits 12-18
++ * slave_exist: bit 19
++ * dash: bits 20-23
++ * step: bits 24-26
++ * flavor: bits 27-31
++ */
++#define REG_CRF_ID_TYPE(val) (((val) & 0x00000FFF) >> 0)
++#define REG_CRF_ID_SLAVE(val) (((val) & 0x00080000) >> 19)
++#define REG_CRF_ID_DASH(val) (((val) & 0x00F00000) >> 20)
++#define REG_CRF_ID_STEP(val) (((val) & 0x07000000) >> 24)
++#define REG_CRF_ID_FLAVOR(val) (((val) & 0xF8000000) >> 27)
++
+ #define UREG_CHICK (0xA05C00)
+ #define UREG_CHICK_MSI_ENABLE BIT(24)
+ #define UREG_CHICK_MSIX_ENABLE BIT(25)
+
++#define SD_REG_VER 0xa29600
++#define SD_REG_VER_GEN2 0x00a2b800
++
++#define REG_CRF_ID_TYPE_JF_1 0x201
++#define REG_CRF_ID_TYPE_JF_2 0x202
++#define REG_CRF_ID_TYPE_HR_CDB 0x503
++#define REG_CRF_ID_TYPE_HR_NONE_CDB 0x504
++#define REG_CRF_ID_TYPE_HR_NONE_CDB_1X1 0x501
++#define REG_CRF_ID_TYPE_HR_NONE_CDB_CCP 0x532
++#define REG_CRF_ID_TYPE_GF 0x410
++#define REG_CRF_ID_TYPE_GF_TC 0xF08
++#define REG_CRF_ID_TYPE_MR 0x810
++#define REG_CRF_ID_TYPE_FM 0x910
++
+ #define HPM_DEBUG 0xA03440
+ #define PERSISTENCE_BIT BIT(12)
+ #define PREG_WFPM_ACCESS BIT(12)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+index 8f0ff540f439..4ebb1871bd1f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+@@ -362,6 +362,20 @@ struct iwl_hcmd_arr {
+ #define HCMD_ARR(x) \
+ { .arr = x, .size = ARRAY_SIZE(x) }
+
++/**
++ * struct iwl_dump_sanitize_ops - dump sanitization operations
++ * @frob_txf: Scrub the TX FIFO data
++ * @frob_hcmd: Scrub a host command, the %hcmd pointer is to the header
++ * but that might be short or long (&struct iwl_cmd_header or
++ * &struct iwl_cmd_header_wide)
++ * @frob_mem: Scrub memory data
++ */
++struct iwl_dump_sanitize_ops {
++ void (*frob_txf)(void *ctx, void *buf, size_t buflen);
++ void (*frob_hcmd)(void *ctx, void *hcmd, size_t buflen);
++ void (*frob_mem)(void *ctx, u32 mem_addr, void *mem, size_t buflen);
++};
++
+ /**
+ * struct iwl_trans_config - transport configuration
+ *
+@@ -586,7 +600,9 @@ struct iwl_trans_ops {
+ u32 value);
+
+ struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
+- u32 dump_mask);
++ u32 dump_mask,
++ const struct iwl_dump_sanitize_ops *sanitize_ops,
++ void *sanitize_ctx);
+ void (*debugfs_cleanup)(struct iwl_trans *trans);
+ void (*sync_nmi)(struct iwl_trans *trans);
+ int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len);
+@@ -723,8 +739,8 @@ struct iwl_self_init_dram {
+ * @debug_info_tlv_list: list of debug info TLVs
+ * @time_point: array of debug time points
+ * @periodic_trig_list: periodic triggers list
+- * @domains_bitmap: bitmap of active domains other than
+- * &IWL_FW_INI_DOMAIN_ALWAYS_ON
++ * @domains_bitmap: bitmap of active domains other than &IWL_FW_INI_DOMAIN_ALWAYS_ON
++ * @ucode_preset: preset based on ucode
+ */
+ struct iwl_trans_debug {
+ u8 n_dest_reg;
+@@ -758,6 +774,7 @@ struct iwl_trans_debug {
+ struct list_head periodic_trig_list;
+
+ u32 domains_bitmap;
++ u32 ucode_preset;
+ };
+
+ struct iwl_dma_ptr {
+@@ -1086,11 +1103,14 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
+ }
+
+ static inline struct iwl_trans_dump_data *
+-iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask)
++iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask,
++ const struct iwl_dump_sanitize_ops *sanitize_ops,
++ void *sanitize_ctx)
+ {
+ if (!trans->ops->dump_data)
+ return NULL;
+- return trans->ops->dump_data(trans, dump_mask);
++ return trans->ops->dump_data(trans, dump_mask,
++ sanitize_ops, sanitize_ctx);
+ }
+
+ static inline struct iwl_device_tx_cmd *
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+index d3013a51a509..a19f646a324f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -1379,12 +1379,49 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+
+ /* converted data from the different status responses */
+ struct iwl_wowlan_status_data {
+- u16 pattern_number;
+- u16 qos_seq_ctr[8];
++ u64 replay_ctr;
++ u32 num_of_gtk_rekeys;
++ u32 received_beacons;
+ u32 wakeup_reasons;
+ u32 wake_packet_length;
+ u32 wake_packet_bufsize;
+- const u8 *wake_packet;
++ u16 pattern_number;
++ u16 non_qos_seq_ctr;
++ u16 qos_seq_ctr[8];
++ u8 tid_tear_down;
++
++ struct {
++ /*
++ * We store both the TKIP and AES representations
++ * coming from the firmware because we decode the
++ * data from there before we iterate the keys and
++ * know which one we need.
++ */
++ struct {
++ struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
++ } tkip, aes;
++ /* including RX MIC key for TKIP */
++ u8 key[WOWLAN_KEY_MAX_SIZE];
++ u8 len;
++ u8 flags;
++ } gtk;
++
++ struct {
++ /* Same as above */
++ struct {
++ struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
++ u64 tx_pn;
++ } tkip, aes;
++ } ptk;
++
++ struct {
++ u64 ipn;
++ u8 key[WOWLAN_KEY_MAX_SIZE];
++ u8 len;
++ u8 flags;
++ } igtk;
++
++ u8 wake_packet[];
+ };
+
+ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
+@@ -1540,77 +1577,90 @@ static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
+ seq->tkip.iv16 = le16_to_cpu(sc->iv16);
+ }
+
+-static void iwl_mvm_set_aes_rx_seq(struct iwl_mvm *mvm, struct aes_sc *scs,
+- struct ieee80211_sta *sta,
+- struct ieee80211_key_conf *key)
++static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key,
++ struct ieee80211_key_seq *seq)
+ {
+ int tid;
+
+- BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS);
+-
+- if (sta && iwl_mvm_has_new_rx_api(mvm)) {
+- struct iwl_mvm_sta *mvmsta;
+- struct iwl_mvm_key_pn *ptk_pn;
+-
+- mvmsta = iwl_mvm_sta_from_mac80211(sta);
+-
+- rcu_read_lock();
+- ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
+- if (WARN_ON(!ptk_pn)) {
+- rcu_read_unlock();
+- return;
+- }
+-
+- for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
+- struct ieee80211_key_seq seq = {};
+- int i;
+-
+- iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
+- ieee80211_set_key_rx_seq(key, tid, &seq);
+- for (i = 1; i < mvm->trans->num_rx_queues; i++)
+- memcpy(ptk_pn->q[i].pn[tid],
+- seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
+- }
+- rcu_read_unlock();
+- } else {
+- for (tid = 0; tid < IWL_NUM_RSC; tid++) {
+- struct ieee80211_key_seq seq = {};
+-
+- iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
+- ieee80211_set_key_rx_seq(key, tid, &seq);
+- }
+- }
++ for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
++ ieee80211_set_key_rx_seq(key, tid, &seq[tid]);
+ }
+
+-static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc *scs,
+- struct ieee80211_key_conf *key)
++static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm,
++ struct iwl_wowlan_status_data *status,
++ struct ieee80211_sta *sta,
++ struct ieee80211_key_conf *key)
+ {
++ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
++ struct iwl_mvm_key_pn *ptk_pn;
+ int tid;
+
+- BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS);
++ iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq);
+
+- for (tid = 0; tid < IWL_NUM_RSC; tid++) {
+- struct ieee80211_key_seq seq = {};
++ if (!iwl_mvm_has_new_rx_api(mvm))
++ return;
+
+- iwl_mvm_tkip_sc_to_seq(&scs[tid], &seq);
+- ieee80211_set_key_rx_seq(key, tid, &seq);
++
++ rcu_read_lock();
++ ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
++ if (WARN_ON(!ptk_pn)) {
++ rcu_read_unlock();
++ return;
++ }
++
++ for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
++ int i;
++
++ for (i = 1; i < mvm->trans->num_rx_queues; i++)
++ memcpy(ptk_pn->q[i].pn[tid],
++ status->ptk.aes.seq[tid].ccmp.pn,
++ IEEE80211_CCMP_PN_LEN);
++ }
++ rcu_read_unlock();
++}
++
++static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
++ union iwl_all_tsc_rsc *sc)
++{
++ int i;
++
++ BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
++ BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
++
++ /* GTK RX counters */
++ for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
++ iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
++ &status->gtk.tkip.seq[i]);
++ iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
++ &status->gtk.aes.seq[i]);
++ }
++
++ /* PTK TX counter */
++ status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
++ ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16);
++ status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn);
++
++ /* PTK RX counters */
++ for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
++ iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i],
++ &status->ptk.tkip.seq[i]);
++ iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i],
++ &status->ptk.aes.seq[i]);
+ }
+ }
+
+ static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
+ struct ieee80211_key_conf *key,
+- struct iwl_wowlan_status *status)
++ struct iwl_wowlan_status_data *status)
+ {
+- union iwl_all_tsc_rsc *rsc = &status->gtk[0].rsc.all_tsc_rsc;
+-
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+- iwl_mvm_set_aes_rx_seq(mvm, rsc->aes.multicast_rsc, NULL, key);
++ iwl_mvm_set_key_rx_seq_tids(key, status->gtk.aes.seq);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+- iwl_mvm_set_tkip_rx_seq(rsc->tkip.multicast_rsc, key);
++ iwl_mvm_set_key_rx_seq_tids(key, status->gtk.tkip.seq);
+ break;
+ default:
+ WARN_ON(1);
+@@ -1619,7 +1669,7 @@ static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
+
+ struct iwl_mvm_d3_gtk_iter_data {
+ struct iwl_mvm *mvm;
+- struct iwl_wowlan_status *status;
++ struct iwl_wowlan_status_data *status;
+ void *last_gtk;
+ u32 cipher;
+ bool find_phase, unhandled_cipher;
+@@ -1633,6 +1683,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
+ void *_data)
+ {
+ struct iwl_mvm_d3_gtk_iter_data *data = _data;
++ struct iwl_wowlan_status_data *status = data->status;
+
+ if (data->unhandled_cipher)
+ return;
+@@ -1661,10 +1712,6 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
+ * note that this assumes no TDLS sessions are active
+ */
+ if (sta) {
+- struct ieee80211_key_seq seq = {};
+- union iwl_all_tsc_rsc *sc =
+- &data->status->gtk[0].rsc.all_tsc_rsc;
+-
+ if (data->find_phase)
+ return;
+
+@@ -1672,16 +1719,12 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+- iwl_mvm_set_aes_rx_seq(data->mvm, sc->aes.unicast_rsc,
+- sta, key);
+- atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn));
++ atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn);
++ iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+- iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
+- iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
+- atomic64_set(&key->tx_pn,
+- (u64)seq.tkip.iv16 |
+- ((u64)seq.tkip.iv32 << 16));
++ atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
++ iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq);
+ break;
+ }
+
+@@ -1703,7 +1746,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
+
+ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+- struct iwl_wowlan_status *status)
++ struct iwl_wowlan_status_data *status)
+ {
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_d3_gtk_iter_data gtkdata = {
+@@ -1717,7 +1760,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+ if (!status || !vif->bss_conf.bssid)
+ return false;
+
+- if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons)
++ if (status->wakeup_reasons & disconnection_reasons)
+ return false;
+
+ /* find last GTK that we used initially, if any */
+@@ -1741,7 +1784,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+ iwl_mvm_d3_update_keys, &gtkdata);
+
+ IWL_DEBUG_WOWLAN(mvm, "num of GTK rekeying %d\n",
+- le32_to_cpu(status->num_of_gtk_rekeys));
++ status->num_of_gtk_rekeys);
+ if (status->num_of_gtk_rekeys) {
+ struct ieee80211_key_conf *key;
+ struct {
+@@ -1750,36 +1793,32 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+ } conf = {
+ .conf.cipher = gtkdata.cipher,
+ .conf.keyidx =
+- iwlmvm_wowlan_gtk_idx(&status->gtk[0]),
++ status->gtk.flags & IWL_WOWLAN_GTK_IDX_MASK,
+ };
+ __be64 replay_ctr;
+
+ IWL_DEBUG_WOWLAN(mvm,
+ "Received from FW GTK cipher %d, key index %d\n",
+ conf.conf.cipher, conf.conf.keyidx);
++
++ BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
++ BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
++ BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256);
++ BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP);
++ BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk.key));
++
++ memcpy(conf.conf.key, status->gtk.key, sizeof(status->gtk.key));
++
+ switch (gtkdata.cipher) {
+ case WLAN_CIPHER_SUITE_CCMP:
+ case WLAN_CIPHER_SUITE_GCMP:
+- BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
+- BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
+ conf.conf.keylen = WLAN_KEY_LEN_CCMP;
+- memcpy(conf.conf.key, status->gtk[0].key,
+- WLAN_KEY_LEN_CCMP);
+ break;
+ case WLAN_CIPHER_SUITE_GCMP_256:
+- BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256);
+ conf.conf.keylen = WLAN_KEY_LEN_GCMP_256;
+- memcpy(conf.conf.key, status->gtk[0].key,
+- WLAN_KEY_LEN_GCMP_256);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+- BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP);
+ conf.conf.keylen = WLAN_KEY_LEN_TKIP;
+- memcpy(conf.conf.key, status->gtk[0].key, 16);
+- /* leave TX MIC key zeroed, we don't use it anyway */
+- memcpy(conf.conf.key +
+- NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
+- status->gtk[0].tkip_mic_key, 8);
+ break;
+ }
+
+@@ -1788,8 +1827,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+ return false;
+ iwl_mvm_set_key_rx_seq(mvm, key, status);
+
+- replay_ctr =
+- cpu_to_be64(le64_to_cpu(status->replay_ctr));
++ replay_ctr = cpu_to_be64(status->replay_ctr);
+
+ ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
+ (void *)&replay_ctr, GFP_KERNEL);
+@@ -1800,7 +1838,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+ WOWLAN_GET_STATUSES, 0) < 10) {
+ mvmvif->seqno_valid = true;
+ /* +0x10 because the set API expects next-to-use, not last-used */
+- mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
++ mvmvif->seqno = status->non_qos_seq_ctr + 0x10;
+ }
+
+ return true;
+@@ -1808,13 +1846,13 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
+
+ /* Occasionally, templates would be nice. This is one of those times ... */
+ #define iwl_mvm_parse_wowlan_status_common(_ver) \
+-static struct iwl_wowlan_status * \
++static struct iwl_wowlan_status_data * \
+ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
+- void *_data, int len) \
++ struct iwl_wowlan_status_ ##_ver *data,\
++ int len) \
+ { \
+- struct iwl_wowlan_status *status; \
+- struct iwl_wowlan_status_ ##_ver *data = _data; \
+- int data_size; \
++ struct iwl_wowlan_status_data *status; \
++ int data_size, i; \
+ \
+ if (len < sizeof(*data)) { \
+ IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); \
+@@ -1832,18 +1870,22 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
+ return ERR_PTR(-ENOMEM); \
+ \
+ /* copy all the common fields */ \
+- status->replay_ctr = data->replay_ctr; \
+- status->pattern_number = data->pattern_number; \
+- status->non_qos_seq_ctr = data->non_qos_seq_ctr; \
+- memcpy(status->qos_seq_ctr, data->qos_seq_ctr, \
+- sizeof(status->qos_seq_ctr)); \
+- status->wakeup_reasons = data->wakeup_reasons; \
+- status->num_of_gtk_rekeys = data->num_of_gtk_rekeys; \
+- status->received_beacons = data->received_beacons; \
+- status->wake_packet_length = data->wake_packet_length; \
+- status->wake_packet_bufsize = data->wake_packet_bufsize; \
++ status->replay_ctr = le64_to_cpu(data->replay_ctr); \
++ status->pattern_number = le16_to_cpu(data->pattern_number); \
++ status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr); \
++ for (i = 0; i < 8; i++) \
++ status->qos_seq_ctr[i] = \
++ le16_to_cpu(data->qos_seq_ctr[i]); \
++ status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); \
++ status->num_of_gtk_rekeys = \
++ le32_to_cpu(data->num_of_gtk_rekeys); \
++ status->received_beacons = le32_to_cpu(data->received_beacons); \
++ status->wake_packet_length = \
++ le32_to_cpu(data->wake_packet_length); \
++ status->wake_packet_bufsize = \
++ le32_to_cpu(data->wake_packet_bufsize); \
+ memcpy(status->wake_packet, data->wake_packet, \
+- le32_to_cpu(status->wake_packet_bufsize)); \
++ status->wake_packet_bufsize); \
+ \
+ return status; \
+ }
+@@ -1852,10 +1894,49 @@ iwl_mvm_parse_wowlan_status_common(v6)
+ iwl_mvm_parse_wowlan_status_common(v7)
+ iwl_mvm_parse_wowlan_status_common(v9)
+
+-static struct iwl_wowlan_status *
++static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status,
++ struct iwl_wowlan_gtk_status *data)
++{
++ BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key));
++ BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
++ sizeof(data->tkip_mic_key) >
++ sizeof(status->gtk.key));
++
++ status->gtk.len = data->key_len;
++ status->gtk.flags = data->key_flags;
++
++ memcpy(status->gtk.key, data->key, sizeof(data->key));
++
++ /* if it's as long as the TKIP encryption key, copy MIC key */
++ if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
++ memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
++ data->tkip_mic_key, sizeof(data->tkip_mic_key));
++}
++
++static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
++ struct iwl_wowlan_igtk_status *data)
++{
++ const u8 *ipn = data->ipn;
++
++ BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key));
++
++ status->igtk.len = data->key_len;
++ status->igtk.flags = data->key_flags;
++
++ memcpy(status->igtk.key, data->key, sizeof(data->key));
++
++ status->igtk.ipn = ((u64)ipn[5] << 0) |
++ ((u64)ipn[4] << 8) |
++ ((u64)ipn[3] << 16) |
++ ((u64)ipn[2] << 24) |
++ ((u64)ipn[1] << 32) |
++ ((u64)ipn[0] << 40);
++}
++
++static struct iwl_wowlan_status_data *
+ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
+ {
+- struct iwl_wowlan_status *status;
++ struct iwl_wowlan_status_data *status;
+ struct iwl_wowlan_get_status_cmd get_status_cmd = {
+ .sta_id = cpu_to_le32(sta_id),
+ };
+@@ -1895,59 +1976,57 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
+ IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
+ struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data;
+
+- status = iwl_mvm_parse_wowlan_status_common_v6(mvm,
+- cmd.resp_pkt->data,
+- len);
++ status = iwl_mvm_parse_wowlan_status_common_v6(mvm, v6, len);
+ if (IS_ERR(status))
+ goto out_free_resp;
+
+ BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) >
+- sizeof(status->gtk[0].key));
+- BUILD_BUG_ON(sizeof(v6->gtk.tkip_mic_key) >
+- sizeof(status->gtk[0].tkip_mic_key));
++ sizeof(status->gtk.key));
++ BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
++ sizeof(v6->gtk.tkip_mic_key) >
++ sizeof(status->gtk.key));
+
+ /* copy GTK info to the right place */
+- memcpy(status->gtk[0].key, v6->gtk.decrypt_key,
++ memcpy(status->gtk.key, v6->gtk.decrypt_key,
+ sizeof(v6->gtk.decrypt_key));
+- memcpy(status->gtk[0].tkip_mic_key, v6->gtk.tkip_mic_key,
++ memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
++ v6->gtk.tkip_mic_key,
+ sizeof(v6->gtk.tkip_mic_key));
+- memcpy(&status->gtk[0].rsc, &v6->gtk.rsc,
+- sizeof(status->gtk[0].rsc));
++
++ iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc);
+
+ /* hardcode the key length to 16 since v6 only supports 16 */
+- status->gtk[0].key_len = 16;
++ status->gtk.len = 16;
+
+ /*
+ * The key index only uses 2 bits (values 0 to 3) and
+ * we always set bit 7 which means this is the
+ * currently used key.
+ */
+- status->gtk[0].key_flags = v6->gtk.key_index | BIT(7);
++ status->gtk.flags = v6->gtk.key_index | BIT(7);
+ } else if (notif_ver == 7) {
+ struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data;
+
+- status = iwl_mvm_parse_wowlan_status_common_v7(mvm,
+- cmd.resp_pkt->data,
+- len);
++ status = iwl_mvm_parse_wowlan_status_common_v7(mvm, v7, len);
+ if (IS_ERR(status))
+ goto out_free_resp;
+
+- status->gtk[0] = v7->gtk[0];
+- status->igtk[0] = v7->igtk[0];
++ iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
++ iwl_mvm_convert_gtk(status, &v7->gtk[0]);
++ iwl_mvm_convert_igtk(status, &v7->igtk[0]);
+ } else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
+ struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
+
+ /* these three command versions have same layout and size, the
+ * difference is only in a few not used (reserved) fields.
+ */
+- status = iwl_mvm_parse_wowlan_status_common_v9(mvm,
+- cmd.resp_pkt->data,
+- len);
++ status = iwl_mvm_parse_wowlan_status_common_v9(mvm, v9, len);
+ if (IS_ERR(status))
+ goto out_free_resp;
+
+- status->gtk[0] = v9->gtk[0];
+- status->igtk[0] = v9->igtk[0];
++ iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
++ iwl_mvm_convert_gtk(status, &v9->gtk[0]);
++ iwl_mvm_convert_igtk(status, &v9->igtk[0]);
+
+ status->tid_tear_down = v9->tid_tear_down;
+ } else {
+@@ -1962,7 +2041,7 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
+ return status;
+ }
+
+-static struct iwl_wowlan_status *
++static struct iwl_wowlan_status_data *
+ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, u8 sta_id)
+ {
+ u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+@@ -1987,29 +2066,17 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif)
+ {
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+- struct iwl_wowlan_status_data status;
+- struct iwl_wowlan_status *fw_status;
++ struct iwl_wowlan_status_data *status;
+ int i;
+ bool keep;
+ struct iwl_mvm_sta *mvm_ap_sta;
+
+- fw_status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id);
+- if (IS_ERR_OR_NULL(fw_status))
++ status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id);
++ if (IS_ERR(status))
+ goto out_unlock;
+
+ IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n",
+- le32_to_cpu(fw_status->wakeup_reasons));
+-
+- status.pattern_number = le16_to_cpu(fw_status->pattern_number);
+- for (i = 0; i < 8; i++)
+- status.qos_seq_ctr[i] =
+- le16_to_cpu(fw_status->qos_seq_ctr[i]);
+- status.wakeup_reasons = le32_to_cpu(fw_status->wakeup_reasons);
+- status.wake_packet_length =
+- le32_to_cpu(fw_status->wake_packet_length);
+- status.wake_packet_bufsize =
+- le32_to_cpu(fw_status->wake_packet_bufsize);
+- status.wake_packet = fw_status->wake_packet;
++ status->wakeup_reasons);
+
+ /* still at hard-coded place 0 for D3 image */
+ mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0);
+@@ -2017,7 +2084,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
+ goto out_free;
+
+ for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
+- u16 seq = status.qos_seq_ctr[i];
++ u16 seq = status->qos_seq_ctr[i];
+ /* firmware stores last-used value, we store next value */
+ seq += 0x10;
+ mvm_ap_sta->tid_data[i].seq_number = seq;
+@@ -2033,15 +2100,15 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
+ /* now we have all the data we need, unlock to avoid mac80211 issues */
+ mutex_unlock(&mvm->mutex);
+
+- iwl_mvm_report_wakeup_reasons(mvm, vif, &status);
++ iwl_mvm_report_wakeup_reasons(mvm, vif, status);
+
+- keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status);
++ keep = iwl_mvm_setup_connection_keep(mvm, vif, status);
+
+- kfree(fw_status);
++ kfree(status);
+ return keep;
+
+ out_free:
+- kfree(fw_status);
++ kfree(status);
+ out_unlock:
+ mutex_unlock(&mvm->mutex);
+ return false;
+@@ -2165,16 +2232,16 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
+ .pattern_idx = -1,
+ };
+ struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
++ struct iwl_wowlan_status_data *status;
+ struct iwl_mvm_nd_query_results query;
+- struct iwl_wowlan_status *fw_status;
+ unsigned long matched_profiles;
+ u32 reasons = 0;
+ int i, n_matches, ret;
+
+- fw_status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA);
+- if (!IS_ERR_OR_NULL(fw_status)) {
+- reasons = le32_to_cpu(fw_status->wakeup_reasons);
+- kfree(fw_status);
++ status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA);
++ if (!IS_ERR(status)) {
++ reasons = status->wakeup_reasons;
++ kfree(status);
+ }
+
+ if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+index 5dc39fbb74d6..ff66001d507e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+@@ -395,10 +395,9 @@ static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf,
+ "A-MPDU size limit %d\n",
+ lq_sta->pers.dbg_agg_frame_count_lim);
+ desc += scnprintf(buff + desc, bufsz - desc,
+- "valid_tx_ant %s%s%s\n",
++ "valid_tx_ant %s%s\n",
+ (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
+- (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
+- (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
++ (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "");
+ desc += scnprintf(buff + desc, bufsz - desc,
+ "last tx rate=0x%X ",
+ lq_sta->last_rate_n_flags);
+@@ -986,8 +985,8 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
+ continue;
+ pos += scnprintf(pos, endpos - pos, "Rate[%d]: ",
+ (int)(ARRAY_SIZE(stats->last_rates) - i));
+- pos += rs_pretty_print_rate(pos, endpos - pos,
+- stats->last_rates[idx]);
++ pos += rs_pretty_print_rate_v1(pos, endpos - pos,
++ stats->last_rates[idx]);
+ if (pos < endpos - 1)
+ *pos++ = '\n';
+ }
+@@ -1060,8 +1059,6 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
+ pos += scnprintf(buf + pos, bufsz - pos, "A");
+ if (mvm->scan_rx_ant & ANT_B)
+ pos += scnprintf(buf + pos, bufsz - pos, "B");
+- if (mvm->scan_rx_ant & ANT_C)
+- pos += scnprintf(buf + pos, bufsz - pos, "C");
+ pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+@@ -1196,7 +1193,6 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
+ struct ieee80211_tx_info *info;
+ struct iwl_mac_beacon_cmd beacon_cmd = {};
+ u8 rate;
+- u16 flags;
+ int i;
+
+ len /= 2;
+@@ -1243,12 +1239,9 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
+ mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ info = IEEE80211_SKB_CB(beacon);
+ rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
+- flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
+
+- if (rate == IWL_FIRST_CCK_RATE)
+- flags |= IWL_MAC_BEACON_CCK;
+-
+- beacon_cmd.flags = cpu_to_le16(flags);
++ beacon_cmd.flags =
++ cpu_to_le16(iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw, rate));
+ beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
+ beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
+index 03e5bf5cb909..949fb790f8fb 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
+@@ -324,6 +324,7 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm,
+ u8 *ctrl_ch_position)
+ {
+ u32 freq = peer->chandef.chan->center_freq;
++ u8 cmd_ver;
+
+ *channel = ieee80211_frequency_to_channel(freq);
+
+@@ -344,6 +345,17 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm,
+ *format_bw = IWL_LOCATION_FRAME_FORMAT_VHT;
+ *format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS;
+ break;
++ case NL80211_CHAN_WIDTH_160:
++ cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP,
++ TOF_RANGE_REQ_CMD,
++ IWL_FW_CMD_VER_UNKNOWN);
++
++ if (cmd_ver >= 13) {
++ *format_bw = IWL_LOCATION_FRAME_FORMAT_HE;
++ *format_bw |= IWL_LOCATION_BW_160MHZ << LOCATION_BW_POS;
++ break;
++ }
++ fallthrough;
+ default:
+ IWL_ERR(mvm, "Unsupported BW in FTM request (%d)\n",
+ peer->chandef.width);
+@@ -1142,6 +1154,7 @@ static u8 iwl_mvm_ftm_get_range_resp_ver(struct iwl_mvm *mvm)
+ static bool iwl_mvm_ftm_resp_size_validation(u8 ver, unsigned int pkt_len)
+ {
+ switch (ver) {
++ case 9:
+ case 8:
+ return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v8);
+ case 7:
+@@ -1205,7 +1218,7 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
+ int peer_idx;
+
+ if (new_api) {
+- if (notif_ver == 8) {
++ if (notif_ver >= 8) {
+ fw_ap = &fw_resp_v8->ap[i];
+ iwl_mvm_ftm_pasn_update_pn(mvm, fw_ap);
+ } else if (notif_ver == 7) {
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
+index eba5433c2626..bda6da7d988e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
+@@ -46,8 +46,8 @@ static int iwl_mvm_ftm_responder_set_bw_v1(struct cfg80211_chan_def *chandef,
+ }
+
+ static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef,
+- u8 *format_bw,
+- u8 *ctrl_ch_position)
++ u8 *format_bw, u8 *ctrl_ch_position,
++ u8 cmd_ver)
+ {
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+@@ -68,6 +68,14 @@ static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef,
+ *format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS;
+ *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef);
+ break;
++ case NL80211_CHAN_WIDTH_160:
++ if (cmd_ver >= 9) {
++ *format_bw = IWL_LOCATION_FRAME_FORMAT_HE;
++ *format_bw |= IWL_LOCATION_BW_160MHZ << LOCATION_BW_POS;
++ *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef);
++ break;
++ }
++ fallthrough;
+ default:
+ return -ENOTSUPP;
+ }
+@@ -140,7 +148,8 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm,
+
+ if (cmd_ver >= 7)
+ err = iwl_mvm_ftm_responder_set_bw_v2(chandef, &cmd.format_bw,
+- &cmd.ctrl_ch_position);
++ &cmd.ctrl_ch_position,
++ cmd_ver);
+ else
+ err = iwl_mvm_ftm_responder_set_bw_v1(chandef, &cmd.format_bw,
+ &cmd.ctrl_ch_position);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+index 74404c96063b..863fec150e53 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+@@ -295,6 +295,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
+ if (ret) {
+ struct iwl_trans *trans = mvm->trans;
+
++ /* SecBoot info */
+ if (trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_22000) {
+ IWL_ERR(mvm,
+@@ -302,6 +303,17 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
+ iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS),
+ iwl_read_umac_prph(trans,
+ UMAG_SB_CPU_2_STATUS));
++ } else if (trans->trans_cfg->device_family >=
++ IWL_DEVICE_FAMILY_8000) {
++ IWL_ERR(mvm,
++ "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
++ iwl_read_prph(trans, SB_CPU_1_STATUS),
++ iwl_read_prph(trans, SB_CPU_2_STATUS));
++ }
++
++ /* LMAC/UMAC PC info */
++ if (trans->trans_cfg->device_family >=
++ IWL_DEVICE_FAMILY_9000) {
+ IWL_ERR(mvm, "UMAC PC: 0x%x\n",
+ iwl_read_umac_prph(trans,
+ UREG_UMAC_CURRENT_PC));
+@@ -312,12 +324,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
+ IWL_ERR(mvm, "LMAC2 PC: 0x%x\n",
+ iwl_read_umac_prph(trans,
+ UREG_LMAC2_CURRENT_PC));
+- } else if (trans->trans_cfg->device_family >=
+- IWL_DEVICE_FAMILY_8000) {
+- IWL_ERR(mvm,
+- "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
+- iwl_read_prph(trans, SB_CPU_1_STATUS),
+- iwl_read_prph(trans, SB_CPU_2_STATUS));
+ }
+
+ if (ret == -ETIMEDOUT)
+@@ -763,14 +769,18 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
+ int ret;
+ struct iwl_host_cmd cmd;
+ u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP,
+- GEO_TX_POWER_LIMIT,
++ PER_CHAIN_LIMIT_OFFSET_CMD,
+ IWL_FW_CMD_VER_UNKNOWN);
+
+ /* the ops field is at the same spot for all versions, so set in v1 */
+ geo_tx_cmd.v1.ops =
+ cpu_to_le32(IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE);
+
+- if (cmd_ver == 3)
++ if (cmd_ver == 5)
++ len = sizeof(geo_tx_cmd.v5);
++ else if (cmd_ver == 4)
++ len = sizeof(geo_tx_cmd.v4);
++ else if (cmd_ver == 3)
+ len = sizeof(geo_tx_cmd.v3);
+ else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
+ IWL_UCODE_TLV_API_SAR_TABLE_VER))
+@@ -782,7 +792,7 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
+ return -EOPNOTSUPP;
+
+ cmd = (struct iwl_host_cmd){
+- .id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT),
++ .id = WIDE_ID(PHY_OPS_GROUP, PER_CHAIN_LIMIT_OFFSET_CMD),
+ .len = { len, },
+ .flags = CMD_WANT_SKB,
+ .data = { &geo_tx_cmd },
+@@ -797,7 +807,7 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
+ resp = (void *)cmd.resp_pkt->data;
+ ret = le32_to_cpu(resp->profile_idx);
+
+- if (WARN_ON(ret > ACPI_NUM_GEO_PROFILES))
++ if (WARN_ON(ret > ACPI_NUM_GEO_PROFILES_REV3))
+ ret = -EIO;
+
+ iwl_free_resp(&cmd);
+@@ -809,36 +819,58 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
+ union iwl_geo_tx_power_profiles_cmd cmd;
+ u16 len;
+ u32 n_bands;
++ u32 n_profiles;
+ int ret;
+ u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP,
+- GEO_TX_POWER_LIMIT,
++ PER_CHAIN_LIMIT_OFFSET_CMD,
+ IWL_FW_CMD_VER_UNKNOWN);
+
+ BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, ops) !=
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) ||
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) !=
+- offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops));
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops) ||
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops) !=
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, ops) ||
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, ops) !=
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, ops));
++
+ /* the ops field is at the same spot for all versions, so set in v1 */
+ cmd.v1.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES);
+
+- if (cmd_ver == 3) {
++ if (cmd_ver == 5) {
++ len = sizeof(cmd.v5);
++ n_bands = ARRAY_SIZE(cmd.v5.table[0]);
++ n_profiles = ACPI_NUM_GEO_PROFILES_REV3;
++ } else if (cmd_ver == 4) {
++ len = sizeof(cmd.v4);
++ n_bands = ARRAY_SIZE(cmd.v4.table[0]);
++ n_profiles = ACPI_NUM_GEO_PROFILES_REV3;
++ } else if (cmd_ver == 3) {
+ len = sizeof(cmd.v3);
+ n_bands = ARRAY_SIZE(cmd.v3.table[0]);
++ n_profiles = ACPI_NUM_GEO_PROFILES;
+ } else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
+ IWL_UCODE_TLV_API_SAR_TABLE_VER)) {
+ len = sizeof(cmd.v2);
+ n_bands = ARRAY_SIZE(cmd.v2.table[0]);
++ n_profiles = ACPI_NUM_GEO_PROFILES;
+ } else {
+ len = sizeof(cmd.v1);
+ n_bands = ARRAY_SIZE(cmd.v1.table[0]);
++ n_profiles = ACPI_NUM_GEO_PROFILES;
+ }
+
+ BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, table) !=
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) ||
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) !=
+- offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table));
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table) ||
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table) !=
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) ||
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) !=
++ offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, table));
+ /* the table is at the same position for all versions, so set use v1 */
+- ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0], n_bands);
++ ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0],
++ n_bands, n_profiles);
+
+ /*
+ * It is a valid scenario to not support SAR, or miss wgds table,
+@@ -851,14 +883,19 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
+ * Set the revision on versions that contain it.
+ * This must be done after calling iwl_sar_geo_init().
+ */
+- if (cmd_ver == 3)
++ if (cmd_ver == 5)
++ cmd.v5.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
++ else if (cmd_ver == 4)
++ cmd.v4.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
++ else if (cmd_ver == 3)
+ cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
+ else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
+ IWL_UCODE_TLV_API_SAR_TABLE_VER))
+ cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
+
+ return iwl_mvm_send_cmd_pdu(mvm,
+- WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT),
++ WIDE_ID(PHY_OPS_GROUP,
++ PER_CHAIN_LIMIT_OFFSET_CMD),
+ 0, len, &cmd);
+ }
+
+@@ -1108,7 +1145,7 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
+ static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
+ {
+ u8 value;
+- int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0, DSM_RFI_FUNC_ENABLE,
++ int ret = iwl_acpi_get_dsm_u8(mvm->fwrt.dev, 0, DSM_RFI_FUNC_ENABLE,
+ &iwl_rfi_guid, &value);
+
+ if (ret < 0) {
+@@ -1133,30 +1170,45 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
+ {
+ int ret;
+ u32 value;
+- struct iwl_lari_config_change_cmd_v4 cmd = {};
++ struct iwl_lari_config_change_cmd_v5 cmd = {};
+
+ cmd.config_bitmap = iwl_acpi_get_lari_config_bitmap(&mvm->fwrt);
+
+- ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0, DSM_FUNC_11AX_ENABLEMENT,
++ ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0, DSM_FUNC_11AX_ENABLEMENT,
+ &iwl_guid, &value);
+ if (!ret)
+ cmd.oem_11ax_allow_bitmap = cpu_to_le32(value);
+- /* apply more config masks here */
+
+- ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0,
++ ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0,
+ DSM_FUNC_ENABLE_UNII4_CHAN,
+ &iwl_guid, &value);
+ if (!ret)
+ cmd.oem_unii4_allow_bitmap = cpu_to_le32(value);
+
++ ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0,
++ DSM_FUNC_ACTIVATE_CHANNEL,
++ &iwl_guid, &value);
++ if (!ret)
++ cmd.chan_state_active_bitmap = cpu_to_le32(value);
++
++ ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0,
++ DSM_FUNC_ENABLE_6E,
++ &iwl_guid, &value);
++ if (!ret)
++ cmd.oem_uhb_allow_bitmap = cpu_to_le32(value);
++
+ if (cmd.config_bitmap ||
++ cmd.oem_uhb_allow_bitmap ||
+ cmd.oem_11ax_allow_bitmap ||
+- cmd.oem_unii4_allow_bitmap) {
++ cmd.oem_unii4_allow_bitmap ||
++ cmd.chan_state_active_bitmap) {
+ size_t cmd_size;
+ u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
+ REGULATORY_AND_NVM_GROUP,
+ LARI_CONFIG_CHANGE, 1);
+- if (cmd_ver == 4)
++ if (cmd_ver == 5)
++ cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5);
++ else if (cmd_ver == 4)
+ cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4);
+ else if (cmd_ver == 3)
+ cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3);
+@@ -1170,9 +1222,13 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
+ le32_to_cpu(cmd.config_bitmap),
+ le32_to_cpu(cmd.oem_11ax_allow_bitmap));
+ IWL_DEBUG_RADIO(mvm,
+- "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, cmd_ver=%d\n",
++ "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, chan_state_active_bitmap=0x%x, cmd_ver=%d\n",
+ le32_to_cpu(cmd.oem_unii4_allow_bitmap),
++ le32_to_cpu(cmd.chan_state_active_bitmap),
+ cmd_ver);
++ IWL_DEBUG_RADIO(mvm,
++ "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x\n",
++ le32_to_cpu(cmd.oem_uhb_allow_bitmap));
+ ret = iwl_mvm_send_cmd_pdu(mvm,
+ WIDE_ID(REGULATORY_AND_NVM_GROUP,
+ LARI_CONFIG_CHANGE),
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+index fd352b2624a6..fd7d4abfb454 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+@@ -604,6 +604,12 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
+
+ ctxt_sta->is_assoc = cpu_to_le32(1);
+
++ if (!mvmvif->authorized &&
++ fw_has_capa(&mvm->fw->ucode_capa,
++ IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO))
++ ctxt_sta->data_policy |=
++ cpu_to_le32(COEX_HIGH_PRIORITY_ENABLE);
++
+ /*
+ * allow multicast data frames only as long as the station is
+ * authorized, i.e., GTK keys are already installed (if needed)
+@@ -812,6 +818,21 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
+ return rate;
+ }
+
++u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx)
++{
++ u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx);
++ bool is_new_rate = iwl_fw_lookup_cmd_ver(fw,
++ LONG_GROUP,
++ BEACON_TEMPLATE_CMD,
++ 0) > 10;
++
++ if (rate_idx <= IWL_FIRST_CCK_RATE)
++ flags |= is_new_rate ? IWL_MAC_BEACON_CCK
++ : IWL_MAC_BEACON_CCK_V1;
++
++ return flags;
++}
++
+ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct sk_buff *beacon,
+@@ -844,9 +865,10 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
+
+ rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
+
+- tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
++ tx->rate_n_flags |=
++ cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate));
+ if (rate == IWL_FIRST_CCK_RATE)
+- tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
++ tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK_V1);
+
+ }
+
+@@ -929,11 +951,7 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm,
+ u16 flags;
+ struct ieee80211_chanctx_conf *ctx;
+ int channel;
+-
+- flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
+-
+- if (rate == IWL_FIRST_CCK_RATE)
+- flags |= IWL_MAC_BEACON_CCK;
++ flags = iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw, rate);
+
+ /* Enable FILS on PSC channels only */
+ rcu_read_lock();
+@@ -942,7 +960,11 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm,
+ WARN_ON(channel == 0);
+ if (cfg80211_channel_is_psc(ctx->def.chan) &&
+ !IWL_MVM_DISABLE_AP_FILS) {
+- flags |= IWL_MAC_BEACON_FILS;
++ flags |= iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
++ BEACON_TEMPLATE_CMD,
++ 0) > 10 ?
++ IWL_MAC_BEACON_FILS :
++ IWL_MAC_BEACON_FILS_V1;
+ beacon_cmd.short_ssid =
+ cpu_to_le32(~crc32_le(~0, vif->bss_conf.ssid,
+ vif->bss_conf.ssid_len));
+@@ -1535,11 +1557,11 @@ void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm,
+ ieee80211_beacon_set_cntdwn(vif, notif->csa_counter);
+ }
+
+-void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
+- struct iwl_rx_cmd_buffer *rxb)
++void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
++ struct iwl_rx_cmd_buffer *rxb)
+ {
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+- struct iwl_channel_switch_noa_notif *notif = (void *)pkt->data;
++ struct iwl_channel_switch_start_notif *notif = (void *)pkt->data;
+ struct ieee80211_vif *csa_vif, *vif;
+ struct iwl_mvm_vif *mvmvif;
+ u32 id_n_color, csa_id, mac_id;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index 3a4585222d6d..9fb9c7dad314 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -145,7 +145,8 @@ static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = {
+ .bandwidths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+ BIT(NL80211_CHAN_WIDTH_20) |
+ BIT(NL80211_CHAN_WIDTH_40) |
+- BIT(NL80211_CHAN_WIDTH_80),
++ BIT(NL80211_CHAN_WIDTH_80) |
++ BIT(NL80211_CHAN_WIDTH_160),
+ .preambles = BIT(NL80211_PREAMBLE_LEGACY) |
+ BIT(NL80211_PREAMBLE_HT) |
+ BIT(NL80211_PREAMBLE_VHT) |
+@@ -2022,7 +2023,8 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
+ }
+
+ sband = mvm->hw->wiphy->bands[chanctx_conf->def.chan->band];
+- own_he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
++ own_he_cap = ieee80211_get_he_iftype_cap(sband,
++ ieee80211_vif_type_p2p(vif));
+
+ sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
+ if (IS_ERR_OR_NULL(sta)) {
+@@ -2234,6 +2236,34 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
+ IWL_ERR(mvm, "Failed to config FW to work HE!\n");
+ }
+
++static void iwl_mvm_protect_assoc(struct iwl_mvm *mvm,
++ struct ieee80211_vif *vif,
++ u32 duration_override)
++{
++ u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
++ u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
++
++ if (duration_override > duration)
++ duration = duration_override;
++
++ /* Try really hard to protect the session and hear a beacon
++ * The new session protection command allows us to protect the
++ * session for a much longer time since the firmware will internally
++ * create two events: a 300TU one with a very high priority that
++ * won't be fragmented which should be enough for 99% of the cases,
++ * and another one (which we configure here to be 900TU long) which
++ * will have a slightly lower priority, but more importantly, can be
++ * fragmented so that it'll allow other activities to run.
++ */
++ if (fw_has_capa(&mvm->fw->ucode_capa,
++ IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
++ iwl_mvm_schedule_session_protection(mvm, vif, 900,
++ min_duration, false);
++ else
++ iwl_mvm_protect_session(mvm, vif, duration,
++ min_duration, 500, false);
++}
++
+ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+@@ -2317,6 +2347,20 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
+ u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
+ iwl_mvm_protect_session(mvm, vif, dur, dur,
+ 5 * dur, false);
++ } else if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
++ &mvm->status) &&
++ !vif->bss_conf.dtim_period) {
++ /*
++ * If we're not restarting and still haven't
++ * heard a beacon (dtim period unknown) then
++ * make sure we still have enough minimum time
++ * remaining in the time event, since the auth
++ * might actually have taken quite a while
++ * (especially for SAE) and so the remaining
++ * time could be small without us having heard
++ * a beacon yet.
++ */
++ iwl_mvm_protect_assoc(mvm, vif, 0);
+ }
+
+ iwl_mvm_sf_update(mvm, vif, false);
+@@ -3192,38 +3236,52 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
+ if (iwl_mvm_phy_ctx_count(mvm) > 1)
+ iwl_mvm_teardown_tdls_peers(mvm);
+
+- if (sta->tdls)
++ if (sta->tdls) {
+ iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr,
+ NL80211_TDLS_ENABLE_LINK);
++ } else {
++ /* enable beacon filtering */
++ WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
+
+- /* enable beacon filtering */
+- WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
++ mvmvif->authorized = 1;
+
+- /*
+- * Now that the station is authorized, i.e., keys were already
+- * installed, need to indicate to the FW that
+- * multicast data frames can be forwarded to the driver
+- */
+- iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
++ /*
++ * Now that the station is authorized, i.e., keys were already
++ * installed, need to indicate to the FW that
++ * multicast data frames can be forwarded to the driver
++ */
++ iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
++ }
+
+ iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+ true);
+ } else if (old_state == IEEE80211_STA_AUTHORIZED &&
+ new_state == IEEE80211_STA_ASSOC) {
+- /* Multicast data frames are no longer allowed */
+- iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
++ if (!sta->tdls) {
++ /* Multicast data frames are no longer allowed */
++ iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+
+- /* disable beacon filtering */
+- ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
+- WARN_ON(ret &&
+- !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
+- &mvm->status));
++ /*
++ * Set this after the above iwl_mvm_mac_ctxt_changed()
++ * to avoid sending high prio again for a little time.
++ */
++ mvmvif->authorized = 0;
++
++ /* disable beacon filtering */
++ ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
++ WARN_ON(ret &&
++ !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
++ &mvm->status));
++ }
+ ret = 0;
+ } else if (old_state == IEEE80211_STA_ASSOC &&
+ new_state == IEEE80211_STA_AUTH) {
+ if (vif->type == NL80211_IFTYPE_AP) {
+ mvmvif->ap_assoc_sta_count--;
+ iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
++ } else if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
++ /* remove session protection if still running */
++ iwl_mvm_stop_session_protection(mvm, vif);
+ }
+ ret = 0;
+ } else if (old_state == IEEE80211_STA_AUTH &&
+@@ -3316,29 +3374,24 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
+ struct ieee80211_prep_tx_info *info)
+ {
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+- u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
+- u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
+-
+- if (info->duration > duration)
+- duration = info->duration;
+
+ mutex_lock(&mvm->mutex);
+- /* Try really hard to protect the session and hear a beacon
+- * The new session protection command allows us to protect the
+- * session for a much longer time since the firmware will internally
+- * create two events: a 300TU one with a very high priority that
+- * won't be fragmented which should be enough for 99% of the cases,
+- * and another one (which we configure here to be 900TU long) which
+- * will have a slightly lower priority, but more importantly, can be
+- * fragmented so that it'll allow other activities to run.
+- */
+- if (fw_has_capa(&mvm->fw->ucode_capa,
+- IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
+- iwl_mvm_schedule_session_protection(mvm, vif, 900,
+- min_duration, false);
+- else
+- iwl_mvm_protect_session(mvm, vif, duration,
+- min_duration, 500, false);
++ iwl_mvm_protect_assoc(mvm, vif, info->duration);
++ mutex_unlock(&mvm->mutex);
++}
++
++static void iwl_mvm_mac_mgd_complete_tx(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_prep_tx_info *info)
++{
++ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
++
++ /* for successful cases (auth/assoc), don't cancel session protection */
++ if (info->success)
++ return;
++
++ mutex_lock(&mvm->mutex);
++ iwl_mvm_stop_session_protection(mvm, vif);
+ mutex_unlock(&mvm->mutex);
+ }
+
+@@ -4704,6 +4757,9 @@ static void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw,
+ if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CS_MODIFY))
+ return;
+
++ IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d count = %d (old %d) mode = %d\n",
++ mvmvif->id, chsw->count, mvmvif->csa_count, chsw->block_tx);
++
+ if (chsw->count >= mvmvif->csa_count && chsw->block_tx) {
+ if (mvmvif->csa_misbehave) {
+ /* Second time, give up on this AP*/
+@@ -4720,8 +4776,6 @@ static void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw,
+ if (mvmvif->csa_failed)
+ goto out_unlock;
+
+- IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d count = %d mode = %d\n",
+- mvmvif->id, chsw->count, chsw->block_tx);
+ WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
+ WIDE_ID(MAC_CONF_GROUP,
+ CHANNEL_SWITCH_TIME_EVENT_CMD),
+@@ -4873,6 +4927,8 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
+
+ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo)
+ {
++ u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
++
+ switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
+ case RATE_MCS_CHAN_WIDTH_20:
+ rinfo->bw = RATE_INFO_BW_20;
+@@ -4888,30 +4944,65 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo)
+ break;
+ }
+
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
+- rinfo->flags |= RATE_INFO_FLAGS_MCS;
+- rinfo->mcs = u32_get_bits(rate_n_flags, RATE_HT_MCS_INDEX_MSK);
+- rinfo->nss = u32_get_bits(rate_n_flags,
+- RATE_HT_MCS_NSS_MSK) + 1;
+- if (rate_n_flags & RATE_MCS_SGI_MSK)
+- rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
+- } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
+- rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
+- rinfo->mcs = u32_get_bits(rate_n_flags,
+- RATE_VHT_MCS_RATE_CODE_MSK);
+- rinfo->nss = u32_get_bits(rate_n_flags,
+- RATE_VHT_MCS_NSS_MSK) + 1;
+- if (rate_n_flags & RATE_MCS_SGI_MSK)
+- rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
+- } else if (rate_n_flags & RATE_MCS_HE_MSK) {
++ if (format == RATE_MCS_CCK_MSK ||
++ format == RATE_MCS_LEGACY_OFDM_MSK) {
++ int rate = u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK);
++
++ /* add the offset needed to get to the legacy ofdm indices */
++ if (format == RATE_MCS_LEGACY_OFDM_MSK)
++ rate += IWL_FIRST_OFDM_RATE;
++
++ switch (rate) {
++ case IWL_RATE_1M_INDEX:
++ rinfo->legacy = 10;
++ break;
++ case IWL_RATE_2M_INDEX:
++ rinfo->legacy = 20;
++ break;
++ case IWL_RATE_5M_INDEX:
++ rinfo->legacy = 55;
++ break;
++ case IWL_RATE_11M_INDEX:
++ rinfo->legacy = 110;
++ break;
++ case IWL_RATE_6M_INDEX:
++ rinfo->legacy = 60;
++ break;
++ case IWL_RATE_9M_INDEX:
++ rinfo->legacy = 90;
++ break;
++ case IWL_RATE_12M_INDEX:
++ rinfo->legacy = 120;
++ break;
++ case IWL_RATE_18M_INDEX:
++ rinfo->legacy = 180;
++ break;
++ case IWL_RATE_24M_INDEX:
++ rinfo->legacy = 240;
++ break;
++ case IWL_RATE_36M_INDEX:
++ rinfo->legacy = 360;
++ break;
++ case IWL_RATE_48M_INDEX:
++ rinfo->legacy = 480;
++ break;
++ case IWL_RATE_54M_INDEX:
++ rinfo->legacy = 540;
++ }
++ return;
++ }
++
++ rinfo->nss = u32_get_bits(rate_n_flags,
++ RATE_MCS_NSS_MSK) + 1;
++ rinfo->mcs = format == RATE_MCS_HT_MSK ?
++ RATE_HT_MCS_INDEX(rate_n_flags) :
++ u32_get_bits(rate_n_flags, RATE_MCS_CODE_MSK);
++
++ if (format == RATE_MCS_HE_MSK) {
+ u32 gi_ltf = u32_get_bits(rate_n_flags,
+ RATE_MCS_HE_GI_LTF_MSK);
+
+ rinfo->flags |= RATE_INFO_FLAGS_HE_MCS;
+- rinfo->mcs = u32_get_bits(rate_n_flags,
+- RATE_VHT_MCS_RATE_CODE_MSK);
+- rinfo->nss = u32_get_bits(rate_n_flags,
+- RATE_VHT_MCS_NSS_MSK) + 1;
+
+ if (rate_n_flags & RATE_MCS_HE_106T_MSK) {
+ rinfo->bw = RATE_INFO_BW_HE_RU;
+@@ -4925,10 +5016,10 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo)
+ rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+ else if (gi_ltf == 2)
+ rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6;
+- else if (rate_n_flags & RATE_MCS_SGI_MSK)
+- rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+- else
++ else if (gi_ltf == 3)
+ rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
++ else
++ rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+ break;
+ case RATE_MCS_HE_TYPE_MU:
+ if (gi_ltf == 0 || gi_ltf == 1)
+@@ -4948,46 +5039,19 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo)
+
+ if (rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK)
+ rinfo->he_dcm = 1;
+- } else {
+- switch (u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK)) {
+- case IWL_RATE_1M_PLCP:
+- rinfo->legacy = 10;
+- break;
+- case IWL_RATE_2M_PLCP:
+- rinfo->legacy = 20;
+- break;
+- case IWL_RATE_5M_PLCP:
+- rinfo->legacy = 55;
+- break;
+- case IWL_RATE_11M_PLCP:
+- rinfo->legacy = 110;
+- break;
+- case IWL_RATE_6M_PLCP:
+- rinfo->legacy = 60;
+- break;
+- case IWL_RATE_9M_PLCP:
+- rinfo->legacy = 90;
+- break;
+- case IWL_RATE_12M_PLCP:
+- rinfo->legacy = 120;
+- break;
+- case IWL_RATE_18M_PLCP:
+- rinfo->legacy = 180;
+- break;
+- case IWL_RATE_24M_PLCP:
+- rinfo->legacy = 240;
+- break;
+- case IWL_RATE_36M_PLCP:
+- rinfo->legacy = 360;
+- break;
+- case IWL_RATE_48M_PLCP:
+- rinfo->legacy = 480;
+- break;
+- case IWL_RATE_54M_PLCP:
+- rinfo->legacy = 540;
+- break;
+- }
++ return;
+ }
++
++ if (rate_n_flags & RATE_MCS_SGI_MSK)
++ rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
++
++ if (format == RATE_MCS_HT_MSK) {
++ rinfo->flags |= RATE_INFO_FLAGS_MCS;
++
++ } else if (format == RATE_MCS_VHT_MSK) {
++ rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
++ }
++
+ }
+
+ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
+@@ -5332,6 +5396,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
+ .sta_rc_update = iwl_mvm_sta_rc_update,
+ .conf_tx = iwl_mvm_mac_conf_tx,
+ .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
++ .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx,
+ .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
+ .flush = iwl_mvm_mac_flush,
+ .sched_scan_start = iwl_mvm_mac_sched_scan_start,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+index f877d86b038e..2b1dcd60e00f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -297,6 +297,7 @@ struct iwl_probe_resp_data {
+ * see enum &iwl_mvm_low_latency_cause for causes.
+ * @low_latency_actual: boolean, indicates low latency is set,
+ * as a result from low_latency bit flags and takes force into account.
++ * @authorized: indicates the AP station was set to authorized
+ * @ps_disabled: indicates that this interface requires PS to be disabled
+ * @queue_params: QoS params for this MAC
+ * @bcast_sta: station used for broadcast packets. Used by the following
+@@ -330,6 +331,7 @@ struct iwl_mvm_vif {
+ bool monitor_active;
+ u8 low_latency: 6;
+ u8 low_latency_actual: 1;
++ u8 authorized:1;
+ bool ps_disabled;
+ struct iwl_mvm_vif_bf_data bf_data;
+
+@@ -1443,12 +1445,17 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm);
+ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm);
+
+ /* Utils */
++int iwl_mvm_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags,
++ enum nl80211_band band);
+ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
+ enum nl80211_band band);
+ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
+ enum nl80211_band band,
+ struct ieee80211_tx_rate *r);
+-u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
++void iwl_mvm_hwrate_to_tx_rate_v1(u32 rate_n_flags,
++ enum nl80211_band band,
++ struct ieee80211_tx_rate *r);
++u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx);
+ u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac);
+
+ static inline void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
+@@ -1629,6 +1636,8 @@ int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
+ void *data, int len);
+ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
+ struct ieee80211_vif *vif);
++u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw,
++ u8 rate_idx);
+ void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
+ __le32 *tim_index, __le32 *tim_size,
+ u8 *beacon, u32 frame_size);
+@@ -1649,8 +1658,8 @@ void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb);
+ void iwl_mvm_rx_missed_vap_notif(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb);
+-void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
+- struct iwl_rx_cmd_buffer *rxb);
++void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm,
++ struct iwl_rx_cmd_buffer *rxb);
+ /* Bindings */
+ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+ int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+@@ -1732,7 +1741,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+ /* rate scaling */
+ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq);
+ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg);
+-int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);
++int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate);
+ void rs_update_last_rssi(struct iwl_mvm *mvm,
+ struct iwl_mvm_sta *mvmsta,
+ struct ieee80211_rx_status *rx_status);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+index da705fcaf0fc..6d18a1fd649b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+@@ -583,8 +583,9 @@ void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
+ return;
+
+ wgds_tbl_idx = iwl_mvm_get_sar_geo_profile(mvm);
+- if (wgds_tbl_idx < 0)
+- IWL_DEBUG_INFO(mvm, "SAR WGDS is disabled (%d)\n",
++ if (wgds_tbl_idx < 1)
++ IWL_DEBUG_INFO(mvm,
++ "SAR WGDS is disabled or error received (%d)\n",
+ wgds_tbl_idx);
+ else
+ IWL_DEBUG_INFO(mvm, "SAR WGDS: geo profile %d is configured\n",
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index 77ea2d0a3091..232ad531d612 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -29,7 +29,6 @@
+
+ #define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
+ MODULE_DESCRIPTION(DRV_DESCRIPTION);
+-MODULE_AUTHOR(DRV_AUTHOR);
+ MODULE_LICENSE("GPL");
+
+ static const struct iwl_op_mode_ops iwl_mvm_ops;
+@@ -384,9 +383,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
+ iwl_mvm_probe_resp_data_notif,
+ RX_HANDLER_ASYNC_LOCKED,
+ struct iwl_probe_resp_data_notif),
+- RX_HANDLER_GRP(MAC_CONF_GROUP, CHANNEL_SWITCH_NOA_NOTIF,
+- iwl_mvm_channel_switch_noa_notif,
+- RX_HANDLER_SYNC, struct iwl_channel_switch_noa_notif),
++ RX_HANDLER_GRP(MAC_CONF_GROUP, CHANNEL_SWITCH_START_NOTIF,
++ iwl_mvm_channel_switch_start_notif,
++ RX_HANDLER_SYNC, struct iwl_channel_switch_start_notif),
+ RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF,
+ iwl_mvm_rx_monitor_notif, RX_HANDLER_ASYNC_LOCKED,
+ struct iwl_datapath_monitor_notif),
+@@ -512,7 +511,7 @@ static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = {
+ HCMD_NAME(CHANNEL_SWITCH_TIME_EVENT_CMD),
+ HCMD_NAME(SESSION_PROTECTION_CMD),
+ HCMD_NAME(SESSION_PROTECTION_NOTIF),
+- HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF),
++ HCMD_NAME(CHANNEL_SWITCH_START_NOTIF),
+ };
+
+ /* Please keep this array *SORTED* by hex value.
+@@ -522,7 +521,7 @@ static const struct iwl_hcmd_names iwl_mvm_phy_names[] = {
+ HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE),
+ HCMD_NAME(CTDP_CONFIG_CMD),
+ HCMD_NAME(TEMP_REPORTING_THRESHOLDS_CMD),
+- HCMD_NAME(GEO_TX_POWER_LIMIT),
++ HCMD_NAME(PER_CHAIN_LIMIT_OFFSET_CMD),
+ HCMD_NAME(CT_KILL_NOTIFICATION),
+ HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE),
+ };
+@@ -726,6 +725,183 @@ static int iwl_mvm_start_post_nvm(struct iwl_mvm *mvm)
+ return 0;
+ }
+
++struct iwl_mvm_frob_txf_data {
++ u8 *buf;
++ size_t buflen;
++};
++
++static void iwl_mvm_frob_txf_key_iter(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_sta *sta,
++ struct ieee80211_key_conf *key,
++ void *data)
++{
++ struct iwl_mvm_frob_txf_data *txf = data;
++ u8 keylen, match, matchend;
++ u8 *keydata;
++ size_t i;
++
++ switch (key->cipher) {
++ case WLAN_CIPHER_SUITE_CCMP:
++ keydata = key->key;
++ keylen = key->keylen;
++ break;
++ case WLAN_CIPHER_SUITE_WEP40:
++ case WLAN_CIPHER_SUITE_WEP104:
++ case WLAN_CIPHER_SUITE_TKIP:
++ /*
++ * WEP has short keys which might show up in the payload,
++ * and then you can deduce the key, so in this case just
++ * remove all FIFO data.
++ * For TKIP, we don't know the phase 2 keys here, so same.
++ */
++ memset(txf->buf, 0xBB, txf->buflen);
++ return;
++ default:
++ return;
++ }
++
++ /* scan for key material and clear it out */
++ match = 0;
++ for (i = 0; i < txf->buflen; i++) {
++ if (txf->buf[i] != keydata[match]) {
++ match = 0;
++ continue;
++ }
++ match++;
++ if (match == keylen) {
++ memset(txf->buf + i - keylen, 0xAA, keylen);
++ match = 0;
++ }
++ }
++
++ /* we're dealing with a FIFO, so check wrapped around data */
++ matchend = match;
++ for (i = 0; match && i < keylen - match; i++) {
++ if (txf->buf[i] != keydata[match])
++ break;
++ match++;
++ if (match == keylen) {
++ memset(txf->buf, 0xAA, i + 1);
++ memset(txf->buf + txf->buflen - matchend, 0xAA,
++ matchend);
++ break;
++ }
++ }
++}
++
++static void iwl_mvm_frob_txf(void *ctx, void *buf, size_t buflen)
++{
++ struct iwl_mvm_frob_txf_data txf = {
++ .buf = buf,
++ .buflen = buflen,
++ };
++ struct iwl_mvm *mvm = ctx;
++
++ /* embedded key material exists only on old API */
++ if (iwl_mvm_has_new_tx_api(mvm))
++ return;
++
++ rcu_read_lock();
++ ieee80211_iter_keys_rcu(mvm->hw, NULL, iwl_mvm_frob_txf_key_iter, &txf);
++ rcu_read_unlock();
++}
++
++static void iwl_mvm_frob_hcmd(void *ctx, void *hcmd, size_t len)
++{
++ /* we only use wide headers for commands */
++ struct iwl_cmd_header_wide *hdr = hcmd;
++ unsigned int frob_start = sizeof(*hdr), frob_end = 0;
++
++ if (len < sizeof(hdr))
++ return;
++
++ /* all the commands we care about are in LONG_GROUP */
++ if (hdr->group_id != LONG_GROUP)
++ return;
++
++ switch (hdr->cmd) {
++ case WEP_KEY:
++ case WOWLAN_TKIP_PARAM:
++ case WOWLAN_KEK_KCK_MATERIAL:
++ case ADD_STA_KEY:
++ /*
++ * blank out everything here, easier than dealing
++ * with the various versions of the command
++ */
++ frob_end = INT_MAX;
++ break;
++ case MGMT_MCAST_KEY:
++ frob_start = offsetof(struct iwl_mvm_mgmt_mcast_key_cmd, igtk);
++ BUILD_BUG_ON(offsetof(struct iwl_mvm_mgmt_mcast_key_cmd, igtk) !=
++ offsetof(struct iwl_mvm_mgmt_mcast_key_cmd_v1, igtk));
++
++ frob_end = offsetofend(struct iwl_mvm_mgmt_mcast_key_cmd, igtk);
++ BUILD_BUG_ON(offsetof(struct iwl_mvm_mgmt_mcast_key_cmd, igtk) <
++ offsetof(struct iwl_mvm_mgmt_mcast_key_cmd_v1, igtk));
++ break;
++ }
++
++ if (frob_start >= frob_end)
++ return;
++
++ if (frob_end > len)
++ frob_end = len;
++
++ memset((u8 *)hcmd + frob_start, 0xAA, frob_end - frob_start);
++}
++
++static void iwl_mvm_frob_mem(void *ctx, u32 mem_addr, void *mem, size_t buflen)
++{
++ const struct iwl_dump_exclude *excl;
++ struct iwl_mvm *mvm = ctx;
++ int i;
++
++ switch (mvm->fwrt.cur_fw_img) {
++ case IWL_UCODE_INIT:
++ default:
++ /* not relevant */
++ return;
++ case IWL_UCODE_REGULAR:
++ case IWL_UCODE_REGULAR_USNIFFER:
++ excl = mvm->fw->dump_excl;
++ break;
++ case IWL_UCODE_WOWLAN:
++ excl = mvm->fw->dump_excl_wowlan;
++ break;
++ }
++
++ BUILD_BUG_ON(sizeof(mvm->fw->dump_excl) !=
++ sizeof(mvm->fw->dump_excl_wowlan));
++
++ for (i = 0; i < ARRAY_SIZE(mvm->fw->dump_excl); i++) {
++ u32 start, end;
++
++ if (!excl[i].addr || !excl[i].size)
++ continue;
++
++ start = excl[i].addr;
++ end = start + excl[i].size;
++
++ if (end <= mem_addr || start >= mem_addr + buflen)
++ continue;
++
++ if (start < mem_addr)
++ start = mem_addr;
++
++ if (end > mem_addr + buflen)
++ end = mem_addr + buflen;
++
++ memset((u8 *)mem + start - mem_addr, 0xAA, end - start);
++ }
++}
++
++static const struct iwl_dump_sanitize_ops iwl_mvm_sanitize_ops = {
++ .frob_txf = iwl_mvm_frob_txf,
++ .frob_hcmd = iwl_mvm_frob_hcmd,
++ .frob_mem = iwl_mvm_frob_mem,
++};
++
+ static struct iwl_op_mode *
+ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+ const struct iwl_fw *fw, struct dentry *dbgfs_dir)
+@@ -775,7 +951,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+ mvm->hw = hw;
+
+ iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm,
+- dbgfs_dir);
++ &iwl_mvm_sanitize_ops, mvm, dbgfs_dir);
+
+ iwl_mvm_get_acpi_tables(mvm);
+
+@@ -868,8 +1044,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+ mvm->cmd_ver.range_resp =
+ iwl_fw_lookup_notif_ver(mvm->fw, LOCATION_GROUP,
+ TOF_RANGE_RESPONSE_NOTIF, 5);
+- /* we only support up to version 8 */
+- if (WARN_ON_ONCE(mvm->cmd_ver.range_resp > 8))
++ /* we only support up to version 9 */
++ if (WARN_ON_ONCE(mvm->cmd_ver.range_resp > 9))
+ goto out_free;
+
+ /*
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
+index f2b090be3898..b2ea2fca5376 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2012-2014, 2018-2019 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
+ * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
+ * Copyright (C) 2015-2017 Intel Deutschland GmbH
+ */
+@@ -128,6 +128,19 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
+ enum ieee80211_ac_numbers ac;
+ bool tid_found = false;
+
++ if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) ||
++ cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
++ cmd->rx_data_timeout_uapsd =
++ cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
++ cmd->tx_data_timeout_uapsd =
++ cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
++ } else {
++ cmd->rx_data_timeout_uapsd =
++ cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
++ cmd->tx_data_timeout_uapsd =
++ cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
++ }
++
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+ /* set advanced pm flag with no uapsd ACs to enable ps-poll */
+ if (mvmvif->dbgfs_pm.use_ps_poll) {
+@@ -182,19 +195,6 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
+
+ cmd->uapsd_max_sp = mvm->hw->uapsd_max_sp_len;
+
+- if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) ||
+- cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
+- cmd->rx_data_timeout_uapsd =
+- cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
+- cmd->tx_data_timeout_uapsd =
+- cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
+- } else {
+- cmd->rx_data_timeout_uapsd =
+- cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
+- cmd->tx_data_timeout_uapsd =
+- cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
+- }
+-
+ if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
+ cmd->heavy_tx_thld_packets =
+ IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+index 2d58cb969918..958702403a45 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+@@ -32,10 +32,6 @@ static u8 rs_fw_set_active_chains(u8 chains)
+ fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK;
+ if (chains & ANT_B)
+ fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK;
+- if (chains & ANT_C)
+- WARN(false,
+- "tlc offload doesn't support antenna C. chains: 0x%x\n",
+- chains);
+
+ return fw_chains;
+ }
+@@ -314,7 +310,19 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
+
+ if (flags & IWL_TLC_NOTIF_FLAG_RATE) {
+ char pretty_rate[100];
++
++ if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP,
++ TLC_MNG_UPDATE_NOTIF, 0) < 3) {
++ rs_pretty_print_rate_v1(pretty_rate, sizeof(pretty_rate),
++ le32_to_cpu(notif->rate));
++ IWL_DEBUG_RATE(mvm,
++ "Got rate in old format. Rate: %s. Converting.\n",
++ pretty_rate);
++ lq_sta->last_rate_n_flags =
++ iwl_new_rate_from_v1(le32_to_cpu(notif->rate));
++ } else {
+ lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate);
++ }
+ rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate),
+ lq_sta->last_rate_n_flags);
+ IWL_DEBUG_RATE(mvm, "new rate: %s\n", pretty_rate);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+index b97708cb869d..f4d02f9fe16d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+@@ -4,11 +4,6 @@
+ * Copyright(c) 2005 - 2014, 2018 - 2021 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/skbuff.h>
+@@ -335,15 +330,15 @@ static const struct rs_tx_column rs_tx_columns[] = {
+ static inline u8 rs_extract_rate(u32 rate_n_flags)
+ {
+ /* also works for HT because bits 7:6 are zero there */
+- return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK);
++ return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK_V1);
+ }
+
+ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+ {
+ int idx = 0;
+
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
+- idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK;
++ if (rate_n_flags & RATE_MCS_HT_MSK_V1) {
++ idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK_V1;
+ idx += IWL_RATE_MCS_0_INDEX;
+
+ /* skip 9M not supported in HT*/
+@@ -351,8 +346,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+ idx += 1;
+ if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE))
+ return idx;
+- } else if (rate_n_flags & RATE_MCS_VHT_MSK ||
+- rate_n_flags & RATE_MCS_HE_MSK) {
++ } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1 ||
++ rate_n_flags & RATE_MCS_HE_MSK_V1) {
+ idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
+ idx += IWL_RATE_MCS_0_INDEX;
+
+@@ -361,8 +356,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+ idx++;
+ if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE))
+ return idx;
+- if ((rate_n_flags & RATE_MCS_HE_MSK) &&
+- (idx <= IWL_LAST_HE_RATE))
++ if ((rate_n_flags & RATE_MCS_HE_MSK_V1) &&
++ idx <= IWL_LAST_HE_RATE)
+ return idx;
+ } else {
+ /* legacy rate format, search for match in table */
+@@ -459,44 +454,8 @@ static const u16 expected_tpt_mimo2_160MHz[4][IWL_RATE_COUNT] = {
+ {0, 0, 0, 0, 971, 0, 1925, 2861, 3779, 5574, 7304, 8147, 8976, 10592, 11640},
+ };
+
+-/* mbps, mcs */
+-static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
+- { "1", "BPSK DSSS"},
+- { "2", "QPSK DSSS"},
+- {"5.5", "BPSK CCK"},
+- { "11", "QPSK CCK"},
+- { "6", "BPSK 1/2"},
+- { "9", "BPSK 1/2"},
+- { "12", "QPSK 1/2"},
+- { "18", "QPSK 3/4"},
+- { "24", "16QAM 1/2"},
+- { "36", "16QAM 3/4"},
+- { "48", "64QAM 2/3"},
+- { "54", "64QAM 3/4"},
+- { "60", "64QAM 5/6"},
+-};
+-
+ #define MCS_INDEX_PER_STREAM (8)
+
+-static const char *rs_pretty_ant(u8 ant)
+-{
+- static const char * const ant_name[] = {
+- [ANT_NONE] = "None",
+- [ANT_A] = "A",
+- [ANT_B] = "B",
+- [ANT_AB] = "AB",
+- [ANT_C] = "C",
+- [ANT_AC] = "AC",
+- [ANT_BC] = "BC",
+- [ANT_ABC] = "ABC",
+- };
+-
+- if (ant > ANT_ABC)
+- return "UNKNOWN";
+-
+- return ant_name[ant];
+-}
+-
+ static const char *rs_pretty_lq_type(enum iwl_table_type type)
+ {
+ static const char * const lq_types[] = {
+@@ -558,7 +517,7 @@ static char *rs_pretty_rate(const struct rs_rate *rate)
+ rate_str = "BAD_RATE";
+
+ sprintf(buf, "(%s|%s|%s)", rs_pretty_lq_type(rate->type),
+- rs_pretty_ant(rate->ant), rate_str);
++ iwl_rs_pretty_ant(rate->ant), rate_str);
+ return buf;
+ }
+
+@@ -654,8 +613,7 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
+ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
+ {
+ return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
+- !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
+- !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
++ !!(rate_n_flags & RATE_MCS_ANT_B_MSK);
+ }
+
+ /*
+@@ -820,12 +778,12 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
+ int index = rate->index;
+
+ ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) &
+- RATE_MCS_ANT_ABC_MSK);
++ RATE_MCS_ANT_AB_MSK);
+
+ if (is_legacy(rate)) {
+ ucode_rate |= iwl_rates[index].plcp;
+ if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
+- ucode_rate |= RATE_MCS_CCK_MSK;
++ ucode_rate |= RATE_MCS_CCK_MSK_V1;
+ return ucode_rate;
+ }
+
+@@ -840,7 +798,7 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
+ IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
+ index = IWL_LAST_HT_RATE;
+ }
+- ucode_rate |= RATE_MCS_HT_MSK;
++ ucode_rate |= RATE_MCS_HT_MSK_V1;
+
+ if (is_ht_siso(rate))
+ ucode_rate |= iwl_rates[index].plcp_ht_siso;
+@@ -853,7 +811,7 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
+ IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);
+ index = IWL_LAST_VHT_RATE;
+ }
+- ucode_rate |= RATE_MCS_VHT_MSK;
++ ucode_rate |= RATE_MCS_VHT_MSK_V1;
+ if (is_vht_siso(rate))
+ ucode_rate |= iwl_rates[index].plcp_vht_siso;
+ else if (is_vht_mimo2(rate))
+@@ -873,9 +831,9 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
+
+ ucode_rate |= rate->bw;
+ if (rate->sgi)
+- ucode_rate |= RATE_MCS_SGI_MSK;
++ ucode_rate |= RATE_MCS_SGI_MSK_V1;
+ if (rate->ldpc)
+- ucode_rate |= RATE_MCS_LDPC_MSK;
++ ucode_rate |= RATE_MCS_LDPC_MSK_V1;
+
+ return ucode_rate;
+ }
+@@ -885,7 +843,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
+ enum nl80211_band band,
+ struct rs_rate *rate)
+ {
+- u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK;
++ u32 ant_msk = ucode_rate & RATE_MCS_ANT_AB_MSK;
+ u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate);
+ u8 nss;
+
+@@ -898,9 +856,9 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
+ rate->ant = (ant_msk >> RATE_MCS_ANT_POS);
+
+ /* Legacy */
+- if (!(ucode_rate & RATE_MCS_HT_MSK) &&
+- !(ucode_rate & RATE_MCS_VHT_MSK) &&
+- !(ucode_rate & RATE_MCS_HE_MSK)) {
++ if (!(ucode_rate & RATE_MCS_HT_MSK_V1) &&
++ !(ucode_rate & RATE_MCS_VHT_MSK_V1) &&
++ !(ucode_rate & RATE_MCS_HE_MSK_V1)) {
+ if (num_of_ant == 1) {
+ if (band == NL80211_BAND_5GHZ)
+ rate->type = LQ_LEGACY_A;
+@@ -912,20 +870,20 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
+ }
+
+ /* HT, VHT or HE */
+- if (ucode_rate & RATE_MCS_SGI_MSK)
++ if (ucode_rate & RATE_MCS_SGI_MSK_V1)
+ rate->sgi = true;
+- if (ucode_rate & RATE_MCS_LDPC_MSK)
++ if (ucode_rate & RATE_MCS_LDPC_MSK_V1)
+ rate->ldpc = true;
+ if (ucode_rate & RATE_MCS_STBC_MSK)
+ rate->stbc = true;
+ if (ucode_rate & RATE_MCS_BF_MSK)
+ rate->bfer = true;
+
+- rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
++ rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK_V1;
+
+- if (ucode_rate & RATE_MCS_HT_MSK) {
+- nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >>
+- RATE_HT_MCS_NSS_POS) + 1;
++ if (ucode_rate & RATE_MCS_HT_MSK_V1) {
++ nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK_V1) >>
++ RATE_HT_MCS_NSS_POS_V1) + 1;
+
+ if (nss == 1) {
+ rate->type = LQ_HT_SISO;
+@@ -938,7 +896,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
+ } else {
+ WARN_ON_ONCE(1);
+ }
+- } else if (ucode_rate & RATE_MCS_VHT_MSK) {
++ } else if (ucode_rate & RATE_MCS_VHT_MSK_V1) {
+ nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
+ RATE_VHT_MCS_NSS_POS) + 1;
+
+@@ -953,7 +911,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
+ } else {
+ WARN_ON_ONCE(1);
+ }
+- } else if (ucode_rate & RATE_MCS_HE_MSK) {
++ } else if (ucode_rate & RATE_MCS_HE_MSK_V1) {
+ nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
+ RATE_VHT_MCS_NSS_POS) + 1;
+
+@@ -981,9 +939,6 @@ static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate)
+ {
+ u8 new_ant_type;
+
+- if (!rate->ant || WARN_ON_ONCE(rate->ant & ANT_C))
+- return 0;
+-
+ if (!rs_is_valid_ant(valid_ant, rate->ant))
+ return 0;
+
+@@ -2552,7 +2507,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
+ }
+
+ IWL_DEBUG_RATE(mvm, "Best ANT: %s Best RSSI: %d\n",
+- rs_pretty_ant(best_ant), best_rssi);
++ iwl_rs_pretty_ant(best_ant), best_rssi);
+
+ if (best_ant != ANT_A && best_ant != ANT_B)
+ rate->ant = first_antenna(valid_tx_ant);
+@@ -2652,7 +2607,6 @@ void rs_update_last_rssi(struct iwl_mvm *mvm,
+ lq_sta->pers.chains = rx_status->chains;
+ lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0];
+ lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1];
+- lq_sta->pers.chain_signal[2] = rx_status->chain_signal[2];
+ lq_sta->pers.last_rssi = S8_MIN;
+
+ for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {
+@@ -2738,8 +2692,8 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
+ return;
+
+ lq_sta = mvm_sta;
+- iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags,
+- info->band, &info->control.rates[0]);
++ iwl_mvm_hwrate_to_tx_rate_v1(lq_sta->last_rate_n_flags,
++ info->band, &info->control.rates[0]);
+ info->control.rates[0].count = 1;
+
+ /* Report the optimal rate based on rssi and STA caps if we haven't
+@@ -2749,8 +2703,8 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
+ optimal_rate = rs_get_optimal_rate(mvm, lq_sta);
+ last_ucode_rate = ucode_rate_from_rs_rate(mvm,
+ optimal_rate);
+- iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, info->band,
+- &txrc->reported_rate);
++ iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band,
++ &txrc->reported_rate);
+ }
+ }
+
+@@ -2909,7 +2863,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
+
+ mvm->drv_rx_stats.success_frames++;
+
+- switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
++ switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) {
+ case RATE_MCS_CHAN_WIDTH_20:
+ mvm->drv_rx_stats.bw_20_frames++;
+ break;
+@@ -2926,10 +2880,10 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
+ WARN_ONCE(1, "bad BW. rate 0x%x", rate);
+ }
+
+- if (rate & RATE_MCS_HT_MSK) {
++ if (rate & RATE_MCS_HT_MSK_V1) {
+ mvm->drv_rx_stats.ht_frames++;
+- nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
+- } else if (rate & RATE_MCS_VHT_MSK) {
++ nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1) + 1;
++ } else if (rate & RATE_MCS_VHT_MSK_V1) {
+ mvm->drv_rx_stats.vht_frames++;
+ nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
+ RATE_VHT_MCS_NSS_POS) + 1;
+@@ -2942,7 +2896,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
+ else if (nss == 2)
+ mvm->drv_rx_stats.mimo2_frames++;
+
+- if (rate & RATE_MCS_SGI_MSK)
++ if (rate & RATE_MCS_SGI_MSK_V1)
+ mvm->drv_rx_stats.sgi_frames++;
+ else
+ mvm->drv_rx_stats.ngi_frames++;
+@@ -3323,7 +3277,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
+ int i;
+ int num_rates = ARRAY_SIZE(lq_cmd->rs_table);
+ __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);
+- u8 ant = (ucode_rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
++ u8 ant = (ucode_rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
+
+ for (i = 0; i < num_rates; i++)
+ lq_cmd->rs_table[i] = ucode_rate_le32;
+@@ -3688,35 +3642,37 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta)
+ IWL_DEBUG_RATE(mvm, "leave\n");
+ }
+
+-int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
++int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate)
+ {
+
+- char *type, *bw;
++ char *type;
+ u8 mcs = 0, nss = 0;
+- u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
++ u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
++ u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) >>
++ RATE_MCS_CHAN_WIDTH_POS;
+
+- if (!(rate & RATE_MCS_HT_MSK) &&
+- !(rate & RATE_MCS_VHT_MSK) &&
+- !(rate & RATE_MCS_HE_MSK)) {
++ if (!(rate & RATE_MCS_HT_MSK_V1) &&
++ !(rate & RATE_MCS_VHT_MSK_V1) &&
++ !(rate & RATE_MCS_HE_MSK_V1)) {
+ int index = iwl_hwrate_to_plcp_idx(rate);
+
+ return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps",
+- rs_pretty_ant(ant),
++ iwl_rs_pretty_ant(ant),
+ index == IWL_RATE_INVALID ? "BAD" :
+- iwl_rate_mcs[index].mbps);
++ iwl_rate_mcs(index)->mbps);
+ }
+
+- if (rate & RATE_MCS_VHT_MSK) {
++ if (rate & RATE_MCS_VHT_MSK_V1) {
+ type = "VHT";
+ mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
+ nss = ((rate & RATE_VHT_MCS_NSS_MSK)
+ >> RATE_VHT_MCS_NSS_POS) + 1;
+- } else if (rate & RATE_MCS_HT_MSK) {
++ } else if (rate & RATE_MCS_HT_MSK_V1) {
+ type = "HT";
+- mcs = rate & RATE_HT_MCS_INDEX_MSK;
+- nss = ((rate & RATE_HT_MCS_NSS_MSK)
+- >> RATE_HT_MCS_NSS_POS) + 1;
+- } else if (rate & RATE_MCS_HE_MSK) {
++ mcs = rate & RATE_HT_MCS_INDEX_MSK_V1;
++ nss = ((rate & RATE_HT_MCS_NSS_MSK_V1)
++ >> RATE_HT_MCS_NSS_POS_V1) + 1;
++ } else if (rate & RATE_MCS_HE_MSK_V1) {
+ type = "HE";
+ mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
+ nss = ((rate & RATE_VHT_MCS_NSS_MSK)
+@@ -3725,29 +3681,12 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
+ type = "Unknown"; /* shouldn't happen */
+ }
+
+- switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
+- case RATE_MCS_CHAN_WIDTH_20:
+- bw = "20Mhz";
+- break;
+- case RATE_MCS_CHAN_WIDTH_40:
+- bw = "40Mhz";
+- break;
+- case RATE_MCS_CHAN_WIDTH_80:
+- bw = "80Mhz";
+- break;
+- case RATE_MCS_CHAN_WIDTH_160:
+- bw = "160Mhz";
+- break;
+- default:
+- bw = "BAD BW";
+- }
+-
+ return scnprintf(buf, bufsz,
+ "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s",
+- rate, type, rs_pretty_ant(ant), bw, mcs, nss,
+- (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
++ rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss,
++ (rate & RATE_MCS_SGI_MSK_V1) ? "SGI " : "NGI ",
+ (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
+- (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
++ (rate & RATE_MCS_LDPC_MSK_V1) ? "LDPC " : "",
+ (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "",
+ (rate & RATE_MCS_BF_MSK) ? "BF " : "");
+ }
+@@ -3830,10 +3769,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
+ lq_sta->active_legacy_rate);
+ desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n",
+ lq_sta->pers.dbg_fixed_rate);
+- desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s%s\n",
++ desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s\n",
+ (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
+- (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
+- (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
++ (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "");
+ desc += scnprintf(buff + desc, bufsz - desc, "lq type %s\n",
+ (is_legacy(rate)) ? "legacy" :
+ is_vht(rate) ? "VHT" : "HT");
+@@ -3891,7 +3829,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
+
+ desc += scnprintf(buff + desc, bufsz - desc,
+ " rate[%d] 0x%X ", i, r);
+- desc += rs_pretty_print_rate(buff + desc, bufsz - desc, r);
++ desc += rs_pretty_print_rate_v1(buff + desc, bufsz - desc, r);
+ if (desc < bufsz - 1)
+ buff[desc++] = '\n';
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+index 32104c9f8f5e..b7bc8c1b2dda 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+@@ -5,11 +5,6 @@
+ * Copyright(c) 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 - 2019 Intel Corporation
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+ *****************************************************************************/
+
+ #ifndef __rs_h__
+@@ -36,11 +31,6 @@ struct iwl_rs_rate_info {
+
+ #define IWL_RATE_60M_PLCP 3
+
+-enum {
+- IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
+- IWL_RATE_INVALID = IWL_RATE_COUNT,
+-};
+-
+ #define LINK_QUAL_MAX_RETRY_NUM 16
+
+ enum {
+@@ -211,13 +201,6 @@ struct rs_rate {
+ #define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80)
+ #define is_ht160(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_160)
+
+-#define IWL_MAX_MCS_DISPLAY_SIZE 12
+-
+-struct iwl_rate_mcs_info {
+- char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
+- char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
+-};
+-
+ /**
+ * struct iwl_lq_sta_rs_fw - rate and related statistics for RS in FW
+ * @last_rate_n_flags: last rate reported by FW
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+index 8ef5399ad9be..d22f40a5354d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
++ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
+ * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2016-2017 Intel Deutschland GmbH
+ */
+@@ -103,7 +103,7 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
+ struct iwl_rx_phy_info *phy_info,
+ struct ieee80211_rx_status *rx_status)
+ {
+- int energy_a, energy_b, energy_c, max_energy;
++ int energy_a, energy_b, max_energy;
+ u32 val;
+
+ val =
+@@ -114,14 +114,10 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
+ energy_b = (val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >>
+ IWL_RX_INFO_ENERGY_ANT_B_POS;
+ energy_b = energy_b ? -energy_b : S8_MIN;
+- energy_c = (val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >>
+- IWL_RX_INFO_ENERGY_ANT_C_POS;
+- energy_c = energy_c ? -energy_c : S8_MIN;
+ max_energy = max(energy_a, energy_b);
+- max_energy = max(max_energy, energy_c);
+
+- IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n",
+- energy_a, energy_b, energy_c, max_energy);
++ IWL_DEBUG_STATS(mvm, "energy In A %d B %d , and max %d\n",
++ energy_a, energy_b, max_energy);
+
+ rx_status->signal = max_energy;
+ rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
+@@ -129,7 +125,6 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
+ >> RX_RES_PHY_FLAGS_ANTENNA_POS;
+ rx_status->chain_signal[0] = energy_a;
+ rx_status->chain_signal[1] = energy_b;
+- rx_status->chain_signal[2] = energy_c;
+ }
+
+ /*
+@@ -235,7 +230,7 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm,
+ mdata->rx.airtime += le16_to_cpu(phy_info->frame_time);
+ }
+
+- if (!(rate_n_flags & (RATE_MCS_HT_MSK | RATE_MCS_VHT_MSK)))
++ if (!(rate_n_flags & (RATE_MCS_HT_MSK_V1 | RATE_MCS_VHT_MSK_V1)))
+ return;
+
+ mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
+@@ -249,10 +244,10 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm,
+ mvmsta->sta_id != mvmvif->ap_sta_id)
+ return;
+
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
+- thr = thresh_tpt[rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK];
+- thr *= 1 + ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >>
+- RATE_HT_MCS_NSS_POS);
++ if (rate_n_flags & RATE_MCS_HT_MSK_V1) {
++ thr = thresh_tpt[rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK_V1];
++ thr *= 1 + ((rate_n_flags & RATE_HT_MCS_NSS_MSK_V1) >>
++ RATE_HT_MCS_NSS_POS_V1);
+ } else {
+ if (WARN_ON((rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK) >=
+ ARRAY_SIZE(thresh_tpt)))
+@@ -262,7 +257,7 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm,
+ RATE_VHT_MCS_NSS_POS);
+ }
+
+- thr <<= ((rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) >>
++ thr <<= ((rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) >>
+ RATE_MCS_CHAN_WIDTH_POS);
+
+ mdata->uapsd_nonagg_detect.rx_bytes += len;
+@@ -455,7 +450,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
+ }
+
+ /* Set up the HT phy flags */
+- switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
++ switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) {
+ case RATE_MCS_CHAN_WIDTH_20:
+ break;
+ case RATE_MCS_CHAN_WIDTH_40:
+@@ -468,20 +463,20 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
+ rx_status->bw = RATE_INFO_BW_160;
+ break;
+ }
+- if (!(rate_n_flags & RATE_MCS_CCK_MSK) &&
+- rate_n_flags & RATE_MCS_SGI_MSK)
++ if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) &&
++ rate_n_flags & RATE_MCS_SGI_MSK_V1)
+ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+ if (rate_n_flags & RATE_HT_MCS_GF_MSK)
+ rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
+- if (rate_n_flags & RATE_MCS_LDPC_MSK)
++ if (rate_n_flags & RATE_MCS_LDPC_MSK_V1)
+ rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
++ if (rate_n_flags & RATE_MCS_HT_MSK_V1) {
+ u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+ RATE_MCS_STBC_POS;
+ rx_status->encoding = RX_ENC_HT;
+- rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
++ rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1;
+ rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+- } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
++ } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) {
+ u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+ RATE_MCS_STBC_POS;
+ rx_status->nss =
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index c12f303cf652..e0601f802628 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -240,8 +240,7 @@ static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm,
+ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
+ struct napi_struct *napi,
+ struct sk_buff *skb, int queue,
+- struct ieee80211_sta *sta,
+- bool csi)
++ struct ieee80211_sta *sta)
+ {
+ if (iwl_mvm_check_pn(mvm, skb, queue, sta))
+ kfree_skb(skb);
+@@ -269,7 +268,6 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
+ (rate_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
+ rx_status->chain_signal[0] = energy_a;
+ rx_status->chain_signal[1] = energy_b;
+- rx_status->chain_signal[2] = S8_MIN;
+ }
+
+ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+@@ -620,7 +618,7 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm,
+ while ((skb = __skb_dequeue(skb_list))) {
+ iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb,
+ reorder_buf->queue,
+- sta, false);
++ sta);
+ reorder_buf->num_stored--;
+ }
+ }
+@@ -1198,7 +1196,7 @@ static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm,
+ }
+
+ if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK, phy_data4) &&
+- (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) {
++ (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) != RATE_MCS_CHAN_WIDTH_20) {
+ he_mu->flags1 |=
+ cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN |
+ IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN);
+@@ -1235,7 +1233,7 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
+ * the TSF/timers are not be transmitted in HE-MU.
+ */
+ u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK);
+- u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
++ u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1;
+ u8 offs = 0;
+
+ rx_status->bw = RATE_INFO_BW_HE_RU;
+@@ -1290,13 +1288,13 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
+
+ if (he_mu)
+ he_mu->flags2 |=
+- le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
++ le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK_V1,
+ rate_n_flags),
+ IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW);
+- else if (he_type == RATE_MCS_HE_TYPE_TRIG)
++ else if (he_type == RATE_MCS_HE_TYPE_TRIG_V1)
+ he->data6 |=
+ cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_KNOWN) |
+- le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
++ le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK_V1,
+ rate_n_flags),
+ IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW);
+ }
+@@ -1508,9 +1506,9 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
+
+ stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS;
+ rx_status->nss =
+- ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
+- RATE_VHT_MCS_NSS_POS) + 1;
+- rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
++ ((rate_n_flags & RATE_MCS_NSS_MSK) >>
++ RATE_MCS_NSS_POS) + 1;
++ rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK;
+ rx_status->encoding = RX_ENC_HE;
+ rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+ if (rate_n_flags & RATE_MCS_BF_MSK)
+@@ -1562,14 +1560,15 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
+ }
+ break;
+ case 3:
+- if ((he_type == RATE_MCS_HE_TYPE_SU ||
+- he_type == RATE_MCS_HE_TYPE_EXT_SU) &&
+- rate_n_flags & RATE_MCS_SGI_MSK)
+- rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
+- else
+- rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
++ rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2;
+ ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X;
+ break;
++ case 4:
++ rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8;
++ ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X;
++ break;
++ default:
++ ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN;
+ }
+
+ he->data5 |= le16_encode_bits(ltf,
+@@ -1653,7 +1652,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
+ struct iwl_mvm_rx_phy_data phy_data = {
+ .info_type = IWL_RX_PHY_INFO_TYPE_NONE,
+ };
+- bool csi = false;
++ u32 format;
++ bool is_sgi;
+
+ if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
+ return;
+@@ -1691,6 +1691,13 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
+ phy_data.d2 = desc->v1.phy_data2;
+ phy_data.d3 = desc->v1.phy_data3;
+ }
++ if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
++ REPLY_RX_MPDU_CMD, 0) < 4) {
++ rate_n_flags = iwl_new_rate_from_v1(rate_n_flags);
++ IWL_DEBUG_DROP(mvm, "Got old format rate, converting. New rate: 0x%x\n",
++ rate_n_flags);
++ }
++ format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
+
+ len = le16_to_cpu(desc->mpdu_len);
+
+@@ -1744,7 +1751,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
+ break;
+ }
+
+- if (rate_n_flags & RATE_MCS_HE_MSK)
++ if (format == RATE_MCS_HE_MSK)
+ iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags,
+ phy_info, queue);
+
+@@ -1761,7 +1768,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
+ /* set the preamble flag if appropriate */
+- if (rate_n_flags & RATE_MCS_CCK_MSK &&
++ if (format == RATE_MCS_CCK_MSK &&
+ phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE)
+ rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
+
+@@ -1937,33 +1944,34 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
+ }
+ }
+
+- if (!(rate_n_flags & RATE_MCS_CCK_MSK) &&
+- rate_n_flags & RATE_MCS_SGI_MSK)
++ is_sgi = format == RATE_MCS_HE_MSK ?
++ iwl_he_is_sgi(rate_n_flags) :
++ rate_n_flags & RATE_MCS_SGI_MSK;
++
++ if (!(format == RATE_MCS_CCK_MSK) && is_sgi)
+ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+- if (rate_n_flags & RATE_HT_MCS_GF_MSK)
+- rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
+ if (rate_n_flags & RATE_MCS_LDPC_MSK)
+ rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
++ if (format == RATE_MCS_HT_MSK) {
+ u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+- RATE_MCS_STBC_POS;
++ RATE_MCS_STBC_POS;
+ rx_status->encoding = RX_ENC_HT;
+- rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
++ rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags);
+ rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+- } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
++ } else if (format == RATE_MCS_VHT_MSK) {
+ u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+- RATE_MCS_STBC_POS;
+- rx_status->nss =
+- ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
+- RATE_VHT_MCS_NSS_POS) + 1;
+- rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
++ RATE_MCS_STBC_POS;
++ rx_status->nss =
++ ((rate_n_flags & RATE_MCS_NSS_MSK) >>
++ RATE_MCS_NSS_POS) + 1;
++ rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK;
+ rx_status->encoding = RX_ENC_VHT;
+ rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+ if (rate_n_flags & RATE_MCS_BF_MSK)
+ rx_status->enc_flags |= RX_ENC_FLAG_BF;
+- } else if (!(rate_n_flags & RATE_MCS_HE_MSK)) {
+- int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
+- rx_status->band);
++ } else if (!(format == RATE_MCS_HE_MSK)) {
++ int rate = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags,
++ rx_status->band);
+
+ if (WARN(rate < 0 || rate > 0xFF,
+ "Invalid rate flags 0x%x, band %d,\n",
+@@ -1994,7 +2002,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
+
+ if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc))
+ iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue,
+- sta, csi);
++ sta);
+ out:
+ rcu_read_unlock();
+ }
+@@ -2013,12 +2021,24 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
+ struct ieee80211_sta *sta = NULL;
+ struct sk_buff *skb;
+ u8 channel, energy_a, energy_b;
++ u32 format;
+ struct iwl_mvm_rx_phy_data phy_data = {
+ .info_type = le32_get_bits(desc->phy_info[1],
+ IWL_RX_PHY_DATA1_INFO_TYPE_MASK),
+ .d0 = desc->phy_info[0],
+ .d1 = desc->phy_info[1],
+ };
++ bool is_sgi;
++
++ if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP,
++ RX_NO_DATA_NOTIF, 0) < 2) {
++ IWL_DEBUG_DROP(mvm, "Got an old rate format. Old rate: 0x%x\n",
++ rate_n_flags);
++ rate_n_flags = iwl_new_rate_from_v1(rate_n_flags);
++ IWL_DEBUG_DROP(mvm, " Rate after conversion to the new format: 0x%x\n",
++ rate_n_flags);
++ }
++ format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
+
+ if (unlikely(iwl_rx_packet_payload_len(pkt) < sizeof(*desc)))
+ return;
+@@ -2075,7 +2095,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
+ break;
+ }
+
+- if (rate_n_flags & RATE_MCS_HE_MSK)
++ if (format == RATE_MCS_HE_MSK)
+ iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags,
+ phy_info, queue);
+
+@@ -2091,23 +2111,24 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
+
+ rcu_read_lock();
+
+- if (!(rate_n_flags & RATE_MCS_CCK_MSK) &&
+- rate_n_flags & RATE_MCS_SGI_MSK)
++ is_sgi = format == RATE_MCS_HE_MSK ?
++ iwl_he_is_sgi(rate_n_flags) :
++ rate_n_flags & RATE_MCS_SGI_MSK;
++
++ if (!(format == RATE_MCS_CCK_MSK) && is_sgi)
+ rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+- if (rate_n_flags & RATE_HT_MCS_GF_MSK)
+- rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
+ if (rate_n_flags & RATE_MCS_LDPC_MSK)
+ rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
++ if (format == RATE_MCS_HT_MSK) {
+ u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+ RATE_MCS_STBC_POS;
+ rx_status->encoding = RX_ENC_HT;
+- rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
++ rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags);
+ rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+- } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
++ } else if (format == RATE_MCS_VHT_MSK) {
+ u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
+ RATE_MCS_STBC_POS;
+- rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
++ rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK;
+ rx_status->encoding = RX_ENC_VHT;
+ rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+ if (rate_n_flags & RATE_MCS_BF_MSK)
+@@ -2120,12 +2141,12 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
+ rx_status->nss =
+ le32_get_bits(desc->rx_vec[0],
+ RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1;
+- } else if (rate_n_flags & RATE_MCS_HE_MSK) {
++ } else if (format == RATE_MCS_HE_MSK) {
+ rx_status->nss =
+ le32_get_bits(desc->rx_vec[0],
+ RX_NO_DATA_RX_VEC0_HE_NSTS_MSK) + 1;
+ } else {
+- int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
++ int rate = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags,
+ rx_status->band);
+
+ if (WARN(rate < 0 || rate > 0xFF,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+index d78e436fa8b5..a138b5c4cce8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+@@ -163,7 +163,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum nl80211_band band,
+ tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
+
+ if (band == NL80211_BAND_2GHZ && !no_cck)
+- return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK |
++ return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK_V1 |
+ tx_ant);
+ else
+ return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant);
+@@ -1995,8 +1995,16 @@ static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
+ {
+ u16 flags = 0;
+
++ /*
++ * If no direct SSIDs are provided perform a passive scan. Otherwise,
++ * if there is a single SSID which is not the broadcast SSID, assume
++ * that the scan is intended for roaming purposes and thus enable Rx on
++ * all chains to improve chances of hearing the beacons/probe responses.
++ */
+ if (params->n_ssids == 0)
+ flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
++ else if (params->n_ssids == 1 && params->ssids[0].ssid_len)
++ flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_USE_ALL_RX_CHAINS;
+
+ if (iwl_mvm_is_scan_fragmented(params->type))
+ flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index 0a13c2bda2ee..bdd4ee432548 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -268,6 +268,7 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
+ int rate_idx = -1;
+ u8 rate_plcp;
+ u32 rate_flags = 0;
++ bool is_cck;
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+
+ /* info->control is only relevant for non HW rate control */
+@@ -299,11 +300,18 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
+ BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
+
+ /* Get PLCP rate for tx_cmd->rate_n_flags */
+- rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
++ rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx);
++ is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE);
+
+- /* Set CCK flag as needed */
+- if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
+- rate_flags |= RATE_MCS_CCK_MSK;
++ /* Set CCK or OFDM flag */
++ if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 8) {
++ if (!is_cck)
++ rate_flags |= RATE_MCS_LEGACY_OFDM_MSK;
++ else
++ rate_flags |= RATE_MCS_CCK_MSK;
++ } else if (is_cck) {
++ rate_flags |= RATE_MCS_CCK_MSK_V1;
++ }
+
+ return (u32)rate_plcp | rate_flags;
+ }
+@@ -1284,31 +1292,72 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status)
+ }
+ #endif /* CONFIG_IWLWIFI_DEBUG */
+
++static int iwl_mvm_get_hwrate_chan_width(u32 chan_width)
++{
++ switch (chan_width) {
++ case RATE_MCS_CHAN_WIDTH_20:
++ return 0;
++ case RATE_MCS_CHAN_WIDTH_40:
++ return IEEE80211_TX_RC_40_MHZ_WIDTH;
++ case RATE_MCS_CHAN_WIDTH_80:
++ return IEEE80211_TX_RC_80_MHZ_WIDTH;
++ case RATE_MCS_CHAN_WIDTH_160:
++ return IEEE80211_TX_RC_160_MHZ_WIDTH;
++ default:
++ return 0;
++ }
++}
++
+ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
+ enum nl80211_band band,
+ struct ieee80211_tx_rate *r)
+ {
+- if (rate_n_flags & RATE_HT_MCS_GF_MSK)
+- r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
+- switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
+- case RATE_MCS_CHAN_WIDTH_20:
+- break;
+- case RATE_MCS_CHAN_WIDTH_40:
+- r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+- break;
+- case RATE_MCS_CHAN_WIDTH_80:
+- r->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
+- break;
+- case RATE_MCS_CHAN_WIDTH_160:
+- r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH;
+- break;
+- }
++ u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
++ u32 rate = format == RATE_MCS_HT_MSK ?
++ RATE_HT_MCS_INDEX(rate_n_flags) :
++ rate_n_flags & RATE_MCS_CODE_MSK;
++
++ r->flags |=
++ iwl_mvm_get_hwrate_chan_width(rate_n_flags &
++ RATE_MCS_CHAN_WIDTH_MSK);
++
+ if (rate_n_flags & RATE_MCS_SGI_MSK)
+ r->flags |= IEEE80211_TX_RC_SHORT_GI;
+- if (rate_n_flags & RATE_MCS_HT_MSK) {
++ if (format == RATE_MCS_HT_MSK) {
+ r->flags |= IEEE80211_TX_RC_MCS;
+- r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
+- } else if (rate_n_flags & RATE_MCS_VHT_MSK) {
++ r->idx = rate;
++ } else if (format == RATE_MCS_VHT_MSK) {
++ ieee80211_rate_set_vht(r, rate,
++ ((rate_n_flags & RATE_MCS_NSS_MSK) >>
++ RATE_MCS_NSS_POS) + 1);
++ r->flags |= IEEE80211_TX_RC_VHT_MCS;
++ } else if (format == RATE_MCS_HE_MSK) {
++ /* mac80211 cannot do this without ieee80211_tx_status_ext()
++ * but it only matters for radiotap */
++ r->idx = 0;
++ } else {
++ r->idx = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags,
++ band);
++ }
++}
++
++void iwl_mvm_hwrate_to_tx_rate_v1(u32 rate_n_flags,
++ enum nl80211_band band,
++ struct ieee80211_tx_rate *r)
++{
++ if (rate_n_flags & RATE_HT_MCS_GF_MSK)
++ r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
++
++ r->flags |=
++ iwl_mvm_get_hwrate_chan_width(rate_n_flags &
++ RATE_MCS_CHAN_WIDTH_MSK_V1);
++
++ if (rate_n_flags & RATE_MCS_SGI_MSK_V1)
++ r->flags |= IEEE80211_TX_RC_SHORT_GI;
++ if (rate_n_flags & RATE_MCS_HT_MSK_V1) {
++ r->flags |= IEEE80211_TX_RC_MCS;
++ r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1;
++ } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) {
+ ieee80211_rate_set_vht(
+ r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK,
+ ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
+@@ -1323,14 +1372,20 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
+ /*
+ * translate ucode response to mac80211 tx status control values
+ */
+-static void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags,
++static void iwl_mvm_hwrate_to_tx_status(const struct iwl_fw *fw,
++ u32 rate_n_flags,
+ struct ieee80211_tx_info *info)
+ {
+ struct ieee80211_tx_rate *r = &info->status.rates[0];
+
++ if (iwl_fw_lookup_notif_ver(fw, LONG_GROUP,
++ TX_CMD, 0) > 6)
++ rate_n_flags = iwl_new_rate_from_v1(rate_n_flags);
++
+ info->status.antenna =
+- ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
+- iwl_mvm_hwrate_to_tx_rate(rate_n_flags, info->band, r);
++ ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS);
++ iwl_mvm_hwrate_to_tx_rate(rate_n_flags,
++ info->band, r);
+ }
+
+ static void iwl_mvm_tx_status_check_trigger(struct iwl_mvm *mvm,
+@@ -1450,7 +1505,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
+ /* the FW should have stopped the queue and not
+ * return this status
+ */
+- WARN_ON(1);
++ IWL_ERR_LIMIT(mvm,
++ "FW reported TX filtered, status=0x%x, FC=0x%x\n",
++ status, le16_to_cpu(hdr->frame_control));
+ info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+ break;
+ default:
+@@ -1472,8 +1529,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
+ iwl_mvm_tx_status_check_trigger(mvm, status, hdr->frame_control);
+
+ info->status.rates[0].count = tx_resp->failure_frame + 1;
+- iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate),
++
++ iwl_mvm_hwrate_to_tx_status(mvm->fw,
++ le32_to_cpu(tx_resp->initial_rate),
+ info);
++
++ /* Don't assign the converted initial_rate, because driver
++ * TLC uses this and doesn't support the new FW rate
++ */
+ info->status.status_driver_data[1] =
+ (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate);
+
+@@ -1835,7 +1898,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
+ info->flags |= IEEE80211_TX_STAT_AMPDU;
+ memcpy(&info->status, &tx_info->status,
+ sizeof(tx_info->status));
+- iwl_mvm_hwrate_to_tx_status(rate, info);
++ iwl_mvm_hwrate_to_tx_status(mvm->fw, rate, info);
+ }
+ }
+
+@@ -1856,7 +1919,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
+ goto out;
+
+ tx_info->band = chanctx_conf->def.chan->band;
+- iwl_mvm_hwrate_to_tx_status(rate, tx_info);
++ iwl_mvm_hwrate_to_tx_status(mvm->fw, rate, tx_info);
+
+ if (!iwl_mvm_has_tlc_offload(mvm)) {
+ IWL_DEBUG_TX_REPLY(mvm,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+index ec8a223f90e8..caf1dcf48888 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+@@ -135,31 +135,25 @@ int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len,
+ return iwl_mvm_send_cmd_status(mvm, &cmd, status);
+ }
+
+-#define IWL_DECLARE_RATE_INFO(r) \
+- [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
++int iwl_mvm_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags,
++ enum nl80211_band band)
++{
++ int format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
++ int rate = rate_n_flags & RATE_LEGACY_RATE_MSK;
++ bool is_LB = band == NL80211_BAND_2GHZ;
+
+-/*
+- * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
+- */
+-static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
+- IWL_DECLARE_RATE_INFO(1),
+- IWL_DECLARE_RATE_INFO(2),
+- IWL_DECLARE_RATE_INFO(5),
+- IWL_DECLARE_RATE_INFO(11),
+- IWL_DECLARE_RATE_INFO(6),
+- IWL_DECLARE_RATE_INFO(9),
+- IWL_DECLARE_RATE_INFO(12),
+- IWL_DECLARE_RATE_INFO(18),
+- IWL_DECLARE_RATE_INFO(24),
+- IWL_DECLARE_RATE_INFO(36),
+- IWL_DECLARE_RATE_INFO(48),
+- IWL_DECLARE_RATE_INFO(54),
+-};
++ if (format == RATE_MCS_LEGACY_OFDM_MSK)
++ return is_LB ? rate + IWL_FIRST_OFDM_RATE :
++ rate;
++
++ /* CCK is not allowed in HB */
++ return is_LB ? rate : -1;
++}
+
+ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
+ enum nl80211_band band)
+ {
+- int rate = rate_n_flags & RATE_LEGACY_RATE_MSK;
++ int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
+ int idx;
+ int band_offset = 0;
+
+@@ -167,16 +161,24 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
+ if (band != NL80211_BAND_2GHZ)
+ band_offset = IWL_FIRST_OFDM_RATE;
+ for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
+- if (fw_rate_idx_to_plcp[idx] == rate)
++ if (iwl_fw_rate_idx_to_plcp(idx) == rate)
+ return idx - band_offset;
+
+ return -1;
+ }
+
+-u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx)
++u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx)
+ {
+- /* Get PLCP rate for tx_cmd->rate_n_flags */
+- return fw_rate_idx_to_plcp[rate_idx];
++ if (iwl_fw_lookup_cmd_ver(fw, LONG_GROUP,
++ TX_CMD, 0) > 8)
++ /* In the new rate legacy rates are indexed:
++ * 0 - 3 for CCK and 0 - 7 for OFDM.
++ */
++ return (rate_idx >= IWL_FIRST_OFDM_RATE ?
++ rate_idx - IWL_FIRST_OFDM_RATE :
++ rate_idx);
++
++ return iwl_fw_rate_idx_to_plcp(rate_idx);
+ }
+
+ u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac)
+@@ -217,6 +219,7 @@ u8 first_antenna(u8 mask)
+ return BIT(ffs(mask) - 1);
+ }
+
++#define MAX_ANT_NUM 2
+ /*
+ * Toggles between TX antennas to send the probe request on.
+ * Receives the bitmask of valid TX antennas and the *index* used
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+index 239a722cd79d..85a6da70ca78 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+@@ -57,6 +57,10 @@ iwl_pcie_ctxt_info_dbg_enable(struct iwl_trans *trans,
+ dbg_flags |= IWL_PRPH_SCRATCH_EDBG_DEST_DRAM;
+ dbg_cfg->hwm_base_addr = cpu_to_le64(frag->physical);
+ dbg_cfg->hwm_size = cpu_to_le32(frag->size);
++ dbg_cfg->debug_token_config = cpu_to_le32(trans->dbg.ucode_preset);
++ IWL_DEBUG_FW(trans,
++ "WRT: Applying DRAM destination (debug_token_config=%u)\n",
++ dbg_cfg->debug_token_config);
+ IWL_DEBUG_FW(trans,
+ "WRT: Applying DRAM destination (alloc_id=%u, num_frags=%u)\n",
+ alloc_id,
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 3b974388d834..c574f041f096 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -499,6 +499,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
+ /* Ma devices */
+ {IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_trans_cfg)},
+ {IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)},
++ {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_ma_trans_cfg)},
+
+ /* Bz devices */
+ {IWL_PCI_DEVICE(0x2727, PCI_ANY_ID, iwl_bz_trans_cfg)},
+@@ -518,7 +519,7 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
+ #define IWL_DEV_INFO(_device, _subdevice, _cfg, _name) \
+ _IWL_DEV_INFO(_device, _subdevice, IWL_CFG_ANY, IWL_CFG_ANY, \
+ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, \
+- IWL_CFG_NO_CDB, _cfg, _name)
++ IWL_CFG_ANY, _cfg, _name)
+
+ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ #if IS_ENABLED(CONFIG_IWLMVM)
+@@ -532,15 +533,25 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name),
+ IWL_DEV_INFO(0xA370, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name),
+ IWL_DEV_INFO(0xA370, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name),
++ IWL_DEV_INFO(0x54F0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name),
++ IWL_DEV_INFO(0x54F0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name),
+ IWL_DEV_INFO(0x51F0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name),
+ IWL_DEV_INFO(0x51F0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name),
++ IWL_DEV_INFO(0x51F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),
++ IWL_DEV_INFO(0x51F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name),
++ IWL_DEV_INFO(0x54F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),
++ IWL_DEV_INFO(0x54F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name),
++ IWL_DEV_INFO(0x7A70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name),
++ IWL_DEV_INFO(0x7A70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name),
+
+ IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name),
++ IWL_DEV_INFO(0x7E40, 0x1691, iwl_cfg_ma_a0_gf4_a0, iwl_ax411_killer_1690s_name),
++ IWL_DEV_INFO(0x7E40, 0x1692, iwl_cfg_ma_a0_gf4_a0, iwl_ax411_killer_1690i_name),
+
+ /* AX200 */
++ IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name),
+ IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name),
+ IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name),
+- IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name),
+
+ /* Qu with Hr */
+ IWL_DEV_INFO(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL),
+@@ -639,6 +650,12 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_DEV_INFO(0x7AF0, 0x0510, iwlax211_2ax_cfg_so_gf_a0, NULL),
+ IWL_DEV_INFO(0x7AF0, 0x0A10, iwlax211_2ax_cfg_so_gf_a0, NULL),
+
++ /* So with JF */
++ IWL_DEV_INFO(0x7A70, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name),
++ IWL_DEV_INFO(0x7A70, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name),
++ IWL_DEV_INFO(0x7AF0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name),
++ IWL_DEV_INFO(0x7AF0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name),
++
+ /* SnJ with HR */
+ IWL_DEV_INFO(0x2725, 0x00B0, iwlax411_2ax_cfg_sosnj_gf4_a0, NULL),
+ IWL_DEV_INFO(0x2726, 0x0090, iwlax211_cfg_snj_gf_a0, NULL),
+@@ -648,6 +665,12 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_DEV_INFO(0x2726, 0x0510, iwlax211_cfg_snj_gf_a0, NULL),
+ IWL_DEV_INFO(0x2726, 0x1651, iwl_cfg_snj_hr_b0, iwl_ax201_killer_1650s_name),
+ IWL_DEV_INFO(0x2726, 0x1652, iwl_cfg_snj_hr_b0, iwl_ax201_killer_1650i_name),
++ IWL_DEV_INFO(0x2726, 0x1671, iwlax211_cfg_snj_gf_a0, iwl_ax211_killer_1675s_name),
++ IWL_DEV_INFO(0x2726, 0x1672, iwlax211_cfg_snj_gf_a0, iwl_ax211_killer_1675i_name),
++ IWL_DEV_INFO(0x2726, 0x1691, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690s_name),
++ IWL_DEV_INFO(0x2726, 0x1692, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690i_name),
++ IWL_DEV_INFO(0x7F70, 0x1691, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690s_name),
++ IWL_DEV_INFO(0x7F70, 0x1692, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690i_name),
+
+ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+ IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY,
+@@ -702,17 +725,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
+ iwl9260_2ac_cfg, iwl9462_name),
+
+- _IWL_DEV_INFO(0x2526, IWL_CFG_ANY,
+- IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY,
+- IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF,
+- IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
+- iwl9260_2ac_cfg, iwl9560_160_name),
+- _IWL_DEV_INFO(0x2526, IWL_CFG_ANY,
+- IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY,
+- IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF,
+- IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
+- iwl9260_2ac_cfg, iwl9560_name),
+-
+ _IWL_DEV_INFO(0x2526, IWL_CFG_ANY,
+ IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY,
+ IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY,
+@@ -1051,11 +1063,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
+ IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
+ iwl_cfg_so_a0_hr_a0, iwl_ax203_name),
+- _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+- IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY,
+- IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY,
+- IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB,
+- iwl_cfg_so_a0_hr_a0, iwl_ax203_name),
+ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+ IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY,
+ IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY,
+@@ -1112,6 +1119,50 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY,
+ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
+ iwl_cfg_bz_a0_mr_a0, iwl_bz_name),
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY,
++ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
++ iwl_cfg_bz_a0_fm_a0, iwl_bz_name),
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY,
++ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
++ iwl_cfg_gl_a0_fm_a0, iwl_bz_name),
++
++/* SoF with JF2 */
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF,
++ IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
++ iwlax210_2ax_cfg_so_jf_b0, iwl9560_160_name),
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF,
++ IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
++ iwlax210_2ax_cfg_so_jf_b0, iwl9560_name),
++
++/* SoF with JF */
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1,
++ IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
++ iwlax210_2ax_cfg_so_jf_b0, iwl9461_160_name),
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV,
++ IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
++ iwlax210_2ax_cfg_so_jf_b0, iwl9462_160_name),
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1,
++ IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
++ iwlax210_2ax_cfg_so_jf_b0, iwl9461_name),
++ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
++ IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
++ IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV,
++ IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB,
++ iwlax210_2ax_cfg_so_jf_b0, iwl9462_name),
+
+ /* SoF with JF2 */
+ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+@@ -1191,16 +1242,158 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
+ #endif /* CONFIG_IWLMVM */
+ };
+
++/*
++ * In case that there is no OTP on the NIC, get the rf id and cdb info
++ * from the prph registers.
++ */
++static int get_crf_id(struct iwl_trans *iwl_trans)
++{
++ int ret = 0;
++ u32 wfpm_ctrl_addr;
++ u32 wfpm_otp_cfg_addr;
++ u32 sd_reg_ver_addr;
++ u32 cdb = 0;
++ u32 val;
++
++ if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
++ wfpm_ctrl_addr = WFPM_CTRL_REG_GEN2;
++ wfpm_otp_cfg_addr = WFPM_OTP_CFG1_ADDR_GEN2;
++ sd_reg_ver_addr = SD_REG_VER_GEN2;
++ /* Qu/Pu families have other addresses */
++ } else {
++ wfpm_ctrl_addr = WFPM_CTRL_REG;
++ wfpm_otp_cfg_addr = WFPM_OTP_CFG1_ADDR;
++ sd_reg_ver_addr = SD_REG_VER;
++ }
++
++ if (!iwl_trans_grab_nic_access(iwl_trans)) {
++ IWL_ERR(iwl_trans, "Failed to grab nic access before reading crf id\n");
++ ret = -EIO;
++ goto out;
++ }
++
++ /* Enable access to peripheral registers */
++ val = iwl_read_umac_prph_no_grab(iwl_trans, wfpm_ctrl_addr);
++ val |= ENABLE_WFPM;
++ iwl_write_umac_prph_no_grab(iwl_trans, wfpm_ctrl_addr, val);
++
++ /* Read crf info */
++ val = iwl_read_prph_no_grab(iwl_trans, sd_reg_ver_addr);
++
++ /* Read cdb info (also contains the jacket info if needed in the future */
++ cdb = iwl_read_umac_prph_no_grab(iwl_trans, wfpm_otp_cfg_addr);
++
++ /* Map between crf id to rf id */
++ switch (REG_CRF_ID_TYPE(val)) {
++ case REG_CRF_ID_TYPE_JF_1:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_JF1 << 12);
++ break;
++ case REG_CRF_ID_TYPE_JF_2:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_JF2 << 12);
++ break;
++ case REG_CRF_ID_TYPE_HR_NONE_CDB:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR1 << 12);
++ break;
++ case REG_CRF_ID_TYPE_HR_CDB:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR2 << 12);
++ break;
++ case REG_CRF_ID_TYPE_GF:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_GF << 12);
++ break;
++ case REG_CRF_ID_TYPE_MR:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_MR << 12);
++ break;
++ case REG_CRF_ID_TYPE_FM:
++ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_FM << 12);
++ break;
++ default:
++ ret = -EIO;
++ IWL_ERR(iwl_trans,
++ "Can find a correct rfid for crf id 0x%x\n",
++ REG_CRF_ID_TYPE(val));
++ goto out_release;
++
++ }
++
++ /* Set CDB capabilities */
++ if (cdb & BIT(4)) {
++ iwl_trans->hw_rf_id += BIT(28);
++ IWL_INFO(iwl_trans, "Adding cdb to rf id\n");
++ }
++
++ IWL_INFO(iwl_trans, "Detected RF 0x%x from crf id 0x%x\n",
++ iwl_trans->hw_rf_id, REG_CRF_ID_TYPE(val));
++
++out_release:
++ iwl_trans_release_nic_access(iwl_trans);
++
++out:
++ return ret;
++}
++
+ /* PCI registers */
+ #define PCI_CFG_RETRY_TIMEOUT 0x041
+
++static const struct iwl_dev_info *
++iwl_pci_find_dev_info(u16 device, u16 subsystem_device,
++ u16 mac_type, u8 mac_step,
++ u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores)
++{
++ int i;
++
++ for (i = ARRAY_SIZE(iwl_dev_info_table) - 1; i >= 0; i--) {
++ const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i];
++
++ if (dev_info->device != (u16)IWL_CFG_ANY &&
++ dev_info->device != device)
++ continue;
++
++ if (dev_info->subdevice != (u16)IWL_CFG_ANY &&
++ dev_info->subdevice != subsystem_device)
++ continue;
++
++ if (dev_info->mac_type != (u16)IWL_CFG_ANY &&
++ dev_info->mac_type != mac_type)
++ continue;
++
++ if (dev_info->mac_step != (u8)IWL_CFG_ANY &&
++ dev_info->mac_step != mac_step)
++ continue;
++
++ if (dev_info->rf_type != (u16)IWL_CFG_ANY &&
++ dev_info->rf_type != rf_type)
++ continue;
++
++ if (dev_info->cdb != (u8)IWL_CFG_ANY &&
++ dev_info->cdb != cdb)
++ continue;
++
++ if (dev_info->rf_id != (u8)IWL_CFG_ANY &&
++ dev_info->rf_id != rf_id)
++ continue;
++
++ if (dev_info->no_160 != (u8)IWL_CFG_ANY &&
++ dev_info->no_160 != no_160)
++ continue;
++
++ if (dev_info->cores != (u8)IWL_CFG_ANY &&
++ dev_info->cores != cores)
++ continue;
++
++ return dev_info;
++ }
++
++ return NULL;
++}
++
+ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ const struct iwl_cfg_trans_params *trans;
+ const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
++ const struct iwl_dev_info *dev_info;
+ struct iwl_trans *iwl_trans;
+ struct iwl_trans_pcie *trans_pcie;
+- int i, ret;
++ int ret;
+ const struct iwl_cfg *cfg;
+
+ trans = (void *)(ent->driver_data & ~TRANS_CFG_MARKER);
+@@ -1222,37 +1415,48 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+
+ trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
+
++ /*
++ * Let's try to grab NIC access early here. Sometimes, NICs may
++ * fail to initialize, and if that happens it's better if we see
++ * issues early on (and can reprobe, per the logic inside), than
++ * first trying to load the firmware etc. and potentially only
++ * detecting any problems when the first interface is brought up.
++ */
++ ret = iwl_finish_nic_init(iwl_trans);
++ if (ret)
++ goto out_free_trans;
++ if (iwl_trans_grab_nic_access(iwl_trans)) {
++ /* all good */
++ iwl_trans_release_nic_access(iwl_trans);
++ } else {
++ ret = -EIO;
++ goto out_free_trans;
++ }
++
+ iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID);
+
+- for (i = 0; i < ARRAY_SIZE(iwl_dev_info_table); i++) {
+- const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i];
+- if ((dev_info->device == (u16)IWL_CFG_ANY ||
+- dev_info->device == pdev->device) &&
+- (dev_info->subdevice == (u16)IWL_CFG_ANY ||
+- dev_info->subdevice == pdev->subsystem_device) &&
+- (dev_info->mac_type == (u16)IWL_CFG_ANY ||
+- dev_info->mac_type ==
+- CSR_HW_REV_TYPE(iwl_trans->hw_rev)) &&
+- (dev_info->mac_step == (u8)IWL_CFG_ANY ||
+- dev_info->mac_step ==
+- CSR_HW_REV_STEP(iwl_trans->hw_rev)) &&
+- (dev_info->rf_type == (u16)IWL_CFG_ANY ||
+- dev_info->rf_type ==
+- CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id)) &&
+- (dev_info->cdb == IWL_CFG_NO_CDB ||
+- CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id)) &&
+- (dev_info->rf_id == (u8)IWL_CFG_ANY ||
+- dev_info->rf_id ==
+- IWL_SUBDEVICE_RF_ID(pdev->subsystem_device)) &&
+- (dev_info->no_160 == (u8)IWL_CFG_ANY ||
+- dev_info->no_160 ==
+- IWL_SUBDEVICE_NO_160(pdev->subsystem_device)) &&
+- (dev_info->cores == (u8)IWL_CFG_ANY ||
+- dev_info->cores ==
+- IWL_SUBDEVICE_CORES(pdev->subsystem_device))) {
+- iwl_trans->cfg = dev_info->cfg;
+- iwl_trans->name = dev_info->name;
+- }
++ /*
++ * The RF_ID is set to zero in blank OTP so read version to
++ * extract the RF_ID.
++ * This is relevant only for family 9000 and up.
++ */
++ if (iwl_trans->trans_cfg->rf_id &&
++ iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 &&
++ !CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans))
++ goto out_free_trans;
++
++ dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
++ CSR_HW_REV_TYPE(iwl_trans->hw_rev),
++ CSR_HW_REV_STEP(iwl_trans->hw_rev),
++ CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id),
++ CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id),
++ IWL_SUBDEVICE_RF_ID(pdev->subsystem_device),
++ IWL_SUBDEVICE_NO_160(pdev->subsystem_device),
++ IWL_SUBDEVICE_CORES(pdev->subsystem_device));
++
++ if (dev_info) {
++ iwl_trans->cfg = dev_info->cfg;
++ iwl_trans->name = dev_info->name;
+ }
+
+ #if IS_ENABLED(CONFIG_IWLMVM)
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+index 8e45eb38304b..14602d6d6699 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+@@ -2149,6 +2149,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
+ u32 inta_fh_msk = ~MSIX_FH_INT_CAUSES_DATA_QUEUE;
+ u32 inta_fh, inta_hw;
+ bool polling = false;
++ bool sw_err;
+
+ if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX)
+ inta_fh_msk |= MSIX_FH_INT_CAUSES_Q0;
+@@ -2221,9 +2222,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
+ wake_up(&trans_pcie->ucode_write_waitq);
+ }
+
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ;
++ else
++ sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR;
++
+ /* Error detected by uCode */
+- if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) ||
+- (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR)) {
++ if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) || sw_err) {
+ IWL_ERR(trans,
+ "Microcode SW error detected. Restarting 0x%X.\n",
+ inta_fh);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+index bf0c32a74ca4..645cb4dd4e5a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+@@ -47,7 +47,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
+
+ iwl_pcie_apm_config(trans);
+
+- ret = iwl_finish_nic_init(trans, trans->trans_cfg);
++ ret = iwl_finish_nic_init(trans);
+ if (ret)
+ return ret;
+
+@@ -131,21 +131,9 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
+ if (trans_pcie->is_down)
+ return;
+
+- if (trans->state >= IWL_TRANS_FW_STARTED) {
+- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+- iwl_set_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_REQ);
+- iwl_poll_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
+- CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
+- 5000);
+- msleep(100);
+- iwl_set_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_SW_RESET);
+- } else if (trans_pcie->fw_reset_handshake) {
++ if (trans->state >= IWL_TRANS_FW_STARTED)
++ if (trans_pcie->fw_reset_handshake)
+ iwl_trans_pcie_fw_reset_handshake(trans);
+- }
+- }
+
+ trans_pcie->is_down = true;
+
+@@ -175,18 +163,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
+ else
+ iwl_pcie_ctxt_info_free(trans);
+
+- /* Make sure (redundant) we've released our request to stay awake */
+- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
+- iwl_clear_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ);
+- else
+- iwl_clear_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+-
+- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+- iwl_set_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_SW_RESET);
+- }
+ /* Stop the device, and put it in low power state */
+ iwl_pcie_gen2_apm_stop(trans, false);
+
+@@ -466,13 +442,15 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
+
+ iwl_pcie_set_ltr(trans);
+
+- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
++ iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE);
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_ROM_START);
+- else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
++ } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+ iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
+- else
++ } else {
+ iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
++ }
+
+ /* re-check RF-Kill state since we may have missed the interrupt */
+ hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index f252680f18e8..1efb53f78a62 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -129,7 +129,12 @@ void iwl_trans_pcie_dump_regs(struct iwl_trans *trans)
+ static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
+ {
+ /* Reset entire device - do controller reset (results in SHRD_HW_RST) */
+- iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ iwl_set_bit(trans, CSR_GP_CNTRL,
++ CSR_GP_CNTRL_REG_FLAG_SW_RESET);
++ else
++ iwl_set_bit(trans, CSR_RESET,
++ CSR_RESET_REG_FLAG_SW_RESET);
+ usleep_range(5000, 6000);
+ }
+
+@@ -306,7 +311,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
+ if (trans->trans_cfg->base_params->pll_cfg)
+ iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+
+- ret = iwl_finish_nic_init(trans, trans->trans_cfg);
++ ret = iwl_finish_nic_init(trans);
+ if (ret)
+ return ret;
+
+@@ -378,7 +383,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
+
+ iwl_trans_pcie_sw_reset(trans);
+
+- ret = iwl_finish_nic_init(trans, trans->trans_cfg);
++ ret = iwl_finish_nic_init(trans);
+ if (WARN_ON(ret)) {
+ /* Release XTAL ON request */
+ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
+@@ -458,6 +463,7 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
+ CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
+ CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS,
+ 100);
++ msleep(100);
+ } else {
+ iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+
+@@ -1056,7 +1062,7 @@ struct iwl_causes_list {
+ u8 addr;
+ };
+
+-static struct iwl_causes_list causes_list[] = {
++static const struct iwl_causes_list causes_list_common[] = {
+ {MSIX_FH_INT_CAUSES_D2S_CH0_NUM, CSR_MSIX_FH_INT_MASK_AD, 0},
+ {MSIX_FH_INT_CAUSES_D2S_CH1_NUM, CSR_MSIX_FH_INT_MASK_AD, 0x1},
+ {MSIX_FH_INT_CAUSES_S2D, CSR_MSIX_FH_INT_MASK_AD, 0x3},
+@@ -1067,25 +1073,26 @@ static struct iwl_causes_list causes_list[] = {
+ {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16},
+ {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17},
+ {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18},
+- {MSIX_HW_INT_CAUSES_REG_SW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x29},
+ {MSIX_HW_INT_CAUSES_REG_SCD, CSR_MSIX_HW_INT_MASK_AD, 0x2A},
+ {MSIX_HW_INT_CAUSES_REG_FH_TX, CSR_MSIX_HW_INT_MASK_AD, 0x2B},
+ {MSIX_HW_INT_CAUSES_REG_HW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x2D},
+ {MSIX_HW_INT_CAUSES_REG_HAP, CSR_MSIX_HW_INT_MASK_AD, 0x2E},
+ };
+
+-static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
+-{
+- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+- int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE;
+- int i, arr_size = ARRAY_SIZE(causes_list);
+- struct iwl_causes_list *causes = causes_list;
++static const struct iwl_causes_list causes_list_pre_bz[] = {
++ {MSIX_HW_INT_CAUSES_REG_SW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x29},
++};
++
++static const struct iwl_causes_list causes_list_bz[] = {
++ {MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ, CSR_MSIX_HW_INT_MASK_AD, 0x29},
++};
++
++static void iwl_pcie_map_list(struct iwl_trans *trans,
++ const struct iwl_causes_list *causes,
++ int arr_size, int val)
++{
++ int i;
+
+- /*
+- * Access all non RX causes and map them to the default irq.
+- * In case we are missing at least one interrupt vector,
+- * the first interrupt vector will serve non-RX and FBQ causes.
+- */
+ for (i = 0; i < arr_size; i++) {
+ iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val);
+ iwl_clear_bit(trans, causes[i].mask_reg,
+@@ -1093,6 +1100,25 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
+ }
+ }
+
++static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
++{
++ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
++ int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE;
++ /*
++ * Access all non RX causes and map them to the default irq.
++ * In case we are missing at least one interrupt vector,
++ * the first interrupt vector will serve non-RX and FBQ causes.
++ */
++ iwl_pcie_map_list(trans, causes_list_common,
++ ARRAY_SIZE(causes_list_common), val);
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ iwl_pcie_map_list(trans, causes_list_bz,
++ ARRAY_SIZE(causes_list_bz), val);
++ else
++ iwl_pcie_map_list(trans, causes_list_pre_bz,
++ ARRAY_SIZE(causes_list_pre_bz), val);
++}
++
+ static void iwl_pcie_map_rx_causes(struct iwl_trans *trans)
+ {
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+@@ -1208,8 +1234,12 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
+ }
+
+ /* Make sure (redundant) we've released our request to stay awake */
+- iwl_clear_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ iwl_clear_bit(trans, CSR_GP_CNTRL,
++ CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ);
++ else
++ iwl_clear_bit(trans, CSR_GP_CNTRL,
++ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+ /* Stop the device, and put it in low power state */
+ iwl_pcie_apm_stop(trans, false);
+@@ -1501,7 +1531,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+- ret = iwl_finish_nic_init(trans, trans->trans_cfg);
++ ret = iwl_finish_nic_init(trans);
+ if (ret)
+ return ret;
+
+@@ -1734,7 +1764,7 @@ static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans)
+ {
+ int ret;
+
+- ret = iwl_finish_nic_init(trans, trans->trans_cfg);
++ ret = iwl_finish_nic_init(trans);
+ if (ret < 0)
+ return ret;
+
+@@ -2140,9 +2170,12 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
+
+ if (trans_pcie->cmd_hold_nic_awake)
+ goto out;
+-
+- __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
+- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
++ CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ);
++ else
++ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
++ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ /*
+ * Above we read the CSR_GP_CNTRL register, which will flush
+ * any previous writes, but we need the write that clears the
+@@ -3203,9 +3236,11 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len)
+ return 0;
+ }
+
+-static struct iwl_trans_dump_data
+-*iwl_trans_pcie_dump_data(struct iwl_trans *trans,
+- u32 dump_mask)
++static struct iwl_trans_dump_data *
++iwl_trans_pcie_dump_data(struct iwl_trans *trans,
++ u32 dump_mask,
++ const struct iwl_dump_sanitize_ops *sanitize_ops,
++ void *sanitize_ctx)
+ {
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ struct iwl_fw_error_dump_data *data;
+@@ -3305,6 +3340,10 @@ static struct iwl_trans_dump_data
+ txcmd->caplen = cpu_to_le32(caplen);
+ memcpy(txcmd->data, cmdq->entries[idx].cmd,
+ caplen);
++ if (sanitize_ops && sanitize_ops->frob_hcmd)
++ sanitize_ops->frob_hcmd(sanitize_ctx,
++ txcmd->data,
++ caplen);
+ txcmd = (void *)((u8 *)txcmd->data + caplen);
+ }
+
+@@ -3365,7 +3404,10 @@ static void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
+
+ if (trans_pcie->msix_enabled) {
+ inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
+- sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++ sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ;
++ else
++ sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
+ } else {
+ inta_addr = CSR_INT;
+ sw_err_bit = CSR_INT_BIT_SW_ERR;
+--
+2.33.1
+