summaryrefslogtreecommitdiff
path: root/net/wifi-firmware-iwlwifi-kmod/files/extract-fw-list.sh
diff options
context:
space:
mode:
Diffstat (limited to 'net/wifi-firmware-iwlwifi-kmod/files/extract-fw-list.sh')
-rw-r--r--net/wifi-firmware-iwlwifi-kmod/files/extract-fw-list.sh219
1 files changed, 219 insertions, 0 deletions
diff --git a/net/wifi-firmware-iwlwifi-kmod/files/extract-fw-list.sh b/net/wifi-firmware-iwlwifi-kmod/files/extract-fw-list.sh
new file mode 100644
index 000000000000..d7c6b5e390f1
--- /dev/null
+++ b/net/wifi-firmware-iwlwifi-kmod/files/extract-fw-list.sh
@@ -0,0 +1,219 @@
+#!/bin/sh
+#
+# Copyright (c) 2025 The FreeBSD Foundation
+#
+# This software was developed by Björn Zeeb
+# under sponsorship from the FreeBSD Foundation.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Generate the firmware flavors and files from the WHENCE file in
+# linux-firmware.git based on the "MAC" names.
+# It is no longer feasible to generate them from the driver as the
+# firmware names are fully dynamic and require at least a register
+# read on each card. The combinations likely go into the hundreds
+# or thousands.
+# We still check for the firmware file with the highest API version
+# available based on each file name and sort out all the others.
+# We also have to sort out the DVM drier parts which we are not
+# interested in.
+#
+
+FWDIR=${1:-/nonexistent}
+
+if test ! -d ${FWDIR} -o ! -r ${FWDIR}/WHENCE; then
+ printf "Cannot find '%s' or '%s/WHENCE'\n" ${FWDIR} ${FWDIR} >&2
+ printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2
+ exit
+fi
+
+sed -e "s@%%XXX%%@iwlwifi -.*@g" ../wifi-firmware-kmod/files/WHENCE.awk.in > WHENCE.awk
+awk -f WHENCE.awk ${FWDIR}/WHENCE > WHENCE
+awk -v FWDIR=${FWDIR} '
+function file_exists(fname)
+{
+ xname=FWDIR "/intel/iwlwifi/" fname;
+
+ #printf("DEBUG: checking for file %s\n", xname);
+
+ if ((getline _ < xname) >= 0) {
+ return 1;
+ }
+}
+
+function known_in_2arr(arr, idx1, idx2)
+{
+ for (both in arr) {
+ split(both, sep, SUBSEP);
+ if (sep[1] == idx1 && sep[2] == idx2) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+function is_dvm(name)
+{
+ if (name ~ /^iwlwifi-(3945|4965|5000|5150|1000|6000|6050|6000g2a|6000g2b|135|100|105|2030|2000)-/) {
+ return 1;
+ }
+ return 0;
+}
+
+function get_flavor(name)
+{
+ # All the WiFi7+ stuff we will have a really hard time to tear apart (MAC, RF).
+ if (name ~ /^dr-/ && name ~ /-(fm|wh|pe)-/) {
+ return "dr";
+ }
+ if (name ~ /^sc-/ && name ~ /-(fm|wh|pe)-/) {
+ return "sc";
+ }
+ if (name ~ /^(gl|bz)-/ && name ~ /-(fm|wh|pe)-/) {
+ return "bz";
+ }
+ # mvm/(gl|bz)? (WiFi-7?)
+ if (name ~ /^(gl|bz)-/ && name ~ /-(gf|jf|hr)-/) {
+ return "bz";
+ }
+ if (name ~ /^(ma|so|ty)-/) {
+ return "ax210";
+ }
+ if (name ~ /^(QuZ|Qu|cc)-/) {
+ return "22000";
+ }
+ if (name ~ /^(9000|9260)/) {
+ return "9000";
+ }
+ if (name ~ /^(8000C|8265)/) {
+ return "8000";
+ }
+ if (name ~ /^(3160|3168|7260|7265|7265D)/) {
+ return "7000";
+ }
+
+ return "";
+}
+
+BEGIN {
+ if (!FWDIR) {
+ printf "USAGE: -v FWDIR=/path/to/linux-firmware.git\n"
+ exit
+ }
+
+ flavors[1] = "7000";
+ flavors[2] = "8000";
+ flavors[3] = "9000";
+ flavors[4] = "22000";
+ flavors[5] = "ax210";
+ flavors[6] = "bz"; # mld starts here
+ flavors[7] = "sc";
+ flavors[8] = "dr";
+}
+{
+ if (! /^File:/) {
+ next;
+ }
+
+ gsub("^File: intel/iwlwifi/", "");
+
+ if (!/\.ucode$/ && !/\.pnvm$/) {
+ print "ERROR :: " $0
+ exit
+ }
+
+ name=$0
+ if (is_dvm(name)) {
+ #print "DEBUG :: skipping DVM firmware file :: " $0;
+ next;
+ }
+ if (!file_exists(name)) {
+ print "DEBUG :: file does not exist :: " $0;
+ next;
+ }
+
+ ispnvm=0
+ if (/\.pnvm$/) {
+ ispnvm=1
+ }
+
+ gsub("^iwlwifi-", "", name);
+ gsub("\.ucode$", "", name);
+ gsub("\.pnvm$", "", name);
+
+ flav=get_flavor(name);
+ ver=name;
+ gsub("-[[:digit:]]*$", "", name);
+ gsub("^.*-", "", ver);
+
+ # Assoc.Arrays are great but we lose the order which we want for the FLAVORs.
+ x1=known_in_2arr(fwver, flav, name);
+ x2=known_in_2arr(fwpnvm, flav, name);
+ if (x1 || x2) {
+ #printf("DEBUG: %s SKIPPING %s/%s, already known in %d,%d\n", $0, flav, name, x1, x2);
+ } else {
+ fwn[flav]++;
+ fwname[flav,fwn[flav]] = name;
+ #printf("DEBUG: %s ADDING %s/%s, already known in %d,%d\n", $0, flav, name, x1, x2);
+ }
+ if (ispnvm) {
+ fwpnvm[flav,name] = 1;
+ } else {
+ if ((fwver[flav,name] + 0) < (ver + 0)) {
+ fwver[flav,name] = ver;
+ } else {
+ printf("DEBUG: skipping %s: %s < %s\n", $0, fwver[flav,name], ver);
+ }
+ }
+}
+END {
+ printf("FWSUBS=");
+ for (f = 1; f <= length(flavors); f++) {
+ if (fwn[flavors[f]] > 0) {
+ printf(" \\\n\t%s", flavors[f]);
+ }
+ }
+ printf("\n\n");
+
+ # Deal with all the firmware flavors:
+ for (f = 1; f <= length(flavors); f++) {
+ flav=flavors[f];
+ if (fwn[flav] > 0) {
+ if (f > 1) {
+ printf("\n");
+ }
+ printf("DISTFILES_%s+=", flav);
+ }
+ # Sort
+ for (i = 1; i < fwn[flav]; i++) {
+ for (j = i + 1; j <= fwn[flav]; j++) {
+ if (fwname[flav,i] > fwname[flav,j]) {
+ t=fwname[flav,i]
+ fwname[flav,i]=fwname[flav,j]
+ fwname[flav,j]=t
+ }
+ }
+ }
+ # Print
+ for (i = 1; i <= fwn[flav]; i++) {
+ if (fwpnvm[flav,fwname[flav,i]]) {
+ printf(" \\\n\t\${FWSUBDIR}/iwlwifi-%s.pnvm\${DISTURL_SUFFIX}", fwname[flav,i]);
+ }
+ printf(" \\\n\t\${FWSUBDIR}/iwlwifi-%s-%s.ucode\${DISTURL_SUFFIX}", fwname[flav,i], fwver[flav,fwname[flav,i]]);
+ }
+ }
+ printf("\n");
+
+ printf("\n");
+ printf("DISTFILES_\${FWDRV}=");
+ for (f = 1; f <= length(flavors); f++) {
+ if (fwn[flavors[f]] > 0) {
+ printf(" \\\n\t\${DISTFILES_%s}", flavors[f]);
+ }
+ }
+ printf("\n");
+}' WHENCE
+
+rm -f WHENCE.awk WHENCE
+
+# end