Date: Thu, 31 Oct 2024 14:34:53 GMT From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 3ed00f392098 - stable/14 - LinuxKPI based WiFi drivers: scripts to extract fwget(8) and port details Message-ID: <202410311434.49VEYrnh005142@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=3ed00f392098a324f34ea5f25a3859d224f72c73 commit 3ed00f392098a324f34ea5f25a3859d224f72c73 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2024-04-28 20:50:12 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2024-10-31 14:33:56 +0000 LinuxKPI based WiFi drivers: scripts to extract fwget(8) and port details Add a "zzz_fw_ports_fwget.sh" script to each LinuxKPI based wireless driver which in essential are all the same and in detail all different. They extract information for fwget(8), wifi-firmware-* ports, man pages and for iwlwififw also for the wiki. Sponsored by: The FreeBSD Foundation Suggested by: imp (to have automation in D44918) (cherry picked from commit 96190b4fef3b4a0cc3ca0606b0c4e3e69a5e6717) --- sys/contrib/dev/athk/ath10k/zzz_fw_ports_fwget.sh | 286 ++++++++++++++++ sys/contrib/dev/athk/ath11k/zzz_fw_ports_fwget.sh | 317 +++++++++++++++++ sys/contrib/dev/athk/ath12k/zzz_fw_ports_fwget.sh | 310 +++++++++++++++++ sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh | 374 +++++++++++++++++++++ .../dev/mediatek/mt76/zzz_fw_ports_fwget.sh | 292 ++++++++++++++++ sys/contrib/dev/rtw88/zzz_fw_ports_fwget.sh | 145 ++++++++ sys/contrib/dev/rtw89/zzz_fw_ports_fwget.sh | 152 +++++++++ 7 files changed, 1876 insertions(+) diff --git a/sys/contrib/dev/athk/ath10k/zzz_fw_ports_fwget.sh b/sys/contrib/dev/athk/ath10k/zzz_fw_ports_fwget.sh new file mode 100644 index 000000000000..71a11a890a48 --- /dev/null +++ b/sys/contrib/dev/athk/ath10k/zzz_fw_ports_fwget.sh @@ -0,0 +1,286 @@ +#!/bin/sh +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 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. +# + +set -e + +DRIVER=ath10k +CHECKFILE=qmi_wlfw_v01.c + +################################################################################ +# +# Check pre-reqs +# +if [ $# -ne 1 ]; then + printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2 + exit 1 +fi + +if [ ! -e ${CHECKFILE} ]; then + printf "ERROR: run from %s driver directory; no %s.c here\n" ${DRIVER} ${CHECKFILE} >&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 + +################################################################################ +# +# Helper functions. +# +# This uses a hack (cpp) to expand some macros for us and parses out the result +# which is the PCI device ID or the firmware directory for that. +# Checking MODULE_FIRMWARE was pointless as it had too many "dead" entries: +# NOTICE: no firmware file found for 'ath10k/QCA6174/hw2.1/firmware-4.bin' +# NOTICE: no firmware file found for 'ath10k/QCA6174/hw3.0/firmware-5.bin' +# NOTICE: no firmware file found for 'ath10k/QCA9887/hw1.0/board-2.bin' +# NOTICE: no firmware file found for 'ath10k/QCA988X/hw2.0/board-2.bin' +# NOTICE: no firmware file found for 'ath10k/QCA988X/hw2.0/firmware-2.bin' +# NOTICE: no firmware file found for 'ath10k/QCA988X/hw2.0/firmware-3.bin' +# +list_fw() +{ + # List of already seen flavor (firmware directory). + sfwl="" + + # List of "supported" device IDs (ignoring Ubiquity). + devidl=$(cpp pci.c 2> /dev/null | awk '/PCI_VDEVICE\(ATHEROS,/ { gsub("^.*, \\(", ""); gsub("\\)\\) },$", ""); print tolower($0); }') + + # List of (device ID) -> (firware directory) mappings. + cpp core.c 2> /dev/null | egrep -E '\.(dev_id|dir) = ' | awk '{ if (/dev_id/) { printf "%s", $0; } else { print; } }' | grep -v 'dev_id = 0,' | sort | uniq | \ + awk '{ + gsub("^.*\\(", ""); + gsub("),.* = ", "\t"); + gsub(",$", ""); + gsub(/"/, ""); + gsub(" ", ""); + print; + }' | \ + while read did fwd; do + + x="" + for d in ${devidl}; do + if test "${did}" == "${d}"; then + x="${d}" + break + fi + done + if test "${x}" == ""; then + # Device ID not in the list of PCI IDs we support. + # At least the Ubiquity one we hit here. + #printf "Device ID %s (%s) not in PCI ID list; skipping\n" ${did} ${fwd} >&2 + continue + fi + + if test ! -d ${LFWDIR}/${fwd}; then + # Leave this on as it MUST not happen. + printf "Firmware dir %s (for %s) does not exist; skipping\n" ${fwd} ${did} >&2 + continue + fi + + flav=$(echo "${fwd}" | awk -v drv=${DRIVER} '{ + # Ports FLAVOR names are [a-z0-9_]. If needed add more mangling magic here. + gsub("^" drv "/", ""); + gsub("/", "_"); + gsub("\\.", ""); + print tolower($0); + }') + + # Print this first or otherwise if two device IDs have the same firmware + # we may not see that. + echo "FWGET ${did} ${flav}" + + x="" + for zf in ${sfwl}; do + if test "${zf}" == "${flav}"; then + x="${zf}" + break + fi + done + if test "${x}" != ""; then + #printf "Flavor %s (firmware directory %s) already seen; skipping\n" ${flav} ${fwd} >&2 + continue + fi + sfwl="${sfwl} ${flav}" + + #echo "==> ${did} -> ${fwd} -> ${flav}" + + lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a \! -name "*.txt" -print) + + # Get a count so we can automatically add \\ apart from the last line. + fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') + + #echo "==> ${flav} :: ${fn} :: ${lx}" >&2 + + if test ${fn} -gt 0; then + + echo "FWS ${flav}" + echo "DISTFILES_${flav}= \\" + for fz in ${lx}; do echo "${fz}"; done | \ + awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ + if (FNR == fn) { x="" } else { x=" \\" }; + gsub("^" drv "/", "${FWSUBDIR}/"); + printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; + }' + + # Check for "lic" files. + lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a -name "*.txt" -print) + + # Get a count so we can automatically add \\ apart from the last line. + fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') + + if test ${fn} -gt 0; then + echo "FWL ${flav}" + echo "DISTFILES_${flav}_lic= \\" + for fz in ${lx}; do echo "${fz}"; done | \ + awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ + if (FNR == fn) { x="" } else { x=" \\" }; + gsub("^" drv "/", "${FWSUBDIR}/"); + printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; + }' + fi + fi + done +} + +################################################################################ +# +# 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 ${DRIVER}-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 + list_fw | grep -v ^FWS | grep -v ^FWL | 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; + }' + + fwsl=$(list_fw | grep ^FWL | 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 + echo "DISTFILES_\${FWDRV}_lic= \\" + for sz in ${fwsl}; do echo "${sz}"; done | \ + awk -v fn=$fn '{ + if (FNR == fn) { x="" } else { x=" \\" }; + printf "\t${DISTFILES_%s_lic}%s\n", $0, x; + }' + else + echo "DISTFILES_\${FWDRV}_lic=" + fi + + ) >> ${portsfile} + + printf "INFO: wifi-firmware-%s-kmod template at %s\n" ${DRIVER} ${portsfile} >&2 +fi + +################################################################################ +# +# Generate the fwget(8) case pattern table (PCI device ID -> fw port flavor). +# + +fwgetfile=$(mktemp -p /tmp ${DRIVER}-fwget.XXXXXX) +:> ${fwgetfile} + +fwsl=$(list_fw | grep ^FWGET | sort) +# Get a count so we can automatically add \\ apart from the last line. +fn=$(echo "${fwsl}" | grep -c FWGET | awk '{ print $1 }') + +if test ${fn} -gt 0; then + + # We need to check for same ID with multiple firmware. + # The list ist sorted by ID so duplicates are next to each other. + cs=$(echo "${fwsl}" | awk '{ print $2 }' | uniq -c | awk '{ print $1 }') + + #echo "==> cs=${cs}" >&2 + + for n in ${cs}; do + + # Skip FWGET + fwsl=${fwsl#*[[:space:]]} + # get device ID + did=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + # get flavor + flav=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + + # printf "===> did %s flav %s\n" ${did} ${flav} >&2 + + if test ${n} -eq 1; then + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"; return 1 ;;\n", + tolower($1), drv, tolower($2); + }' >> ${fwgetfile} + else + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"\n", + tolower($1), drv, tolower($2); + }' >> ${fwgetfile} + + i=1 + while test ${i} -lt ${n}; do + # Skip FWGET + fwsl=${fwsl#*[[:space:]]} + # get device ID + did=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + # get flavor + flav=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + + #printf "===> did %s flav %s\n" ${did} ${flav} >&2 + + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t\taddpkg \"wifi-firmware-%s-kmod-%s\"\n", + drv, tolower($2); + }' >> ${fwgetfile} + + i=$((i + 1)) + done + + printf "\t\treturn 1 ;;\n" >> ${fwgetfile} + fi + done +fi + +printf "INFO: fwget pci_network_qca %s template at %s\n" ${DRIVER} ${fwgetfile} >&2 + +# end diff --git a/sys/contrib/dev/athk/ath11k/zzz_fw_ports_fwget.sh b/sys/contrib/dev/athk/ath11k/zzz_fw_ports_fwget.sh new file mode 100644 index 000000000000..9de14ed45442 --- /dev/null +++ b/sys/contrib/dev/athk/ath11k/zzz_fw_ports_fwget.sh @@ -0,0 +1,317 @@ +#!/bin/sh +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 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. +# + +set -e + +DRIVER=ath11k +CHECKFILE=debugfs_htt_stats.c + +################################################################################ +# +# Check pre-reqs +# +if [ $# -ne 1 ]; then + printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2 + exit 1 +fi + +if [ ! -e ${CHECKFILE} ]; then + printf "ERROR: run from %s driver directory; no %s.c here\n" ${DRIVER} ${CHECKFILE} >&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 +LFWDIR=${LFWDIR}/${DRIVER} + +################################################################################ +# +# Helper functions. +# +# This uses a hack (cpp) to expand some macros for us and parses out the result +# which is the PCI device ID or the firmware directory for that. +# +# Driver is there, the firmware not yet...? +# ==> 0x1101 -> ATH11K_HW_QCA6390_HW20 -> QCA6390/hw2.0 +# ==> 0x1104 -> ATH11K_HW_QCN9074_HW10 -> QCN9074/hw1.0 +# ==> 0x1103 -> ATH11K_HW_WCN6855_HW20 -> WCN6855/hw2.0 +# ==> 0x1103 -> ATH11K_HW_WCN6855_HW21 -> WCN6855/hw2.1 +# Firmware dir WCN6855/hw2.1 (for 0x1103) does not exist; skipping +# +list_fw() +{ + # List of already seen flavor (firmware directory). + sfwl="" + + # List of "supported" device IDs. + devidl=$(cpp pci.c 2> /dev/null | awk '/PCI_VDEVICE\(QCOM,/ { gsub("^.*, ", ""); gsub("\\) },$", ""); print tolower($0); }') + # Turn them into a regex. + didreg=$(echo "${devidl}" | xargs -J % echo -n % | sed -e 's, ,|,g') + # List the device ID cases along with their hw_rev which we can go and take to lookup fw. + hwrevs=$(cpp pci.c 2> /dev/null | egrep -E "(case (${didreg})|ab->hw_rev = )" | awk '{ + if (FNR > 1 && /case/) { + printf "\n"; + } + gsub("^.*case[[:space:]]*", ""); + gsub("[[:space:]]*ab->hw_rev = ", " "); + gsub("[:;]", ""); + printf "%s", $0; + }') + + # hwrevs is a list of (device IDs) -> (1..n hardware revisions) mappings. + #echo "==> ${devidl} :: ${didreg} :: ${hwrevs}" >&2 + + # List of (hardware revision) -> (firware directory) mappings. + l=$(cpp core.c 2> /dev/null | egrep -E '\.(hw_rev|dir) = ' | awk '{ if (/hw_rev/) { printf "%s", $0; } else { print; } }' | sort | uniq | \ + awk '{ + gsub("^.*hw_rev = ", ""); + gsub(",.* = ", "\t"); + gsub(",$", ""); + gsub(/"/, ""); + gsub(" ", ""); + gsub("\t", " "); + print; + }') + #echo "===> ${l}" >&2 + + ll=$(echo "${l}" | wc -w | awk '{ print $1 }') + while test "${ll}" -gt 1; do + hwr=${l%%[[:space:]]*} + l=${l#*[[:space:]]} + fwd=${l%%[[:space:]]*} + l=${l#*[[:space:]]} + + #echo "=+=> ${hwr} -> ${fwd}" >&2 + eval fwd_${hwr}=${fwd} + ll=$(echo "${l}" | wc -w | awk '{ print $1 }') + done + + echo "${hwrevs}" | \ + while read did hwrl; do + hwrn=$(echo "${hwrl}" | wc -w | awk '{ print $1 }') + if test ${hwrn} -lt 1; then + printf "Device ID %s has no hardware revisions (%s); skipping\n" "${did}" ${hwrn} >&2 + continue + fi + + for hwrx in ${hwrl}; do + + eval fwd=\${fwd_${hwrx}} + #echo "===> ${did} -> ${hwrx} -> ${fwd}" >&2 + + if test ! -d ${LFWDIR}/${fwd}; then + #printf "Firmware dir %s (for %s) does not exist; skipping\n" ${fwd} ${did} >&2 + continue + fi + + flav=$(echo "${fwd}" | awk -v drv=${DRIVER} '{ + # Ports FLAVOR names are [a-z0-9_]. If needed add more mangling magic here. + gsub("^" drv "/", ""); + gsub("/", "_"); + gsub("\\.", ""); + print tolower($0); + }') + + # Print this first or otherwise if two device IDs have the same firmware + # we may not see that. + echo "FWGET ${did} ${flav}" + + x="" + for zf in ${sfwl}; do + if test "${zf}" == "${flav}"; then + x="${zf}" + break + fi + done + if test "${x}" != ""; then + #printf "Flavor %s (firmware directory %s) already seen; skipping\n" ${flav} ${fwd} >&2 + continue + fi + sfwl="${sfwl} ${flav}" + + #echo "==> ${did} -> ${fwd} -> ${flav}" + + lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a \! -name "*.txt" -print) + + # Get a count so we can automatically add \\ apart from the last line. + fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') + + #echo "==> ${flav} :: ${fn} :: ${lx}" >&2 + + if test ${fn} -gt 0; then + + echo "FWS ${flav}" + echo "DISTFILES_${flav}= \\" + for fz in ${lx}; do echo "${fz}"; done | \ + awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ + if (FNR == fn) { x="" } else { x=" \\" }; + #gsub("^" drv "/", "${FWSUBDIR}/"); + gsub("^", "${FWSUBDIR}/"); + printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; + }' + + # Check for "lic" files. + lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a -name "*.txt" -print) + + # Get a count so we can automatically add \\ apart from the last line. + fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') + + if test ${fn} -gt 0; then + echo "FWL ${flav}" + echo "DISTFILES_${flav}_lic= \\" + for fz in ${lx}; do echo "${fz}"; done | \ + awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ + if (FNR == fn) { x="" } else { x=" \\" }; + #gsub("^" drv "/", "${FWSUBDIR}/"); + gsub("^", "${FWSUBDIR}/"); + printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; + }' + fi + fi + done + + done +} + +################################################################################ +# +# 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 ${DRIVER}-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 + list_fw | grep -v ^FWS | grep -v ^FWL | 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; + }' + + fwsl=$(list_fw | grep ^FWL | 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 + echo "DISTFILES_\${FWDRV}_lic= \\" + for sz in ${fwsl}; do echo "${sz}"; done | \ + awk -v fn=$fn '{ + if (FNR == fn) { x="" } else { x=" \\" }; + printf "\t${DISTFILES_%s_lic}%s\n", $0, x; + }' + else + echo "DISTFILES_\${FWDRV}_lic=" + fi + + ) >> ${portsfile} + + printf "INFO: wifi-firmware-%s-kmod template at %s\n" ${DRIVER} ${portsfile} >&2 +fi + +################################################################################ +# +# Generate the fwget(8) case pattern table (PCI device ID -> fw port flavor). +# + +fwgetfile=$(mktemp -p /tmp ${DRIVER}-fwget.XXXXXX) +:> ${fwgetfile} + +fwsl=$(list_fw | grep ^FWGET | sort) +# Get a count so we can automatically add \\ apart from the last line. +fn=$(echo "${fwsl}" | grep -c FWGET | awk '{ print $1 }') + +if test ${fn} -gt 0; then + + # We need to check for same ID with multiple firmware. + # The list ist sorted by ID so duplicates are next to each other. + cs=$(echo "${fwsl}" | awk '{ print $2 }' | uniq -c | awk '{ print $1 }') + + #echo "==> cs=${cs}" >&2 + + for n in ${cs}; do + + # Skip FWGET + fwsl=${fwsl#*[[:space:]]} + # get device ID + did=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + # get flavor + flav=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + + # printf "===> did %s flav %s\n" ${did} ${flav} >&2 + + if test ${n} -eq 1; then + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"; return 1 ;;\n", + tolower($1), drv, tolower($2); + }' >> ${fwgetfile} + else + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"\n", + tolower($1), drv, tolower($2); + }' >> ${fwgetfile} + + i=1 + while test ${i} -lt ${n}; do + # Skip FWGET + fwsl=${fwsl#*[[:space:]]} + # get device ID + did=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + # get flavor + flav=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + + #printf "===> did %s flav %s\n" ${did} ${flav} >&2 + + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t\taddpkg \"wifi-firmware-%s-kmod-%s\"\n", + drv, tolower($2); + }' >> ${fwgetfile} + + i=$((i + 1)) + done + + printf "\t\treturn 1 ;;\n" >> ${fwgetfile} + fi + done +fi + +printf "INFO: fwget pci_network_qca %s template at %s\n" ${DRIVER} ${fwgetfile} >&2 + +# end diff --git a/sys/contrib/dev/athk/ath12k/zzz_fw_ports_fwget.sh b/sys/contrib/dev/athk/ath12k/zzz_fw_ports_fwget.sh new file mode 100644 index 000000000000..500f5de05cc4 --- /dev/null +++ b/sys/contrib/dev/athk/ath12k/zzz_fw_ports_fwget.sh @@ -0,0 +1,310 @@ +#!/bin/sh +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 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. +# + +set -e + +DRIVER=ath12k +CHECKFILE=dp_mon.c + +################################################################################ +# +# Check pre-reqs +# +if [ $# -ne 1 ]; then + printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2 + exit 1 +fi + +if [ ! -e ${CHECKFILE} ]; then + printf "ERROR: run from %s driver directory; no %s.c here\n" ${DRIVER} ${CHECKFILE} >&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 +LFWDIR=${LFWDIR}/${DRIVER} + +################################################################################ +# +# Helper functions. +# +# This uses a hack (cpp) to expand some macros for us and parses out the result +# which is the PCI device ID or the firmware directory for that. +# +list_fw() +{ + # List of already seen flavor (firmware directory). + sfwl="" + + # List of "supported" device IDs. + devidl=$(cpp pci.c 2> /dev/null | awk '/PCI_VDEVICE\(QCOM,/ { gsub("^.*, ", ""); gsub("\\) },$", ""); print tolower($0); }') + # Turn them into a regex. + didreg=$(echo "${devidl}" | xargs -J % echo -n % | sed -e 's, ,|,g') + # List the device ID cases along with their hw_rev which we can go and take to lookup fw. + hwrevs=$(cpp pci.c 2> /dev/null | egrep -E "(case (${didreg})|ab->hw_rev = )" | awk '{ + if (FNR > 1 && /case/) { + printf "\n"; + } + gsub("^.*case[[:space:]]*", ""); + gsub("[[:space:]]*ab->hw_rev = ", " "); + gsub("[:;]", ""); + printf "%s", $0; + }') + + # hwrevs is a list of (device IDs) -> (1..n hardware revisions) mappings. + #echo "==> ${devidl} :: ${didreg} :: ${hwrevs}" >&2 + + # List of (hardware revision) -> (firware directory) mappings. + l=$(cpp hw.c 2> /dev/null | egrep -E '\.(hw_rev|dir) = ' | awk '{ if (/hw_rev/) { printf "%s", $0; } else { print; } }' | sort | uniq | \ + awk '{ + gsub("^.*hw_rev = ", ""); + gsub(",.* = ", "\t"); + gsub(",$", ""); + gsub(/"/, ""); + gsub(" ", ""); + gsub("\t", " "); + print; + }') + #echo "===> ${l}" >&2 + + ll=$(echo "${l}" | wc -w | awk '{ print $1 }') + while test "${ll}" -gt 1; do + hwr=${l%%[[:space:]]*} + l=${l#*[[:space:]]} + fwd=${l%%[[:space:]]*} + l=${l#*[[:space:]]} + + #echo "=+=> ${hwr} -> ${fwd}" >&2 + eval fwd_${hwr}=${fwd} + ll=$(echo "${l}" | wc -w | awk '{ print $1 }') + done + + echo "${hwrevs}" | \ + while read did hwrl; do + hwrn=$(echo "${hwrl}" | wc -w | awk '{ print $1 }') + if test ${hwrn} -lt 1; then + printf "Device ID %s has no hardware revisions (%s); skipping\n" "${did}" ${hwrn} >&2 + continue + fi + + for hwrx in ${hwrl}; do + + eval fwd=\${fwd_${hwrx}} + #echo "===> ${did} -> ${hwrx} -> ${fwd}" >&2 + + if test ! -d ${LFWDIR}/${fwd}; then + #printf "Firmware dir %s (for %s) does not exist; skipping\n" ${fwd} ${did} >&2 + continue + fi + + flav=$(echo "${fwd}" | awk -v drv=${DRIVER} '{ + # Ports FLAVOR names are [a-z0-9_]. If needed add more mangling magic here. + gsub("^" drv "/", ""); + gsub("/", "_"); + gsub("\\.", ""); + print tolower($0); + }') + + # Print this first or otherwise if two device IDs have the same firmware + # we may not see that. + echo "FWGET ${did} ${flav}" + + x="" + for zf in ${sfwl}; do + if test "${zf}" == "${flav}"; then + x="${zf}" + break + fi + done + if test "${x}" != ""; then + #printf "Flavor %s (firmware directory %s) already seen; skipping\n" ${flav} ${fwd} >&2 + continue + fi + sfwl="${sfwl} ${flav}" + + #echo "==> ${did} -> ${fwd} -> ${flav}" + + lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a \! -name "*.txt" -print) + + # Get a count so we can automatically add \\ apart from the last line. + fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') + + #echo "==> ${flav} :: ${fn} :: ${lx}" >&2 + + if test ${fn} -gt 0; then + + echo "FWS ${flav}" + echo "DISTFILES_${flav}= \\" + for fz in ${lx}; do echo "${fz}"; done | \ + awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ + if (FNR == fn) { x="" } else { x=" \\" }; + #gsub("^" drv "/", "${FWSUBDIR}/"); + gsub("^", "${FWSUBDIR}/"); + printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; + }' + + # Check for "lic" files. + lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a -name "*.txt" -print) + + # Get a count so we can automatically add \\ apart from the last line. + fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') + + if test ${fn} -gt 0; then + echo "FWL ${flav}" + echo "DISTFILES_${flav}_lic= \\" + for fz in ${lx}; do echo "${fz}"; done | \ + awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ + if (FNR == fn) { x="" } else { x=" \\" }; + #gsub("^" drv "/", "${FWSUBDIR}/"); + gsub("^", "${FWSUBDIR}/"); + printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; + }' + fi + fi + done + + done +} + +################################################################################ +# +# 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 ${DRIVER}-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 + list_fw | grep -v ^FWS | grep -v ^FWL | 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; + }' + + fwsl=$(list_fw | grep ^FWL | 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 + echo "DISTFILES_\${FWDRV}_lic= \\" + for sz in ${fwsl}; do echo "${sz}"; done | \ + awk -v fn=$fn '{ + if (FNR == fn) { x="" } else { x=" \\" }; + printf "\t${DISTFILES_%s_lic}%s\n", $0, x; + }' + else + echo "DISTFILES_\${FWDRV}_lic=" + fi + + ) >> ${portsfile} + + printf "INFO: wifi-firmware-%s-kmod template at %s\n" ${DRIVER} ${portsfile} >&2 +fi + +################################################################################ +# +# Generate the fwget(8) case pattern table (PCI device ID -> fw port flavor). +# + +fwgetfile=$(mktemp -p /tmp ${DRIVER}-fwget.XXXXXX) +:> ${fwgetfile} + +fwsl=$(list_fw | grep ^FWGET | sort) +# Get a count so we can automatically add \\ apart from the last line. +fn=$(echo "${fwsl}" | grep -c FWGET | awk '{ print $1 }') + +if test ${fn} -gt 0; then + + # We need to check for same ID with multiple firmware. + # The list ist sorted by ID so duplicates are next to each other. + cs=$(echo "${fwsl}" | awk '{ print $2 }' | uniq -c | awk '{ print $1 }') + + #echo "==> cs=${cs}" >&2 + + for n in ${cs}; do + + # Skip FWGET + fwsl=${fwsl#*[[:space:]]} + # get device ID + did=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + # get flavor + flav=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + + # printf "===> did %s flav %s\n" ${did} ${flav} >&2 + + if test ${n} -eq 1; then + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"; return 1 ;;\n", + tolower($1), drv, tolower($2); + }' >> ${fwgetfile} + else + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"\n", + tolower($1), drv, tolower($2); + }' >> ${fwgetfile} + + i=1 + while test ${i} -lt ${n}; do + # Skip FWGET + fwsl=${fwsl#*[[:space:]]} + # get device ID + did=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + # get flavor + flav=${fwsl%%[[:space:]]*} + fwsl=${fwsl#*[[:space:]]} + + #printf "===> did %s flav %s\n" ${did} ${flav} >&2 + + echo "${did} ${flav}" | awk -v drv=${DRIVER} '{ + printf "\t\taddpkg \"wifi-firmware-%s-kmod-%s\"\n", + drv, tolower($2); + }' >> ${fwgetfile} + + i=$((i + 1)) + done + + printf "\t\treturn 1 ;;\n" >> ${fwgetfile} + fi + done +fi + +printf "INFO: fwget pci_network_qca %s template at %s\n" ${DRIVER} ${fwgetfile} >&2 + +# end diff --git a/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh b/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh new file mode 100644 index 000000000000..60c75c00cbc7 --- /dev/null +++ b/sys/contrib/dev/iwlwifi/zzz_fw_ports_fwget.sh @@ -0,0 +1,374 @@ +#!/bin/sh +#- +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2024 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 *** 963 LINES SKIPPED ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202410311434.49VEYrnh005142>