Tüm eğitimler
TEKNİK REHBER GÖMÜLÜ LİNUX USB NETWORKING 2026

usbnet
Linux USB Ağ Sürücü Çatısı

USB ağ cihazlarını destekleyen Linux kernel çatı sürücüsü: mimari, desteklenen cihaz sınıfları, URB/skb akışı, mini-sürücü yazımı ve performans ayarı.

00 usbnet nedir — çatı mimari genel bakış

usbnet, USB üzerinden ethernet benzeri bağlantı sağlayan cihazlar için Linux kernel'in ortak sürücü çatısıdır. Her desteklenen cihaz türü için tekrar tekrar USB altyapısı yazmak yerine, usbnet.ko temel kodu sağlar; cihaza özgü farklılıklar küçük mini-sürücü modülleriyle eklenir.

Neden bir çatı sürücüye ihtiyaç vardır

USB ağ cihazları arasında ortak olan pek çok şey vardır: URB gönderme/alma, netdev kaydı, bağlantı durumu izleme, Ethernet çerçeve kapsülleme. Farklı olan ise her protokolün veya cihazın uyguladığı kapsülleme biçimi (RNDIS, CDC ECM, NCM, ASIX özel protokolü, vb.). usbnet bu ikisini birbirinden ayırır.

Kullanıcı alanı (socket, ping, iperf3)
        │
   Linux IP yığını (IPv4/IPv6)
        │
  net_device (eth0 / usb0)    ← usbnet çatısı kaydeder
        │
  usbnet.ko çatısı            ← ortak URB, kuyruk, timer, link
        │
  mini-sürücü                 ← cihaza özgü: bind, rx_fixup, tx_fixup
  (asix / smsc95xx / cdc_ether / rndis_host / r8152 …)
        │
  USB Core (usb_submit_urb, usb_alloc_urb)
        │
  USB Host Controller (XHCI/EHCI/OHCI)
        │
  Fiziksel USB bağlantısı — USB Ethernet dongle veya Linux gadget
    

usbnet ile yönetilen temel sorumluluklar

URB havuzuRX ve TX için URB (USB Request Block) havuzu yönetir; otomatik yeniden gönderim
netdev opsndo_open, ndo_stop, ndo_start_xmit, ndo_set_mac_address — hepsini uygular
Bağlantı izlemePeriyodik link_reset çağrısı veya CDC bildirim EP'si üzerinden carrier durumu
SKB yönetimiUSB paketlerini sk_buff'a dönüştürme ve ağ yığınına aktarma
Güç yönetimiUSB autosuspend/resume desteği, remote wakeup

Kernel kaynak konumu

drivers/net/usb/
├── usbnet.c          # Çatı çekirdeği — ~2200 satır
├── usbnet.h          # API başlıkları
├── asix_devices.c    # ASIX AX88xxx mini-sürücüsü
├── asix_common.c
├── cdc_ether.c       # CDC ECM/EEM mini-sürücüsü
├── cdc_ncm.c         # CDC NCM mini-sürücüsü
├── rndis_host.c      # RNDIS host mini-sürücüsü
├── smsc95xx.c        # SMSC LAN9500/9512 (RPi B/B+)
├── r8152.c           # Realtek RTL8152/8153 USB Ethernet
├── lan78xx.c         # Microchip LAN7800 (RPi 3B+/4)
└── ...               # ~30 mini-sürücü dosyası

01 Desteklenen cihaz sınıfları ve mini-sürücüler

usbnet çatısını kullanan mini-sürücüler iki kategoriye ayrılır: USB-IF standart CDC sınıflarını destekleyen sürücüler ve üretici özel protokollerini uygulayan sürücüler.

Standart CDC sınıf sürücüleri

ModülProtokolKullanım
cdc_ether.koCDC ECM (Ethernet Control Model)Linux gadget ECM, iOS tethering (ipheth aracılığıyla)
cdc_ncm.koCDC NCM (Network Control Model)Android 10+ tethering, Linux gadget NCM, modern dongle'lar
cdc_mbim.koMBIM (Mobile Broadband Interface Model)4G/5G USB modemler, Sierra Wireless, Quectel EC25
rndis_host.koRNDIS (Microsoft tescilli)Android tethering, Windows Phone, Linux RNDIS gadget
cdc_subset.koCDC subset (basitleştirilmiş)Blink, Epson, Sharp özel USB NIC

