-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathsynciwl.sh
More file actions
executable file
·264 lines (234 loc) · 11.1 KB
/
Copy pathsynciwl.sh
File metadata and controls
executable file
·264 lines (234 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2017-present Team LibreELEC (https://libreelec.tv)
TMPDIR=.unpack.tmp
KERNEL=$1
# API numbering is Core+3.
# Intel states:
#
# "Since core 97, pnvm files are no longer needed for those devices."
#
# This applies only to the BZ and GL firmware families introduced with
# core97/core98 firmware. Their PNVM data is embedded in the .ucode image,
# so standalone .pnvm files are no longer required.
#
# Other device families (TY, SO, MA, etc.) still require standalone PNVM
# files unless Intel documents otherwise.
PNVM_EMBED_API_MIN=100
function pnvm_embedded()
{
local prefix="$1" api="$2"
case "${prefix}" in
iwlwifi-bz-*|iwlwifi-gl-*)
[ "${api}" -ge "${PNVM_EMBED_API_MIN}" ]
;;
*)
return 1
;;
esac
}
if [ -z "${KERNEL}" ]; then
echo "Script to synchronise this repo with the most suitable linux-firmware file for the specified kernel."
echo
echo "Run this script in the root of the iwlwifi-firmware repository."
echo
echo "Remember to delete ${TMPDIR} before committing changes!"
echo
echo "Usage: $0 <kernel version>"
echo
echo " Example: $0 4.10.2"
echo " Example: $0 4.11-rc2"
echo " Example: DEBUG=y $0 4.11-rc2"
echo
echo " DEBUG=y - enable debug output"
echo " DRYRUN=y - don't update filesystem"
echo " IPV4=y - use only IPv4 for curl and git clone"
exit 1
fi
[ -z "${IPV4}" ] && USEIPV4= || USEIPV4="-4"
function get_kernel_max()
{
local filename device prefix kernel_max api_max
local driver_path def_device
driver_path=linux-${KERNEL}/drivers/net/wireless/intel/iwlwifi
[ -d linux-${KERNEL}/drivers/net/wireless/intel/iwlwifi ] || driver_path=linux-${KERNEL}/drivers/net/wireless/iwlwifi
# Config files moved to cfg subdir in 4.13-rc1
[ -d ${driver_path}/cfg ] && driver_path+=/cfg
while read -r filename; do
[ -n "${DEBUG}" ] && printf "DEBUG: reading filename %s\n" "${filename}" >&2
def_device="$(basename ${filename} .c | sed 's/rf-//' | tr '[:lower:]' '[:upper:]')"
while read -r prefix; do
device="$(echo "${prefix}" | awk -F- '{ print $2 }')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" >&2
[ -z "${device}" ] && continue
api_max="$(grep "^MODULE_FIRMWARE(IWL${device}_MODULE_FIRMWARE(.*))" ${filename} | sed 's/[()]/ /g' | awk '$3 ~ /.*_UCODE_API_MAX$/ {print $3}')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s api_max %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" "${api_max}" >&2
kernel_max=
[ -n "${api_max}" ] && kernel_max="$(grep "#define[[:space:]]*${api_max}" ${filename} | awk '{ print $3 }')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s api_max %s kernel_max %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" "${api_max}" "${kernel_max}" >&2
[ -z "${kernel_max}" ] && kernel_max="$(grep "#define[[:space:]]*IWL${device}_UCODE_API_MAX" ${filename} | awk '{ print $3 }')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s api_max %s kernel_max %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" "${api_max}" "${kernel_max}" >&2
[ -z "${kernel_max}" ] && kernel_max="$(grep "#define[[:space:]]*IWL${def_device}_UCODE_API_MAX" ${filename} | awk '{ print $3 }')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s api_max %s kernel_max %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" "${api_max}" "${kernel_max}" >&2
[ -z "${kernel_max}" ] && kernel_max="$(grep "#define[[:space:]]*IWL_${def_device}_UCODE_API_MAX" ${filename} | awk '{ print $3 }')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s api_max %s kernel_max %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" "${api_max}" "${kernel_max}" >&2
# required to add 3 to CORE_MAX since linux-6.18
[ -z "${kernel_max}" ] && kernel_max="$(grep "#define[[:space:]]*IWL_${def_device}_UCODE_CORE_MAX" ${filename} | awk '{ print $3 + 3 }')"
[ -n "${DEBUG}" ] && printf "DEBUG: filename %s def_device %s prefix %s device %s api_max %s kernel_max %s\n" "${filename}" "${def_device}" "${prefix}" "${device}" "${api_max}" "${kernel_max}" >&2
[ -n "${kernel_max}" ] || continue
# since linux-6.5 the trailing dash was removed - add it back
[[ "${prefix}" != *- ]] && prefix="${prefix}-"
echo "${device} ${prefix} ${kernel_max}"
done <<< "$(grep "#define[[:space:]]*IWL.*_FW_PRE[[:space:]]*\".*\"$" ${filename} | awk '{ print $3 }' | sed 's/"//g')"
done <<< "$(ls -1 ${driver_path}/*.c)"
}
function get_firmwares()
{
local directory="$1" prefix="$2"
local firmware api
(
cd "${directory}"
while read -r firmware; do
api="${firmware#${prefix}}"
api="${api%\.ucode}"
[[ ${api} =~ ^c[0-9]+ ]] && api=$((${api#c} + 3))
echo "${api}"
done <<< "$(ls -1 ${prefix}*.ucode 2>/dev/null)"
) | sort -k1nr | tr '\n' ',' | grep -v "^,$"
}
function sync_pnvm()
{
local prefix="$1" keepver="$2"
local pnvm_name="${prefix%-}.pnvm"
local have="../firmware/${pnvm_name}"
local src="linux-firmware/intel/iwlwifi/${pnvm_name}"
local md5old md5new
if [ -n "${keepver}" ] && ! pnvm_embedded "${prefix%-}" "${keepver}"; then
# Standalone PNVM required - keep it in sync.
if [ -f "${src}" ]; then
if [ ! -f "${have}" ]; then
echo " Adding new PNVM file: ${pnvm_name}"
[ -z "${DRYRUN}" ] && cp "${src}" "${have}"
else
md5old="$(md5sum "${have}" | awk '{print $1}')"
md5new="$(md5sum "${src}" | awk '{print $1}')"
if [ "${md5old}" != "${md5new}" ]; then
echo " Updating existing PNVM file: ${pnvm_name}"
[ -z "${DRYRUN}" ] && cp "${src}" "${have}"
fi
fi
fi
else
# PNVM is embedded in the firmware image.
if [ -f "${have}" ]; then
echo " Removing obsolete PNVM file (embedded in firmware): ${pnvm_name}"
[ -z "${DRYRUN}" ] && rm -f "${have}"
fi
fi
}
function sync_max_firmware()
{
local device="$1" prefix="$2" kernel_max="$3"
local linux_fw="$(get_firmwares linux-firmware/intel/iwlwifi "${prefix}")"
local thisrepo="$(get_firmwares ../firmware "${prefix}")"
local firmware keepver md5old md5new
[ -z "${linux_fw}" -a -z "${thisrepo}" ] && return 0
[ -n "${DEBUG}" ] && printf "DEBUG: %-6s %-15s kernel max=%-2s linux fw=%s this repo=%s\n" "${device}" "${prefix}" "${kernel_max}" "${linux_fw:0:-1}" "${thisrepo:0:-1}" >&2
printf "%-25s - kernel max is %2d, linux-firmware max is %2d, this repo max is %2d\n" "${prefix:0:-1}" ${kernel_max} ${linux_fw%%,*} ${thisrepo%%,*}
for firmware in ${linux_fw//,/ }; do
if [ ${firmware} -le ${kernel_max} ]; then
keepver=${firmware}
coreversion="c$((${firmware}-3))"
if [ ! -f ../firmware/${prefix}${coreversion}.ucode ] &&
[ ! -f ../firmware/${prefix}${firmware}.ucode ]; then
if [ -f linux-firmware/intel/iwlwifi/${prefix}${coreversion}.ucode ]; then
echo " Adding new version : ${prefix}${coreversion}.ucode"
[ -z "${DRYRUN}" ] && cp linux-firmware/intel/iwlwifi/${prefix}${coreversion}.ucode ../firmware
else
echo " Adding new version : ${prefix}${firmware}.ucode"
[ -z "${DRYRUN}" ] && cp linux-firmware/intel/iwlwifi/${prefix}${firmware}.ucode ../firmware
fi
elif [ -f ../firmware/${prefix}${coreversion}.ucode ]; then
md5old="$(md5sum ../firmware/${prefix}${coreversion}.ucode | awk '{print $1}')"
md5new="$(md5sum linux-firmware/intel/iwlwifi/${prefix}${coreversion}.ucode | awk '{print $1}')"
if [ "${md5old}" != "${md5new}" ]; then
echo " Updating existing version: ${prefix}${coreversion}.ucode"
[ -z "${DRYRUN}" ] && cp linux-firmware/intel/iwlwifi/${prefix}${coreversion}.ucode ../firmware
fi
else
md5old="$(md5sum ../firmware/${prefix}${firmware}.ucode | awk '{print $1}')"
md5new="$(md5sum linux-firmware/intel/iwlwifi/${prefix}${firmware}.ucode | awk '{print $1}')"
if [ "${md5old}" != "${md5new}" ]; then
echo " Updating existing version: ${prefix}${firmware}.ucode"
[ -z "${DRYRUN}" ] && cp linux-firmware/intel/iwlwifi/${prefix}${firmware}.ucode ../firmware
fi
fi
break
fi
done
for firmware in ${thisrepo//,/ }; do
[ "${firmware}" == "${keepver}" ] && continue
coreversion="c$((${firmware}-3))"
if [ ${firmware} -gt ${kernel_max} ]; then
if [ -f ../firmware/${prefix}${coreversion}.ucode ]; then
echo " Removing incompatible version: ${prefix}${coreversion}.ucode"
[ -z "${DRYRUN}" ] && rm -f ../firmware/${prefix}${coreversion}.ucode
else
echo " Removing incompatible version: ${prefix}${firmware}.ucode"
[ -z "${DRYRUN}" ] && rm -f ../firmware/${prefix}${firmware}.ucode
fi
elif [ -n "${keepver}" ]; then
if [ -f ../firmware/${prefix}${coreversion}.ucode ]; then
echo " Removing old version: ${prefix}${coreversion}.ucode"
[ -z "${DRYRUN}" ] && rm -f ../firmware/${prefix}${coreversion}.ucode
else
echo " Removing old version: ${prefix}${firmware}.ucode"
[ -z "${DRYRUN}" ] && rm -f ../firmware/${prefix}${firmware}.ucode
fi
else
echo " Unable to identify suitable max version - keeping existing firmware files"
fi
done
sync_pnvm "${prefix}" "${keepver}"
}
mkdir -p $TMPDIR || exit
cd $TMPDIR || exit
# unpack kernel
echo "Unpacking kernel ${KERNEL}..."
if [ ! -d linux-${KERNEL} ] ; then
if [[ ${KERNEL} =~ .*-rc[0-9]* ]]; then
url="http://www.kernel.org/pub/linux/kernel/v4.x/testing/linux-${KERNEL}.tar.xz"
if ! curl --fail --head --location ${url} &>/dev/null; then
url="https://git.kernel.org/torvalds/t/linux-${KERNEL}.tar.gz"
fi
else
url="http://www.kernel.org/pub/linux/kernel/v${KERNEL:0:1}.x/linux-${KERNEL}.tar.xz"
fi
if [[ ${url} =~ .*.gz ]]; then
curl ${USEIPV4} --location --progress-bar "${url}" | tar xzf -
else
curl ${USEIPV4} --location --progress-bar "${url}" | tar xJf -
fi
[ $? -eq 0 ] || exit 1
fi
# clone/update linux-firmware
if [ -d linux-firmware ]; then
echo "Updating linux-firmware repository..."
(
cd linux-firmware &&
git fetch ${USEIPV4} --depth=1 origin &&
git reset --hard origin/HEAD
) || exit 1
else
echo "Cloning linux-firmware repository..."
git clone ${USEIPV4} \
https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git \
--depth=1 linux-firmware || exit 1
fi
echo "Synchronising repo with kernel and firmware..."
echo "Firmware versions are shown as API (not CORE), firmware files since API 104 are in the firmware as c101."
echo " API = CORE+3. e.g. 104 = c101 + 3"
echo
while read -r device prefix kernel_max; do
[ -n "{device}" -a -n "${prefix}" -a -n "${kernel_max}" ] && sync_max_firmware "${device}" "${prefix}" "${kernel_max}"
done <<< "$(get_kernel_max | sed -e 's/bz-a0/bz-b0/' -e 's/wh-a0/wh-b0/' | sort -u | sort -k1n)"