aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh416
1 files changed, 71 insertions, 345 deletions
diff --git a/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh b/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh
index afbd52b9fa40..c817aff071bf 100644
--- a/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh
+++ b/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh
@@ -2,376 +2,102 @@
#-
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2024-2025 The FreeBSD Foundation
+# Copyright (c) 2024-2026 The FreeBSD Foundation
#
# This software was developed by Björn Zeeb
# under sponsorship from the FreeBSD Foundation.
#
# This is neither efficient nor elegant but we need it few times
-# a year and it does the job.
-#
-#
-# USAGE: please check out the correct tag/hash for ports in the
-# linux-firmware.git repository you point this script to.
-#
-# USAGE: please make sure to pre-load if_iwlwifi.ko so that we
-# have access to the sysctl. You do not need to have a supported
-# card in the system.
-# In case that is not possible you can save the results to a file
-# and provide that locally. It will be renamed at the end of the
-# run.
+# a year and it does the job. And it turns out there is a lot of
+# churn so keep the solutions quick and dirty.
#
set -e
-# sysctl -n compat.linuxkpi.iwlwifi_pci_ids_name > iwlwifi_pci_ids_name.txt
-PCI_IDS_FILE=iwlwifi_pci_ids_name.txt
-D_PCI_IDS_FILE=`pwd`/${PCI_IDS_FILE}
-
-################################################################################
-#
-# Check pre-reqs
-#
-if [ $# -ne 1 ]; then
- printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2
- exit 1
-fi
-
-if [ ! -d cfg/ -o ! -e cfg/bz.c ]; then
- printf "ERROR: run from iwlwifi driver directory; no cfg/bz.c here\n" >&2
- exit 1
-fi
-
-LFWDIR=${1}
-if test ! -d ${LFWDIR} -o ! -e ${LFWDIR}/WHENCE; then
- printf "ERROR: cannot find linux-firmware.git at '%s'\n" ${LFWDIR} >&2
- exit 1
-fi
-
-if test -r ${D_PCI_IDS_FILE}; then
- printf "NOTICE: using proovided ${D_PCI_IDS_FILE}\n" >&2
-else
-
- kldstat -n if_iwlwifi.ko > /dev/null 2>&1
- rc=$?
- case ${rc} in
- 0) ;;
- *) printf "ERROR: please pre-load if_iwlwifi.ko (you do not need a device)\n" >&2
- exit 1
- ;;
- esac
-
- sysctl -N compat.linuxkpi.iwlwifi_pci_ids_name > /dev/null 2>&1
- rc=$?
- case ${rc} in
- 0) sysctl -n compat.linuxkpi.iwlwifi_pci_ids_name > ${D_PCI_IDS_FILE}
- ;;
- *) printf "ERROR: cannot get compat.linuxkpi.iwlwifi_pci_ids_name\n" >&2
- exit 1
- ;;
- esac
-fi
-
-# We need to be in the config directory for simplicity.
-cd cfg
-
-################################################################################
-
-# Get a list of all device/firmware flavors as seen/supported by the driver.
-flavors=$(awk -F\\t '{
- if (/^$/) { next; }
- if ($5 == "undefined") { next; }
- print tolower($5);
-}' ${D_PCI_IDS_FILE} | sort -V | uniq)
-
-################################################################################
-#
-# Helper functions.
-#
-
-#
-# This uses a hack (cpp) to expand some macros for us and parses out the result
-# which is the firmware name with the maximum FW version supported for that
-# firmware.
-# We then go and check that said firmware actually exists in linux-firmware.git.
-# We try to find a lower version number if the "MAX" version given from the cpp
-# output does not (yet) publicly exist.
-# .pnvm files are now properly listed as MODULE_FIRMWARE so no more magic needed
-# for them.
-# Given the filename matches a "flavor" at this point, we then group all the
-# available firmware files from this flavor together and print it as a ports
-# Makefile variable.
-#
-# We also print some other meta-data that callers will filter out depending on
-# their needs to generate other lists and mappings.
-#
-
-# For each get a list of firmware names we know.
-list_fw()
-{
- for f in ${flavors}; do
- #echo "==> ${f}"
- #awk -F \\t -v flav=${f} '{
- # if ($5 != flav) { next; }
- # # No firmwre; skip.
- # if ($3 ~ /^$/) { next; }
- # if ($3 == "(null)") { next; };
- # print $3;
- #}' ${D_PCI_IDS_FILE} | sort | uniq
-
- # For now the flavor names and the file names are 1:1 which makes this
- # a lot easier (given some sysctl/file entries are not able to list
- # their firmware but we know their "flavor".
- l=$(cpp ${f}.c 2>&1 | awk '
- /^MODULE_FIRMWARE\(/ {
- gsub(/"/, "");
- gsub("__stringify\\(", "");
- gsub("\\);$", "");
- gsub("\\)", "");
- gsub("^MODULE_FIRMWARE\\(", "");
- gsub(" ", "");
- printf "%s\n", $0;
- }' | sort -V | uniq)
- #echo "${l}"
-
- lx=""
- for fx in ${l}; do
- if test -e ${LFWDIR}/${fx}; then
- lx="${lx} ${fx}"
-
- # Check for matching .pnvm file.
- # They are now properly listed in MODULE_FIRMWARE() as well so no more magic.
- #px=$(echo ${fx} | awk '{ gsub("-[[:digit:]]*.ucode", ".pnvm"); print; }')
- #if test -e ${LFWDIR}/${px}; then
- # lx="${lx} ${px}"
- #fi
- else
- case "${fx}" in
- *.pnvm)
- printf "NOTICE: pnvm file not found for '%s'\n" ${fx} >&2
- ;;
- *.ucode)
- # Try lowering the version number.
- bn=$(echo ${fx} | awk '{ gsub("-[[:digit:]]*.ucode", ""); print; }')
- vn=$(echo ${fx} | awk '{ gsub(".ucode$", ""); gsub("^.*-", ""); print; }')
- #echo "BN ${bn} VN ${vn}"
- # Single digits are not zero-padded so just ${i} will be fine.
- for i in `jot ${vn} ${vn} 1`; do
- xn="${bn}-${i}.ucode"
- if test -e ${LFWDIR}/${xn}; then
- lx="${lx} ${xn}"
- break
- fi
- done
- ;;
- *)
- printf "NOTICE: file for unknown firmware type not found for '%s'\n" ${fx} >&2
- ;;
- esac
- fi
- done
+unsortedf=$(mktemp -p /tmp iwlwifi-fwget-unsorted.XXXXXX)
+sortedf=$(mktemp -p /tmp iwlwifi-fwget-sorted.XXXXXX)
+:> ${unsortedf}
+:> ${sortedf}
- # Get a count so we can automatically add \\ apart from the last line.
- fn=$(echo "${lx}" | wc -w | awk '{ print $1 }')
-
- #echo "==> ${f} :: ${fn} :: ${lx}"
-
- if test ${fn} -gt 0; then
-
- # Ports FLAVOR names are [a-z0-9_]. If needed add more mangling magic here.
- flav=`echo ${f} | awk '{ printf "%s", tolower($0); }'`
-
- echo "FWS ${flav}"
- echo "DISTFILES_${flav}= \\"
- for fz in ${lx}; do echo "${fz}"; done | \
- awk -v fn=$fn -v fwg=${flav} '{
- if (FNR == fn) { x="" } else { x=" \\" };
- printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x;
- fwn=$0;
- gsub("-[[:digit:]]*\.ucode$", "", fwn);
- printf "FWGET %s %s\n", fwg, fwn;
- }'
- fi
-
- done
+cpp -DCONFIG_IWLMVM -DCONFIG_IWLMLD \
+ -I../../../compat/linuxkpi/common/include pcie/drv.c 2> /dev/null | \
+grep __builtin_choose_expr | \
+awk 'BEGIN {
+ lt=""
}
-
-################################################################################
-#
-# Generate the PORTS file template.
-#
-
-fwsl=$(list_fw | grep ^FWS | awk '{ print $2 }')
-# Get a count so we can automatically add \\ apart from the last line.
-fn=$(echo "${fwsl}" | wc -w | awk '{ print $1 }')
-
-if test ${fn} -gt 0; then
-
- portsfile=$(mktemp -p /tmp iwlwifi-fwport.XXXXXX)
-
- :> ${portsfile}
- (
- echo "FWSUBS= \\"
- for sz in ${fwsl}; do echo "${sz}"; done | \
- awk -v fn=$fn '{ if (FNR == fn) { x="" } else { x=" \\" }; printf "\t%s%s\n", $0, x; }'
-
- echo
- echo "# Do not prefix with empty \${FWSUBDIR}/!"
- list_fw | grep -v ^FWS | grep -v ^FWGET
-
- echo
- echo "DISTFILES_\${FWDRV}= \\"
- for sz in ${fwsl}; do echo "${sz}"; done | \
- awk -v fn=$fn '{ if (FNR == fn) { x="" } else { x=" \\" }; printf "\t${DISTFILES_%s}%s\n", $0, x; }'
- echo "DISTFILES_\${FWDRV}_lic="
- ) >> ${portsfile}
-
- printf "INFO: wifi-firmware-iwlwifi-kmod template at %s\n" ${portsfile} >&2
-fi
-
-################################################################################
-#
-# Generate a temporary firmware -> flavor mapping table for fwget generation.
-#
-
-mapfile=$(mktemp -p /tmp iwlwifi-mapfile.XXXXXX)
-:> ${mapfile}
-
-fwgl=$(list_fw | grep FWGET)
-# Get a count so we can automatically add \\ apart from the last line.
-fn=$(echo "${fwgl}" | wc -w | awk '{ print $1 }')
-if test ${fn} -gt 0; then
-
- (
- list_fw | grep FWGET | grep -v '.pnvm' | \
- while read x flav fw; do
- printf "%s\t%s\n" ${fw} ${flav}
- done | \
- sort -n | uniq
- ) >> ${mapfile}
-fi
-
-################################################################################
-#
-# Try to generate the PCI ID -> port flavor mapping
-#
-# We get PCI ID, description, firmware base from the sysctl and can work our
-# way back from fw name base to flavor via the mapping table file.
-#
-
-fwgetfile=$(mktemp -p /tmp iwlwifi-fwget.XXXXXX)
-:> ${fwgetfile}
-
-awk 'BEGIN { FS="\t"; }
{
- # Skip empty lines.
- if (/^$/) { next; }
- # Skip "undefined" flavors as we have no idea what chipset.
- if ($5 == "undefined") { next; }
-
- # No firmware name; do not skip!
- # All we need is the flavor, which we now always have.
- #if ($3 == "(null)") { next; };
+ if (!/.vendor = 0x8086,/) {
+ printf "ERROR: %s\n", $0;
+ exit
+ }
- FLAV=tolower($5);
+ d=$6;
+ sv=$9;
+ sd=$12;
+ t=$15;
- split($1, i, "/");
- gsub("\t.*$", "", i[4]);
- # Not an Intel Vednor ID; skip.
- if (i[1] != "0x8086") { next; };
+ gsub("\\(", "", d);
+ gsub(")", "", d);
+ gsub(",", "", d);
- # No defined device ID; skip.
- if (i[2] == "0xffff") { next; };
+ gsub("\\(", "", sv);
+ gsub(")", "", sv);
+ gsub(",", "", sv);
- # Adjust wildcards or a ill-printed 0.
- if (i[3] == "0xffffffff") { i[3] = "*"; };
- if (i[4] == "000000") { i[4] = "0x0000"; };
- if (i[4] == "0xffffffff") { i[4] = "*"; };
- if (i[4] == "0xffff") { i[4] = "*"; };
+ gsub("\\(", "", sd);
+ gsub(")", "", sd);
+ gsub(",", "", sd);
- printf "%s\t%s/%s/%s\n", FLAV, i[2], i[3], i[4];
-}' ${D_PCI_IDS_FILE} | \
-sort -V | uniq | \
-while read flav match; do
+ gsub("-1U", "*", d);
+ gsub("-1U", "*", sv);
+ gsub("-1U", "*", sd);
- #flav=$(awk -v fw=$fw '{ if ($1 == fw) { print $2; } }' ${mapfile})
- #echo "${fw} :: ${match} :: ${flav}"
+ gsub("^.*\\(", "", t);
+ gsub(")", "", t);
+ gsub(",", "", t);
+ gsub("^iwl_", "", t);
+ gsub("^iwl", "", t);
+ gsub("_mac_cfg$", "", t);
+ gsub("_.*$", "", t);
- if test "${flav}" != ""; then
- printf "${flav}\t${match}\t${flav}\n"
- else
- #echo "NO FLAV ${fw} ${match}" >&2
- fi
-
-done | \
-awk 'BEGIN { FS="\t"; FWN=""; }
-{
- FW=$1;
- if (FWN != FW) { printf "\n\t# %s\n", FW; FWN=FW; };
+ t=tolower(t)
+ if (t != lt) {
+ printf "\n\t# %s\n", t;
+ lt = t;
+ }
+ if (t == "9560") { t = "9000"; }
+ if (t == "ax200") { t = "22000"; }
+ if (t == "qu") { t = "22000"; }
+ if (t == "cc") { t = "22000"; }
+ if (t == "ma") { t = "ax210"; }
+ if (t == "so") { t = "ax210"; }
+ if (t == "ty") { t = "ax210"; }
+ if (t == "gl") { t = "bz"; }
+ if (t != "7000" && t != "8000" && t != "9000" && t != "22000" && t != "ax210" && t != "bz" && t != "sc") {
+ printf "ERROR: invalid flavor '%s': %s\n", t, $0;
+ exit
+ }
- printf "\t%s) addpkg \"wifi-firmware-iwlwifi-kmod-%s\"; return 1 ;;\n", $2, $3;
-} END {
- printf "\n";
-}' >> ${fwgetfile}
+ printf "\t%s/%s/%s) addpkg \"wifi-firmware-iwlwifi-kmod-%s\"; return 1 ;;\n", tolower(d), tolower(sv), tolower(sd), t;
-printf "INFO: fwget pci_network_intel template at %s\n" ${fwgetfile} >&2
+}' > ${unsortedf}
-################################################################################
-#
-# Try to build the iwlwififw.4 bits too.
-#
-
-dl=$(grep -v ^$ ${D_PCI_IDS_FILE} | uniq | \
-awk '
-{
- # Sourt out duplicate lines.
- if (dup[$0]++) { next; }
+( for f in \
+ 7000 \
+ 8000 \
+ 9000 \
+ 22000 \
+ ax210 \
+ bz \
+ sc ; do
- split($0, a, "\t");
- ids=a[1];
- name=a[2];
- fw=a[3];
- flavor=a[5];
+ printf "\n\t# %s\n" ${f}
+ grep "wifi-firmware-iwlwifi-kmod-${f}" ${unsortedf} | sort -n
- #my ($v, $d, $sv, $sd) = split("/", $ids);
- split(ids, i, "/");
- gsub("^0xffff+", "any", i[1]);
- gsub("^0xffff+", "any", i[2]);
- gsub("^0xffff+", "any", i[3]);
- gsub("^0xffff+", "any", i[4]);
+done; echo ) > ${sortedf}
- if (name == "") { name="(unknown)"; }
- if (fw == "") { fw="(unknown)"; }
- if (flavor == "") { flavor="iwlwifi"; }
- if (flavor == "undefined") { flavor="iwlwifi"; }
-
- # iwlwififw.4
- printf ".It \"\"\n.It %s\n.It %s Ta %s Ta %s Ta %s Ta %s Ta %s\n", name, i[1], i[2], i[3], i[4], flavor, fw;
-
- # wiki
- # XXX TODO possibly quote some in `` to avoid automatic linking?
- # || PCI IDs || Chipset Name || Firmware prefix || Comment ||
- printf "WIKI || %s / %s / %s / %s || %s || %s || ||\n", i[1], i[2], i[3], i[4], name, fw;
- if ((FNR % 25) == 0) { printf "WIKI \n"; }
-}')
-
-manfwfile=$(mktemp -p /tmp iwlwifi-iwlwififw4.XXXXXX)
-:> ${manfwfile}
-echo "${dl}" | grep -v ^WIKI >> ${manfwfile}
-printf "INFO: share/man/man4/iwlwififw.4 template at %s\n" ${manfwfile} >&2
-
-wikifile=$(mktemp -p /tmp iwlwifi-wiki.XXXXXX)
-:> ${wikifile}
-echo "${dl}" | awk '/^WIKI / { gsub("^WIKI ", ""); print; }' >> ${wikifile}
-printf "INFO: WIKI template at %s\n" ${wikifile} >&2
-
-
-################################################################################
-#
-# Cleanup
-#
-rm ${mapfile}
-mv -f ${D_PCI_IDS_FILE} ${D_PCI_IDS_FILE}.old
+rm -f ${unsortedf}
+printf "INFO: fwget(8) template at %s\n" ${sortedf} >&2
# end