Üretici özel mini-sürücüleri

ModülÇipYaygın kullanım
asix.koASIX AX88172/AX88772/AX88179USB 2.0 Ethernet dongle (100M/1G)
smsc95xx.koSMSC LAN9500/9512/9514Raspberry Pi 2B, Raspberry Pi B/B+ dahili USB hub
lan78xx.koMicrochip LAN7800/7801Raspberry Pi 3B+, Raspberry Pi 4 dahili USB3 Ethernet
r8152.koRealtek RTL8152/RTL8153USB 3.0 Gigabit Ethernet dongle (TP-Link UE300 vb.)
ax88179_178a.koASIX AX88179USB 3.0 Gigabit Ethernet dongle
qmi_wwan.koQualcomm QMI modemQuectel EC20/EC25/EM06, Sierra EM7455 (LTE)
aqc111.koAquantia AQC111UUSB 3.1 Gen1 2.5G Ethernet dongle

Bir cihazın hangi modülü kullandığını bulma

# USB cihazı bağla, dmesg'de modül adını bul
dmesg | tail -30
# [  42.123] usb 1-1.2: new high-speed USB device number 5
# [  42.234] smsc95xx 1-1.2:1.0 eth0: register 'smsc95xx' at usb-bcm2708_usb-1.1

# Arayüzden modülü bul
ethtool -i eth0
# driver: smsc95xx
# version: 2.6.0
# bus-info: usb-bcm2708_usb-1.1

# lsusb ile VID:PID → modprobe.d veya modalias
lsusb | grep "0424:9514"
modinfo smsc95xx | grep "alias.*0424"

02 USB URB mekanizması ve veri akışı

usbnet'in temel görevi, Linux ağ yığını ile USB aktarım katmanı arasında verimli bir köprü kurmaktır. Bu köprü URB (USB Request Block) kuyrukları üzerine inşa edilmiştir.

RX akışı (alma)

