I am doing some source code porting works on linux kernel recently.
After I reboot my server (ubuntu 14.04) into new kernel version of 3.19.8, it can’t be connected by using ssh but only by using serial port.
The server is using a USB network card, so firstly I suspect some kernel driver for USB NIC has missing in .config file. Therefore I boot back into the old version kernel and try to find some useful information in ‘dmesg’:
asix 3-1.4:1.0 eth5: register 'asix' at usb-0000:00:11.0-1.4, ASIX AX88772B USB 2.0 Ethernet, 00:24:9c:04:44:28 ...... eth3: link up, 100Mbps, full-duplex, lpa 0x45E1
The eth3 is using MII port, so when I try to grep “link up …lpa” in 3.19.8 kernel source code, I find out it must be printed by these codes in drivers/net/mii.c:
unsigned int mii_check_media (struct mii_if_info *mii,
unsigned int ok_to_print,
unsigned int init_media)
{
......
if (ok_to_print)
netdev_info(mii->dev, "link up, %uMbps, %s-duplex, lpa 0x%04X\n",
lpa2 & (LPA_1000FULL | LPA_1000HALF) ? 1000 :
media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ?
100 : 10,
duplex ? "full" : "half",
lpa);
......
The only place “ASIX AX88772B” driver call mii_check_media is in drivers/net/usb/asix_devices.c:
static int ax88772_link_reset(struct usbnet *dev)
{
u16 mode;
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
mode = AX88772_MEDIUM_DEFAULT;
......
static const struct driver_info ax88772b_info = {
.description = "ASIX AX88772B USB 2.0 Ethernet",
.bind = ax88772_bind,
.unbind = ax88772_unbind,
.status = asix_status,
.link_reset = ax88772_link_reset,
.reset = ax88772_reset,
.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
FLAG_MULTI_PACKET,
.rx_fixup = asix_rx_fixup_common,
.tx_fixup = asix_tx_fixup,
.data = FLAG_EEPROM_MAC,
};
So far, the reason is that: the system does not “reset” the USB network card after booting up. But why it only forget to reset USB NIC in 3.19.8 kernel? After checking the /etc/network/interfaces:
auto eth0 iface eth0 inet dhcp auto eth3 iface eth3 inet dhcp auto usbnet0
the answer is: the device name of the USB NIC has been changed to “eth5” by udevd in 3.9.18 kernel (new version kernel recognise new network port so eth0/eth1/eth2/eth3/eth4 all has been occupied by system) so the network scripts can’t start it up.
Solution:
Fix the name of USB NIC by adding below content into /etc/udev/rules.d/70-persistent-net.rules:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:24:9c:04:44:28", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="usbnet0"
and add configurations into /etc/network/interfaces to start “usbnet0” up automatically:
auto usbnet0 iface usbnet0 inet dhcp