-
-
Save dafta/0aadeba3aa8bcbbc8b92a233977571ed to your computer and use it in GitHub Desktop.
#!/bin/sh | |
if [ "$UID" -ne 0 ]; then | |
echo "This script needs to be executed as root" | |
exit 1 | |
fi | |
vendor_id="0x3000" # Valve | |
product_id="0x28DE" | |
serial_number="$(dmidecode -s system-serial-number)" # The Steam Deck's serial number | |
manufacturer="Valve" # Manufacturer | |
product="Steam Deck" # Product | |
device="0x1004" # Device version | |
usb_version="0x0200" # USB 2.0 | |
device_class="2" # Communications | |
cfg1="CDC" # Config 1 description | |
cfg2="RNDIS" # Config 2 description | |
power=250 # Max power | |
dev_mac1="42:61:64:55:53:42" | |
host_mac1="48:6f:73:74:50:43" | |
dev_mac2="42:61:64:55:53:44" | |
host_mac2="48:6f:73:74:50:45" | |
ms_vendor_code="0xcd" # Microsoft | |
ms_qw_sign="MSFT100" # Microsoft | |
ms_compat_id="RNDIS" # Matches Windows RNDIS drivers | |
ms_subcompat_id="5162001" # Matches Windows RNDIS 6.0 driver | |
cdc_mode="ecm" # Which CDC gadget to use | |
start_rndis=true # Whether to start the Microsoft RNDIS gadget | |
while getopts "ncerR" option ${@:2}; do | |
case "${option}" in | |
"n") | |
cdc_mode=ncm | |
;; | |
"c") | |
cdc_mode=ecm | |
;; | |
"e") | |
cdc_mode=eem | |
;; | |
"r") | |
start_rndis=true | |
;; | |
"R") | |
start_rndis=false | |
;; | |
esac | |
done | |
case "$1" in | |
start) | |
# Create the networkd config file for the USB interface | |
cat << EOF > /etc/systemd/network/usb0.network | |
[Match] | |
Name=usb0 | |
[Network] | |
Address=192.168.100.1/24 | |
DHCPServer=true | |
IPMasquerade=ipv4 | |
[DHCPServer] | |
PoolOffset=100 | |
PoolSize=20 | |
EmitDNS=yes | |
DNS=8.8.8.8 | |
EOF | |
cat << EOF > /etc/systemd/network/usb1.network | |
[Match] | |
Name=usb1 | |
[Network] | |
Address=192.168.101.1/24 | |
DHCPServer=true | |
IPMasquerade=ipv4 | |
[DHCPServer] | |
PoolOffset=100 | |
PoolSize=20 | |
EmitDNS=yes | |
DNS=8.8.8.8 | |
EOF | |
# Start networkd | |
systemctl start systemd-networkd | |
# Enable DRD driver | |
echo -n "0000:04:00.3" > /sys/bus/pci/drivers/xhci_hcd/unbind | |
echo -n "0000:04:00.3" > /sys/bus/pci/drivers/dwc3-pci/bind | |
# Load the drivers | |
modprobe libcomposite | |
# Create the gadget | |
mkdir /sys/kernel/config/usb_gadget/g.1 | |
cd /sys/kernel/config/usb_gadget/g.1 | |
# Specify the vendor and product ID | |
echo "${vendor_id}" > idVendor | |
echo "${product_id}" > idProduct | |
# Create the gadget configuration | |
mkdir configs/c.1 | |
# Create the strings directories | |
mkdir strings/0x409 | |
mkdir configs/c.1/strings/0x409 | |
# Specify the serial number, manufacturer, and product strings | |
echo "${serial_number}" > strings/0x409/serialnumber | |
echo "${manufacturer}" > strings/0x409/manufacturer | |
echo "${product}" > strings/0x409/product | |
# Specify the device version, USB specification, and device class | |
echo "${device}" > bcdDevice | |
echo "${usb_version}" > bcdUSB | |
echo "${device_class}" > bDeviceClass | |
# Set the configuration description and power | |
echo "${cfg1}" > configs/c.1/strings/0x409/configuration | |
echo "${power}" > configs/c.1/MaxPower | |
# Create the gadget function | |
mkdir functions/${cdc_mode}.0 | |
# Set the MAC addresses of the gadget | |
echo "${host_mac1}" > functions/${cdc_mode}.0/host_addr | |
echo "${dev_mac1}" > functions/${cdc_mode}.0/dev_addr | |
# Start RNDIS if enabled | |
if [ "${start_rndis}" = true ]; then | |
# Create the gadget configuration | |
mkdir configs/c.2 | |
# Create the strings directories | |
mkdir configs/c.2/strings/0x409 | |
# Specify the configuration description and power | |
echo "${cfg2}" > configs/c.2/strings/0x409/configuration | |
echo "${power}" > configs/c.2/MaxPower | |
# Set some Microsoft specific configuration | |
echo "1" > os_desc/use | |
echo "${ms_vendor_code}" > os_desc/b_vendor_code | |
echo "${ms_qw_sign}" > os_desc/qw_sign | |
# Create the gadget function | |
mkdir functions/rndis.0 | |
# Set the MAC addresses of the gadget | |
echo "${host_mac2}" > functions/rndis.0/host_addr | |
echo "${dev_mac2}" > functions/rndis.0/dev_addr | |
# Set the RNDIS driver version | |
echo "${ms_compat_id}" > functions/rndis.0/os_desc/interface.rndis/compatible_id | |
echo "${ms_subcompat_id}" > functions/rndis.0/os_desc/interface.rndis/sub_compatible_id | |
fi | |
# Associate the CDC function with its configuration | |
ln -s functions/${cdc_mode}.0 configs/c.1/ | |
# Associate the RNDIS function with its configuration | |
if [ "${start_rndis}" = true ]; then | |
ln -s functions/rndis.0 configs/c.2 | |
ln -s configs/c.2 os_desc | |
fi | |
# Enable the gadget | |
ls /sys/class/udc > UDC | |
;; | |
stop) | |
# Disable the gadget | |
cd /sys/kernel/config/usb_gadget/g.1 | |
echo "" > UDC | |
# Remove functions from the configuration | |
rm configs/c.1/ncm.0 2> /dev/null | |
rm configs/c.1/ecm.0 2> /dev/null | |
rm configs/c.1/eem.0 2> /dev/null | |
rm configs/c.2/rndis.0 2> /dev/null | |
# Remove the strings directories in configurations | |
rmdir configs/c.1/strings/0x409 | |
rmdir configs/c.2/strings/0x409 2> /dev/null | |
# Remove the configurations | |
rmdir configs/c.1 | |
rm os_desc/c.2 2> /dev/null | |
rmdir configs/c.2 2> /dev/null | |
# Remove the functions | |
rmdir functions/ncm.0 2> /dev/null | |
rmdir functions/ecm.0 2> /dev/null | |
rmdir functions/eem.0 2> /dev/null | |
rmdir functions/rndis.0 2> /dev/null | |
# Remove the strings directories in the gadget | |
rmdir strings/0x409 | |
# Delete the gadget | |
cd .. | |
rmdir g.1 | |
# Unload the drivers | |
cd ../../ | |
modprobe -r usb_f_ncm | |
modprobe -r usb_f_ecm | |
modprobe -r usb_f_eem | |
modprobe -r usb_f_rndis | |
modprobe -r libcomposite | |
# Disable DRD driver | |
echo -n "0000:04:00.3" > /sys/bus/pci/drivers/dwc3-pci/unbind | |
echo -n "0000:04:00.3" > /sys/bus/pci/drivers/xhci_hcd/bind | |
# Stop networkd | |
systemctl stop systemd-networkd 2> /dev/null | |
# Remove the networkd config files for USB interfaces | |
rm /etc/systemd/network/usb0.network | |
rm /etc/systemd/network/usb1.network | |
;; | |
*) | |
echo "Usage:" | |
echo -e "\t./usb-ether.sh start\tStarts the USB ethernet" | |
echo -e "\t\t-n\tUse the CDC-NCM USB Ethernet driver (for OSX and iOS)" | |
echo -e "\t\t-c\tUse the CDC-ECM USB Ethernet driver (default)" | |
echo -e "\t\t-e\tUse the CDC-EEM USB Ethernet driver" | |
echo -e "\t\t-r\tEnable the RNDIS USB Ethernet driver for Windows (default)" | |
echo -e "\t\t-R\tDisable the RNDIS USB Ethernet driver for Windows" | |
echo -e "\t./usb-ether.sh stop - Stops the USB ethernet" | |
;; | |
esac |
Is there any chance of this being made into a Decky plugin like mentioned here?
I'm already working on it, but progress is slow when DRD breaks every other update by Valve.
Completely fair, glad to hear it. Thank you for all your hard work!
so i'm no linux genius, is this an install or a no-install?
@indianaliam1 No install, just download and run the script from a terminal.
seems didnt work with last update
This from above fixed it for me on the current version:
echo -n "0000:04:00.3" > /sys/bus/pci/drivers/xhci_hcd/unbind
echo -n "0000:04:00.3" > /sys/bus/pci/drivers/dwc3-pci/bind
I had thought I had done this back in May but if I just do sudo then these commands it didn't work. I needed to use "sudo -i" to go into the root user account outright, issue these commands, and then issue the command "exit" to leave and go back to my normal user account.
if you issue the command "sudo lspci -v" from your usual user account you'll be able to see what driver is being used for your different devices, going down to 04.00.3 you'll be able to see if it says xhci or dwc3 as the active driver. For DRD to be the one you are using it needs to show dwc3 as the active driver instead of the xhci.
Ensuring that DRD is selected in the UEFI doesn't seem to be enough to get it to actually use DRD instead of XHCI in the current version.
Edit: Yep, I just disabled, booted, checked, re-enabled, booted, checked and all enabling DRD seems to do in latest builds is allow dwc3 to be an option, but not actually make it the active option, and the script can't make it the active driver either.
but if I just do sudo then these commands it didn't work. I needed to use "sudo -i" to go into the root user account outright, issue these commands, and then issue the command "exit" to leave and go back to my normal user account.
This is because of how bash works. When you do the above commands with sudo, it's the echo command that's run as root, but the redirect to file is done as the normal bash user and therefore doesn't have permission to write to that file. You can avoid this by replacing the file redirect with the tee
command, like this:
echo -n "0000:04:00.3" | sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind
echo -n "0000:04:00.3" | sudo tee /sys/bus/pci/drivers/dwc3-pci/bind
Notice that only tee
has sudo
in front of it, and not echo
.
and the script can't make it the active driver either.
Not sure what you mean by this. In it's current state, yeah it doesn't, but if you add the two commands to the start and end respectively (the original version, you don't need the tee
command here because the whole script is run as root), then the script would handle making the correct driver active.
@dafta wow, your approach works, all i need its dhcp server in steamdeck, thank you!
@dafta wow, your approach works, all i need its dhcp server in steamdeck, thank you!
Does the DHCP server not work for you? It should be included in systemd-networkd, and the configuration that's included in this script is supposed to enable the DHCP server on that network, lines 60 and 76.
@dafta wow, your approach works, all i need its dhcp server in steamdeck, thank you!
Does the DHCP server not work for you? It should be included in systemd-networkd, and the configuration that's included in this script is supposed to enable the DHCP server on that network, lines 60 and 76.
I have no idea what happens with him, so I just use static address, also I executed this in terminal on steamdeck sudo ip addr add 192.168.100.2/24 dev usb0
for static ip
sudo ip link set usb0 up
Okay, that's interesting. I'll try and see if it works for me.
So for the Arch Linux noobs who have stumbled over this script, could I talk someone here into writing up a step-by-step for this? I've done my best to google my way through things-- I'm into hour six of trying-- but I haven't had any luck with it. The script ran, but I honestly don't know what to do next. The deck shows a wired connection (Io) as well as wireless, but either something went wrong halfway through, or something's messed up with the Io connection settings. Ideally I'd like to get it set up so that I can click a shortcut(s?) on the desktop as a toggle, but just really ANY kind of help or guide would be much appreciated. Steam Link over USB is a tantalizing prospect, so I have a hunch I won't be the only one to end up in the weeds on this. Help, pretty please?
So for the Arch Linux noobs who have stumbled over this script, could I talk someone here into writing up a step-by-step for this? I've done my best to google my way through things-- I'm into hour six of trying-- but I haven't had any luck with it. The script ran, but I honestly don't know what to do next. The deck shows a wired connection (Io) as well as wireless, but either something went wrong halfway through, or something's messed up with the Io connection settings. Ideally, I'd like to get it set up so that I can click a shortcut(s?) on the desktop as a toggle, but just really ANY kind of help or guide would be much appreciated. Steam Link over USB is a tantalizing prospect, so I have a hunch I won't be the only one to end up in the weeds on this. Help, pretty please?
there are 2 steps you need to additionally:
- before running script use
echo -n "0000:04:00.3" | sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind
echo -n "0000:04:00.3" | sudo tee /sys/bus/pci/drivers/dwc3-pci/bind
- after running the script with the correct parameter (it depends on the client OS you want to use) you need to configure either DHCP or static address for host and client.
sudo ip addr add 192.168.100.2/24 dev usb0
sudo ip link set usb0
next just test via ping or iperf3 -c 192.168.100.1 if you configure 100.x subnet.
- before running script use
echo -n "0000:04:00.3" | sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind echo -n "0000:04:00.3" | sudo tee /sys/bus/pci/drivers/dwc3-pci/bind
I added this directly into the script, so this isn't necessary if you have the latest version of the script.
You should also check if you enabled USB DRD in the BIOS, and that you have a recent BIOS version that has working DRD.
Also, @kolanski I tried the script again to see if it works still, and DHCP was working for me. I'm not sure why it doesn't work for you.
Also, @kolanski I tried the script again to see if it works still, and DHCP was working for me. I'm not sure why it doesn't work for you.
I just have old revision of script)
@dafta Thanks for the swift reply. It does seem unlikely that my dock is capable of that, there was one entry in UDC folder while nothing is plugged, and then no entries while docked.
Also looked around in dmesg output for clues, the dock shows up there as a "xHCI Host Controller" with the manufacturer as "Linux 6.1.52-valve16-1-neptune-61 xhci-hcd", despite DRD being ON. Didn't find if this can be changed somehow, probably not.
So yeah, doesn't really seem to work, but thanks for clarifying nonetheless.