[USB donanımı Bulk IN EP'den veri alır]
        │
  URB tamamlanma callback: rx_complete()
        │
  usbnet: SKB ayır (netdev_alloc_skb)
        │
  mini-sürücü: rx_fixup()   ← kapsülleme kaldır (RNDIS header, NCM NTB vb.)
        │
  netif_rx() / napi_gro_receive()
        │
  Linux IP yığını işler
    

TX akışı (gönderme)

[Uygulama socket'e yazar]
        │
  Linux IP yığını → ndo_start_xmit()
        │
  usbnet: SKB'yi TX kuyruğuna ekle (sk_buff_head)
        │
  usbnet_tx_timeout / txhr:
  mini-sürücü: tx_fixup()   ← başlık ekle (RNDIS header, NCM NTB oluştur)
        │
  usb_submit_urb(urb, GFP_ATOMIC)
        │
  USB donanımı Bulk OUT EP üzerinden gönderir
        │
  URB tamamlanma: tx_complete() → URB serbest bırak, kuyruktan sonraki al
    

URB havuzu boyutu

usbnet varsayılan olarak 16 RX URB ve 16 TX URB tahsis eder. Bu değer mini-sürücü tarafından driver_info.rx_urb_size ve usbnet->rx_urb_size ile ayarlanabilir.

/* usbnet.h — temel sürücü veri yapısı */
struct usbnet {
    struct usb_device    *udev;
    struct usb_interface *intf;
    struct driver_info   *driver_info;
    struct net_device    *net;
    struct sk_buff_head   txq;          /* TX kuyruğu */
    struct sk_buff_head   rxq;          /* RX kuyruğu */
    struct sk_buff_head   done;         /* tamamlanan RX SKB'ler */
    unsigned long         rx_urb_size;  /* RX URB buffer boyutu */
    unsigned              rxq_maxlen;   /* max bekleyen RX URB sayısı */
    /* ... */
};

Sıfır-uzunluk paket (ZLP) sorunu

USB Bulk aktarımlarında, veri uzunluğu endpoint'in wMaxPacketSize'ının tam katıysa, USB protokolü aktarımın bittiğini anlayamaz. usbnet, bu durumda ZLP (Zero-Length Packet) gönderir. Bazı mini-sürücüler bunu FLAG_SEND_ZLP bayrağıyla kontrol eder.

/* FLAG değerleri — driver_info.flags */
#define FLAG_FRAMING_NC    0x0001  /* NCM çerçeveleme */
#define FLAG_FRAMING_GL    0x0002  /* RNDIS çerçeveleme */
#define FLAG_FRAMING_Z     0x0004  /* Zaurus çerçeveleme */
#define FLAG_FRAMING_RN    0x0008  /* RNDIS zincir çerçeveleme */
#define FLAG_NO_SETINT     0x0010  /* SET_INTERFACE gönderme */
#define FLAG_ETHER         0x0020  /* Ethernet cihaz */
#define FLAG_SEND_ZLP      0x1000  /* ZLP gönder */

03 usbnet API — temel veri yapıları

Bir mini-sürücü yazmak veya mevcut birini anlamak için driver_info yapısı ve usbnet'in sunduğu yardımcı fonksiyonlar iyi bilinmelidir.

driver_info yapısı

/* include/linux/usb/usbnet.h */
struct driver_info {
    char    *description;

    int     flags;              /* FLAG_* bitleri */

    /* Cihaza özgü başlatma */
    int     (*bind)(struct usbnet *, struct usb_interface *);
    /* Temizleme */
    void    (*unbind)(struct usbnet *, struct usb_interface *);
    /* Bağlantı durumunu sorgula */
    int     (*status)(struct usbnet *, struct urb *);
    /* Bağlantıyı yeniden kur */
    int     (*link_reset)(struct usbnet *);
    /* Sıfırla */
    int     (*reset)(struct usbnet *);
    /* RX paketi işle: kapsüllemeyi kaldır, netif_rx çağır */
    int     (*rx_fixup)(struct usbnet *, struct sk_buff *);
    /* TX paketi hazırla: başlık ekle, SKB döndür */
    struct sk_buff *(*tx_fixup)(struct usbnet *, struct sk_buff *, gfp_t);
    /* ethtool ops (isteğe bağlı) */
    void    (*recover)(struct usbnet *);

    int     in;                 /* Bulk IN endpoint indeksi */
    int     out;                /* Bulk OUT endpoint indeksi */
    unsigned long   data;       /* mini-sürücü özel veri */
};

usb_driver ile usbnet kayıt

/* Örnek: basit CDC ECM benzeri kayıt */
static const struct usb_device_id my_products[] = {
    {
        USB_DEVICE(0x1234, 0xabcd),
        .driver_info = (unsigned long)&my_info,
    },
    {},
};
MODULE_DEVICE_TABLE(usb, my_products);

static struct usb_driver my_driver = {
    .name       = "my_usbnet",
    .id_table   = my_products,
    .probe      = usbnet_probe,      /* usbnet çatısı probe — doğrudan kullan */
    .disconnect = usbnet_disconnect,
    .suspend    = usbnet_suspend,
    .resume     = usbnet_resume,
    .supports_autosuspend = 1,
};
module_usb_driver(my_driver);

Kullanışlı usbnet yardımcı fonksiyonları

FonksiyonAçıklama
usbnet_probe()Standart USB probe — çoğu mini-sürücü doğrudan kullanır
usbnet_disconnect()Cihaz ayrıldığında netdev kayıt silme ve URB temizleme
usbnet_skb_return()RX SKB'yi netif_rx'e teslim et
usbnet_get_endpoints()USB arayüzünden Bulk IN/OUT EP'leri otomatik bul
usbnet_read_cmd()USB Control okuma (vendor komutları için)
usbnet_write_cmd()USB Control yazma
usbnet_suspend()USB autosuspend — tüm URB'leri iptal, netif_stop_queue

04 Mini-sürücü yazımı: driver_info yapısı

Standart CDC protokolleriyle uyumlu olmayan özel bir USB ağ cihazı için minimal bir usbnet mini-sürücüsü nasıl yazılır?

Minimal mini-sürücü iskeleti

#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/usbnet.h>

/* bind: donanım başlat, endpoint'leri bul */
static int mydev_bind(struct usbnet *dev, struct usb_interface *intf)
{
    int ret;

    /* Standart endpoint keşfi */
    ret = usbnet_get_endpoints(dev, intf);
    if (ret)
        return ret;

    /* RX URB başına buffer boyutu */
    dev->rx_urb_size = dev->net->mtu + dev->net->hard_header_len + 8;

    /* Cihaz başlatma komutu (vendor-specific control transfer) */
    ret = usbnet_write_cmd(dev, 0x01, USB_DIR_OUT | USB_TYPE_VENDOR,
                           0x0000, 0x0000, NULL, 0);
    return ret;
}

/* rx_fixup: USB paketinden özel başlığı kaldır */
static int mydev_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
    /* Örnek: cihazımız 4 byte özel başlık ekliyor */
    if (skb->len < 4 + ETH_HLEN)
        return 0;   /* hatalı paket — at */

    skb_pull(skb, 4);   /* 4 byte başlığı kaldır */
    return 1;           /* 1: geçerli paket, ağ yığınına ilet */
}

/* tx_fixup: gönderilecek pakete özel başlık ekle */
static struct sk_buff *mydev_tx_fixup(struct usbnet *dev,
                                       struct sk_buff *skb, gfp_t flags)
{
    __le32 header;

    /* Başa 4 byte alan aç */
    if (skb_headroom(skb) < 4) {
        struct sk_buff *skb2 = skb_realloc_headroom(skb, 4);
        dev_kfree_skb_any(skb);
        if (!skb2)
            return NULL;
        skb = skb2;
    }

    skb_push(skb, 4);
    header = cpu_to_le32(skb->len - 4);   /* uzunluk alanı */
    memcpy(skb->data, &header, 4);
    return skb;
}

static const struct driver_info mydev_info = {
    .description = "MyDevice USB Ethernet",
    .flags       = FLAG_ETHER | FLAG_FRAMING_GL,
    .bind        = mydev_bind,
    .rx_fixup    = mydev_rx_fixup,
    .tx_fixup    = mydev_tx_fixup,
};

static const struct usb_device_id mydev_ids[] = {
    { USB_DEVICE(0x1234, 0x5678), .driver_info = (unsigned long)&mydev_info },
    {}
};
MODULE_DEVICE_TABLE(usb, mydev_ids);

static struct usb_driver mydev_driver = {
    .name         = "mydev_usbnet",
    .id_table     = mydev_ids,
    .probe        = usbnet_probe,
    .disconnect   = usbnet_disconnect,
    .suspend      = usbnet_suspend,
    .resume       = usbnet_resume,
    .supports_autosuspend = 1,
};
module_usb_driver(mydev_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MyDevice USB Ethernet mini-driver");

Kernal modülü derleme (out-of-tree)

# Makefile
obj-m := mydev_usbnet.o

KDIR ?= /lib/modules/$(shell uname -r)/build

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean

# Cross-compile (ARM64 hedef)
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- KDIR=/path/to/kernel make

05 rx_fixup ve tx_fixup — paket dönüşümü

rx_fixup ve tx_fixup, protokol kapsülleme farklarını usbnet çatısından gizleyen en kritik mini-sürücü fonksiyonlarıdır. Gerçek dünya örneklerine bakarak farklı yaklaşımlar inceleyelim.

CDC NCM: NTB çerçevesini parçalara ayırma (rx_fixup)

/* cdc_ncm.c'den basitleştirilmiş */
static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
    struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
    struct usb_cdc_ncm_nth16 *hdr;
    struct usb_cdc_ncm_ndp16 *ndp;
    int  ndpoffset, x, actlen;
    u16  wDatagramIndex, wDatagramLength;

    hdr = (struct usb_cdc_ncm_nth16 *)skb->data;
    /* NTH imzasını doğrula */
    if (hdr->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN))
        goto error;

    ndpoffset = le16_to_cpu(hdr->wNdpIndex);

    /* NTB içindeki her datagram için ayrı SKB oluştur */
    while (ndpoffset) {
        ndp = (struct usb_cdc_ncm_ndp16 *)(skb->data + ndpoffset);
        for (x = 0; x < (ndp->wLength / 4) - 1; x++) {
            wDatagramIndex  = le16_to_cpu(ndp->dpe16[x].wDatagramIndex);
            wDatagramLength = le16_to_cpu(ndp->dpe16[x].wDatagramLength);
            if (!wDatagramLength)
                break;
            /* Her datagram için yeni SKB */
            usbnet_skb_return(dev, netdev_alloc_skb_ip_align(dev->net,
                              wDatagramLength));
        }
        ndpoffset = le16_to_cpu(ndp->wNextNdpIndex);
    }
    return 1;
error:
    dev->net->stats.rx_errors++;
    return 0;
}

