inapp OTG ethernet

Setting-up the USB OTG port as an Ethernet 'gadget' device.

About "sunxi"

sunxi is the community working on the open-source environment for Allwinner chips... but it has to be kept in mind, and they write it right on the top of the front page [1], that:

Allwinner [...] is violating the GPLv2 license in several ways and has so far not shown willingness to resolve this.

sunxi has a special more-detailed page [2] about the Nano Pi NEO from FriendlyARM.

There are many ways to turn the USB OTG port into a device endpoint: [3]. Instructions for building the OTG support and the g_ether module in the kernel: [4].

USB On-the-Go with the official image (fail)

As of 2017.02.25, the kernel embedded with the official Ubuntu image is:

root@FriendlyARM:~# uname -a
Linux FriendlyARM 3.4.39-h3 #24 SMP PREEMPT Sat Feb 4 15:23:58 CST 2017 armv7l armv7l armv7l GNU/Linux

Unfortunately, they did not build the required modules with the kernel:

root@FriendlyARM:~# modprobe g_ether
modprobe: FATAL: Module g_ether not found in directory /lib/modules/3.4.39-h3

According to sunxi-3.4:

Currently, the g_ether module is not compiled as part of our kernel configuration.

USB On-the-Go with Armbian (success)

As of 2017.02.25, the kernel embedded with the Armbian Ubuntu image is:

root@nanopineo:~# uname -a
Linux nanopineo 3.4.113-sun8i #28 SMP PREEMPT Thu Feb 2 02:01:28 CET 2017 armv7l armv7l armv7l GNU/Linux

Fortunately, they did build the required modules with the kernel:

root@nanopineo:~# ls /lib/modules/3.4.113-sun8i/kernel/drivers/usb/gadget/
g_cdc.ko    g_hid.ko           g_multi.ko  g_printer.ko
g_ether.ko  g_mass_storage.ko  g_ncm.ko    g_serial.ko

Manual setup of USB-Ethernet "gadget"

Armbian is configured by default to provide a serial console (with g_serial) via USB OTG:

root@nanopineo:~# lsmod
Module                  Size  Used by
pcf8591                 3363  0
bmp085                  3487  0
g_serial               27617  0
btrfs                 712409  0

Unload the serial gadget first, make sure the current OTG role is not yet set to device. Load the ethernet gadget, and set the OTG mode:

rmmod g_serial
echo -n 0 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role
modprobe g_ether
echo -n 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role

You can check that the kernel module is loaded:

root@nanopineo:~# dmesg | grep g_ether
[    8.750273] g_ether gadget: using random self ethernet address
[    8.756928] g_ether gadget: using random host ethernet address
[    8.765644] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
[    8.765684] g_ether gadget: g_ether ready

When you change the OTG role to 2, this line is appended to syslog:

[  422.237341] g_ether gadget: high-speed config #1: CDC Ethernet (EEM)

On the other side of the USB cable, the computer should see a new USB Ethernet device:

vjp@vjp-TravelMate-P645-S:~$ lsusb
Bus 002 Device 023: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget

Note: if you type ifconfig at this point, it will not show any usb0 network interface device on the NanoPi. You have to type it explicitely:

root@nanopineo:~# ifconfig usb0
usb0      Link encap:Ethernet  HWaddr 02:78:18:6c:7c:ce
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Automatic setup of USB-Ethernet "gadget"

To prevent the module g_serial from being loaded at start-up, edit /etc/modules, and replace g_serial with g_ether.

To configure the usb0 network interface at start-up, add this to /etc/network/interfaces:

allow-hotplug usb0
iface usb0 inet static
hwaddress ether 02:78:18:6c:7c:ce
pre-up /bin/sh -c 'echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role'