intel: implement support for RPC-powered xmm7360
Signed-off-by: Thomas Vogt <acc-github@tovotu.de>
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# 2024 Thomas Vogt
|
||||
#
|
||||
# RPC-powered Intel XMM7360 (8086:7360) FCC unlock
|
||||
|
||||
if [[ "$FCC_UNLOCK_DEBUG_LOG" == '1' ]]; then
|
||||
exec 3>&1 4>&2
|
||||
trap 'exec 2>&4 1>&3' 0 1 2 3
|
||||
exec 1>>/var/log/mm-xmm7360-fcc.log 2>&1
|
||||
fi
|
||||
|
||||
# require program name and at least 2 arguments
|
||||
[ $# -lt 2 ] && exit 1
|
||||
|
||||
# first argument is DBus path, not needed here
|
||||
shift
|
||||
|
||||
# second and next arguments are control port names
|
||||
for PORT in "$@"; do
|
||||
# support for XMM7360 has been added in 5.18
|
||||
# match port type, assuming Linux 5.14 and newer
|
||||
grep -q XMMRPC "/sys/class/wwan/$PORT/type" 2>/dev/null && {
|
||||
XMMRPC_PORT=$PORT
|
||||
break
|
||||
}
|
||||
done
|
||||
|
||||
# fail if no XMMRPC port exposed
|
||||
[ -n "$XMMRPC_PORT" ] || exit 2
|
||||
|
||||
DEVICE=/dev/${XMMRPC_PORT}
|
||||
|
||||
log() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "$1" >&2
|
||||
}
|
||||
|
||||
reverseHexEndianness() {
|
||||
num="$1"
|
||||
printf "%s" "${num:6:2}${num:4:2}${num:2:2}${num:0:2}"
|
||||
}
|
||||
|
||||
littleEndianToDec() {
|
||||
printf "%d" "0x$1"
|
||||
}
|
||||
|
||||
bigEndianToDec() {
|
||||
littleEndianToDec "$(reverseHexEndianness "$1")"
|
||||
}
|
||||
|
||||
readNBytesAsHex() {
|
||||
data=$(head "-c$1" <&99 | xxd -p -c0 | tr -d '\n')
|
||||
printf "%s" "$data"
|
||||
}
|
||||
|
||||
writeHexAsBinary() {
|
||||
printf "%s" "$1" | xxd -r -p >&99
|
||||
}
|
||||
|
||||
readResponseAsHex() {
|
||||
length_hex=$(readNBytesAsHex 4)
|
||||
length=$(bigEndianToDec "$length_hex")
|
||||
content=$(readNBytesAsHex $length)
|
||||
printf "%s" "$length_hex$content"
|
||||
}
|
||||
|
||||
rpc_command() {
|
||||
exec 99<>"$DEVICE"
|
||||
writeHexAsBinary $1
|
||||
answer=$(readResponseAsHex) # ignore "async-ack" response
|
||||
answer=$(readResponseAsHex)
|
||||
printf "%s" "$answer"
|
||||
exec 99>&-
|
||||
}
|
||||
|
||||
VENDOR_ID_HASH="3df8c719"
|
||||
|
||||
for i in {1..3}; do
|
||||
log "Attempt #${i} to unlock WWAN modem"
|
||||
|
||||
log "Requesting FCC lock state from modem"
|
||||
# --> (async) csi-fcc-lock-query-req
|
||||
RESP=$(rpc_command "1c00000002040000001c02040000018e11000101020411000101020400000000")
|
||||
MODE=$(littleEndianToDec "${RESP: -8}")
|
||||
STATE=$(littleEndianToDec "${RESP: -20:8}")
|
||||
|
||||
log "Got response from modem: state=$STATE, mode=$MODE"
|
||||
|
||||
if [ "$MODE" = "0" ]; then
|
||||
log "FCC lock is deactivated, nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$STATE" != "0" ]; then
|
||||
log "FCC already unlocked, nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Requesting challenge from modem"
|
||||
# --> (async) csi-fcc-lock-gen-challenge-req
|
||||
RESP=$(rpc_command "1c00000002040000001c02040000019011000101020411000101020400000000")
|
||||
HEX_CHALLENGE=$(printf "%s" "${RESP: -8}")
|
||||
|
||||
log "Got challenge from modem: $HEX_CHALLENGE"
|
||||
REVERSE_HEX_CHALLENGE=$(reverseHexEndianness "${HEX_CHALLENGE}")
|
||||
COMBINED_CHALLENGE="${REVERSE_HEX_CHALLENGE}${VENDOR_ID_HASH}"
|
||||
RESPONSE_HASH=$(printf "%s" "$COMBINED_CHALLENGE" | xxd -r -p | sha256sum | cut -d ' ' -f 1)
|
||||
REVERSED_RESPONSE=$(reverseHexEndianness "${RESPONSE_HASH:0:8}")
|
||||
|
||||
log "Sending hash to modem: $REVERSED_RESPONSE"
|
||||
# --> (async) csi-fcc-lock-ver-challenge-req
|
||||
RESP=$(rpc_command "1c00000002040000001c020400000192110001010204110001010204${REVERSED_RESPONSE}")
|
||||
UNLOCK_RESPONSE=$(littleEndianToDec "${RESP: -8}")
|
||||
|
||||
if [ "$UNLOCK_RESPONSE" = "0" ]; then
|
||||
error "Unlock failed."
|
||||
else
|
||||
log "FCC unlock successful (response $UNLOCK_RESPONSE)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
exit 2
|
||||
|
||||
@@ -15,6 +15,7 @@ examples = files(
|
||||
'1199',
|
||||
'14c3',
|
||||
'2c7c',
|
||||
'8086:7360',
|
||||
)
|
||||
|
||||
install_data(
|
||||
|
||||
Reference in New Issue
Block a user