RNDIS: başlık doğrulama ve kaldırma (rx_fixup)

/* rndis_host.c'den */
static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
    /* RNDIS DATA mesajı: REMOTE_NDIS_PACKET_MSG */
    struct rndis_data_hdr *hdr = (struct rndis_data_hdr *)skb->data;
    u32 msg_type, msg_len, data_offset, data_len;

    msg_type   = le32_to_cpu(hdr->msg_type);
    msg_len    = le32_to_cpu(hdr->msg_len);
    data_offset = le32_to_cpu(hdr->data_offset);
    data_len   = le32_to_cpu(hdr->data_len);

    if (msg_type != RNDIS_MSG_PACKET)
        return 0;   /* kontrol mesajı — başka kanalda işle */

    /* Başlığı kaldır, sadece ethernet payload bırak */
    skb_pull(skb, 8 + data_offset);
    skb_trim(skb, data_len);
    return 1;
}

tx_fixup: SMSC LAN9500 özel başlık ekleme

/* smsc95xx.c'den basitleştirilmiş */
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
                                          struct sk_buff *skb, gfp_t flags)
{
    u32 tx_cmd_a, tx_cmd_b;

    /* TX Command başlığı için alan aç */
    if (skb_headroom(skb) < SMSC95XX_TX_OVERHEAD) {
        struct sk_buff *skb2 = skb_realloc_headroom(skb, SMSC95XX_TX_OVERHEAD);
        dev_kfree_skb_any(skb);
        if (!skb2)
            return NULL;
        skb = skb2;
    }

