-
-
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 |
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)
Is there meant to be anything on screen when I run usb-ether.sh start?
I run the script and then it just puts me back into bash.
Running sudo lspci -v seems to show it's still using the xhci driver, and running usb-tether.sh stop shows that no such device exists.
Running usb-ether.sh twice in a row results in things showing up, and Windows making the usb sound, but it gives device is busy errors and I don't see anything available on Windows.
I'm on bios F7A0120, which reading through here appears to be a supported bios.
Edit: I was looking in the wrong place in lspci, it shows that the driver is replaced properly
There's no output when the script runs correctly.
Edit: I was looking in the wrong place for lspci, it shows that the driver is replaced properly
What do you mean by this?
I was looking at the title, which said "[xhci]" when I should've been looking at active driver.
In any case, if there's no output when I start the script, how do I know if the script is working or not? I know that when I try to stop it, it says no device exists, which suggests starting it doesn't make it fully work.
I know that when I try to stop it, it says no device exists, which suggests starting it doesn't make it fully work.
It's most likely lines 217 and 218 that say this, in which case it's safe to ignore the message. This is an optional step to revert lines 90 and 91, which also might not be necessary in certain conditions.
In any case, if there's no output in the start script, it should work. You should only have to run start once. You can try restarting the steam deck to remove any configuration that might be leftover from starting it twice or incorrectly stopping it, just in case, and then starting the script. Also, check if DRD is enabled in the BIOS. BIOS 120 did work, but it was a bit finnicky and it might require you to disable DRD, restart, and reenable DRD. Instead of that, you could also upgrade your BIOS to a newer version, as 121 and onwards seem to have fixed most of the quirkiness.
Sorry for taking so long to respond back, but it does not seem like I'm able to get it working on 120 even after disabling, restarting, and reenabling DRD. I don't hear anything in windows when I plug the usb cable either. It just doesn't seem to want to do anything until I run start twice, which causes Windows to detect the usb but doesn't seem to work by other means. And it appears to be line 177 that is saying "no such device", not 217 or 218
I switched to the beta branch which is on 131 and it seems to also be giving me issues. It tells me "No such Device" and "Device or resource busy" on lines 90 and 91.
Edit: I switched back to stable and I'm still on 131. Guess the deck doesn't allow for downgrades using that method.
Either way the first part still applies. I'm getting the same exact response.
I switched to the beta branch which is on 131 and it seems to also be giving me issues. It tells me "No such Device" and "Device or resource busy" on lines 90 and 91.
This should be okay as those lines fail because the USB controller is already bound to the correct driver, hence the "No such device" when trying to unbind from the one that's not loaded and the "Device busy" when trying to bind to the one that already is.
And it appears to be line 177 that is saying "no such device", not 217 or 218
This, however, shouldn't happen. Several things to try here. First would be to check in the BIOS if DRD is enabled, because the BIOS options get reset to the new BIOS version's default settings, which are currently set to DRD off. And again, if it's on already, turn it off, reboot, and turn it on again, in case the option wasn't appplied correctly on update.
Next, you could remove entirely the lines 90-91 and 217-218, as they don't seem to be needed in your case and the script might exit prematurely when those commands fail.
If none of those work, could you show me the output of lsmod | grep dwc
?
dwc3_pci 24576 0
The output when the script is started:
dwc3 200704 0
roles 16384 1 dwc3
ulpi 20480 1 dwc3
udc_core 81920 5 usb_f_rndis, u_ether, usb_f_ecm,libcomposite,dwc3
dwc3_pci 24576 0
The output when the script is stopped is the same, except for udc_core
udc core 81920 1 dwc3
hello i new on linux, i have a steamdeck i have a error for to use this scrypt , i want connect at my mbp for play with steam link my bios is F7A0131 sudo /home/deck/Desktop/usb-ether.sh start -n
0000:04:00.3tee: /sys/bus/pci/drivers/xhci_hcd/unbind: Aucun périphérique de ce type
tee: /sys/bus/pci/drivers/dwc3-pci/bind: Aucun fichier ou dossier de ce type
0000:04:00.3mkdir: impossible de créer le répertoire « /sys/kernel/config/usb_gadget/g.1 »: Le fichier existe
mkdir: impossible de créer le répertoire « configs/c.1 »: Le fichier existe
mkdir: impossible de créer le répertoire « strings/0x409 »: Le fichier existe
mkdir: impossible de créer le répertoire « configs/c.1/strings/0x409 »: Le fichier existe
mkdir: impossible de créer le répertoire « functions/ncm.0 »: Le fichier existe
/home/deck/Desktop/usb-ether.sh: ligne 129 : echo: erreur d'écriture : Périphérique ou ressource occupé
/home/deck/Desktop/usb-ether.sh: ligne 130 : echo: erreur d'écriture : Périphérique ou ressource occupé
mkdir: impossible de créer le répertoire « configs/c.2 »: Le fichier existe
mkdir: impossible de créer le répertoire « configs/c.2/strings/0x409 »: Le fichier existe
mkdir: impossible de créer le répertoire « functions/rndis.0 »: Le fichier existe
/home/deck/Desktop/usb-ether.sh: ligne 153 : echo: erreur d'écriture : Périphérique ou ressource occupé
/home/deck/Desktop/usb-ether.sh: ligne 154 : echo: erreur d'écriture : Périphérique ou ressource occupé
ln: impossible de créer le lien symbolique 'configs/c.1/ncm.0': Le fichier existe
ln: impossible de créer le lien symbolique 'configs/c.2/rndis.0': Le fichier existe
ln: impossible de créer le lien symbolique 'os_desc/c.2': Le fichier existe
I'm not sure what I did, but after a combination of messing around with this script and another script I found on the reddit thread, I did finally managed to get this to work. It felt like I was cheating the system because of how many attempts failed but I finally got it to work once.
I opened the deck and applied an update that came out today. And now the script doesn't work again. Using my previous method of running the script twice is no longer working, either. For that matter, before the update the gadget would still persist even after restarting the system, but after the update, restarting the system now results in the gadget being deleted.
I can't help but to feel that Valve put a hard lockdown on sys in the recent update, or something. I thought I'd at least let you know, just in case the latest update did actually end up killing the script.
I believe that this issue has always been on the deck's side. There's no indication that the script was functioning, and when trying to stop it, it'd say the device (the gadget) doesn't exist, suggesting it was never created in the first place. It would be nice to get more hands on troubleshooting with this, but with the latest update, I'm unsure if there's anything that can be done about it now. Unless I'm messing something up, somehow. I did check the folders that were supposed to be created when the script is run, so the only thing I can guess is that it's actually running the gadget that isn't working, and the script has no way of showcasing it working or not.
DRD is on, and I've disabled/enabled it many times. Doing anything with the bios and messing with the USB cable make no difference. At this point even lsmod is only showing one line, instead of the many I showed before. My BIOS version is still 131. It hasn't changed with the update.
I'm not sure what I did, but after a combination of messing around with this script and another script I found on the reddit thread, I did finally managed to get this to work. It felt like I was cheating the system because of how many attempts failed but I finally got it to work once.
I opened the deck and applied an update that came out today. And now the script doesn't work again. Using my previous method of running the script twice is no longer working, either. For that matter, before the update the gadget would still persist even after restarting the system, but after the update, restarting the system now results in the gadget being deleted.
I can't help but to feel that Valve put a hard lockdown on sys in the recent update, or something. I thought I'd at least let you know, just in case the latest update did actually end up killing the script.
I believe that this issue has always been on the deck's side. There's no indication that the script was functioning, and when trying to stop it, it'd say the device (the gadget) doesn't exist, suggesting it was never created in the first place. It would be nice to get more hands on troubleshooting with this, but with the latest update, I'm unsure if there's anything that can be done about it now. Unless I'm messing something up, somehow. I did check the folders that were supposed to be created when the script is run, so the only thing I can guess is that it's actually running the gadget that isn't working, and the script has no way of showcasing it working or not.
DRD is on, and I've disabled/enabled it many times. Doing anything with the bios and messing with the USB cable make no difference. At this point even lsmod is only showing one line, instead of the many I showed before. My BIOS version is still 131. It hasn't changed with the update.
I think we need to freeze steam os version it worked.
I think we need to freeze steam os version it worked.
What do you mean? How would we freeze the steam os version?
I can't help but to feel that Valve put a hard lockdown on sys in the recent update, or something. I thought I'd at least let you know, just in case the latest update did actually end up killing the script.
It's very likely that an update did end up killing the script, but it's not Valve putting a hard lockdown on anything. This happens every now and again because they aren't currently focused on USB DRD and the drivers sometimes stop working until they fix it. It's just a matter of time until it starts working again. It might even work on the beta right now, or stable if you're on beta. It's also possible that the script needs updating.
There's no indication that the script was functioning
I never added any, this script was mostly a proof of concept.
with the latest update, I'm unsure if there's anything that can be done about it now.
Like I said, it's only a matter of time until it works again, or the script might need updating. I will, however, not be updating this script, it's provided as-is and is and always was just a proof of concept. I'm working on instead adding this feature to my decky plugin, DeckMTP, with the next version, and slowly adding more USB gadgets and features with time.
Ah, I thought the plugin was cancelled since I first saw it mentioned years ago. Is it something you're actively working on, or are you waiting on something else before you can work on it?
The main thing I'd like is to remove the latency in Steam Link between the deck and my PC, since my router is on the other side of the house from where my computer is. And throughout what I've searched, it seemed like this script was the only thing I could find that could do it. Would the plugin be able to do this? And would it be anything I could use within the next year or two?
No, the plugin was never canceled, some things had to be rewritten first to allow this to happen. I'm still working on it, however this is unpaid work that I'm working on in my free time whenever I'm able to and I'm not burnt out from actual work.
Would the plugin be able to do this?
Both the plugin, and this script if you manage to get it to run, should be able to do this. I've seen people use this script for this exact reason.
And would it be anything I could use within the next year or two?
It's the very next thing on my list of priorities. A couple of months will do it most likely.
I'm already working on it, but progress is slow when DRD breaks every other update by Valve.