Skip to content

Commit 1534a01

Browse files
committed
[mellanox] Extend Mellanox FW utils with CPLD update
Signed-off-by: Nazarii Hnydyn <[email protected]>
1 parent 9871e04 commit 1534a01

File tree

1 file changed

+240
-44
lines changed

1 file changed

+240
-44
lines changed

platform/mellanox/mlnx-fw-upgrade.j2

+240-44
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,62 @@ declare -r SCRIPT_NAME="$(basename "$0")"
44
declare -r SCRIPT_PATH="$(readlink -f "$0")"
55
declare -r SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
66

7+
declare -r VERBOSE_ERROR="1"
8+
declare -r VERBOSE_WARNING="2"
9+
declare -r VERBOSE_NOTICE="3"
10+
declare -r VERBOSE_INFO="4"
11+
12+
declare -r VERBOSE_MAX="${VERBOSE_INFO}"
13+
declare -r VERBOSE_MIN="${VERBOSE_ERROR}"
14+
15+
declare -r YES_PARAM="yes"
16+
declare -r NO_PARAM="no"
17+
718
declare -r EXIT_SUCCESS="0"
8-
declare -r EXIT_ERROR="1"
19+
declare -r EXIT_FAILURE="1"
920

1021
declare -r QUERY_CMD="mlxfwmanager --query"
1122
declare -r BURN_CMD="mlxfwmanager -u -f -y"
1223

1324
declare -r FW_FILE="/etc/mlnx/fw-SPC.mfa"
14-
declare -r QUERY_FILE="/tmp/mlnxfwmanager-query.txt"
25+
declare -r QUERY_FILE="/tmp/mlxfwmanager-query.txt"
1526

1627
declare -r FW_REQUIRED="{{ MLNX_FW_VERSION }}"
1728

18-
IMAGE_UPGRADE="no"
29+
IMAGE_UPGRADE="${NO_PARAM}"
30+
CPLD_UPGRADE="${NO_PARAM}"
31+
VERBOSE_LEVEL="${VERBOSE_MIN}"
1932

2033
function PrintHelp() {
2134
echo
2235
echo "Usage: ./${SCRIPT_NAME} [OPTIONS]"
2336
echo
2437
echo "OPTIONS:"
25-
echo " -u, --upgrade Upgrade MLNX ASIC firmware using next boot image (useful after SONiC-To-SONiC update)"
38+
echo " -u, --upgrade Upgrade firmware using next boot image (useful after SONiC-To-SONiC update)"
39+
echo " -c, --cpld Upgrade CPLD firmware (requires -u|--upgrade)"
40+
echo " -v, --verbose Verbose mode"
2641
echo " -h, --help Print help"
2742
echo
2843
echo "Examples:"
2944
echo " ./${SCRIPT_NAME}"
30-
echo " ./${SCRIPT_NAME} --upgrade"
45+
echo " ./${SCRIPT_NAME} --upgrade --cpld --verbose"
46+
echo " ./${SCRIPT_NAME} --upgrade --verbose"
3147
echo " ./${SCRIPT_NAME} --help"
3248
echo
3349
}
3450

3551
function ParseArguments() {
36-
while [ $# -ge 1 ]; do
52+
while [[ $# -ge 1 ]]; do
3753
case "$1" in
3854
-u|--upgrade)
39-
IMAGE_UPGRADE="yes"
55+
IMAGE_UPGRADE="${YES_PARAM}"
56+
VERBOSE_LEVEL="${VERBOSE_MAX}"
57+
;;
58+
-c|--cpld)
59+
CPLD_UPGRADE="${YES_PARAM}"
60+
;;
61+
-v|--verbose)
62+
VERBOSE_LEVEL="${VERBOSE_MAX}"
4063
;;
4164
-h|--help)
4265
PrintHelp
@@ -47,43 +70,119 @@ function ParseArguments() {
4770
done
4871
}
4972

