1*96190b4fSBjoern A. Zeeb#!/bin/sh 2*96190b4fSBjoern A. Zeeb#- 3*96190b4fSBjoern A. Zeeb# SPDX-License-Identifier: BSD-2-Clause 4*96190b4fSBjoern A. Zeeb# 5*96190b4fSBjoern A. Zeeb# Copyright (c) 2024 The FreeBSD Foundation 6*96190b4fSBjoern A. Zeeb# 7*96190b4fSBjoern A. Zeeb# This software was developed by Björn Zeeb 8*96190b4fSBjoern A. Zeeb# under sponsorship from the FreeBSD Foundation. 9*96190b4fSBjoern A. Zeeb# 10*96190b4fSBjoern A. Zeeb# This is neither efficient nor elegant but we need it few times 11*96190b4fSBjoern A. Zeeb# a year and it does the job. 12*96190b4fSBjoern A. Zeeb# 13*96190b4fSBjoern A. Zeeb# 14*96190b4fSBjoern A. Zeeb# USAGE: please check out the correct tag/hash for ports in the 15*96190b4fSBjoern A. Zeeb# linux-firmware.git repository you point this script to. 16*96190b4fSBjoern A. Zeeb# 17*96190b4fSBjoern A. Zeeb 18*96190b4fSBjoern A. Zeebset -e 19*96190b4fSBjoern A. Zeeb 20*96190b4fSBjoern A. ZeebDRIVER=rtw89 21*96190b4fSBjoern A. ZeebCHECKFILE=rtw8922a.c 22*96190b4fSBjoern A. Zeeb 23*96190b4fSBjoern A. Zeeb################################################################################ 24*96190b4fSBjoern A. Zeeb# 25*96190b4fSBjoern A. Zeeb# Check pre-reqs 26*96190b4fSBjoern A. Zeeb# 27*96190b4fSBjoern A. Zeebif [ $# -ne 1 ]; then 28*96190b4fSBjoern A. Zeeb printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2 29*96190b4fSBjoern A. Zeeb exit 1 30*96190b4fSBjoern A. Zeebfi 31*96190b4fSBjoern A. Zeeb 32*96190b4fSBjoern A. Zeebif [ ! -e ${CHECKFILE} ]; then 33*96190b4fSBjoern A. Zeeb printf "ERROR: run from %s driver directory; no %s.c here\n" ${DRIVER} ${CHECKFILE} >&2 34*96190b4fSBjoern A. Zeeb exit 1 35*96190b4fSBjoern A. Zeebfi 36*96190b4fSBjoern A. Zeeb 37*96190b4fSBjoern A. ZeebLFWDIR=${1} 38*96190b4fSBjoern A. Zeebif test ! -d ${LFWDIR} -o ! -e ${LFWDIR}/WHENCE; then 39*96190b4fSBjoern A. Zeeb printf "ERROR: cannot find linux-firmware.git at '%s'\n" ${LFWDIR} >&2 40*96190b4fSBjoern A. Zeeb exit 1 41*96190b4fSBjoern A. Zeebfi 42*96190b4fSBjoern A. Zeeb 43*96190b4fSBjoern A. Zeeb 44*96190b4fSBjoern A. Zeeb################################################################################ 45*96190b4fSBjoern A. Zeeb# 46*96190b4fSBjoern A. Zeeb# Helper functions. 47*96190b4fSBjoern A. Zeeb# 48*96190b4fSBjoern A. Zeeb# This uses a hack (cpp) to expand some macros for us and parses out the result 49*96190b4fSBjoern A. Zeeb# which is the firmware name with the maximum FW version supported for that 50*96190b4fSBjoern A. Zeeb# firmware (where applicable). 51*96190b4fSBjoern A. Zeeb# 52*96190b4fSBjoern A. Zeeblist_fw() 53*96190b4fSBjoern A. Zeeb{ 54*96190b4fSBjoern A. Zeeb for f in `ls -1 rtw?????.c rtw?????e.c`; do 55*96190b4fSBjoern A. Zeeb 56*96190b4fSBjoern A. Zeeb l=$(cpp ${f} 2>&1 | awk '/^MODULE_FIRMWARE\(/ { gsub(/"/, ""); gsub("__stringify\\(", ""); gsub("\\);$", ""); gsub("\\)", ""); gsub("^MODULE_FIRMWARE\\(", ""); gsub(" ", ""); printf "%s\n", $0; }' | sort -n | uniq) 57*96190b4fSBjoern A. Zeeb if test "${l}" == ""; then 58*96190b4fSBjoern A. Zeeb continue 59*96190b4fSBjoern A. Zeeb fi 60*96190b4fSBjoern A. Zeeb lx="" 61*96190b4fSBjoern A. Zeeb for fx in ${l}; do 62*96190b4fSBjoern A. Zeeb if test -e ${LFWDIR}/${fx}; then 63*96190b4fSBjoern A. Zeeb lx="${lx} ${fx}" 64*96190b4fSBjoern A. Zeeb # else 65*96190b4fSBjoern A. Zeeb # printf "NOTICE: no firmware file found for '%s'\n" ${fx} >&2 66*96190b4fSBjoern A. Zeeb fi 67*96190b4fSBjoern A. Zeeb done 68*96190b4fSBjoern A. Zeeb 69*96190b4fSBjoern A. Zeeb # Get a count so we can automatically add \\ apart from the last line. 70*96190b4fSBjoern A. Zeeb fn=$(echo "${lx}" | wc -w | awk '{ print $1 }') 71*96190b4fSBjoern A. Zeeb 72*96190b4fSBjoern A. Zeeb # echo "==> ${f} :: ${fn} :: ${lx}" 73*96190b4fSBjoern A. Zeeb 74*96190b4fSBjoern A. Zeeb if test ${fn} -gt 0; then 75*96190b4fSBjoern A. Zeeb 76*96190b4fSBjoern A. Zeeb # Ports FLAVOR names are [a-z0-9_]. If needed add more mangling magic here. 77*96190b4fSBjoern A. Zeeb flav=`echo ${f%%.c} | awk '{ printf "%s", tolower($0); }'` 78*96190b4fSBjoern A. Zeeb 79*96190b4fSBjoern A. Zeeb echo "FWS ${flav}" 80*96190b4fSBjoern A. Zeeb echo "DISTFILES_${flav}= \\" 81*96190b4fSBjoern A. Zeeb for fz in ${lx}; do echo "${fz}"; done | \ 82*96190b4fSBjoern A. Zeeb awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{ 83*96190b4fSBjoern A. Zeeb if (FNR == fn) { x="" } else { x=" \\" }; 84*96190b4fSBjoern A. Zeeb gsub("^" drv "/", "${FWSUBDIR}/"); 85*96190b4fSBjoern A. Zeeb printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x; 86*96190b4fSBjoern A. Zeeb }' 87*96190b4fSBjoern A. Zeeb fi 88*96190b4fSBjoern A. Zeeb 89*96190b4fSBjoern A. Zeeb done 90*96190b4fSBjoern A. Zeeb} 91*96190b4fSBjoern A. Zeeb 92*96190b4fSBjoern A. Zeeb################################################################################ 93*96190b4fSBjoern A. Zeeb# 94*96190b4fSBjoern A. Zeeb# Generate the PORTS file template. 95*96190b4fSBjoern A. Zeeb# 96*96190b4fSBjoern A. Zeeb 97*96190b4fSBjoern A. Zeebfwsl=$(list_fw | grep ^FWS | awk '{ print $2 }') 98*96190b4fSBjoern A. Zeeb# Get a count so we can automatically add \\ apart from the last line. 99*96190b4fSBjoern A. Zeebfn=$(echo "${fwsl}" | wc -w | awk '{ print $1 }') 100*96190b4fSBjoern A. Zeeb 101*96190b4fSBjoern A. Zeebif test ${fn} -gt 0; then 102*96190b4fSBjoern A. Zeeb 103*96190b4fSBjoern A. Zeeb portsfile=$(mktemp -p /tmp ${DRIVER}-fwport.XXXXXX) 104*96190b4fSBjoern A. Zeeb 105*96190b4fSBjoern A. Zeeb :> ${portsfile} 106*96190b4fSBjoern A. Zeeb ( 107*96190b4fSBjoern A. Zeeb echo "FWSUBS= \\" 108*96190b4fSBjoern A. Zeeb for sz in ${fwsl}; do echo "${sz}"; done | \ 109*96190b4fSBjoern A. Zeeb awk -v fn=$fn '{ 110*96190b4fSBjoern A. Zeeb if (FNR == fn) { x="" } else { x=" \\" }; 111*96190b4fSBjoern A. Zeeb printf "\t%s%s\n", $0, x; 112*96190b4fSBjoern A. Zeeb }' 113*96190b4fSBjoern A. Zeeb 114*96190b4fSBjoern A. Zeeb echo 115*96190b4fSBjoern A. Zeeb list_fw | grep -v ^FWS 116*96190b4fSBjoern A. Zeeb 117*96190b4fSBjoern A. Zeeb echo 118*96190b4fSBjoern A. Zeeb echo "DISTFILES_\${FWDRV}= \\" 119*96190b4fSBjoern A. Zeeb for sz in ${fwsl}; do echo "${sz}"; done | \ 120*96190b4fSBjoern A. Zeeb awk -v fn=$fn '{ 121*96190b4fSBjoern A. Zeeb if (FNR == fn) { x="" } else { x=" \\" }; 122*96190b4fSBjoern A. Zeeb printf "\t${DISTFILES_%s}%s\n", $0, x; 123*96190b4fSBjoern A. Zeeb }' 124*96190b4fSBjoern A. Zeeb ) >> ${portsfile} 125*96190b4fSBjoern A. Zeeb 126*96190b4fSBjoern A. Zeeb printf "INFO: wifi-firmware-%s-kmod template at %s\n" ${DRIVER} ${portsfile} >&2 127*96190b4fSBjoern A. Zeebfi 128*96190b4fSBjoern A. Zeeb 129*96190b4fSBjoern A. Zeeb################################################################################ 130*96190b4fSBjoern A. Zeeb# 131*96190b4fSBjoern A. Zeeb# Generate the fwget(8) case pattern table (PCI device ID -> fw port flavor). 132*96190b4fSBjoern A. Zeeb# 133*96190b4fSBjoern A. Zeeb 134*96190b4fSBjoern A. Zeebfwgetfile=$(mktemp -p /tmp ${DRIVER}-fwget.XXXXXX) 135*96190b4fSBjoern A. Zeeb:> ${fwgetfile} 136*96190b4fSBjoern A. Zeeb 137*96190b4fSBjoern A. Zeebfor f in `ls -1 rtw?????.c rtw?????e.c`; do 138*96190b4fSBjoern A. Zeeb 139*96190b4fSBjoern A. Zeeb # Ports FLAVOR names are [a-z0-9_]. If needed add more mangling magic here. 140*96190b4fSBjoern A. Zeeb n=${f%.c}; 141*96190b4fSBjoern A. Zeeb n=${n%e}; 142*96190b4fSBjoern A. Zeeb 143*96190b4fSBjoern A. Zeeb awk -v n=${n} -v drv=${DRIVER} '/PCI_DEVICE\(PCI_VENDOR_ID_REALTEK,/ { 144*96190b4fSBjoern A. Zeeb gsub(").*", "", $2); 145*96190b4fSBjoern A. Zeeb printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"; return 1 ;;\n", 146*96190b4fSBjoern A. Zeeb tolower($2), drv, tolower(n); 147*96190b4fSBjoern A. Zeeb }' ${f} 148*96190b4fSBjoern A. Zeebdone >> ${fwgetfile} 149*96190b4fSBjoern A. Zeeb 150*96190b4fSBjoern A. Zeebprintf "INFO: fwget pci_network_realtek %s template at %s\n" ${DRIVER} ${fwgetfile} >&2 151*96190b4fSBjoern A. Zeeb 152*96190b4fSBjoern A. Zeeb# end 153