diff options
-rw-r--r-- | .SRCINFO | 2 | ||||
-rw-r--r-- | PKGBUILD | 4 | ||||
-rw-r--r-- | iwlwifi-next-patches-through-2020-11-08-5.15.3.patch | 8714 |
3 files changed, 8720 insertions, 0 deletions
@@ -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 @@ -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, >kdata); + + 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 + |