73+
function LogError() {
74+
if [[ "${VERBOSE_LEVEL}" -ge "${VERBOSE_ERROR}" ]]; then
75+
echo "ERROR: $*"
76+
fi
77+
}
78+
79+
function LogWarning() {
80+
if [[ "${VERBOSE_LEVEL}" -ge "${VERBOSE_WARNING}" ]]; then
81+
echo "WARNING: $*"
82+
fi
83+
}
84+
85+
function LogNotice() {
86+
if [[ "${VERBOSE_LEVEL}" -ge "${VERBOSE_NOTICE}" ]]; then
87+
echo "NOTICE: $*"
88+
fi
89+
}
90+
91+
function LogInfo() {
92+
if [[ "${VERBOSE_LEVEL}" -ge "${VERBOSE_INFO}" ]]; then
93+
echo "INFO: $*"
94+
fi
95+
}
96+
97+
function ExitFailure() {
98+
if [[ "${VERBOSE_LEVEL}" -ge "${VERBOSE_ERROR}" ]]; then
99+
echo
100+
LogError "$@"
101+
echo
102+
fi
103+
104+
exit "${EXIT_FAILURE}"
105+
}
106+
107+
function ExitSuccess() {
108+
if [[ "${VERBOSE_LEVEL}" -ge "${VERBOSE_INFO}" ]]; then
109+
echo
110+
LogInfo "$@"
111+
echo
112+
fi
113+
114+
exit "${EXIT_SUCCESS}"
115+
}
116+
117+
function ParseMachineConf() {
118+
ONIE_MACHINE="$(cat /host/machine.conf | grep 'onie_machine=' | cut -f2 -d'=')"
119+
ONIE_PLATFORM="$(cat /host/machine.conf | grep 'onie_platform=' | cut -f2 -d'=')"
120+
}
121+
122+
function ShowProgressBar() {
123+
local -rA SPIN=(
124+
[0]="-"
125+
[1]="\\"
126+
[2]="|"
127+
[3]="/"
128+
)
129+
130+
if [[ "${VERBOSE_LEVEL}" -lt "${VERBOSE_INFO}" ]]; then
131+
sleep 2s
132+
return "${EXIT_SUCCESS}"
133+
fi
134+
135+
for i in "${SPIN[@]}"; do
136+
echo -ne "\r[${i}] ${1}"
137+
sleep 0.5s
138+
done
139+
140+
echo -ne "\033[1K\r"
141+
}
142+
50143
function WaitForDevice() {
51144
local -i QUERY_RETRY_COUNT_MAX="10"
52145
local -i QUERY_RETRY_COUNT="0"
53146

54-
${QUERY_CMD} > /dev/null
147+
${QUERY_CMD} &> /dev/null
55148

56149
while [[ ("${QUERY_RETRY_COUNT}" -lt "${QUERY_RETRY_COUNT_MAX}") && ("$?" -ne "0") ]]; do
57150
sleep 1s
58151
((QUERY_RETRY_COUNT++))
59-
${QUERY_CMD} > /dev/null
152+
${QUERY_CMD} &> /dev/null
60153
done
61154
}
62155