    tx_cmd_b = (u32)(skb->len);
    tx_cmd_a = tx_cmd_b | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;

    skb_push(skb, 4);
    cpu_to_le32s(&tx_cmd_b);
    memcpy(skb->data, &tx_cmd_b, 4);

    skb_push(skb, 4);
    cpu_to_le32s(&tx_cmd_a);
    memcpy(skb->data, &tx_cmd_a, 4);

    return skb;
}

06 Performans ayarı: tx_qlen, MTU, URB kuyruğu

USB ağ bağlantısının performansı, doğru URB kuyruk derinliği, MTU boyutu ve NCM agregasyon parametreleriyle önemli ölçüde artırılabilir.

tx_qlen — TX kuyruk derinliği

# tx_qlen: kaç URB'nin eş zamanlı gönderilmesine izin verilir
# Varsayılan: 4, maksimum: 32

# Çalışma zamanında değiştir
echo 16 > /sys/class/net/usb0/tx_queue_len

# veya usbnet modülü için sysfs
# /sys/bus/usb/devices/1-1.2:1.0/ altında
find /sys/bus/usb -name "tx_qlen" 2>/dev/null

MTU ayarı ve Jumbo frame

# USB Ethernet cihazlar genellikle 1500 byte MTU destekler
# Bazı CDC NCM cihazlar 9000+ (Jumbo) destekler

# MTU'yu artır (cihaz destekliyorsa)
ip link set usb0 mtu 4096

# MTU sınırını kernel'de kontrol et
ethtool -k usb0 | grep -i "scatter\|jumbo\|large"

# r8152 sürücüsü için Jumbo frame
ip link set eth0 mtu 9000   # RTL8153 USB3 Gigabit

NCM NTB maksimum boyutu

# CDC NCM — NTB (Network Transfer Block) boyutunu artır
# /sys/class/net/usb0/cdc_ncm/ altında

ls /sys/class/net/usb0/
# Alternatif: ethtool ile coalesce parametreleri
ethtool -C usb0 tx-frames 32 rx-frames 32

# NCM NTB max boyutu sysfs üzerinden
cat /sys/bus/usb/drivers/cdc_ncm/*/cdc_ncm/rx_max
echo 32768 > /sys/bus/usb/drivers/cdc_ncm/*/cdc_ncm/rx_max

