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
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ül | Protokol | Kullanım |
|---|---|---|
| cdc_ether.ko | CDC ECM (Ethernet Control Model) | Linux gadget ECM, iOS tethering (ipheth aracılığıyla) |
| cdc_ncm.ko | CDC NCM (Network Control Model) | Android 10+ tethering, Linux gadget NCM, modern dongle'lar |
| cdc_mbim.ko | MBIM (Mobile Broadband Interface Model) | 4G/5G USB modemler, Sierra Wireless, Quectel EC25 |
| rndis_host.ko | RNDIS (Microsoft tescilli) | Android tethering, Windows Phone, Linux RNDIS gadget |
| cdc_subset.ko | CDC subset (basitleştirilmiş) | Blink, Epson, Sharp özel USB NIC |
Üretici özel mini-sürücüleri
| Modül | Çip | Yaygın kullanım |
|---|---|---|
| asix.ko | ASIX AX88172/AX88772/AX88179 | USB 2.0 Ethernet dongle (100M/1G) |
| smsc95xx.ko | SMSC LAN9500/9512/9514 | Raspberry Pi 2B, Raspberry Pi B/B+ dahili USB hub |
| lan78xx.ko | Microchip LAN7800/7801 | Raspberry Pi 3B+, Raspberry Pi 4 dahili USB3 Ethernet |
| r8152.ko | Realtek RTL8152/RTL8153 | USB 3.0 Gigabit Ethernet dongle (TP-Link UE300 vb.) |
| ax88179_178a.ko | ASIX AX88179 | USB 3.0 Gigabit Ethernet dongle |
| qmi_wwan.ko | Qualcomm QMI modem | Quectel EC20/EC25/EM06, Sierra EM7455 (LTE) |
| aqc111.ko | Aquantia AQC111U | USB 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ı
| Fonksiyon | Açı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ı / belirti | Anlam | Çözüm |
|---|---|---|
usbnet: rx submit: -71 | EPROTO — USB protokol hatası, bağlantı kararsız | USB kablosu veya hub değiştir; powered hub kullan |
usbnet: kevent 10 may have been dropped | RX kuyruğu doldu — işlem gecikti | tx_qlen artır, CPU yükünü azalt |
smsc95xx: Failed to read reg | USB Control transfer başarısız | cihaz resetle; modülü kaldır/yükle |
| Arayüz var ama IP alınmıyor | carrier down veya DHCP yanıt yok | ip link show usb0 ile LOWER_UP durumunu kontrol et |
| Rastgele kopuyor | USB autosuspend cihazı uyutuyor | echo -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