Fast direct USB connectivity
This commit is contained in:
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
msg() {
|
||||
printf '\n==> %s\n' "$*"
|
||||
}
|
||||
|
||||
msg "Bringing down old Apple USB fallback interfaces"
|
||||
sudo ifconfig en4 down 2>/dev/null || true
|
||||
sudo ifconfig en5 down 2>/dev/null || true
|
||||
sudo ifconfig en6 down 2>/dev/null || true
|
||||
|
||||
msg "Bringing down current anpi interfaces"
|
||||
sudo ifconfig anpi0 down 2>/dev/null || true
|
||||
sudo ifconfig anpi1 down 2>/dev/null || true
|
||||
sudo ifconfig anpi2 down 2>/dev/null || true
|
||||
|
||||
msg "Stopping likely bad exporter services"
|
||||
sudo launchctl bootout system/com.apple.usbmuxd 2>/dev/null || true
|
||||
sudo launchctl bootout system/com.apple.remoted 2>/dev/null || true
|
||||
launchctl bootout "gui/$(id -u)/com.apple.remoted" 2>/dev/null || true
|
||||
|
||||
sudo pkill -x usbmuxd 2>/dev/null || true
|
||||
sudo pkill -x remoted 2>/dev/null || true
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
Now unplug and replug the cable.
|
||||
|
||||
After reconnect, press Enter to continue.
|
||||
EOF
|
||||
|
||||
read -r _
|
||||
|
||||
msg "Bringing up anpi interfaces and requesting DHCP"
|
||||
for ifn in anpi0 anpi1 anpi2; do
|
||||
sudo ifconfig "$ifn" up 2>/dev/null || true
|
||||
sudo ipconfig set "$ifn" DHCP 2>/dev/null || true
|
||||
done
|
||||
|
||||
sleep 3
|
||||
|
||||
msg "Resulting interface state"
|
||||
for ifn in anpi0 anpi1 anpi2; do
|
||||
echo
|
||||
echo "--- $ifn ---"
|
||||
ifconfig "$ifn" 2>/dev/null || true
|
||||
ipconfig getifaddr "$ifn" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Use whichever interface got 10.42.0.x or 10.43.0.x"
|
||||
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
KVER="$(uname -r)"
|
||||
WORKDIR="${HOME}/apple1905-cdcncm"
|
||||
SRCVER="6.14.0-1015.15"
|
||||
SRCNAME="linux-nvidia-6.14"
|
||||
BASE_URL="https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/${SRCNAME}/${SRCVER}"
|
||||
|
||||
ORIG="${SRCNAME}_6.14.0.orig.tar.gz"
|
||||
DIFF="${SRCNAME}_${SRCVER}.diff.gz"
|
||||
DSC="${SRCNAME}_${SRCVER}.dsc"
|
||||
|
||||
KBUILD="/lib/modules/${KVER}/build"
|
||||
|
||||
msg() { printf '\n==> %s\n' "$*"; }
|
||||
die() { echo "ERROR: $*" >&2; exit 1; }
|
||||
need_cmd() { command -v "$1" >/dev/null 2>&1 || die "Missing command: $1"; }
|
||||
|
||||
[[ $EUID -eq 0 ]] || die "Run with sudo"
|
||||
[[ -d "$KBUILD" ]] || die "Missing kernel headers/build dir: $KBUILD"
|
||||
|
||||
need_cmd curl
|
||||
need_cmd dpkg-source
|
||||
need_cmd make
|
||||
need_cmd python3
|
||||
need_cmd modprobe
|
||||
need_cmd insmod
|
||||
need_cmd modinfo
|
||||
need_cmd ip
|
||||
need_cmd dmesg
|
||||
need_cmd find
|
||||
|
||||
msg "Installing build deps"
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
linux-headers-"${KVER}" \
|
||||
dpkg-dev \
|
||||
ca-certificates \
|
||||
curl \
|
||||
kmod \
|
||||
zstd \
|
||||
python3
|
||||
|
||||
msg "Preparing workspace"
|
||||
rm -rf "$WORKDIR"
|
||||
mkdir -p "$WORKDIR"
|
||||
cd "$WORKDIR"
|
||||
|
||||
msg "Downloading exact source package for ${SRCNAME} ${SRCVER}"
|
||||
curl -fL "${BASE_URL}/${ORIG}" -o "${ORIG}"
|
||||
curl -fL "${BASE_URL}/${DIFF}" -o "${DIFF}"
|
||||
curl -fL "${BASE_URL}/${DSC}" -o "${DSC}"
|
||||
|
||||
msg "Extracting source"
|
||||
dpkg-source -x "${DSC}"
|
||||
|
||||
SRCDIR="$(find . -maxdepth 1 -mindepth 1 -type d -name "${SRCNAME}-*" | head -n1)"
|
||||
[[ -n "${SRCDIR}" ]] || die "Could not find extracted source directory"
|
||||
cd "${SRCDIR}"
|
||||
|
||||
[[ -f drivers/net/usb/cdc_ncm.c ]] || die "cdc_ncm.c not found in source tree"
|
||||
|
||||
msg "Patching cdc_ncm.c"
|
||||
python3 <<'PY'
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
p = Path("drivers/net/usb/cdc_ncm.c")
|
||||
s = p.read_text()
|
||||
|
||||
if "0x05ac, 0x1905, 0" not in s:
|
||||
block = (
|
||||
'\t/* Apple Mac direct USB-C networking quirk */\n'
|
||||
'\t{ USB_DEVICE_INTERFACE_NUMBER(0x05ac, 0x1905, 0),\n'
|
||||
'\t .driver_info = (unsigned long)&apple_private_interface_info,\n'
|
||||
'\t},\n'
|
||||
'\t{ USB_DEVICE_INTERFACE_NUMBER(0x05ac, 0x1905, 2),\n'
|
||||
'\t .driver_info = (unsigned long)&apple_private_interface_info,\n'
|
||||
'\t},\n'
|
||||
)
|
||||
|
||||
pat = re.compile(
|
||||
r'(\{\s*USB_INTERFACE_INFO\s*\(\s*USB_CLASS_COMM\s*,\s*USB_CDC_SUBCLASS_NCM\s*,\s*USB_CDC_PROTO_NONE\s*\)\s*,\s*\.driver_info\s*=\s*\(unsigned long\)&cdc_ncm_info\s*,\s*\},)',
|
||||
re.S,
|
||||
)
|
||||
s2, n = pat.subn(block + r'\1', s, count=1)
|
||||
if n != 1:
|
||||
raise SystemExit("Could not find generic CDC NCM class-match entry to patch")
|
||||
s = s2
|
||||
|
||||
# Patch old bind check if needed.
|
||||
# Old style:
|
||||
# if (!dev->in || !dev->out || !dev->status)
|
||||
# New behavior for this Mac:
|
||||
# allow missing status endpoint for 05ac:1905
|
||||
old = re.compile(
|
||||
r'if\s*\(\s*!dev->in\s*\|\|\s*!dev->out\s*\|\|\s*!dev->status\s*\)',
|
||||
re.S,
|
||||
)
|
||||
repl = (
|
||||
'if (!dev->in || !dev->out || '
|
||||
'(!dev->status && '
|
||||
'!(le16_to_cpu(dev->udev->descriptor.idVendor) == 0x05ac && '
|
||||
'le16_to_cpu(dev->udev->descriptor.idProduct) == 0x1905)))'
|
||||
)
|
||||
s, n = old.subn(repl, s, count=1)
|
||||
|
||||
# If the tree already has the newer FLAG_LINK_INTR logic, leave it alone.
|
||||
if n == 0 and "FLAG_LINK_INTR" not in s:
|
||||
raise SystemExit("Could not patch bind_common() missing-status check")
|
||||
|
||||
# Add a loud marker so we know the patched module actually loaded.
|
||||
if 'Apple 05ac:1905 quirk test module loaded' not in s:
|
||||
m = re.search(r'static\s+int\s+__init\s+cdc_ncm_init\s*\(\s*void\s*\)\s*\{', s)
|
||||
if m:
|
||||
insert_at = m.end()
|
||||
s = s[:insert_at] + '\n\tpr_info("cdc_ncm: Apple 05ac:1905 quirk test module loaded\\n");' + s[insert_at:]
|
||||
|
||||
p.write_text(s)
|
||||
print("Patched", p)
|
||||
PY
|
||||
|
||||
msg "Preparing out-of-tree build dir"
|
||||
mkdir -p buildmod
|
||||
cp drivers/net/usb/cdc_ncm.c buildmod/
|
||||
|
||||
cat > buildmod/Makefile <<'EOF'
|
||||
obj-m += cdc_ncm.o
|
||||
ccflags-y += -Wno-error
|
||||
|
||||
all:
|
||||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
|
||||
EOF
|
||||
|
||||
msg "Building patched module"
|
||||
cd buildmod
|
||||
make -C "$KBUILD" M="$PWD" modules
|
||||
PATCHED_KO="$PWD/cdc_ncm.ko"
|
||||
[[ -f "$PATCHED_KO" ]] || die "Patched cdc_ncm.ko was not built"
|
||||
|
||||
msg "Patched module info"
|
||||
modinfo "$PATCHED_KO" | sed -n '1,20p'
|
||||
|
||||
msg "Reloading module stack"
|
||||
modprobe -r cdc_mbim 2>/dev/null || true
|
||||
modprobe -r cdc_ncm 2>/dev/null || true
|
||||
insmod "$PATCHED_KO"
|
||||
|
||||
msg "Recent dmesg"
|
||||
dmesg | tail -n 60
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Done.
|
||||
|
||||
Now:
|
||||
1. run: sudo dmesg -w
|
||||
2. unplug and replug the USB-C cable to the Mac
|
||||
3. then run:
|
||||
ip -br link
|
||||
lsusb | grep 05ac:1905
|
||||
|
||||
You want to see:
|
||||
- cdc_ncm: Apple 05ac:1905 quirk test module loaded
|
||||
- no bind() failure for 05ac:1905
|
||||
- a new interface appearing
|
||||
|
||||
Workspace:
|
||||
$WORKDIR
|
||||
|
||||
EOF
|
||||
Executable
+155
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
PATCHED_CDC_NCM="/root/apple1905-cdcncm/linux-nvidia-6.14-6.14.0/buildmod/cdc_ncm.ko"
|
||||
|
||||
need() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "Missing command: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
msg() {
|
||||
printf '\n==> %s\n' "$*"
|
||||
}
|
||||
|
||||
[[ $EUID -eq 0 ]] || {
|
||||
echo "Run with sudo." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
need modprobe
|
||||
need insmod
|
||||
need nmcli
|
||||
need lsusb
|
||||
need ip
|
||||
need awk
|
||||
need grep
|
||||
|
||||
[[ -f $PATCHED_CDC_NCM ]] || {
|
||||
echo "Patched module not found: $PATCHED_CDC_NCM" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
msg "Removing old hard-block config if present"
|
||||
rm -f /etc/modprobe.d/zz-kill-mac-usb-net.conf
|
||||
depmod -a
|
||||
|
||||
msg "Loading USB4 / Type-C / Thunderbolt support"
|
||||
modprobe typec || true
|
||||
modprobe typec_ucsi || true
|
||||
modprobe ucsi_acpi || true
|
||||
modprobe thunderbolt || true
|
||||
modprobe typec_thunderbolt || true
|
||||
modprobe thunderbolt_net || true
|
||||
|
||||
msg "Unloading stock USB network stack"
|
||||
modprobe -r cdc_mbim cdc_wdm cdc_ncm cdc_ether usbnet 2>/dev/null || true
|
||||
|
||||
msg "Loading dependency modules"
|
||||
modprobe usbnet
|
||||
modprobe cdc_ether
|
||||
|
||||
msg "Loading patched cdc_ncm"
|
||||
if lsmod | grep -q '^cdc_ncm '; then
|
||||
echo "cdc_ncm already loaded"
|
||||
else
|
||||
insmod "$PATCHED_CDC_NCM"
|
||||
fi
|
||||
|
||||
msg "Current module state"
|
||||
lsmod | grep -E 'typec|ucsi|thunderbolt|cdc_ncm|cdc_ether|usbnet' || true
|
||||
|
||||
cat <<'EOF'
|
||||
|
||||
Now do this on the Mac:
|
||||
1. Run the Mac script below
|
||||
2. Replug the cable
|
||||
3. Wait for the Mac to land on the fast bus
|
||||
|
||||
Then run this same script again with:
|
||||
sudo ./spark-usbc-setup.sh finalize
|
||||
|
||||
EOF
|
||||
|
||||
if [[ ${1:-} != "finalize" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg "Waiting for Apple Mac on fast bus (Bus 004 @ 10000M or equivalent)"
|
||||
for _ in $(seq 1 60); do
|
||||
if lsusb -t | grep -q '05ac:1905\|Driver=\[none\], 10000M'; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
msg "lsusb -t snapshot"
|
||||
lsusb -t
|
||||
echo
|
||||
lsusb | grep '05ac:1905' || true
|
||||
|
||||
msg "Waiting for new Apple USB NICs"
|
||||
for _ in $(seq 1 30); do
|
||||
mapfile -t APPLE_IFS < <(
|
||||
ip -o link | awk -F': ' '{print $2}' |
|
||||
grep '^enx36be1bab12' || true
|
||||
)
|
||||
if [[ ${#APPLE_IFS[@]} -ge 2 ]]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [[ ${#APPLE_IFS[@]} -lt 2 ]]; then
|
||||
echo "Did not find two Apple USB interfaces." >&2
|
||||
ip -br link
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IF0="${APPLE_IFS[0]}"
|
||||
IF1="${APPLE_IFS[1]}"
|
||||
|
||||
msg "Found interfaces: $IF0 and $IF1"
|
||||
|
||||
msg "Resetting old NetworkManager profiles"
|
||||
nmcli connection delete mac-usb-dhcp-0 2>/dev/null || true
|
||||
nmcli connection delete mac-usb-dhcp-1 2>/dev/null || true
|
||||
|
||||
msg "Bringing up shared DHCP on both interfaces"
|
||||
nmcli connection add type ethernet ifname "$IF0" con-name mac-usb-dhcp-0
|
||||
nmcli connection modify mac-usb-dhcp-0 \
|
||||
ipv4.method shared \
|
||||
ipv6.method disabled \
|
||||
ipv4.addresses 10.42.0.1/24
|
||||
nmcli connection up mac-usb-dhcp-0
|
||||
|
||||
nmcli connection add type ethernet ifname "$IF1" con-name mac-usb-dhcp-1
|
||||
nmcli connection modify mac-usb-dhcp-1 \
|
||||
ipv4.method shared \
|
||||
ipv6.method disabled \
|
||||
ipv4.addresses 10.43.0.1/24
|
||||
nmcli connection up mac-usb-dhcp-1
|
||||
|
||||
msg "Current addresses"
|
||||
ip -br addr show dev "$IF0"
|
||||
ip -br addr show dev "$IF1"
|
||||
|
||||
msg "Recent NetworkManager log"
|
||||
journalctl -u NetworkManager -n 60 --no-pager || true
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Done.
|
||||
|
||||
DGX shared-DHCP interfaces:
|
||||
$IF0 -> 10.42.0.1/24
|
||||
$IF1 -> 10.43.0.1/24
|
||||
|
||||
Next on the Mac:
|
||||
sudo ipconfig set anpi0 DHCP
|
||||
sudo ipconfig set anpi1 DHCP
|
||||
sudo ipconfig set anpi2 DHCP
|
||||
|
||||
EOF
|
||||
Reference in New Issue
Block a user