xref: /freebsd/sys/contrib/dev/athk/ath10k/zzz_fw_ports_fwget.sh (revision 96190b4fef3b4a0cc3ca0606b0c4e3e69a5e6717)
1#!/bin/sh
2#-
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2024 The FreeBSD Foundation
6#
7# This software was developed by Björn Zeeb
8# under sponsorship from the FreeBSD Foundation.
9#
10# This is neither efficient nor elegant but we need it few times
11# a year and it does the job.
12#
13#
14# USAGE: please check out the correct tag/hash for ports in the
15# linux-firmware.git repository you point this script to.
16#
17
18set -e
19
20DRIVER=ath10k
21CHECKFILE=qmi_wlfw_v01.c
22
23################################################################################
24#
25# Check pre-reqs
26#
27if [ $# -ne 1 ]; then
28	printf "USAGE: %s /path/to/linux-firmware.git\n" $0 >&2
29	exit 1
30fi
31
32if [ ! -e ${CHECKFILE} ]; then
33	printf "ERROR: run from %s driver directory; no %s.c here\n" ${DRIVER} ${CHECKFILE} >&2
34	exit 1
35fi
36
37LFWDIR=${1}
38if test ! -d ${LFWDIR} -o ! -e ${LFWDIR}/WHENCE; then
39	printf "ERROR: cannot find linux-firmware.git at '%s'\n" ${LFWDIR} >&2
40	exit 1
41fi
42
43################################################################################
44#
45# Helper functions.
46#
47# This uses a hack (cpp) to expand some macros for us and parses out the result
48# which is the PCI device ID or the firmware directory for that.
49# Checking MODULE_FIRMWARE was pointless as it had too many "dead" entries:
50# NOTICE: no firmware file found for 'ath10k/QCA6174/hw2.1/firmware-4.bin'
51# NOTICE: no firmware file found for 'ath10k/QCA6174/hw3.0/firmware-5.bin'
52# NOTICE: no firmware file found for 'ath10k/QCA9887/hw1.0/board-2.bin'
53# NOTICE: no firmware file found for 'ath10k/QCA988X/hw2.0/board-2.bin'
54# NOTICE: no firmware file found for 'ath10k/QCA988X/hw2.0/firmware-2.bin'
55# NOTICE: no firmware file found for 'ath10k/QCA988X/hw2.0/firmware-3.bin'
56#
57list_fw()
58{
59	# List of already seen flavor (firmware directory).
60	sfwl=""
61
62	# List of "supported" device IDs (ignoring Ubiquity).
63	devidl=$(cpp pci.c 2> /dev/null | awk '/PCI_VDEVICE\(ATHEROS,/ { gsub("^.*, \\(", ""); gsub("\\)\\) },$", ""); print tolower($0); }')
64
65	# List of (device ID) -> (firware directory) mappings.
66	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 | \
67	awk '{
68		gsub("^.*\\(", "");
69		gsub("),.* = ", "\t");
70		gsub(",$", "");
71		gsub(/"/, "");
72		gsub(" ", "");
73		print;
74	}' | \
75	while read did fwd; do
76
77		x=""
78		for d in ${devidl}; do
79			if test "${did}" == "${d}"; then
80				x="${d}"
81				break
82			fi
83		done
84		if test "${x}" == ""; then
85			# Device ID not in the list of PCI IDs we support.
86			# At least the Ubiquity one we hit here.
87			#printf "Device ID %s (%s) not in PCI ID list; skipping\n" ${did} ${fwd} >&2
88			continue
89		fi
90
91		if test ! -d ${LFWDIR}/${fwd}; then
92			# Leave this on as it MUST not happen.
93			printf "Firmware dir %s (for %s) does not exist; skipping\n" ${fwd} ${did} >&2
94			continue
95		fi
96
97		flav=$(echo "${fwd}" | awk -v drv=${DRIVER} '{
98			# Ports FLAVOR names are [a-z0-9_].  If needed add more mangling magic here.
99			gsub("^" drv "/", "");
100			gsub("/", "_");
101			gsub("\\.", "");
102			print tolower($0);
103		}')
104
105		# Print this first or otherwise if two device IDs have the same firmware
106		# we may not see that.
107		echo "FWGET ${did} ${flav}"
108
109		x=""
110		for zf in ${sfwl}; do
111			if test "${zf}" == "${flav}"; then
112				x="${zf}"
113				break
114			fi
115		done
116		if test "${x}" != ""; then
117			#printf "Flavor %s (firmware directory %s) already seen; skipping\n" ${flav} ${fwd} >&2
118			continue
119		fi
120		sfwl="${sfwl} ${flav}"
121
122		#echo "==> ${did} -> ${fwd} -> ${flav}"
123
124		lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a \! -name "*.txt" -print)
125
126		# Get a count so we can automatically add \\ apart from the last line.
127		fn=$(echo "${lx}" | wc -w | awk '{ print $1 }')
128
129		#echo "==> ${flav} :: ${fn} :: ${lx}" >&2
130
131		if test ${fn} -gt 0; then
132
133			echo "FWS ${flav}"
134			echo "DISTFILES_${flav}= \\"
135			for fz in ${lx}; do echo "${fz}"; done | \
136			awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{
137				if (FNR == fn) { x="" } else { x=" \\" };
138				gsub("^" drv "/", "${FWSUBDIR}/");
139				printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x;
140			}'
141
142			# Check for "lic" files.
143			lx=$(cd ${LFWDIR} && find ${fwd} -type f \! -name "*sdio*" -a -name "*.txt" -print)
144
145			# Get a count so we can automatically add \\ apart from the last line.
146			fn=$(echo "${lx}" | wc -w | awk '{ print $1 }')
147
148			if test ${fn} -gt 0; then
149				echo "FWL ${flav}"
150				echo "DISTFILES_${flav}_lic= \\"
151				for fz in ${lx}; do echo "${fz}"; done | \
152				awk -v fn=$fn -v fwg=${flav} -v drv=${DRIVER} '{
153					if (FNR == fn) { x="" } else { x=" \\" };
154					gsub("^" drv "/", "${FWSUBDIR}/");
155					printf "\t%s${DISTURL_SUFFIX}%s\n", $0, x;
156				}'
157			fi
158		fi
159	done
160}
161
162################################################################################
163#
164# Generate the PORTS file template.
165#
166
167fwsl=$(list_fw | grep ^FWS | awk '{ print $2 }')
168# Get a count so we can automatically add \\ apart from the last line.
169fn=$(echo "${fwsl}" | wc -w | awk '{ print $1 }')
170
171if test ${fn} -gt 0; then
172
173	portsfile=$(mktemp -p /tmp ${DRIVER}-fwport.XXXXXX)
174
175	:> ${portsfile}
176	(
177	echo "FWSUBS= \\"
178	for sz in ${fwsl}; do echo "${sz}"; done | \
179	awk -v fn=$fn '{
180		if (FNR == fn) { x="" } else { x=" \\" };
181		printf "\t%s%s\n", $0, x;
182	}'
183
184	echo
185	list_fw | grep -v ^FWS | grep -v ^FWL | grep -v ^FWGET
186
187	echo
188	echo "DISTFILES_\${FWDRV}= \\"
189	for sz in ${fwsl}; do echo "${sz}"; done | \
190	awk -v fn=$fn '{
191		if (FNR == fn) { x="" } else { x=" \\" };
192		printf "\t${DISTFILES_%s}%s\n", $0, x;
193	}'
194
195	fwsl=$(list_fw | grep ^FWL | awk '{ print $2 }')
196	# Get a count so we can automatically add \\ apart from the last line.
197	fn=$(echo "${fwsl}" | wc -w | awk '{ print $1 }')
198	if test ${fn} -gt 0; then
199		echo "DISTFILES_\${FWDRV}_lic= \\"
200		for sz in ${fwsl}; do echo "${sz}"; done | \
201		awk -v fn=$fn '{
202			if (FNR == fn) { x="" } else { x=" \\" };
203			printf "\t${DISTFILES_%s_lic}%s\n", $0, x;
204		}'
205	else
206		echo "DISTFILES_\${FWDRV}_lic="
207	fi
208
209	) >> ${portsfile}
210
211	printf "INFO: wifi-firmware-%s-kmod template at %s\n" ${DRIVER} ${portsfile} >&2
212fi
213
214################################################################################
215#
216# Generate the fwget(8) case pattern table (PCI device ID -> fw port flavor).
217#
218
219fwgetfile=$(mktemp -p /tmp ${DRIVER}-fwget.XXXXXX)
220:> ${fwgetfile}
221
222fwsl=$(list_fw | grep ^FWGET | sort)
223# Get a count so we can automatically add \\ apart from the last line.
224fn=$(echo "${fwsl}" | grep -c FWGET | awk '{ print $1 }')
225
226if test ${fn} -gt 0; then
227
228	# We need to check for same ID with multiple firmware.
229	# The list ist sorted by ID so duplicates are next to each other.
230	cs=$(echo "${fwsl}" | awk '{ print $2 }' | uniq -c | awk '{ print $1 }')
231
232	#echo "==> cs=${cs}" >&2
233
234	for n in ${cs}; do
235
236		# Skip FWGET
237		fwsl=${fwsl#*[[:space:]]}
238		# get device ID
239		did=${fwsl%%[[:space:]]*}
240		fwsl=${fwsl#*[[:space:]]}
241		# get flavor
242		flav=${fwsl%%[[:space:]]*}
243		fwsl=${fwsl#*[[:space:]]}
244
245		# printf "===> did %s flav %s\n" ${did} ${flav} >&2
246
247		if test ${n} -eq 1; then
248			echo "${did} ${flav}" | awk -v drv=${DRIVER} '{
249				printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"; return 1 ;;\n",
250				    tolower($1), drv, tolower($2);
251			}' >> ${fwgetfile}
252		else
253			echo "${did} ${flav}" | awk -v drv=${DRIVER} '{
254				printf "\t%s)\taddpkg \"wifi-firmware-%s-kmod-%s\"\n",
255				    tolower($1), drv, tolower($2);
256			}' >> ${fwgetfile}
257
258			i=1
259			while test ${i} -lt ${n}; do
260				# Skip FWGET
261				fwsl=${fwsl#*[[:space:]]}
262				# get device ID
263				did=${fwsl%%[[:space:]]*}
264				fwsl=${fwsl#*[[:space:]]}
265				# get flavor
266				flav=${fwsl%%[[:space:]]*}
267				fwsl=${fwsl#*[[:space:]]}
268
269				#printf "===> did %s flav %s\n" ${did} ${flav} >&2
270
271				echo "${did} ${flav}" | awk -v drv=${DRIVER} '{
272					printf "\t\taddpkg \"wifi-firmware-%s-kmod-%s\"\n",
273					    drv, tolower($2);
274				}' >> ${fwgetfile}
275
276				i=$((i + 1))
277			done
278
279			printf "\t\treturn 1 ;;\n" >> ${fwgetfile}
280		fi
281	done
282fi
283
284printf "INFO: fwget pci_network_qca %s template at %s\n" ${DRIVER} ${fwgetfile} >&2
285
286# end
287