63156
function RunCmd() {
64-
$1
65-
if [[ $? != 0 ]]; then
66-
echo "Command failed: cmd=$1, errno=$?"
67-
exit "${EXIT_ERROR}"
157+
local _EXIT_CODE="${EXIT_SUCCESS}"
158+
159+
if [[ "${VERBOSE_LEVEL}" -eq "${VERBOSE_MAX}" ]]; then
160+
eval "$@"
161+
else
162+
eval "$@" &>/dev/null
163+
fi
164+
165+
_EXIT_CODE="$?"
166+
if [[ "${_EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
167+
ExitFailure "command failed: $@"
68168
fi
69169
}
70170

71-
function UpgradeFW() {
171+
function UpgradeASICFW() {
72172
local _FW_FILE="$1"
73173

74-
if [ ! -z "${_FW_FILE}" ]; then
75-
if [ ! -f "${_FW_FILE}" ]; then
76-
echo "No such file: ${_FW_FILE}"
77-
exit "${EXIT_ERROR}"
174+
if [[ ! -z "${_FW_FILE}" ]]; then
175+
if [[ ! -f "${_FW_FILE}" ]]; then
176+
ExitFailure "no such file: ${_FW_FILE}"
78177
fi
79178

80-
RunCmd "${QUERY_CMD} -i ${_FW_FILE}" > "${QUERY_FILE}"
179+
RunCmd "${QUERY_CMD} -i ${_FW_FILE} > ${QUERY_FILE}"
81180

82181
local -r _FW_INFO="$(grep FW ${QUERY_FILE})"
83182
local -r _FW_CURRENT="$(echo ${_FW_INFO} | cut -f2 -d' ')"
84183
local -r _FW_AVAILABLE="$(echo ${_FW_INFO} | cut -f3 -d' ')"
85184
else
86-
RunCmd "${QUERY_CMD}" > "${QUERY_FILE}"
185+
RunCmd "${QUERY_CMD} > ${QUERY_FILE}"
87186

88187
local -r _FW_INFO="$(grep FW ${QUERY_FILE})"
89188
local -r _FW_CURRENT="$(echo ${_FW_INFO} | cut -f2 -d' ')"
@@ -93,51 +192,148 @@ function UpgradeFW() {
93192
fi
94193

95194
if [[ -z "${_FW_CURRENT}" ]]; then
96-
echo "Could not retreive current FW version"
97-
exit "${EXIT_ERROR}"
195+
ExitFailure "could not retrieve current ASIC firmware version"
98196
fi
99197

100198
if [[ -z "${_FW_AVAILABLE}" ]]; then
101-
echo "Could not retreive available FW version"
102-
exit "${EXIT_ERROR}"
199+
ExitFailure "could not retrieve available ASIC firmware version"
200+
fi
201+
202+
if [[ "${_FW_CURRENT}" = "${_FW_AVAILABLE}" ]]; then
203+
LogInfo "ASIC firmware is up to date"
204+
return "${EXIT_SUCCESS}"
205+
fi
206+
207+
LogNotice "ASIC firmware upgrade is required. Installing compatible version..."
208+
209+
LogInfo "current ASIC firmware version: ${_FW_CURRENT}"
210+
LogInfo "target ASIC firmware version: ${_FW_AVAILABLE}"
211+
212+
LogInfo "ASIC firmware file: ${_FW_FILE}"
213+
214+
RunCmd "${BURN_CMD} -i ${_FW_FILE}"
215+
}
216+
217+
function UpgradeCPLDFW_Worker() {
218+
local -r _CPLD_BURN_FILE="${1}"
219+
local -r _CPLD_REFRESH_FILE="${2}"
220+
local -r _ASIC_DEV="$(find /dev/mst -iname '*_pciconf0')"
221+
222+
if [[ "${UPDATE_MLNX_CPLD_FW}" = "1" ]]; then
223+
RunCmd "cpldupdate --dev ${_ASIC_DEV} ${_CPLD_REFRESH_FILE}"
224+
return "${EXIT_SUCCESS}"
103225
fi
104226

105-
if [[ "${_FW_CURRENT}" == "${_FW_AVAILABLE}" ]]; then
106-
echo "Mellanox firmware is up to date"
227+
RunCmd "cpldupdate --dev ${_ASIC_DEV} ${_CPLD_BURN_FILE}"
228+
RunCmd "cpldupdate --dev ${_ASIC_DEV} ${_CPLD_REFRESH_FILE}"
229+
}
230+
231+
function UpgradeCPLDFW() {
232+
local -r _CPLD_ARCHIVE="$1"
233+
234+
if [[ "${UPDATE_MLNX_CPLD_FW}" = "1" ]]; then
235+
LogWarning "forced CPLD refresh was requested for ${ONIE_PLATFORM}"
236+
CPLD_UPGRADE="${YES_PARAM}"
237+
fi
238+
239+
if [[ "${CPLD_UPGRADE}" != "${YES_PARAM}" ]]; then
240+
LogNotice "CPLD upgrade was not requested for ${ONIE_PLATFORM}"
241+
return "${EXIT_SUCCESS}"
242+
fi
243+
244+
if [[ ! -f "${_CPLD_ARCHIVE}" ]]; then
245+
LogNotice "CPLD update $(basename ${_CPLD_ARCHIVE}) was not provided for ${ONIE_PLATFORM}"
246+
return "${EXIT_SUCCESS}"
247+
fi
248+
249+
CPLD_DIR="$(mktemp -d)"
250+
251+
RunCmd "tar xzf ${_CPLD_ARCHIVE} -C ${CPLD_DIR}"
252+
253+
local -r _CPLD_BURN_FILE="${CPLD_DIR}/$(cat ${CPLD_DIR}/bundle.txt | grep 'burn=' | cut -f2 -d'=')"
254+
local -r _CPLD_REFRESH_FILE="${CPLD_DIR}/$(cat ${CPLD_DIR}/bundle.txt | grep 'refresh=' | cut -f2 -d'=')"
255+
local -r _CPLD_VERSION="$(cat ${CPLD_DIR}/bundle.txt | grep 'version=' | cut -f2 -d'=')"
256+
257+
local _CURRENT_CPLD_VERSION="${_CPLD_VERSION}"
258+
local _TARGET_CPLD_VERSION="${_CPLD_VERSION}"
259+
260+
if [[ -f /bsp/cpld/cpld_mgmt_version ]]; then
261+
_CURRENT_CPLD_VERSION="$(cat /bsp/cpld/cpld_mgmt_version)"
262+
elif [[ -f /var/run/hw-management/system/cpld1_version ]]; then
263+
_CURRENT_CPLD_VERSION="$(cat /var/run/hw-management/system/cpld1_version)"
107264
else
108-
echo "Mellanox firmware upgrade is required. Installing compatible version..."
109-
RunCmd "${BURN_CMD} -i ${_FW_FILE}"
265+
ExitFailure "could not retrieve current CPLD firmware version"
110266
fi
267+
268+
if [[ "${_CURRENT_CPLD_VERSION}" = "${_TARGET_CPLD_VERSION}" ]]; then
269+
LogInfo "CPLD firmware is up to date"
270+
return "${EXIT_SUCCESS}"
271+
fi
272+
273+
LogNotice "CPLD firmware upgrade is required. Installing compatible version..."
274+
275+
LogInfo "current CPLD firmware version: ${_CURRENT_CPLD_VERSION}"
276+
LogInfo "target CPLD firmware version: ${_TARGET_CPLD_VERSION}"
277+
278+
LogInfo "CPLD burn firmware file: ${_CPLD_BURN_FILE}"
279+
LogInfo "CPLD refresh firmware file: ${_CPLD_REFRESH_FILE}"
280+
281+
UpgradeCPLDFW_Worker "${_CPLD_BURN_FILE}" "${_CPLD_REFRESH_FILE}" &
282+
local -r _PID="$!"
283+
284+
while $(ps -e -o pid | grep -E "^[[:blank:]]*${_PID}$" &> /dev/null); do
285+
ShowProgressBar "CPLD update..."
286+
done
287+
288+
RunCmd "wait ${_PID}"
111289
}
112290

113291
function UpgradeFWFromImage() {
114-
local -r _NEXT_SONIC_IMAGE="$(sonic_installer list | grep "Next: " | cut -f2 -d' ')"
115-
local -r _CURRENT_SONIC_IMAGE="$(sonic_installer list | grep "Current: " | cut -f2 -d' ')"
292+
local -r _NEXT_SONIC_IMAGE="$(sonic_installer list | grep 'Next: ' | cut -f2 -d' ')"
293+
local -r _CURRENT_SONIC_IMAGE="$(sonic_installer list | grep 'Current: ' | cut -f2 -d' ')"
116294

117-
local -r _FS_PATH="/host/image-${_NEXT_SONIC_IMAGE#SONiC-OS-}/fs.squashfs"
118-
local -r _FS_MOUNTPOINT="/tmp/image-${_NEXT_SONIC_IMAGE#SONiC-OS-}-fs"
295+
if [[ "${_CURRENT_SONIC_IMAGE}" = "${_NEXT_SONIC_IMAGE}" ]]; then
296+
ExitSuccess "firmware is up to date"
297+
fi
119298

120-
if [[ "${_CURRENT_SONIC_IMAGE}" == "${_NEXT_SONIC_IMAGE}" ]]; then
121-
echo "Mellanox firmware is up to date"
122-
else
123-
mkdir -p "${_FS_MOUNTPOINT}"
124-
mount -t squashfs "${_FS_PATH}" "${_FS_MOUNTPOINT}"
299+
FS_PATH="/host/image-${_NEXT_SONIC_IMAGE#SONiC-OS-}/fs.squashfs"
300+
FS_MOUNTPOINT="/tmp/image-${_NEXT_SONIC_IMAGE#SONiC-OS-}-fs"
125301

126-
UpgradeFW "${_FS_MOUNTPOINT}/etc/mlnx/fw-SPC.mfa"
302+
RunCmd "mkdir -p ${FS_MOUNTPOINT}"
303+
RunCmd "mount -t squashfs ${FS_PATH} ${FS_MOUNTPOINT}"
127304

128-
umount -rf "${_FS_MOUNTPOINT}"
129-
rm -rf "${_FS_MOUNTPOINT}"
305+
UpgradeASICFW "${FS_MOUNTPOINT}${FW_FILE}"
306+
UpgradeCPLDFW "${FS_MOUNTPOINT}/etc/mlnx/cpld/${ONIE_MACHINE#mlnx_}_cpld.tar.gz"
307+
}
308+
309+
function Cleanup() {
310+
if [[ -d "${FS_MOUNTPOINT}" ]]; then
311+
umount -rf "${FS_MOUNTPOINT}"
312+
rm -rf "${FS_MOUNTPOINT}"
313+
fi
314+
315+
if [[ -d "${CPLD_DIR}" ]]; then
316+
rm -rf "${CPLD_DIR}"
130317
fi
131318
}
132319

320+
trap Cleanup EXIT
321+
322+
ParseMachineConf
133323
ParseArguments "$@"
134324

135325
WaitForDevice
136326

137-
if [ "${IMAGE_UPGRADE}" != "yes" ]; then
138-
UpgradeFW
139-
else
327+
if [[ "${CPLD_UPGRADE}" = "${YES_PARAM}" ]]; then
328+
if [[ "${IMAGE_UPGRADE}" = "${NO_PARAM}" ]]; then
329+
ExitFailure "mandatory parameter was not provided: -u|--upgrade"
330+
fi
331+
fi
332+
333+
if [[ "${IMAGE_UPGRADE}" = "${YES_PARAM}" ]]; then
140334
UpgradeFWFromImage
335+
else
336+
UpgradeASICFW
141337
fi
142338

143-
exit "${EXIT_SUCCESS}"
339+
ExitSuccess "firmware upgrade is completed"

0 commit comments

Comments
 (0)