iperf3 ile performans ölçümü

# Host tarafı (Windows veya Linux PC)
iperf3 -s

# Cihaz tarafı (Linux gadget)
iperf3 -c 192.168.7.1 -t 30 -P 4    # 4 paralel akış
iperf3 -c 192.168.7.1 -t 30 -R       # ters yön (upload)

# Tipik sonuçlar (USB 2.0 High-Speed, 480 Mbit/s fiziksel)
# RNDIS:    ~ 200-280 Mbit/s TCP
# CDC ECM:  ~ 250-300 Mbit/s TCP
# CDC NCM:  ~ 350-420 Mbit/s TCP (agregasyon avantajı)

CPU yük analizi

# IRQ/softirq dağılımı izle
watch -n 1 cat /proc/interrupts | grep usb
watch -n 1 cat /proc/softirqs | grep -E "NET_RX|NET_TX"

# perf ile USB ağ yük noktalarını bul
perf top -e cycles:u -p $(pgrep iperf3)
# Yoğun görülen semboller:
#   usbnet_start_xmit   ← TX giriş noktası
#   rx_complete          ← RX tamamlama callback
#   cdc_ncm_rx_fixup    ← NCM NTB ayrıştırma

07 Hata ayıklama: ethtool, sysfs, dynamic_debug

usbnet tabanlı bir sürücünün sorunlarını teşhis etmek için kernel dynamic debug altyapısı, ethtool istatistikleri ve USB izleme araçları birlikte kullanılır.

ethtool istatistikleri

# Ayrıntılı sürücü istatistikleri
ethtool -S usb0

# Örnek çıktı (smsc95xx)
# NIC statistics:
#      rx_fcs_errors: 0
#      rx_alignment_errors: 0
#      rx_dropped: 0
#      tx_dropped: 0
#      collisions: 0

# Bağlantı hızı ve durumu
ethtool usb0
# Speed: 100Mb/s
# Duplex: Full
# Link detected: yes

# Sürücü bilgisi
ethtool -i usb0
# driver: smsc95xx
# firmware-version: N/A
# bus-info: usb-3f980000.usb-1.1

dynamic_debug ile çalışma zamanı debug mesajları

# usbnet modülü için debug mesajlarını aç
echo "module usbnet +p" > /sys/kernel/debug/dynamic_debug/control

# Belirli bir dosya için
echo "file drivers/net/usb/usbnet.c +p" > /sys/kernel/debug/dynamic_debug/control

# smsc95xx modülü için
echo "module smsc95xx +p" > /sys/kernel/debug/dynamic_debug/control

# dmesg'de görünen debug mesajları:
dmesg | grep -E "usbnet|smsc95"
# usbnet: rx submit, 60 byte, flags=0x201
# usbnet: tx: start 1/16

sysfs üzerinden arayüz durumu

# Arayüz statistikleri
cat /sys/class/net/usb0/statistics/rx_bytes
cat /sys/class/net/usb0/statistics/tx_errors
cat /sys/class/net/usb0/statistics/collisions

# USB cihaz bilgileri
cat /sys/bus/usb/devices/1-1.2/idVendor
cat /sys/bus/usb/devices/1-1.2/idProduct
cat /sys/bus/usb/devices/1-1.2/speed       # 480 = High-Speed, 5000 = SuperSpeed
cat /sys/bus/usb/devices/1-1.2/manufacturer

Yaygın hata kalıpları

dmesg mesajı / belirtiAnlamÇözüm
usbnet: rx submit: -71EPROTO — USB protokol hatası, bağlantı kararsızUSB kablosu veya hub değiştir; powered hub kullan
usbnet: kevent 10 may have been droppedRX kuyruğu doldu — işlem geciktitx_qlen artır, CPU yükünü azalt
smsc95xx: Failed to read regUSB Control transfer başarısızcihaz resetle; modülü kaldır/yükle
Arayüz var ama IP alınmıyorcarrier down veya DHCP yanıt yokip link show usb0 ile LOWER_UP durumunu kontrol et
Rastgele kopuyorUSB autosuspend cihazı uyutuyorecho -1 > /sys/bus/usb/devices/1-X/power/autosuspend_delay_ms

USB autosuspend devre dışı bırakma

# Belirli cihaz için autosuspend kapat
echo -1 > /sys/bus/usb/devices/1-1.2/power/autosuspend_delay_ms

# udev kuralı ile kalıcı
# /etc/udev/rules.d/91-usb-noautosuspend.rules
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0424", \
  ATTRS{idProduct}=="9514", TEST=="power/autosuspend_delay_ms", \
  ATTR{power/autosuspend_delay_ms}="-1"

08 Gerçek dünya senaryoları: RPi, BBB, gömülü gateway

usbnet tabanlı sürücülerin yaygın gömülü Linux senaryolarında nasıl kullanıldığını, karşılaşılan pratik sorunları ve çözümlerini ele alalım.

Raspberry Pi 3B+ / 4 dahili USB Ethernet

# RPi 3B+: Microchip LAN7515 = USB3 hub + LAN7800 Ethernet
# Sürücü: lan78xx.ko (usbnet tabanlı)

# RPi 4: Broadcom BCM54213PE — PCIe üzerinden, usbnet DEĞİL
# RPi Zero / Zero W: USB OTG gadget modu kullanılır

# RPi 3B+ üzerinde lan78xx sürücüsü
dmesg | grep lan78
# lan78xx 1-1.1:1.0 eth0: register 'lan78xx' at usb-xhci-hcd.0-1.1

# lan78xx performans ayarı
ethtool -G eth0 rx 256 tx 256   # ring buffer büyüt
ethtool -C eth0 rx-usecs 100    # coalescing

BeagleBone Black — gadget + host aynı anda

# BBB: USB0 = gadget (bilgisayara bağlanır), USB1 = host (dongle takılır)

# USB0 gadget tarafı
# /opt/scripts/boot/autoconfigure_usb0.sh otomatik çalışır
# Windows: 192.168.7.2, macOS/Linux: 192.168.6.2

# USB1 host tarafına USB Ethernet dongle takılırsa
dmesg | grep asix   # ASIX dongle varsa
ip link show        # eth1 veya usb1 oluşur
udhcpc -i eth1      # DHCP

# BBB'yi Linux router yap
# eth0 (Ethernet) → usb0 (USB gadget) köprüsü
ip route add default via 192.168.7.1   # Windows gateway
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Gömülü gateway: LTE modem + usbnet

# Quectel EC25 LTE modem — qmi_wwan veya cdc_mbim sürücüsü
# qmi_wwan da usbnet tabanlıdır

# Modülleri yükle
modprobe qmi_wwan
modprobe option   # AT port için

# QMI ile bağlantı kur
apt install libqmi-utils udhcpc

qmicli -d /dev/cdc-wdm0 --dms-get-model
qmicli -d /dev/cdc-wdm0 --wds-start-network="apn=internet" --client-no-release-cid

udhcpc -i wwan0

# Bağlantı durumu izle
qmicli -d /dev/cdc-wdm0 --nas-get-signal-strength

USB Ethernet dongle seçim rehberi (gömülü projeler)

KullanımÖnerilen çipSürücüNot
USB 2.0, 100M, düşük maliyetASIX AX88772Basix.koÇok yaygın, iyi destekli
USB 3.0, GigabitRealtek RTL8153r8152.koRPi 4 aksesuarlarında yaygın
USB 3.0, Gigabit, yüksek performansASIX AX88179Aax88179_178a.koNAS/NVR gibi yoğun trafik
USB 3.1, 2.5GbEAquantia AQC111Uaqc111.koKernel 5.6+ gerektirir
LTE modem ağıQuectel EC25/EM06qmi_wwan.kolibqmi ile QMI protokolü

Üretimde dikkat edilecekler

VID:PID beyaz listesiudev kurallarıyla sadece onaylı dongle'ların ağa çıkmasına izin ver
Autosuspend politikasıKritik ağ bağlantılarında autosuspend'i kapat; pil varsa gereksinime göre ayarla
Watchdogusbnet link_reset periyodunu izle; kopan bağlantıyı yeniden kuran servisi systemd ile çalıştır
Firmware güncellemeBazı çipler (ASIX, Realtek) USB üzerinden firmware günceller — firmware.bin yolunu kontrol et